source: icGREP/icgrep-devel/icgrep/UCD/PropertyObjects.cpp @ 5234

Last change on this file since 5234 was 5234, checked in by nmedfort, 2 years ago

Modified memory alignment mechanism for GetPropertyValueGrepString? + misc. changes.

File size: 6.9 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters, Inc.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters, Inc.
5 *
6 */
7
8#include "PropertyObjects.h"
9#include "PropertyObjectTable.h"
10#include <llvm/Support/Casting.h>
11#include <algorithm>
12#include <assert.h>
13#include <sstream>
14
15using namespace llvm;
16
17namespace UCD {
18
19using PropertyStringStream =
20    std::basic_stringstream<char, std::char_traits<char>, PropertyStringAllocator>;
21
22std::string canonicalize_value_name(const std::string & prop_or_val) {
23    std::locale loc;
24    std::stringstream s;
25
26    for (char c : prop_or_val) {
27        if ((c != '_') && (c != ' ') && (c != '-')) {
28            s << std::tolower(c, loc);
29        }
30    }
31    return s.str();
32}
33
34int PropertyObject::GetPropertyValueEnumCode(const std::string & value_spec) {
35    throw std::runtime_error("Property " + value_spec + " unsupported.");
36}
37const PropertyString & PropertyObject::GetPropertyValueGrepString() {
38    throw std::runtime_error("Property Value Grep String unsupported.");
39}
40
41UnicodeSet UnsupportedPropertyObject::GetCodepointSet(const std::string &) {
42    throw std::runtime_error("Property " + UCD::property_full_name[the_property] + " unsupported.");
43}
44
45UnicodeSet UnsupportedPropertyObject::GetCodepointSet(const int) {
46    throw std::runtime_error("Property " + UCD::property_full_name[the_property] + " unsupported.");
47}
48
49const UnicodeSet & EnumeratedPropertyObject::GetCodepointSet(const std::string & value_spec) {
50    const int property_enum_val = GetPropertyValueEnumCode(value_spec);
51    if (property_enum_val < 0) {
52        throw std::runtime_error("Enumerated Property " + UCD::property_full_name[the_property] + ": unknown value: " + value_spec);
53    }
54    return GetCodepointSet(property_enum_val);
55}
56
57const UnicodeSet & EnumeratedPropertyObject::GetCodepointSet(const int property_enum_val) const {
58    assert (property_enum_val >= 0);
59    return *(property_value_sets[property_enum_val]);
60}
61
62std::vector<UnicodeSet> & EnumeratedPropertyObject::GetEnumerationBasisSets() {
63    // Return the previously computed vector of basis sets, if it exists.
64    if (LLVM_UNLIKELY(enumeration_basis_sets.empty())) {
65        // Otherwise compute and return.
66        // Basis set i is the set of all codepoints whose numerical enumeration code e
67        // has bit i set, i.e., (e >> i) & 1 == 1.
68        unsigned basis_count = 1;
69        while ((1UL << basis_count) < independent_enum_count) {
70            basis_count++;
71        }
72        for (unsigned i = 0; i < basis_count; i++) {
73            enumeration_basis_sets.push_back(UnicodeSet());
74            for (unsigned e = 0; e < independent_enum_count; e++) {
75                if (((e >> i) & 1UL) == 0) {
76                    enumeration_basis_sets[i] = enumeration_basis_sets[i] + *property_value_sets[e];
77                }
78            }
79        }
80    }
81    return enumeration_basis_sets;
82};
83
84const PropertyString &EnumeratedPropertyObject::GetPropertyValueGrepString() {
85    if (LLVM_LIKELY(property_value_grep_string.empty())) {
86        PropertyStringStream buffer;
87        for (unsigned i = 0; i != property_value_full_names.size(); i++) {
88            buffer << canonicalize_value_name(property_value_full_names[i]) + "\n";
89        }
90        for (unsigned i = 0; i != property_value_enum_names.size(); i++) {
91            buffer << canonicalize_value_name(property_value_enum_names[i]) + "\n";
92        }
93        property_value_grep_string.assign(buffer.str());
94    }
95    return property_value_grep_string;
96}
97
98int EnumeratedPropertyObject::GetPropertyValueEnumCode(const std::string & value_spec) {
99    // The canonical full names are not stored in the precomputed alias map,
100    // to save space in the executable.   Add them if the property is used.
101    if (uninitialized) {
102        for (unsigned i = 0; i != property_value_full_names.size(); i++) {
103            property_value_aliases.insert({canonicalize_value_name(property_value_full_names[i]), i});
104        }
105        for (unsigned i = 0; i != property_value_enum_names.size(); i++) {
106            property_value_aliases.insert({canonicalize_value_name(property_value_enum_names[i]), i});
107        }
108        uninitialized = false;
109    }
110    const auto valit = property_value_aliases.find(value_spec);
111    if (valit == property_value_aliases.end())
112        return -1;
113    return valit->second;
114}
115
116PropertyObject::iterator ExtensionPropertyObject::begin() const {
117    if (const auto * obj = dyn_cast<EnumeratedPropertyObject>(property_object_table[base_property])) {
118        return obj->begin();
119    }
120    throw std::runtime_error("Iterators unsupported for this type of PropertyObject.");
121}
122
123PropertyObject::iterator ExtensionPropertyObject::end() const {
124    if (const auto * obj = dyn_cast<EnumeratedPropertyObject>(property_object_table[base_property])) {
125        return obj->end();
126    }
127    throw std::runtime_error("Iterators unsupported for this type of PropertyObject.");
128}
129
130const UnicodeSet & ExtensionPropertyObject::GetCodepointSet(const std::string & value_spec) {
131    int property_enum_val = GetPropertyValueEnumCode(value_spec);
132    if (property_enum_val == -1) {
133        throw std::runtime_error("Extension Property " + UCD::property_full_name[the_property] +  ": unknown value: " + value_spec);
134    }
135    return GetCodepointSet(property_enum_val);
136}
137
138const UnicodeSet & ExtensionPropertyObject::GetCodepointSet(const int property_enum_val) const {
139    assert (property_enum_val >= 0);
140    return *(property_value_sets[property_enum_val]);
141}
142
143int ExtensionPropertyObject::GetPropertyValueEnumCode(const std::string & value_spec) {
144    return property_object_table[base_property]->GetPropertyValueEnumCode(value_spec);
145}
146
147const PropertyString & ExtensionPropertyObject::GetPropertyValueGrepString() {
148    return property_object_table[base_property]->GetPropertyValueGrepString();
149}
150
151const UnicodeSet & BinaryPropertyObject::GetCodepointSet(const std::string & value_spec) {
152    int property_enum_val = Binary_ns::Y;
153    if (value_spec.length() != 0) {
154        auto valit = Binary_ns::aliases_only_map.find(value_spec);
155        if (valit == Binary_ns::aliases_only_map.end()) {
156            throw std::runtime_error("Binary Property " + UCD::property_full_name[the_property] +  ": bad value: " + value_spec);
157        }
158        property_enum_val = valit->second;
159    }
160    return GetCodepointSet(property_enum_val);
161}
162
163const UnicodeSet & BinaryPropertyObject::GetCodepointSet(const int property_enum_val) {
164    if (property_enum_val == Binary_ns::Y) {
165        return mY;
166    }
167    if (mNoUninitialized) {
168        mN = ~mY;
169        mNoUninitialized = false;
170    }
171    return mN;
172}
173
174const PropertyString & BinaryPropertyObject::GetPropertyValueGrepString() {
175    if (property_value_grep_string.empty()) {
176        PropertyStringStream buffer;
177        for (const auto & prop : Binary_ns::aliases_only_map) {
178            buffer << std::get<0>(prop) + "\n";
179        }
180        property_value_grep_string.assign(buffer.str());
181    }
182    return property_value_grep_string;
183}
184
185}
Note: See TracBrowser for help on using the repository browser.