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

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

Throw exceptions in preference to exit(-1)

File size: 5.2 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        enum property_kind_t {
34                NumericProperty, CodepointProperty, StringProperty, MiscellaneousProperty, EnumeratedProperty, CatalogProperty, BinaryProperty
35        };
36       
37        class PropertyObject {
38        public:
39//        enum class ClassTypeId : unsigned {
40//            NumericProperty, CodepointProperty, StringProperty, MiscellaneousProperty, EnumeratedProperty, CatalogProperty, BinaryProperty
41//        };
42//        inline ClassTypeId getClassTypeId() const {
43//            return mClassTypeId;
44//        }
45                PropertyObject(property_t p, property_kind_t k) : the_property(p), the_kind(k) {}
46               
47                property_t the_property;
48                property_kind_t the_kind;
49               
50                virtual UnicodeSet GetCodepointSet(std::string value_spec) = 0;
51        };
52       
53        class UnsupportedPropertyObject : public PropertyObject {
54        public:
55                UnsupportedPropertyObject(property_t p, property_kind_t k) : PropertyObject(p, k) {}
56                UnicodeSet GetCodepointSet(std::string value_spec);     
57        };
58       
59        UnicodeSet UnsupportedPropertyObject::GetCodepointSet(std::string value_spec) {
60                throw std::runtime_error("Property " + UCD::property_full_name[the_property] + " unsupported.");
61        }
62       
63        class EnumeratedPropertyObject : public PropertyObject {
64        public:
65               
66                EnumeratedPropertyObject(UCD::property_t p, 
67                                 const std::vector<std::string> enum_names,
68                                 const std::vector<std::string> names,
69                                         const std::unordered_map<std::string, int> aliases,
70                                         const std::vector<UnicodeSet> sets) : 
71                PropertyObject(p, EnumeratedProperty), property_value_enum_names(enum_names), property_value_full_names(names), property_value_aliases(aliases), aliases_initialized(false), property_value_sets(sets) {}
72                int GetPropertyValueEnumCode(std::string s);
73                UnicodeSet GetCodepointSet(std::string value_spec);     
74               
75        private:
76        const std::vector<std::string> property_value_enum_names;  // never changes
77        const std::vector<std::string> property_value_full_names;  // never changes
78                std::unordered_map<std::string, int> property_value_aliases;
79                bool aliases_initialized; // full names must be added dynamically.
80                std::vector<UnicodeSet> property_value_sets;                 
81        };
82       
83        UnicodeSet EnumeratedPropertyObject::GetCodepointSet(std::string value_spec) {
84                int property_enum_val = GetPropertyValueEnumCode(value_spec);
85                if (property_enum_val == -1) {
86                        throw std::runtime_error("Enumerated Property " + UCD::property_full_name[the_property] +  ": unknown value: " + value_spec);
87                }
88                else {
89                        //std::cout << "Enumerated Property: " << UCD::property_full_name[the_property] << ", value: " << property_value_full_names[property_enum_val] << "(" << property_enum_val << ").\n";
90                        return property_value_sets[property_enum_val];
91                }
92        }
93       
94        int EnumeratedPropertyObject::GetPropertyValueEnumCode(std::string s) {
95                // The canonical full names are not stored in the precomputed alias map,
96                // to save space in the executable.   Add them if the property is used.
97                if (!aliases_initialized) {
98            for (int v = 0; v < property_value_full_names.size(); v++) {
99                property_value_aliases.insert({canonicalize_value_name(property_value_full_names[v]), v});
100            }
101            for (int v = 0; v < property_value_enum_names.size(); v++) {
102                property_value_aliases.insert({canonicalize_value_name(property_value_enum_names[v]), v});
103            }
104                        aliases_initialized = true;
105                }
106                auto valit = property_value_aliases.find(s);
107                if (valit == property_value_aliases.end()) return -1;
108                else return valit->second;
109        }
110       
111        class BinaryPropertyObject : public PropertyObject {
112        public:
113                UnicodeSet the_codepoint_set;
114                BinaryPropertyObject(UCD::property_t p, UnicodeSet s) : PropertyObject(p, BinaryProperty), the_codepoint_set(s) {}
115                UnicodeSet GetCodepointSet(std::string value_spec);     
116        };
117       
118        UnicodeSet BinaryPropertyObject::GetCodepointSet(std::string value_spec) {
119                int property_enum_val = Binary_ns::Y; // default value
120                if (value_spec != "") {
121                        auto valit = Binary_ns::aliases_only_map.find(value_spec);
122                        if (valit == Binary_ns::aliases_only_map.end()) {
123                                throw std::runtime_error("Binary Property " + UCD::property_full_name[the_property] +  ": bad value: " + value_spec);
124                        }
125                        else property_enum_val = valit->second;
126                        if (property_enum_val == Binary_ns::Y) return the_codepoint_set;
127                        else return uset_complement(the_codepoint_set);
128                }
129        else return the_codepoint_set;
130        }
131}
132       
133#endif
Note: See TracBrowser for help on using the repository browser.