Skip to content

Commit

Permalink
Use enum classes for facet types
Browse files Browse the repository at this point in the history
Changes `character_facet_type` & `locale_category_type` to the enum classes `char_facet_t` & `category_t`
This avoids a name clash with e.g. `calendar_facet` but is a breaking change
  • Loading branch information
Flamefire committed Oct 24, 2022
1 parent 64ad69c commit e5ed439
Show file tree
Hide file tree
Showing 34 changed files with 478 additions and 308 deletions.
23 changes: 13 additions & 10 deletions doc/changelog.txt
Expand Up @@ -9,16 +9,19 @@
\page changelog Changelog

- 1.81.0
- Require C++11 or higher
- Modernize code (C++11 features instead of Boost replacements, consistent formatting)
- Error on use of `-sICU_LINK_LOCALE` and `-sICU_LINK`, use `-sICU_*_NAME` when `-sICU_PATH` is not enough
- Fix build on macOS with iconv
- Fix int-overflow on negative roll of years in `date_time`
- Assume and use UTF-16 encoding for Windows `wchar_t-codecvt`
- Fix rounding issues with calendar time
- Make `basic_format` movable allowing it to be returned from functions
- Fix conversion of e.g. codepage iso-2022-jp on Windows
- Add more Windows codepages, e.g. cp1025, and various ISO and IBM codepages
- Breaking changes
- Require C++11 or higher
- Modernize code (C++11 features instead of Boost replacements, consistent formatting)
- Error on use of `-sICU_LINK_LOCALE` and `-sICU_LINK`, use `-sICU_*_NAME` when `-sICU_PATH` is not enough
- Convert `character_facet_type` & `locale_category_type` to the enum classes `char_facet_t` & `category_t`
- Other improvements and fixes
- Fix build on macOS with iconv
- Fix int-overflow on negative roll of years in `date_time`
- Assume and use UTF-16 encoding for Windows `wchar_t-codecvt`
- Fix rounding issues with calendar time
- Make `basic_format` movable allowing it to be returned from functions
- Fix conversion of e.g. codepage iso-2022-jp on Windows
- Add more Windows codepages, e.g. cp1025, and various ISO and IBM codepages
- 1.80.0
- Deprecated support for C++03 and earlier, C++11 will be required in the next release
- Provide `-sICU_LINK_LOCALE` as a temporary replacement for `-sICU_LINK` which is incompatible with Boost.Regex.
Expand Down
2 changes: 1 addition & 1 deletion doc/locale_gen.txt
Expand Up @@ -63,7 +63,7 @@ For example:

\code
generator gen;
gen.characters(wchar_t_facet);
gen.characters(char_facet_t::wchar_f);
gen.categories(collation_facet | formatting_facet);
std::locale::global(gen("de_DE.UTF-8"));
\endcode
Expand Down
124 changes: 86 additions & 38 deletions include/boost/locale/generator.hpp
Expand Up @@ -28,47 +28,60 @@ namespace locale {
class localization_backend;
class localization_backend_manager;

constexpr uint32_t nochar_facet = 0; ///< Unspecified character category for character independent facets
constexpr uint32_t char_facet = 1 << 0; ///< 8-bit character facets
constexpr uint32_t wchar_t_facet = 1 << 1; ///< wide character facets
constexpr uint32_t char16_t_facet = 1 << 2; ///< C++11 char16_t facets
constexpr uint32_t char32_t_facet = 1 << 3; ///< C++11 char32_t facets

constexpr uint32_t character_first_facet = char_facet; ///< First facet specific for character type
constexpr uint32_t character_last_facet = char32_t_facet; ///< Last facet specific for character type
constexpr uint32_t all_characters = 0xFFFF; ///< Special mask -- generate all

typedef uint32_t character_facet_type; ///< type that specifies the character type that locales can be generated for

constexpr uint32_t convert_facet = 1 << 0; ///< Generate conversion facets
constexpr uint32_t collation_facet = 1 << 1; ///< Generate collation facets
constexpr uint32_t formatting_facet = 1 << 2; ///< Generate numbers, currency, date-time formatting facets
constexpr uint32_t parsing_facet = 1 << 3; ///< Generate numbers, currency, date-time formatting facets
constexpr uint32_t message_facet = 1 << 4; ///< Generate message facets
constexpr uint32_t codepage_facet = 1
<< 5; ///< Generate character set conversion facets (derived from std::codecvt)
constexpr uint32_t boundary_facet = 1 << 6; ///< Generate boundary analysis facet

constexpr uint32_t per_character_facet_first = convert_facet; ///< First facet specific for character
constexpr uint32_t per_character_facet_last = boundary_facet; ///< Last facet specific for character

constexpr uint32_t calendar_facet = 1 << 16; ///< Generate boundary analysis facet
constexpr uint32_t information_facet = 1 << 17; ///< Generate general locale information facet

constexpr uint32_t non_character_facet_first = calendar_facet; ///< First character independent facet
constexpr uint32_t non_character_facet_last = information_facet; ///< Last character independent facet

constexpr uint32_t all_categories = 0xFFFFFFFFu; ///< Generate all of them
/// Type that specifies the character type that locales can be generated for
///
/// Supports bitwise OR and bitwise AND (the latter returning if the type is set)
enum class char_facet_t : uint32_t {
nochar = 0, ///< Unspecified character category for character independent facets
char_f = 1 << 0, ///< 8-bit character facets
wchar_f = 1 << 1, ///< wide character facets
char16_f = 1 << 2, ///< C++11 char16_t facets
char32_f = 1 << 3, ///< C++11 char32_t facets
};
typedef BOOST_DEPRECATED("Use char_facet_t") char_facet_t character_facet_type;

typedef uint32_t locale_category_type; ///< a type used for more fine grained generation of facets
/// First facet specific for character type
constexpr char_facet_t character_facet_first = char_facet_t::char_f;
/// Last facet specific for character type
constexpr char_facet_t character_facet_last = char_facet_t::char32_f;
/// Special mask -- generate all
constexpr char_facet_t all_characters = char_facet_t(0xFFFFFFFFu);

/// Type used for more fine grained generation of facets
///
/// Supports bitwise OR and bitwise AND (the latter returning if the type is set)
enum class category_t : uint32_t {
convert = 1 << 0, ///< Generate conversion facets
collation = 1 << 1, ///< Generate collation facets
formatting = 1 << 2, ///< Generate numbers, currency, date-time formatting facets
parsing = 1 << 3, ///< Generate numbers, currency, date-time formatting facets
message = 1 << 4, ///< Generate message facets
codepage = 1 << 5, ///< Generate character set conversion facets (derived from std::codecvt)
boundary = 1 << 6, ///< Generate boundary analysis facet
calendar = 1 << 16, ///< Generate boundary analysis facet
information = 1 << 17, ///< Generate general locale information facet
};
typedef BOOST_DEPRECATED("Use category_t") category_t locale_category_type;

/// First facet specific for character
constexpr category_t per_character_facet_first = category_t::convert;
/// Last facet specific for character
constexpr category_t per_character_facet_last = category_t::boundary;
/// First character independent facet
constexpr category_t non_character_facet_first = category_t::calendar;
/// Last character independent facet
constexpr category_t non_character_facet_last = category_t::information;
/// First category facet
constexpr category_t category_first = category_t::convert;
/// Last category facet
constexpr category_t category_last = category_t::information;
/// Generate all of them
constexpr category_t all_categories = category_t(0xFFFFFFFFu);

/// \brief the major class used for locale generation
///
/// This class is used for specification of all parameters required for locale generation and
/// caching. This class const member functions are thread safe if locale class implementation is thread safe.
///

class BOOST_LOCALE_DECL generator {
public:
///
Expand All @@ -85,20 +98,20 @@ namespace locale {
///
/// Set types of facets that should be generated, default all
///
void categories(locale_category_type cats);
void categories(category_t cats);
///
/// Get types of facets that should be generated, default all
///
locale_category_type categories() const;
category_t categories() const;

///
/// Set the characters type for which the facets should be generated, default all supported
///
void characters(character_facet_type chars);
void characters(char_facet_t chars);
///
/// Get the characters type for which the facets should be generated, default all supported
///
character_facet_type characters() const;
char_facet_t characters() const;

///
/// Add a new domain of messages that would be generated. It should be set in order to enable
Expand Down Expand Up @@ -216,6 +229,41 @@ namespace locale {
hold_ptr<data> d;
};

constexpr char_facet_t operator|(const char_facet_t lhs, const char_facet_t rhs)
{
return char_facet_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
}
constexpr char_facet_t operator^(const char_facet_t lhs, const char_facet_t rhs)
{
return char_facet_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs));
}
constexpr bool operator&(const char_facet_t lhs, const char_facet_t rhs)
{
return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u;
}
// Prefix increment: Return the next value
BOOST_CXX14_CONSTEXPR inline char_facet_t& operator++(char_facet_t& v)
{
return v = char_facet_t(static_cast<uint32_t>(v) ? static_cast<uint32_t>(v) << 1 : 1);
}

constexpr category_t operator|(const category_t lhs, const category_t rhs)
{
return category_t(static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs));
}
constexpr category_t operator^(const category_t lhs, const category_t rhs)
{
return category_t(static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs));
}
constexpr bool operator&(const category_t lhs, const category_t rhs)
{
return (static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs)) != 0u;
}
// Prefix increment: Return the next value
BOOST_CXX14_CONSTEXPR inline category_t& operator++(category_t& v)
{
return v = category_t(static_cast<uint32_t>(v) << 1);
}
} // namespace locale
} // namespace boost
#ifdef BOOST_MSVC
Expand Down
5 changes: 2 additions & 3 deletions include/boost/locale/localization_backend.hpp
Expand Up @@ -68,8 +68,7 @@ namespace boost { namespace locale {
///
/// Create a facet for category \a category and character type \a type
///
virtual std::locale
install(const std::locale& base, locale_category_type category, character_facet_type type = nochar_facet) = 0;
virtual std::locale install(const std::locale& base, category_t category, char_facet_t type) = 0;

}; // localization_backend

Expand Down Expand Up @@ -139,7 +138,7 @@ namespace boost { namespace locale {
/// Select specific backend by name for a category \a category. It allows combining different
/// backends for user preferences.
///
void select(const std::string& backend_name, locale_category_type category = all_categories);
void select(const std::string& backend_name, category_t category = all_categories);

///
/// Set new global backend manager, the old one is returned.
Expand Down
11 changes: 4 additions & 7 deletions include/boost/locale/util.hpp
Expand Up @@ -202,12 +202,10 @@ namespace boost { namespace locale {
/// of wide encoding type
///
BOOST_LOCALE_DECL
std::locale
create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt, character_facet_type type);
std::locale create_codecvt(const std::locale& in, std::unique_ptr<base_converter> cvt, char_facet_t type);

BOOST_DEPRECATED("This function is deprecated, use 'create_codecvt()'")
inline std::locale
create_codecvt_from_pointer(const std::locale& in, base_converter* cvt, character_facet_type type)
inline std::locale create_codecvt_from_pointer(const std::locale& in, base_converter* cvt, char_facet_t type)
{
return create_codecvt(in, std::unique_ptr<base_converter>(cvt), type);
}
Expand All @@ -231,7 +229,7 @@ namespace boost { namespace locale {
/// new locale that is based on \a in and uses new facet.
///
BOOST_LOCALE_DECL
std::locale create_utf8_codecvt(const std::locale& in, character_facet_type type);
std::locale create_utf8_codecvt(const std::locale& in, char_facet_t type);

///
/// This function installs codecvt that can be used for conversion between single byte
Expand All @@ -240,8 +238,7 @@ namespace boost { namespace locale {
/// Throws boost::locale::conv::invalid_charset_error if the chacater set is not supported or isn't single byte
/// character set
BOOST_LOCALE_DECL
std::locale
create_simple_codecvt(const std::locale& in, const std::string& encoding, character_facet_type type);
std::locale create_simple_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type);
} // namespace util
}} // namespace boost::locale

Expand Down
14 changes: 7 additions & 7 deletions src/boost/locale/icu/all_generator.hpp
Expand Up @@ -11,13 +11,13 @@

namespace boost { namespace locale { namespace impl_icu {
struct cdata;
std::locale create_convert(const std::locale&, const cdata&, character_facet_type); // ok
std::locale create_collate(const std::locale&, const cdata&, character_facet_type); // ok
std::locale create_formatting(const std::locale&, const cdata&, character_facet_type); // ok
std::locale create_parsing(const std::locale&, const cdata&, character_facet_type); // ok
std::locale create_codecvt(const std::locale&, const std::string& encoding, character_facet_type); // ok
std::locale create_boundary(const std::locale&, const cdata&, character_facet_type); // ok
std::locale create_calendar(const std::locale&, const cdata&); // ok
std::locale create_convert(const std::locale&, const cdata&, char_facet_t); // ok
std::locale create_collate(const std::locale&, const cdata&, char_facet_t); // ok
std::locale create_formatting(const std::locale&, const cdata&, char_facet_t); // ok
std::locale create_parsing(const std::locale&, const cdata&, char_facet_t); // ok
std::locale create_codecvt(const std::locale&, const std::string& encoding, char_facet_t); // ok
std::locale create_boundary(const std::locale&, const cdata&, char_facet_t); // ok
std::locale create_calendar(const std::locale&, const cdata&); // ok

}}} // namespace boost::locale::impl_icu

Expand Down
10 changes: 5 additions & 5 deletions src/boost/locale/icu/boundary.cpp
Expand Up @@ -193,17 +193,17 @@ namespace boost { namespace locale {
}} // namespace boundary::impl_icu

namespace impl_icu {
std::locale create_boundary(const std::locale& in, const cdata& cd, character_facet_type type)
std::locale create_boundary(const std::locale& in, const cdata& cd, char_facet_t type)
{
using namespace boost::locale::boundary::impl_icu;
switch(type) {
case char_facet: return std::locale(in, new boundary_indexing_impl<char>(cd));
case wchar_t_facet: return std::locale(in, new boundary_indexing_impl<wchar_t>(cd));
case char_facet_t::char_f: return std::locale(in, new boundary_indexing_impl<char>(cd));
case char_facet_t::wchar_f: return std::locale(in, new boundary_indexing_impl<wchar_t>(cd));
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
case char16_t_facet: return std::locale(in, new boundary_indexing_impl<char16_t>(cd));
case char_facet_t::char16_f: return std::locale(in, new boundary_indexing_impl<char16_t>(cd));
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
case char32_t_facet: return std::locale(in, new boundary_indexing_impl<char32_t>(cd));
case char_facet_t::char32_f: return std::locale(in, new boundary_indexing_impl<char32_t>(cd));
#endif
default: return in;
}
Expand Down
2 changes: 1 addition & 1 deletion src/boost/locale/icu/codecvt.cpp
Expand Up @@ -108,7 +108,7 @@ namespace boost { namespace locale { namespace impl_icu {
}
}

std::locale create_codecvt(const std::locale& in, const std::string& encoding, character_facet_type type)
std::locale create_codecvt(const std::locale& in, const std::string& encoding, char_facet_t type)
{
if(conv::impl::normalize_encoding(encoding.c_str()) == "utf8")
return util::create_utf8_codecvt(in, type);
Expand Down
10 changes: 5 additions & 5 deletions src/boost/locale/icu/collator.cpp
Expand Up @@ -174,16 +174,16 @@ namespace boost { namespace locale { namespace impl_icu {
}
#endif

std::locale create_collate(const std::locale& in, const cdata& cd, character_facet_type type)
std::locale create_collate(const std::locale& in, const cdata& cd, char_facet_t type)
{
switch(type) {
case char_facet: return std::locale(in, new collate_impl<char>(cd));
case wchar_t_facet: return std::locale(in, new collate_impl<wchar_t>(cd));
case char_facet_t::char_f: return std::locale(in, new collate_impl<char>(cd));
case char_facet_t::wchar_f: return std::locale(in, new collate_impl<wchar_t>(cd));
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
case char16_t_facet: return std::locale(in, new collate_impl<char16_t>(cd));
case char_facet_t::char16_f: return std::locale(in, new collate_impl<char16_t>(cd));
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
case char32_t_facet: return std::locale(in, new collate_impl<char32_t>(cd));
case char_facet_t::char32_f: return std::locale(in, new collate_impl<char32_t>(cd));
#endif
default: return in;
}
Expand Down
10 changes: 5 additions & 5 deletions src/boost/locale/icu/conversion.cpp
Expand Up @@ -165,21 +165,21 @@ namespace boost { namespace locale { namespace impl_icu {

#endif // BOOST_LOCALE_WITH_CASEMAP

std::locale create_convert(const std::locale& in, const cdata& cd, character_facet_type type)
std::locale create_convert(const std::locale& in, const cdata& cd, char_facet_t type)
{
switch(type) {
case char_facet:
case char_facet_t::char_f:
#ifdef BOOST_LOCALE_WITH_CASEMAP
if(cd.utf8)
return std::locale(in, new utf8_converter_impl(cd));
#endif
return std::locale(in, new converter_impl<char>(cd));
case wchar_t_facet: return std::locale(in, new converter_impl<wchar_t>(cd));
case char_facet_t::wchar_f: return std::locale(in, new converter_impl<wchar_t>(cd));
#ifdef BOOST_LOCALE_ENABLE_CHAR16_T
case char16_t_facet: return std::locale(in, new converter_impl<char16_t>(cd));
case char_facet_t::char16_f: return std::locale(in, new converter_impl<char16_t>(cd));
#endif
#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
case char32_t_facet: return std::locale(in, new converter_impl<char32_t>(cd));
case char_facet_t::char32_f: return std::locale(in, new converter_impl<char32_t>(cd));
#endif
default: return in;
}
Expand Down

0 comments on commit e5ed439

Please sign in to comment.