Characters¶
utf8_char, utf16_char, and utf32_char are validated single-scalar value types.
They are useful when you want to store or pass one Unicode scalar value without dropping down to raw UTF-8 bytes or UTF-16 code units.
For the named unicode_ranges::characters catalog, include unicode_ranges_all.hpp or include unicode_ranges/characters.hpp directly. The lighter unicode_ranges_borrowed.hpp umbrella no longer pulls that catalog in automatically.
When the character is known at compile time, the literal operators such as _u8c, _u16c, and _u32c are usually the nicest entry point. from_scalar(...) is the runtime path when the scalar value arrives as data.
Unless a section explicitly narrows the discussion, the UTF-8, UTF-16, and UTF-32 character APIs are structurally parallel.
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
const auto sparkle = "โจ"_u8c;
const auto smile = u"๐"_u16c;
const auto rocket = U"๐"_u32c;
std::println("{}", sparkle); // โจ
std::println("{}", sparkle.code_unit_count()); // 3
std::println("{}", smile); // ๐
std::println("{}", smile.code_unit_count()); // 2
std::println("{}", rocket); // ๐
std::println("{}", rocket.code_unit_count()); // 1
std::println("{}", "x"_u8c.ascii_uppercase()); // X
}
Constants And Default Construction¶
Synopsis¶
utf8_char() = default;
utf16_char() = default;
utf32_char() = default;
static const utf8_char replacement_character;
static const utf8_char null_terminator;
static const utf16_char replacement_character;
static const utf16_char null_terminator;
static const utf32_char replacement_character;
static const utf32_char null_terminator;
Behavior¶
- Value-initialized
utf8_char,utf16_char, andutf32_charhold U+0000. replacement_characteris U+FFFD.null_terminatoris U+0000.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
Default construction is non-throwing.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
int main()
{
utf8_char zero8{};
utf16_char zero16{};
utf32_char zero32{};
std::println("{}", zero8.as_scalar()); // 0
std::println("{}", zero16.as_scalar()); // 0
std::println("{}", zero32.as_scalar()); // 0
std::println("{}", utf8_char::replacement_character); // ๏ฟฝ
std::println("{}", utf16_char::null_terminator.as_scalar()); // 0
std::println("{}", utf32_char::null_terminator.as_scalar()); // 0
}
Checked Scalar Construction¶
Synopsis¶
static constexpr std::optional<utf8_char> from_scalar(std::uint32_t scalar) noexcept;
static constexpr std::optional<utf16_char> from_scalar(std::uint32_t scalar) noexcept;
static constexpr std::optional<utf32_char> from_scalar(std::uint32_t scalar) noexcept;
Behavior¶
Constructs a validated character from a Unicode scalar value and reports failure with std::optional.
Return value¶
- Returns the constructed character when
scalaris a valid Unicode scalar value. - Returns
std::nulloptfor invalid inputs such as surrogate code points or values above U+10FFFF.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
Always noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
int main()
{
const auto omega = utf8_char::from_scalar(U'ฮฉ').value();
const auto rocket = utf16_char::from_scalar(U'๐').value();
const auto invalid = utf8_char::from_scalar(0xD800u);
std::println("{}", omega); // ฮฉ
std::println("{}", rocket); // ๐
std::println("{}", invalid.has_value()); // false
}
Unchecked Construction¶
Synopsis¶
static constexpr utf8_char from_scalar_unchecked(std::uint32_t scalar) noexcept;
template<typename CharT>
static constexpr utf8_char from_utf8_bytes_unchecked(const CharT* bytes, std::size_t size) noexcept;
static constexpr utf16_char from_scalar_unchecked(std::uint32_t scalar) noexcept;
template<typename CharT>
static constexpr std::optional<utf16_char>
from_utf16_code_units(const CharT* code_units, std::size_t size) noexcept;
template<typename CharT>
static constexpr utf16_char
from_utf16_code_units_unchecked(const CharT* code_units, std::size_t size) noexcept;
static constexpr utf32_char from_scalar_unchecked(std::uint32_t scalar) noexcept;
template<typename CharT>
static constexpr std::optional<utf32_char>
from_utf32_code_points(const CharT* code_points, std::size_t size) noexcept;
template<typename CharT>
static constexpr utf32_char
from_utf32_code_points_unchecked(const CharT* code_points, std::size_t size) noexcept;
Behavior¶
from_scalar_uncheckedtrusts that the supplied scalar is valid.from_utf8_bytes_uncheckedtrusts thatbytes[0, size)encodes exactly one valid UTF-8 scalar.from_utf16_code_unitsvalidates that the range holds exactly one valid UTF-16 scalar.from_utf16_code_units_uncheckedtrusts that the supplied code units hold exactly one valid UTF-16 scalar.from_utf32_code_pointsvalidates that the range holds exactly one valid UTF-32 scalar.from_utf32_code_points_uncheckedtrusts that the supplied code points hold exactly one valid UTF-32 scalar.
Return value¶
- The checked UTF-16 constructor returns
std::nulloptwhen the range is not exactly one valid UTF-16 character. - The checked UTF-32 constructor returns
std::nulloptwhen the range is not exactly one valid UTF-32 character. - The unchecked constructors always return a value.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
All listed overloads are noexcept.
Example¶
Prefer the checked constructors and literals in normal user code. The unchecked overloads are for already-trusted input.
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
int main()
{
const auto trusted_utf8 = utf8_char::from_utf8_bytes_unchecked(u8"โจ", 3);
const auto trusted_scalar = utf16_char::from_scalar_unchecked(U'๐');
const auto checked_utf16 = utf16_char::from_utf16_code_units(u"๐", 2).value();
std::println("{}", trusted_utf8); // โจ
std::println("{}", trusted_scalar); // ๐
std::println("{}", checked_utf16); // ๐
}
Scalar Value, Encoding, And Cross-Encoding Conversion¶
Synopsis¶
constexpr std::uint32_t as_scalar() const noexcept;
constexpr operator utf16_char() const noexcept; // utf8_char only
constexpr operator utf32_char() const noexcept; // utf8_char and utf16_char
constexpr operator utf8_char() const noexcept; // utf16_char only
constexpr operator utf16_char() const noexcept; // utf32_char only
constexpr operator utf8_char() const noexcept; // utf32_char only
template <typename Allocator = std::allocator<char8_t>>
constexpr basic_utf8_string<Allocator> to_utf8_owned(const Allocator& alloc = Allocator()) const;
template <typename Allocator = std::allocator<char16_t>>
constexpr basic_utf16_string<Allocator> to_utf16_owned(const Allocator& alloc = Allocator()) const;
template <typename Allocator = std::allocator<char32_t>>
constexpr basic_utf32_string<Allocator> to_utf32_owned(const Allocator& alloc = Allocator()) const;
constexpr std::size_t code_unit_count() const noexcept;
template<typename CharT, typename OutIt>
constexpr std::size_t encode_utf8(OutIt out) const noexcept;
template<typename CharT, typename OutIt>
constexpr std::size_t encode_utf16(OutIt out) const noexcept;
template<typename CharT, typename OutIt>
constexpr std::size_t encode_utf32(OutIt out) const noexcept;
Behavior¶
as_scalar()returns the Unicode scalar value represented by the object.- The conversion operators transcode a single scalar between the UTF-8, UTF-16, and UTF-32 character representations.
to_utf8_owned(),to_utf16_owned(), andto_utf32_owned()materialize a one-character owning string in the corresponding encoding.code_unit_count()returns the number of code units used by the current encoding:- UTF-8:
1to4 - UTF-16:
1or2 - UTF-32:
1 encode_utf8(),encode_utf16(), andencode_utf32()copy the current value into an output iterator and return the number of code units written.
Return value¶
as_scalar()returns the scalar directly.encode_*()returns the number of output code units.to_*_owned()returns an owning validated string containing exactly one character.
Complexity¶
Constant.
Exceptions¶
as_scalar(), the conversion operators,code_unit_count(), andencode_*()do not throw.to_*_owned()may throw allocator or container exceptions.
noexcept¶
as_scalar(), conversion operators,code_unit_count(), andencode_*()arenoexcept.to_*_owned()is notnoexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <format>
#include <print>
#include <string>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
const auto sparkle = "โจ"_u8c;
const utf16_char sparkle16 = sparkle;
std::string encoded8;
sparkle.encode_utf8<char>(std::back_inserter(encoded8));
std::u16string encoded16;
sparkle.encode_utf16<char16_t>(std::back_inserter(encoded16));
std::println("{}", std::format("{:X}", sparkle.as_scalar())); // 2728
std::println("{}", sparkle16); // โจ
std::println("{}", sparkle.to_utf8_owned()); // โจ
std::println("{}", sparkle16.to_utf16_owned()); // โจ
std::println("{}", sparkle.code_unit_count()); // 3
std::println("{}", encoded8); // โจ
std::println("{}", utf16_string_view::from_code_units(encoded16).value()); // โจ
}
Scalar Iteration Helpers¶
Synopsis¶
constexpr utf8_char& operator++() noexcept;
constexpr utf8_char operator++(int) noexcept;
constexpr utf8_char& operator--() noexcept;
constexpr utf8_char operator--(int) noexcept;
constexpr utf16_char& operator++() noexcept;
constexpr utf16_char operator++(int) noexcept;
constexpr utf16_char& operator--() noexcept;
constexpr utf16_char operator--(int) noexcept;
constexpr utf32_char& operator++() noexcept;
constexpr utf32_char operator++(int) noexcept;
constexpr utf32_char& operator--() noexcept;
constexpr utf32_char operator--(int) noexcept;
Behavior¶
Advances or retreats across Unicode scalar values, skipping the surrogate range.
The operations wrap:
- decrementing U+0000 produces U+10FFFF
- incrementing U+10FFFF produces U+0000
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
All four operators are noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <format>
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
auto latin = "A"_u8c;
++latin;
auto before_surrogates = utf16_char::from_scalar(0xD7FFu).value();
++before_surrogates;
auto wrap = utf8_char::from_scalar(0x10FFFFu).value();
++wrap;
std::println("{}", latin); // B
std::println("{}", std::format("{:X}", before_surrogates.as_scalar())); // E000
std::println("{}", wrap.as_scalar()); // 0
}
Unicode Classification Predicates¶
Synopsis¶
constexpr bool is_ascii() const noexcept;
constexpr bool is_alphabetic() const noexcept;
constexpr bool is_alphanumeric() const noexcept;
constexpr bool is_control() const noexcept;
constexpr bool is_digit() const noexcept;
constexpr bool is_lowercase() const noexcept;
constexpr bool is_numeric() const noexcept;
constexpr bool is_uppercase() const noexcept;
constexpr bool is_whitespace() const noexcept;
Behavior¶
is_ascii()tests whether the scalar is in the ASCII range.- The remaining predicates use the Unicode property tables shipped with the library.
is_alphanumeric()is defined asis_alphabetic() || is_numeric().
Return value¶
Returns true when the current scalar has the queried property.
Complexity¶
Constant, with table lookups for the Unicode property predicates.
Exceptions¶
None.
noexcept¶
All listed overloads are noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
std::println("{}", "ฮฉ"_u8c.is_alphabetic()); // true
std::println("{}", "ฮฉ"_u8c.is_ascii()); // false
std::println("{}", "7"_u8c.is_digit()); // true
std::println("{}", " "_u8c.is_whitespace()); // true
}
Unicode Property Queries¶
Synopsis¶
constexpr unicode_general_category general_category() const noexcept;
constexpr std::uint8_t canonical_combining_class() const noexcept;
constexpr unicode_grapheme_break_property grapheme_break_property() const noexcept;
constexpr unicode_script script() const noexcept;
constexpr unicode_east_asian_width east_asian_width() const noexcept;
constexpr unicode_line_break_class line_break_class() const noexcept;
constexpr unicode_bidi_class bidi_class() const noexcept;
constexpr unicode_word_break_property word_break_property() const noexcept;
constexpr unicode_sentence_break_property sentence_break_property() const noexcept;
constexpr bool is_emoji() const noexcept;
constexpr bool is_emoji_presentation() const noexcept;
constexpr bool is_extended_pictographic() const noexcept;
Behavior¶
- All of these methods are locale-independent scalar-property queries.
general_category()returns the Unicode General_Category bucket for the scalar.canonical_combining_class()returns the canonical combining class used by normalization and canonical reordering.grapheme_break_property(),line_break_class(),word_break_property(), andsentence_break_property()expose the default Unicode segmentation and line-breaking properties for the scalar.script()returns the Unicode Script property. Punctuation and separators often come back ascommon, while combining marks are ofteninherited.east_asian_width()returns the Unicode East Asian Width class used by terminal and grid-width heuristics.bidi_class()returns the scalar's Unicode bidirectional class. This is a property lookup, not full bidi reordering.is_emoji()tests the UnicodeEmojiproperty.is_emoji_presentation()tests the UnicodeEmoji_Presentationproperty.is_extended_pictographic()tests the UnicodeExtended_Pictographicproperty used by segmentation algorithms.- These are scalar properties only. They do not inspect grapheme clusters or emoji ZWJ sequences.
Return value¶
- The enum-returning methods return the property value for the current scalar.
canonical_combining_class()returns the canonical combining class number.- The boolean methods return
truewhen the scalar has the queried property.
Complexity¶
Constant, with table lookups.
Exceptions¶
None.
noexcept¶
All listed overloads are noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
std::println("{}", "A"_u8c.general_category() == unicode_general_category::uppercase_letter); // true
std::println("{}", "ฬ"_u8c.canonical_combining_class() == 230); // true
std::println("{}", "ฬ"_u8c.grapheme_break_property() == unicode_grapheme_break_property::extend); // true
std::println("{}", "ฮฉ"_u8c.script() == unicode_script::greek); // true
std::println("{}", "็"_u8c.east_asian_width() == unicode_east_asian_width::wide); // true
std::println("{}", "A"_u8c.line_break_class() == unicode_line_break_class::alphabetic); // true
std::println("{}", "ุด"_u8c.bidi_class() == unicode_bidi_class::arabic_letter); // true
std::println("{}", "A"_u8c.word_break_property() == unicode_word_break_property::a_letter); // true
std::println("{}", "."_u8c.sentence_break_property() == unicode_sentence_break_property::a_term); // true
std::println("{}", "๐"_u8c.is_emoji()); // true
std::println("{}", "๐"_u8c.is_emoji_presentation()); // true
std::println("{}", "๐"_u8c.is_extended_pictographic()); // true
std::println("{}", U"ฮฉ"_u32c.script() == unicode_script::greek); // true
std::println("{}", U"๐"_u32c.is_emoji()); // true
}
ASCII Classification Predicates¶
Synopsis¶
constexpr bool is_ascii_alphabetic() const noexcept;
constexpr bool is_ascii_alphanumeric() const noexcept;
constexpr bool is_ascii_control() const noexcept;
constexpr bool is_ascii_digit() const noexcept;
constexpr bool is_ascii_graphic() const noexcept;
constexpr bool is_ascii_hexdigit() const noexcept;
constexpr bool is_ascii_lowercase() const noexcept;
constexpr bool is_ascii_octdigit() const noexcept;
constexpr bool is_ascii_punctuation() const noexcept;
constexpr bool is_ascii_uppercase() const noexcept;
constexpr bool is_ascii_whitespace() const noexcept;
Behavior¶
These methods first require the value to be ASCII and then apply the corresponding ASCII-only classification rule.
Return value¶
Returns false for all non-ASCII characters.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
All listed overloads are noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
std::println("{}", "A"_u8c.is_ascii_alphabetic()); // true
std::println("{}", "9"_u8c.is_ascii_hexdigit()); // true
std::println("{}", "รฉ"_u8c.is_ascii_alphabetic()); // false
}
ASCII Transforms And ASCII Comparison¶
Synopsis¶
constexpr utf8_char ascii_lowercase() const noexcept;
constexpr utf8_char ascii_uppercase() const noexcept;
constexpr bool eq_ignore_ascii_case(utf8_char other) const noexcept;
constexpr void swap(utf8_char& other) noexcept;
constexpr utf16_char ascii_lowercase() const noexcept;
constexpr utf16_char ascii_uppercase() const noexcept;
constexpr bool eq_ignore_ascii_case(utf16_char other) const noexcept;
constexpr void swap(utf16_char& other) noexcept;
constexpr utf32_char ascii_lowercase() const noexcept;
constexpr utf32_char ascii_uppercase() const noexcept;
constexpr bool eq_ignore_ascii_case(utf32_char other) const noexcept;
constexpr void swap(utf32_char& other) noexcept;
Behavior¶
ascii_lowercase()andascii_uppercase()only modify ASCII letters.- Non-ASCII characters are returned unchanged.
eq_ignore_ascii_case()lowercases both operands with the ASCII-only transform and compares the results.swap()exchanges the stored code units.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
All listed overloads are noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
auto left = "A"_u8c;
auto right = "Z"_u8c;
left.swap(right);
std::println("{}", "x"_u8c.ascii_uppercase()); // X
std::println("{}", "ร"_u8c.ascii_lowercase()); // ร
std::println("{}", "x"_u8c.eq_ignore_ascii_case("X"_u8c)); // true
std::println("{}", left); // Z
std::println("{}", right); // A
}
Comparison, Streaming, Hashing, And Formatting¶
Synopsis¶
friend constexpr bool operator==(const utf8_char&, const utf8_char&) = default;
friend constexpr auto operator<=>(const utf8_char&, const utf8_char&) = default;
friend constexpr bool operator==(const utf8_char& lhs, char rhs) noexcept;
friend constexpr bool operator==(const utf8_char& lhs, char8_t rhs) noexcept;
friend std::ostream& operator<<(std::ostream& os, const utf8_char& ch);
friend constexpr bool operator==(const utf16_char&, const utf16_char&) = default;
friend constexpr auto operator<=>(const utf16_char&, const utf16_char&) = default;
friend constexpr bool operator==(const utf16_char& lhs, char16_t rhs) noexcept;
friend std::ostream& operator<<(std::ostream& os, const utf16_char& ch);
friend constexpr bool operator==(const utf32_char&, const utf32_char&) = default;
friend constexpr auto operator<=>(const utf32_char&, const utf32_char&) = default;
friend constexpr bool operator==(const utf32_char& lhs, char32_t rhs) noexcept;
friend std::ostream& operator<<(std::ostream& os, const utf32_char& ch);
template<> struct std::hash<utf8_char>;
template<> struct std::hash<utf16_char>;
template<> struct std::hash<utf32_char>;
template<> struct std::formatter<utf8_char, char>;
template<> struct std::formatter<utf8_char, wchar_t>;
template<> struct std::formatter<utf16_char, char>;
template<> struct std::formatter<utf16_char, wchar_t>;
template<> struct std::formatter<utf32_char, char>;
template<> struct std::formatter<utf32_char, wchar_t>;
Behavior¶
- The defaulted comparisons compare the stored encoded value.
utf8_charcompares directly withcharandchar8_twhen the value is a single-byte ASCII code point.utf16_charcompares directly withchar16_twhen the value is a single UTF-16 code unit.utf32_charcompares directly withchar32_tbecause every UTF-32 character is one code point unit.- Stream insertion writes a textual representation:
utf8_charwrites its UTF-8 bytes directlyutf16_chartranscodes to UTF-8 forstd::ostreamutf32_chartranscodes to UTF-8 forstd::ostreamstd::hashhashes the encoded text representation.- The
std::formatterspecializations support: - normal textual formatting
'c'as a text presentation alias- numeric presentations
d,b,B,o,x,X, which formatas_scalar()
Complexity¶
Constant.
Exceptions¶
- The comparison overloads and hashers do not throw.
- Stream insertion may report stream errors through the stream object.
- Formatter parsing may throw
std::format_errorfor unsupported or malformed format specifiers.
noexcept¶
- The comparison overloads and hashers are non-throwing.
- Stream insertion and formatters are not
noexcept.
Example¶
#include "unicode_ranges_all.hpp"
#include <format>
#include <functional>
#include <print>
#include <sstream>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
const auto euro = "โฌ"_u8c;
const auto grin = u"๐"_u16c;
std::ostringstream out;
out << euro;
std::println("{}", euro == "โฌ"_u8c); // true
std::println("{}", std::hash<utf8_char>{}(euro) == std::hash<utf8_char>{}("โฌ"_u8c)); // true
std::println("{}", out.str()); // โฌ
std::println("{}", std::format("{:X}", euro)); // 20AC
std::println("{}", std::format("{}", grin)); // ๐
}
Character Literals¶
Synopsis¶
using namespace unicode_ranges::literals;
consteval utf8_char operator ""_u8c();
consteval utf16_char operator ""_u16c();
consteval utf32_char operator ""_u32c();
Behavior¶
The literal must encode exactly one valid UTF-8, UTF-16, or UTF-32 character in the corresponding encoding.
Return value¶
Returns the validated utf8_char, utf16_char, or utf32_char.
Exceptions¶
Because these are consteval literals, invalid input is rejected during compilation rather than at runtime.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
using namespace unicode_ranges::literals;
int main()
{
constexpr auto sparkle = "โจ"_u8c;
constexpr auto grin = u"๐"_u16c;
constexpr auto rocket = U"๐"_u32c;
std::println("{}", sparkle); // โจ
std::println("{}", grin); // ๐
std::println("{}", rocket); // ๐
}
Curated Character Namespaces¶
Synopsis¶
namespace unicode_ranges::characters::utf8
{
namespace punctuation { inline constexpr utf8_char ...; }
namespace symbols { inline constexpr utf8_char ...; }
namespace currency { inline constexpr utf8_char ...; }
namespace math { inline constexpr utf8_char ...; }
namespace arrows { inline constexpr utf8_char ...; }
namespace emojis { inline constexpr utf8_char ...; }
}
namespace unicode_ranges::characters::utf16
{
namespace punctuation { inline constexpr utf16_char ...; }
namespace symbols { inline constexpr utf16_char ...; }
namespace currency { inline constexpr utf16_char ...; }
namespace math { inline constexpr utf16_char ...; }
namespace arrows { inline constexpr utf16_char ...; }
namespace emojis { inline constexpr utf16_char ...; }
}
namespace unicode_ranges::characters::utf32
{
namespace punctuation { inline constexpr utf32_char ...; }
namespace symbols { inline constexpr utf32_char ...; }
namespace currency { inline constexpr utf32_char ...; }
namespace math { inline constexpr utf32_char ...; }
namespace arrows { inline constexpr utf32_char ...; }
namespace emojis { inline constexpr utf32_char ...; }
}
Behavior¶
- These namespaces provide a curated convenience set of commonly used punctuation, symbols, currency signs, arrows, math symbols, and emoji.
characters::utf8::...constants areutf8_char.characters::utf16::...constants areutf16_char.characters::utf32::...constants areutf32_char.- Both trees expose the same names so you can choose the encoding that matches the surrounding API.
- This is intentionally not a complete Unicode catalog.
Complexity¶
Constant.
Exceptions¶
None.
noexcept¶
Accessing the constants is non-throwing.
Example¶
#include "unicode_ranges_all.hpp"
#include <print>
using namespace unicode_ranges;
int main()
{
std::println("{}", characters::utf8::currency::euro_sign); // โฌ
std::println("{}", characters::utf8::math::approximately_equal_to); // โ
std::println("{}", characters::utf8::emojis::clown_face); // ๐คก
std::println("{}", characters::utf8::emojis::party_popper); // ๐
std::println("{}", characters::utf16::currency::euro_sign); // โฌ
std::println("{}", characters::utf16::arrows::right_arrow); // โ
std::println("{}", characters::utf16::emojis::red_heart); // โค
std::println("{}", characters::utf16::emojis::rocket); // ๐
std::println("{}", characters::utf32::currency::euro_sign); // โฌ
std::println("{}", characters::utf32::symbols::section_sign); // ยง
std::println("{}", characters::utf32::emojis::sparkles); // โจ
std::println("{}", characters::utf32::emojis::rocket); // ๐
}