source: icGREP/icgrep-devel/icgrep/UCD/PropertyObjects.h @ 4435

Last change on this file since 4435 was 4435, checked in by cameron, 5 years ago

Switch to dyn_cast system for PropertyObjects?

File size: 5.8 KB
RevLine 
[4189]1#ifndef PROPERTYOBJECTS_H
2#define PROPERTYOBJECTS_H
3/*
4 *  Copyright (c) 2014 International Characters, Inc.
5 *  This software is licensed to the public under the Open Software License 3.0.
6 *  icgrep is a trademark of International Characters, Inc.
7 *
8 */
9
10#include <string>
11#include <vector>
[4380]12#include <iostream>
[4189]13#include <unordered_map>
[4431]14#include <stdexcept>
[4189]15#include "unicode_set.h"
16#include "PropertyAliases.h"
17#include "PropertyValueAliases.h"
18
19std::string canonicalize_value_name(std::string prop_or_val) {
20        std::locale loc;
21        std::string s = "";
22        for (unsigned int i = 0; i < prop_or_val.length(); ++i) {
23                char c = prop_or_val.at(i);
[4380]24                if ((c != '_') && (c != ' ') && (c != '-')) {
[4189]25                        s += std::tolower(c, loc);
26                }
27        }
[4380]28        return s;
[4189]29}
30
31
32namespace UCD {
[4435]33   
[4189]34        class PropertyObject {
35        public:
[4435]36        enum class ClassTypeId : unsigned {
37            NumericProperty, CodepointProperty, StringProperty, MiscellaneousProperty, EnumeratedProperty, CatalogProperty, BinaryProperty,  UnsupportedProperty
38        };
39        inline ClassTypeId getClassTypeId() const {
40            return the_kind;
41        }
42                PropertyObject(property_t p, ClassTypeId k) : the_property(p), the_kind(k) {}
43       
[4189]44                property_t the_property;
[4435]45                ClassTypeId the_kind;
[4189]46               
[4380]47                virtual UnicodeSet GetCodepointSet(std::string value_spec) = 0;
[4189]48        };
49       
50        class UnsupportedPropertyObject : public PropertyObject {
51        public:
[4435]52        static inline bool classof(const PropertyObject * p) {
53            return p->getClassTypeId() == ClassTypeId::UnsupportedProperty;
54        }
55        static inline bool classof(const void *) {
56            return false;
57        }
58       
59                UnsupportedPropertyObject(property_t p, ClassTypeId k) : PropertyObject(p, k) {}
[4189]60                UnicodeSet GetCodepointSet(std::string value_spec);     
61        };
62       
63        UnicodeSet UnsupportedPropertyObject::GetCodepointSet(std::string value_spec) {
[4431]64                throw std::runtime_error("Property " + UCD::property_full_name[the_property] + " unsupported.");
[4189]65        }
66       
67        class EnumeratedPropertyObject : public PropertyObject {
68        public:
[4435]69        static inline bool classof(const PropertyObject * p) {
70            return p->getClassTypeId() == ClassTypeId::EnumeratedProperty;
71        }
72        static inline bool classof(const void *) {
73            return false;
74        }
[4189]75               
76                EnumeratedPropertyObject(UCD::property_t p, 
[4380]77                                 const std::vector<std::string> enum_names,
78                                 const std::vector<std::string> names,
[4189]79                                         const std::unordered_map<std::string, int> aliases,
80                                         const std::vector<UnicodeSet> sets) : 
[4435]81                PropertyObject(p, ClassTypeId::EnumeratedProperty), property_value_enum_names(enum_names), property_value_full_names(names), property_value_aliases(aliases), aliases_initialized(false), property_value_sets(sets) {}
[4189]82                int GetPropertyValueEnumCode(std::string s);
83                UnicodeSet GetCodepointSet(std::string value_spec);     
84               
85        private:
[4380]86        const std::vector<std::string> property_value_enum_names;  // never changes
87        const std::vector<std::string> property_value_full_names;  // never changes
88                std::unordered_map<std::string, int> property_value_aliases;
[4189]89                bool aliases_initialized; // full names must be added dynamically.
90                std::vector<UnicodeSet> property_value_sets;                 
91        };
92       
93        UnicodeSet EnumeratedPropertyObject::GetCodepointSet(std::string value_spec) {
94                int property_enum_val = GetPropertyValueEnumCode(value_spec);
95                if (property_enum_val == -1) {
[4431]96                        throw std::runtime_error("Enumerated Property " + UCD::property_full_name[the_property] +  ": unknown value: " + value_spec);
[4189]97                }
98                else {
[4431]99                        //std::cout << "Enumerated Property: " << UCD::property_full_name[the_property] << ", value: " << property_value_full_names[property_enum_val] << "(" << property_enum_val << ").\n";
[4189]100                        return property_value_sets[property_enum_val];
101                }
102        }
103       
104        int EnumeratedPropertyObject::GetPropertyValueEnumCode(std::string s) {
105                // The canonical full names are not stored in the precomputed alias map,
106                // to save space in the executable.   Add them if the property is used.
107                if (!aliases_initialized) {
[4380]108            for (int v = 0; v < property_value_full_names.size(); v++) {
109                property_value_aliases.insert({canonicalize_value_name(property_value_full_names[v]), v});
110            }
111            for (int v = 0; v < property_value_enum_names.size(); v++) {
112                property_value_aliases.insert({canonicalize_value_name(property_value_enum_names[v]), v});
113            }
[4189]114                        aliases_initialized = true;
115                }
116                auto valit = property_value_aliases.find(s);
117                if (valit == property_value_aliases.end()) return -1;
118                else return valit->second;
119        }
120       
121        class BinaryPropertyObject : public PropertyObject {
122        public:
[4435]123        static inline bool classof(const PropertyObject * p) {
124            return p->getClassTypeId() == ClassTypeId::BinaryProperty;
125        }
126        static inline bool classof(const void *) {
127            return false;
128        }
129               
130                BinaryPropertyObject(UCD::property_t p, UnicodeSet s) : PropertyObject(p, ClassTypeId::BinaryProperty), the_codepoint_set(s) {}
[4189]131                UnicodeSet GetCodepointSet(std::string value_spec);     
[4435]132    private:
133                UnicodeSet the_codepoint_set;       
[4189]134        };
135       
136        UnicodeSet BinaryPropertyObject::GetCodepointSet(std::string value_spec) {
[4380]137                int property_enum_val = Binary_ns::Y; // default value
[4189]138                if (value_spec != "") {
[4380]139                        auto valit = Binary_ns::aliases_only_map.find(value_spec);
140                        if (valit == Binary_ns::aliases_only_map.end()) {
[4431]141                                throw std::runtime_error("Binary Property " + UCD::property_full_name[the_property] +  ": bad value: " + value_spec);
[4189]142                        }
143                        else property_enum_val = valit->second;
[4380]144                        if (property_enum_val == Binary_ns::Y) return the_codepoint_set;
[4189]145                        else return uset_complement(the_codepoint_set);
146                }
[4380]147        else return the_codepoint_set;
[4189]148        }
149}
150       
151#endif
Note: See TracBrowser for help on using the repository browser.