1 | // |
2 | // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh) |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. |
5 | // https://www.boost.org/LICENSE_1_0.txt |
6 | |
7 | #ifndef BOOST_LOCALE_GENERATOR_HPP |
8 | #define BOOST_LOCALE_GENERATOR_HPP |
9 | |
10 | #include <boost/locale/hold_ptr.hpp> |
11 | #include <cstdint> |
12 | #include <locale> |
13 | #include <memory> |
14 | #include <string> |
15 | |
16 | #ifdef BOOST_MSVC |
17 | # pragma warning(push) |
18 | # pragma warning(disable : 4275 4251 4231 4660) |
19 | #endif |
20 | |
21 | namespace boost { |
22 | |
23 | /// |
24 | /// \brief This is the main namespace that encloses all localization classes |
25 | /// |
26 | namespace locale { |
27 | |
28 | class localization_backend; |
29 | class localization_backend_manager; |
30 | |
31 | /// Type that specifies the character type that locales can be generated for |
32 | /// |
33 | /// Supports bitwise OR and bitwise AND (the latter returning if the type is set) |
34 | enum class char_facet_t : uint32_t { |
35 | nochar = 0, ///< Unspecified character category for character independent facets |
36 | char_f = 1 << 0, ///< 8-bit character facets |
37 | wchar_f = 1 << 1, ///< wide character facets |
38 | #ifdef __cpp_char8_t |
39 | char8_f = 1 << 2, ///< C++20 char8_t facets |
40 | #endif |
41 | #ifdef BOOST_LOCALE_ENABLE_CHAR16_T |
42 | char16_f = 1 << 3, ///< C++11 char16_t facets |
43 | #endif |
44 | #ifdef BOOST_LOCALE_ENABLE_CHAR32_T |
45 | char32_f = 1 << 4, ///< C++11 char32_t facets |
46 | #endif |
47 | }; |
48 | typedef BOOST_DEPRECATED("Use char_facet_t" ) char_facet_t character_facet_type; |
49 | |
50 | /// First facet specific for character type |
51 | constexpr char_facet_t character_facet_first = char_facet_t::char_f; |
52 | /// Last facet specific for character type |
53 | constexpr char_facet_t character_facet_last = |
54 | #ifdef BOOST_LOCALE_ENABLE_CHAR32_T |
55 | char_facet_t::char32_f; |
56 | #elif defined BOOST_LOCALE_ENABLE_CHAR16_T |
57 | char_facet_t::char16_f; |
58 | #elif defined __cpp_char8_t |
59 | char_facet_t::char8_f; |
60 | #else |
61 | char_facet_t::wchar_f; |
62 | #endif |
63 | /// Special mask -- generate all |
64 | constexpr char_facet_t all_characters = char_facet_t(0xFFFFFFFFu); |
65 | |
66 | /// Type used for more fine grained generation of facets |
67 | /// |
68 | /// Supports bitwise OR and bitwise AND (the latter returning if the type is set) |
69 | enum class category_t : uint32_t { |
70 | convert = 1 << 0, ///< Generate conversion facets |
71 | collation = 1 << 1, ///< Generate collation facets |
72 | formatting = 1 << 2, ///< Generate numbers, currency, date-time formatting facets |
73 | parsing = 1 << 3, ///< Generate numbers, currency, date-time formatting facets |
74 | message = 1 << 4, ///< Generate message facets |
75 | codepage = 1 << 5, ///< Generate character set conversion facets (derived from std::codecvt) |
76 | boundary = 1 << 6, ///< Generate boundary analysis facet |
77 | calendar = 1 << 16, ///< Generate boundary analysis facet |
78 | information = 1 << 17, ///< Generate general locale information facet |
79 | }; |
80 | typedef BOOST_DEPRECATED("Use category_t" ) category_t locale_category_type; |
81 | |
82 | /// First facet specific for character |
83 | constexpr category_t per_character_facet_first = category_t::convert; |
84 | /// Last facet specific for character |
85 | constexpr category_t per_character_facet_last = category_t::boundary; |
86 | /// First character independent facet |
87 | constexpr category_t non_character_facet_first = category_t::calendar; |
88 | /// Last character independent facet |
89 | constexpr category_t non_character_facet_last = category_t::information; |
90 | /// First category facet |
91 | constexpr category_t category_first = category_t::convert; |
92 | /// Last category facet |
93 | constexpr category_t category_last = category_t::information; |
94 | /// Generate all of them |
95 | constexpr category_t all_categories = category_t(0xFFFFFFFFu); |
96 | |
97 | /// \brief the major class used for locale generation |
98 | /// |
99 | /// This class is used for specification of all parameters required for locale generation and |
100 | /// caching. This class const member functions are thread safe if locale class implementation is thread safe. |
101 | class BOOST_LOCALE_DECL generator { |
102 | public: |
103 | /// Create new generator using global localization_backend_manager |
104 | generator(); |
105 | /// Create new generator using specific localization_backend_manager |
106 | generator(const localization_backend_manager&); |
107 | |
108 | ~generator(); |
109 | |
110 | /// Set types of facets that should be generated, default all |
111 | void categories(category_t cats); |
112 | /// Get types of facets that should be generated, default all |
113 | category_t categories() const; |
114 | |
115 | /// Set the characters type for which the facets should be generated, default all supported |
116 | void characters(char_facet_t chars); |
117 | /// Get the characters type for which the facets should be generated, default all supported |
118 | char_facet_t characters() const; |
119 | |
120 | /// Add a new domain of messages that would be generated. It should be set in order to enable |
121 | /// messages support. |
122 | /// |
123 | /// Messages domain has following format: "name" or "name/encoding" |
124 | /// where name is the base name of the "mo" file where the catalog is stored |
125 | /// without ".mo" extension. For example for file \c /usr/share/locale/he/LC_MESSAGES/blog.mo |
126 | /// it would be \c blog. |
127 | /// |
128 | /// You can optionally specify the encoding of the keys in the sources by adding "/encoding_name" |
129 | /// For example blog/cp1255. |
130 | /// |
131 | /// If not defined all keys are assumed to be UTF-8 encoded. |
132 | /// |
133 | /// \note When you select a domain for the program using dgettext or message API, you |
134 | /// do not specify the encoding part. So for example if the provided |
135 | /// domain name was "blog/windows-1255" then for translation |
136 | /// you should use dgettext("blog","Hello") |
137 | void add_messages_domain(const std::string& domain); |
138 | |
139 | /// Set default message domain. If this member was not called, the first added messages domain is used. |
140 | /// If the domain \a domain is not added yet it is added. |
141 | void set_default_messages_domain(const std::string& domain); |
142 | |
143 | /// Remove all added domains from the list |
144 | void clear_domains(); |
145 | |
146 | /// Add a search path where dictionaries are looked in. |
147 | /// |
148 | /// \note |
149 | /// |
150 | /// - Under the Windows platform the path is treated as a path in the locale's encoding so |
151 | /// if you create locale "en_US.windows-1251" then path would be treated as cp1255, |
152 | /// and if it is en_US.UTF-8 it is treated as UTF-8. File name is always opened with |
153 | /// a wide file name as wide file names are the native file name on Windows. |
154 | /// |
155 | /// - Under POSIX platforms all paths passed as-is regardless of encoding as narrow |
156 | /// encodings are the native encodings for POSIX platforms. |
157 | /// |
158 | void add_messages_path(const std::string& path); |
159 | |
160 | /// Remove all added paths |
161 | void clear_paths(); |
162 | |
163 | /// Remove all cached locales |
164 | void clear_cache(); |
165 | |
166 | /// Turn locale caching ON |
167 | void locale_cache_enabled(bool on); |
168 | |
169 | /// Get locale cache option |
170 | bool locale_cache_enabled() const; |
171 | |
172 | /// Check if by default ANSI encoding is selected or UTF-8 onces. The default is false. |
173 | bool use_ansi_encoding() const; |
174 | |
175 | /// Select ANSI encodings as default system encoding rather then UTF-8 by default |
176 | /// under Windows. |
177 | /// |
178 | /// The default is the most portable and most powerful encoding, UTF-8, but the user |
179 | /// can select "system" one if dealing with legacy applications |
180 | void use_ansi_encoding(bool enc); |
181 | |
182 | /// Generate a locale with id \a id |
183 | std::locale generate(const std::string& id) const; |
184 | /// Generate a locale with id \a id. Use \a base as a locale to which all facets are added, |
185 | /// instead of std::locale::classic(). |
186 | std::locale generate(const std::locale& base, const std::string& id) const; |
187 | /// Shortcut to generate(id) |
188 | std::locale operator()(const std::string& id) const { return generate(id); } |
189 | |
190 | private: |
191 | void set_all_options(localization_backend& backend, const std::string& id) const; |
192 | |
193 | generator(const generator&); |
194 | void operator=(const generator&); |
195 | |
196 | struct data; |
197 | hold_ptr<data> d; |
198 | }; |
199 | |
200 | constexpr char_facet_t operator|(const char_facet_t lhs, const char_facet_t rhs) |
201 | { |
202 | return char_facet_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs)); |
203 | } |
204 | constexpr char_facet_t operator^(const char_facet_t lhs, const char_facet_t rhs) |
205 | { |
206 | return char_facet_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs)); |
207 | } |
208 | constexpr bool operator&(const char_facet_t lhs, const char_facet_t rhs) |
209 | { |
210 | return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u; |
211 | } |
212 | // Prefix increment: Return the next value |
213 | BOOST_CXX14_CONSTEXPR inline char_facet_t& operator++(char_facet_t& v) |
214 | { |
215 | return v = char_facet_t(static_cast<uint32_t>(v) ? static_cast<uint32_t>(v) << 1 : 1); |
216 | } |
217 | |
218 | constexpr category_t operator|(const category_t lhs, const category_t rhs) |
219 | { |
220 | return category_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs)); |
221 | } |
222 | constexpr category_t operator^(const category_t lhs, const category_t rhs) |
223 | { |
224 | return category_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs)); |
225 | } |
226 | constexpr bool operator&(const category_t lhs, const category_t rhs) |
227 | { |
228 | return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u; |
229 | } |
230 | // Prefix increment: Return the next value |
231 | BOOST_CXX14_CONSTEXPR inline category_t& operator++(category_t& v) |
232 | { |
233 | return v = category_t(static_cast<uint32_t>(v) << 1); |
234 | } |
235 | } // namespace locale |
236 | } // namespace boost |
237 | #ifdef BOOST_MSVC |
238 | # pragma warning(pop) |
239 | #endif |
240 | |
241 | #endif |
242 | |