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

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

Switch to dyn_cast system for PropertyObjects?

File size: 5.8 KB
Line 
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>
12#include <iostream>
13#include <unordered_map>
14#include <stdexcept>
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);
24                if ((c != '_') && (c != ' ') && (c != '-')) {
25                        s += std::tolower(c, loc);
26                }
27        }
28        return s;
29}
30
31
32namespace UCD {
33   
34        class PropertyObject {
35        public:
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       
44                property_t the_property;
45                ClassTypeId the_kind;
46               
47                virtual UnicodeSet GetCodepointSet(std::string value_spec) = 0;
48        };
49       
50        class UnsupportedPropertyObject : public PropertyObject {
51        public:
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) {}
60                UnicodeSet GetCodepointSet(std::string value_spec);     
61        };
62       
63        UnicodeSet UnsupportedPropertyObject::GetCodepointSet(std::string value_spec) {
64                throw std::runtime_error("Property " + UCD::property_full_name[the_property] + " unsupported.");
65        }
66       
67        class EnumeratedPropertyObject : public PropertyObject {
68        public:
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        }
75               
76                EnumeratedPropertyObject(UCD::property_t p, 
77                                 const std::vector<std::string> enum_names,
78                                 const std::vector<std::string> names,
79                                         const std::unordered_map<std::string, int> aliases,
80                                         const std::vector<UnicodeSet> sets) : 
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) {}
82                int GetPropertyValueEnumCode(std::string s);
83                UnicodeSet GetCodepointSet(std::string value_spec);     
84               
85        private:
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;
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) {
96                        throw std::runtime_error("Enumerated Property " + UCD::property_full_name[the_property] +  ": unknown value: " + value_spec);
97                }
98                else {
99                        //std::cout << "Enumerated Property: " << UCD::property_full_name[the_property] << ", value: " << property_value_full_names[property_enum_val] << "(" << property_enum_val << ").\n";
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) {
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            }
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:
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) {}
131                UnicodeSet GetCodepointSet(std::string value_spec);     
132    private:
133                UnicodeSet the_codepoint_set;       
134        };
135       
136        UnicodeSet BinaryPropertyObject::GetCodepointSet(std::string value_spec) {
137                int property_enum_val = Binary_ns::Y; // default value
138                if (value_spec != "") {
139                        auto valit = Binary_ns::aliases_only_map.find(value_spec);
140                        if (valit == Binary_ns::aliases_only_map.end()) {
141                                throw std::runtime_error("Binary Property " + UCD::property_full_name[the_property] +  ": bad value: " + value_spec);
142                        }
143                        else property_enum_val = valit->second;
144                        if (property_enum_val == Binary_ns::Y) return the_codepoint_set;
145                        else return uset_complement(the_codepoint_set);
146                }
147        else return the_codepoint_set;
148        }
149}
150       
151#endif
Note: See TracBrowser for help on using the repository browser.