From 809f6739a66018f43913bf4fb87d40f6dc41a2ce Mon Sep 17 00:00:00 2001 From: AWE Henry Date: Mon, 27 Nov 2023 15:23:39 +0800 Subject: [PATCH] update --- include/papilio/core.hpp | 253 +----------------- include/papilio/core.inl | 4 +- .../papilio/detail/{detail.hpp => compat.hpp} | 0 include/papilio/format.hpp | 23 +- include/papilio/{detail => }/iterstream.hpp | 68 +++-- include/papilio/type.hpp | 103 +++++++ include/papilio/utf/codepoint.hpp | 12 + include/papilio/utf/common.hpp | 10 +- src/core.cpp | 16 +- src/detail/detail.cpp | 7 - src/script.cpp | 4 +- test/CMakeLists.txt | 2 +- test/test_core.cpp | 18 -- test/test_detail_iterstream.cpp | 51 ---- test/test_iterstream.cpp | 119 ++++++++ test/test_type.cpp | 23 ++ 16 files changed, 349 insertions(+), 364 deletions(-) rename include/papilio/detail/{detail.hpp => compat.hpp} (100%) rename include/papilio/{detail => }/iterstream.hpp (52%) delete mode 100644 src/detail/detail.cpp delete mode 100644 test/test_detail_iterstream.cpp create mode 100644 test/test_iterstream.cpp diff --git a/include/papilio/core.hpp b/include/papilio/core.hpp index 5621498..b5c1789 100644 --- a/include/papilio/core.hpp +++ b/include/papilio/core.hpp @@ -8,9 +8,9 @@ #include #include #include +#include "macros.hpp" #include "type.hpp" #include "container.hpp" -#include "macros.hpp" #include "utf/utf.hpp" #include "error.hpp" #include "locale.hpp" @@ -28,26 +28,6 @@ namespace papilio class dynamic_format_context; class format_spec_parse_context; - namespace detail - { - [[nodiscard]] - constexpr bool is_digit(char ch) noexcept - { - return '0' <= ch && ch <= '9'; - } - - template - [[nodiscard]] - constexpr bool is_identifier_ch(CharT ch, bool first = false) noexcept - { - bool digit = is_digit(ch); - if(first && digit) - return false; - - return ('A' <= ch && ch <= 'z') || digit || ch == '_'; - } - } - enum class format_align : std::uint8_t { default_align = 0, @@ -63,240 +43,13 @@ namespace papilio space }; - class common_format_spec - { - public: - common_format_spec() = default; - common_format_spec(const common_format_spec&) noexcept = default; - - void reset() noexcept - { - *this = common_format_spec(); - } - - [[nodiscard]] - static constexpr bool is_align_spec(char32_t ch) noexcept - { - return - ch == '<' || - ch == '^' || - ch == '>'; - } - [[nodiscard]] - static constexpr format_align get_align(char32_t ch) noexcept - { - switch(ch) - { - using enum format_align; - case '<': - return left; - case '^': - return middle; - case '>': - return right; - default: - return default_align; - } - } - - [[nodiscard]] - static constexpr bool is_sign_spec(char32_t ch) noexcept - { - return - ch == '+' || - ch == ' ' || - ch == '-'; - } - [[nodiscard]] - static constexpr format_sign get_sign(char32_t ch) noexcept - { - switch(ch) - { - using enum format_sign; - [[likely]] case '+': - return positive; - case ' ': - return space; - default: - case '-': - return negative; - } - } - - [[nodiscard]] - bool has_fill() const noexcept - { - return m_fill != U'\0'; - } - [[nodiscard]] - utf::codepoint fill() const noexcept - { - return m_fill; - } - void fill(utf::codepoint cp) noexcept - { - m_fill = cp; - } - [[nodiscard]] - utf::codepoint fill_or(utf::codepoint or_cp) const noexcept - { - return has_fill() ? m_fill : or_cp; - } - [[nodiscard]] - format_align align() const noexcept - { - return m_align; - } - void align(format_align val) noexcept - { - m_align = val; - } - [[nodiscard]] - format_sign sign() const noexcept - { - return m_sign; - } - void sign(format_sign val) noexcept - { - m_sign = val; - } - [[nodiscard]] - bool alternate_form() const noexcept - { - return m_alternate_form; - } - void alternate_form(bool val) noexcept - { - m_alternate_form = val; - } - [[nodiscard]] - bool fill_zero() const noexcept - { - return m_fill_zero; - } - void fill_zero(bool val) noexcept - { - m_fill_zero = val; - } - [[nodiscard]] - std::size_t width() const noexcept - { - return m_width; - } - void width(std::size_t val) noexcept - { - m_width = val; - } - [[nodiscard]] - std::size_t precision() const noexcept - { - return m_precision; - } - void precision(std::size_t val) noexcept - { - m_precision = val; - } - [[nodiscard]] - bool use_locale() const noexcept - { - return m_use_locale; - } - void use_locale(bool val) noexcept - { - m_use_locale = val; - } - [[nodiscard]] - bool has_type_char() const noexcept - { - return m_type_char != U'\0'; - } - [[nodiscard]] - utf::codepoint type_char() const noexcept - { - return m_type_char; - } - void type_char(utf::codepoint cp) noexcept - { - m_type_char = cp; - } - [[nodiscard]] - utf::codepoint type_char_or(utf::codepoint or_cp) const noexcept - { - return has_type_char() ? m_type_char : or_cp; - } - - private: - utf::codepoint m_fill = U'\0'; - format_align m_align = format_align::default_align; - format_sign m_sign = format_sign::default_sign; - bool m_alternate_form = false; // specified by '#' - bool m_fill_zero = false; - std::size_t m_width = 0; - std::size_t m_precision = -1; - bool m_use_locale = false; - utf::codepoint m_type_char = U'\0'; - }; - - template - struct named_arg - { - using named_arg_tag = void; - - const char* name; - const T& value; - - named_arg() = delete; - constexpr named_arg(const named_arg&) noexcept = default; - constexpr named_arg(const char* name_, const T& value_) noexcept - : name(name_), value(value_) {} - - named_arg& operator=(const named_arg&) = delete; - }; - - template - constexpr inline bool is_named_arg_v = requires() - { - typename T::named_arg_tag; - }; - - template - constexpr named_arg arg(const char* name, const T& value) noexcept - { - return named_arg(name, value); - } - - inline namespace literals - { - struct named_arg_proxy - { - const char* name; - - named_arg_proxy() = delete; - named_arg_proxy(const named_arg_proxy&) = delete; - constexpr named_arg_proxy(const char* name_) noexcept - : name(name_) {} - - template - constexpr named_arg operator=(const T& value) noexcept - { - return named_arg(name, value); - } - }; - - [[nodiscard]] - constexpr named_arg_proxy operator""_a(const char* name, std::size_t) noexcept - { - return named_arg_proxy(name); - } - } - class indexing_value { public: using char_type = char; using string_type = std::basic_string; using string_view_type = std::basic_string_view; - using index_type = std::make_signed_t; // ssize_t + using index_type = ssize_t; using underlying_type = std::variant< index_type, slice, @@ -432,7 +185,7 @@ namespace papilio } [[nodiscard]] - static bool validate(string_view_type name) noexcept; + static bool validate(utf::string_ref name) noexcept; private: utf::string_container m_name; diff --git a/include/papilio/core.inl b/include/papilio/core.inl index 34de3f1..dad6a8d 100644 --- a/include/papilio/core.inl +++ b/include/papilio/core.inl @@ -5,7 +5,7 @@ #include #include #include -#include "detail/iterstream.hpp" +#include "iterstream.hpp" namespace papilio @@ -56,7 +56,7 @@ namespace papilio else if constexpr(detail::has_ostream_support_helper) { using context_traits = format_context_traits; - using streambuf_type = detail::basic_iterbuf< + using streambuf_type = basic_iterbuf< char, typename context_traits::iterator >; diff --git a/include/papilio/detail/detail.hpp b/include/papilio/detail/compat.hpp similarity index 100% rename from include/papilio/detail/detail.hpp rename to include/papilio/detail/compat.hpp diff --git a/include/papilio/format.hpp b/include/papilio/format.hpp index 7e4a125..46006c4 100644 --- a/include/papilio/format.hpp +++ b/include/papilio/format.hpp @@ -66,7 +66,7 @@ namespace papilio template format_to_n_result vformat_to_n(OutputIt out, std::iter_difference_t n, std::string_view fmt, const dynamic_format_args& store) { - auto result = vformat_to( + auto result = PAPILIO_NS vformat_to( detail::format_to_n_wrapper(out, n), fmt, store @@ -76,7 +76,7 @@ namespace papilio template format_to_n_result vformat_to_n(OutputIt out, std::iter_difference_t n, const std::locale& loc, std::string_view fmt, const dynamic_format_args& store) { - auto result = vformat_to( + auto result = PAPILIO_NS vformat_to( detail::format_to_n_wrapper(out, n), loc, fmt, @@ -93,46 +93,43 @@ namespace papilio OutputIt format_to(OutputIt out, std::string_view fmt, Args&&... args) { // use namespace prefix to avoid collision with std::format caused by ADL - return vformat_to(out, fmt, papilio::make_format_args(std::forward(args)...)); + return vformat_to(out, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template OutputIt format_to(OutputIt out, std::locale& loc, std::string_view fmt, Args&&... args) { // use namespace prefix to avoid collision with std::format caused by ADL - return vformat_to(out, loc, fmt, papilio::make_format_args(std::forward(args)...)); + return vformat_to(out, loc, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template format_to_n_result format_to_n(OutputIt out, std::iter_difference_t n, std::string_view fmt, Args&&... args) { - return vformat_to_n(out, n, fmt, papilio::make_format_args(std::forward(args)...)); + return vformat_to_n(out, n, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template format_to_n_result format_to_n(OutputIt out, std::iter_difference_t n, const std::locale& loc, std::string_view fmt, Args&&... args) { - return vformat_to_n(out, n, loc, fmt, papilio::make_format_args(std::forward(args)...)); + return vformat_to_n(out, n, loc, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template std::size_t formatted_size(std::string_view fmt, Args&&... args) { - // use namespace prefix to avoid collision with std::format caused by ADL - return vformatted_size(fmt, papilio::make_format_args(std::forward(args)...)); + return vformatted_size(fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template std::size_t formatted_size(const std::locale& loc, std::string_view fmt, Args&&... args) { - // use namespace prefix to avoid collision with std::format caused by ADL - return vformatted_size(loc, fmt, papilio::make_format_args(std::forward(args)...)); + return vformatted_size(loc, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template std::string format(std::string_view fmt, Args&&... args) { - // use namespace prefix to avoid collision with std::format caused by ADL - return vformat(fmt, papilio::make_format_args(std::forward(args)...)); + return vformat(fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } template std::string format(const std::locale& loc, std::string_view fmt, Args&&... args) { // use namespace prefix to avoid collision with std::format caused by ADL - return PAPILIO_NS vformat(loc, fmt, papilio::make_format_args(std::forward(args)...)); + return vformat(loc, fmt, PAPILIO_NS make_format_args(std::forward(args)...)); } } diff --git a/include/papilio/detail/iterstream.hpp b/include/papilio/iterstream.hpp similarity index 52% rename from include/papilio/detail/iterstream.hpp rename to include/papilio/iterstream.hpp index b61a2ec..24bc174 100644 --- a/include/papilio/detail/iterstream.hpp +++ b/include/papilio/iterstream.hpp @@ -6,37 +6,39 @@ #include -namespace papilio::detail +namespace papilio { - // helper - template - struct basic_iterbuf_input_buf + namespace detail { - [[nodiscard]] - CharT* gbuf_ptr() noexcept + template + struct basic_iterbuf_base : public std::basic_streambuf { - return &m_buf_ch; - } + [[nodiscard]] + CharT* gbuf_ptr() noexcept + { + return &m_buf_ch; + } - private: - CharT m_buf_ch = static_cast(0); - }; - template - class basic_iterbuf_input_buf {}; + private: + CharT m_buf_ch = static_cast(0); + }; + template + class basic_iterbuf_base : public std::basic_streambuf {}; + } // output iterator stream buffer template class basic_iterbuf : - public std::basic_streambuf, public basic_iterbuf_input_buf, CharT> + public detail::basic_iterbuf_base, CharT> { - using base = std::basic_streambuf; + using base = detail::basic_iterbuf_base, CharT>; public: using char_type = CharT; using iterator = Iterator; using int_type = base::int_type; using traits_type = base::traits_type; - basic_iterbuf() = delete; + basic_iterbuf() = default; basic_iterbuf(Iterator iter) noexcept(std::is_nothrow_move_constructible_v) : basic_iterbuf(std::in_place, std::move(iter)) {} template @@ -93,4 +95,38 @@ namespace papilio::detail } } }; + + template + using iterbuf = basic_iterbuf; + template + using witerbuf = basic_iterbuf; + + template Iterator> + class basic_oiterstream : public std::basic_ostream + { + using base = std::basic_ostream; + public: + using iterator = Iterator; + + basic_oiterstream() = default; + basic_oiterstream(Iterator iter) + : base(&m_buf), m_buf(std::move(iter)) {} + template + basic_oiterstream(std::in_place_t, Args&&... args) + : base(&m_buf), m_buf(std::in_place, std::forward(args)...) {} + + [[nodiscard]] + Iterator get() const + { + return m_buf.get(); + } + + private: + basic_iterbuf m_buf; + }; + + template Iterator> + using oiterstream = basic_oiterstream; + template Iterator> + using woiterstream = basic_oiterstream; } diff --git a/include/papilio/type.hpp b/include/papilio/type.hpp index 39b6e6b..9532868 100644 --- a/include/papilio/type.hpp +++ b/include/papilio/type.hpp @@ -126,4 +126,107 @@ namespace papilio return second - first; } }; + + template + struct basic_named_arg + { + static_assert(!std::is_reference_v, "T cannot be a reference"); + + using named_arg_tag = void; + + using char_type = CharT; + using string_view_type = std::basic_string_view; + using value_type = T; + using reference = std::add_lvalue_reference_t; + + string_view_type name; + reference value; + + basic_named_arg() = delete; + constexpr basic_named_arg(const basic_named_arg&) noexcept = default; + constexpr basic_named_arg(string_view_type arg_name, reference arg_value) noexcept + : name(arg_name), value(arg_value) {} + + basic_named_arg& operator=(const basic_named_arg&) = delete; + + [[nodiscard]] + constexpr reference get() const noexcept + { + return value; + } + + constexpr operator reference() const noexcept + { + return value; + } + }; + + template + using named_arg = basic_named_arg; + template + using wnamed_arg = basic_named_arg; + + namespace detail + { + template + concept is_named_arg_helper = requires() { typename T::named_arg_tag; }; + } + + template + struct is_named_arg : public std::bool_constant> {}; + + template + constexpr inline bool is_named_arg_v = is_named_arg::value; + + template + constexpr auto arg(const CharT* name, T&& value) noexcept + { + return basic_named_arg>(name, value); + } + template + constexpr auto arg(const std::basic_string_view name, T&& value) noexcept + { + return basic_named_arg>(name, value); + } + + namespace detail + { + template + struct named_arg_proxy + { + using string_view_type = std::basic_string_view; + + string_view_type name; + + named_arg_proxy() = delete; + named_arg_proxy(const named_arg_proxy&) = delete; + constexpr named_arg_proxy(const CharT* arg_name, std::size_t size) noexcept + : name(arg_name, size) {} + + named_arg_proxy& operator=(const named_arg_proxy&) = delete; + + template + [[nodiscard]] + constexpr auto operator=(T&& value) noexcept + { + return PAPILIO_NS arg(name, std::forward(value)); + } + }; + } + + inline namespace literals + { + inline namespace named_arg_literals + { + constexpr auto operator""_a(const char* name, std::size_t size) noexcept + { + return PAPILIO_NS detail::named_arg_proxy(name, size); + } + + constexpr auto operator""_a(const wchar_t* name, std::size_t size) noexcept + { + return PAPILIO_NS detail::named_arg_proxy(name, size); + } + } + } } diff --git a/include/papilio/utf/codepoint.hpp b/include/papilio/utf/codepoint.hpp index f3762cd..1d2d1bb 100644 --- a/include/papilio/utf/codepoint.hpp +++ b/include/papilio/utf/codepoint.hpp @@ -18,6 +18,8 @@ namespace papilio::utf { + // vvv decoders vvv + template <> class decoder { @@ -103,6 +105,8 @@ namespace papilio::utf static auto from_codepoint(codepoint cp) -> from_codepoint_result; }; + // ^^^ decoders ^^^ / vvv codepoint vvv + class codepoint { public: @@ -319,6 +323,14 @@ namespace papilio::utf return 1; } + // Locale independent APIs + + [[nodiscard]] + constexpr bool is_digit() const noexcept + { + return utf::is_digit(*this); + } + private: char8_t m_data[4]; }; diff --git a/include/papilio/utf/common.hpp b/include/papilio/utf/common.hpp index 2af087c..bd0d247 100644 --- a/include/papilio/utf/common.hpp +++ b/include/papilio/utf/common.hpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include @@ -433,6 +433,14 @@ namespace papilio::utf #undef PAPILIO_UTF_INDEX_OFFSET #undef PAPILIO_UTF_INDEX_OFFSET_R + // vvv locale independent APIs vvv + + [[nodiscard]] + constexpr bool is_digit(char32_t ch) noexcept + { + return U'0' <= ch && ch <= U'9'; + } + inline namespace literals {} } diff --git a/src/core.cpp b/src/core.cpp index 3ab5435..53bf495 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -8,13 +8,23 @@ namespace papilio { - bool attribute_name::validate(string_view_type name) noexcept + static bool is_identifier_ch(char32_t ch, bool first = false) noexcept + { + bool digit = utf::is_digit(ch); + if(first && digit) + return false; + + return digit || ('A' <= ch && ch <= 'z') || ch == '_' || ch >= 128; + } + + bool attribute_name::validate(utf::string_ref name) noexcept { bool first = true; - for(char_type c : name) + for(char32_t c : name) { - if(!detail::is_identifier_ch(c, first)) + if(!is_identifier_ch(c, first)) return false; + if(first) first = false; } diff --git a/src/detail/detail.cpp b/src/detail/detail.cpp deleted file mode 100644 index b574cca..0000000 --- a/src/detail/detail.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - - -namespace papilio::detail -{ - -} diff --git a/src/script.cpp b/src/script.cpp index fa7a06d..f69d2e5 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include namespace papilio::script @@ -303,7 +303,7 @@ namespace papilio::script break; default: - papilio::detail::unreachable(); + PAPILIO_UNREACHABLE(); } } end_loop: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ecdd7b..9e7d728 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,7 +14,7 @@ define_papilio_test(test_core) define_papilio_test(test_container) -define_papilio_test(test_detail_iterstream) +define_papilio_test(test_iterstream) define_papilio_test(test_memory) diff --git a/test/test_core.cpp b/test/test_core.cpp index a4f565b..dadf1a0 100644 --- a/test/test_core.cpp +++ b/test/test_core.cpp @@ -4,24 +4,6 @@ #include -TEST(TestCore, Utilities) -{ - using namespace std::literals; - - { - using namespace papilio; - - const std::string str_val = "hello world"; - const auto a_0 = arg("string", str_val); - EXPECT_STREQ(a_0.name, "string"); - EXPECT_EQ(a_0.value, "hello world"); - - const int int_val = 1; - const auto a_1 = "integer"_a = int_val; - EXPECT_STREQ(a_1.name, "integer"); - EXPECT_EQ(a_1.value, int_val); - } -} TEST(TestCore, AttributeName) { using namespace std::literals; diff --git a/test/test_detail_iterstream.cpp b/test/test_detail_iterstream.cpp deleted file mode 100644 index c44e25c..0000000 --- a/test/test_detail_iterstream.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include - - -TEST(TestDetailIterStream, Iterbuf) -{ - using papilio::detail::basic_iterbuf; - - // input - { - std::string src = "12345"; - - using streambuf_type = basic_iterbuf< - char, decltype(std::begin(src)) - >; - - streambuf_type sbuf(std::begin(src)); - std::istream is(&sbuf); - - char result_buf[5]{}; - is.read(result_buf, 5); - EXPECT_EQ(std::string_view(result_buf, 5), "12345"); - EXPECT_EQ(sbuf.get(), src.end()); - EXPECT_TRUE(is.good()); - } - - // output - { - std::string buf; - - using streambuf_type = basic_iterbuf< - char, std::back_insert_iterator - >; - - streambuf_type sbuf(std::back_inserter(buf)); - std::ostream os(&sbuf); - - os << "hello"; - EXPECT_EQ(buf, "hello"); - EXPECT_TRUE(os.good()); - } -} - -int main(int argc, char* argv[]) -{ - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/test_iterstream.cpp b/test/test_iterstream.cpp new file mode 100644 index 0000000..157d7b4 --- /dev/null +++ b/test/test_iterstream.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#include + + +TEST(basic_iter_buf, input) +{ + using namespace papilio; + + std::string src = "12345"; + + using streambuf_type = iterbuf; + + streambuf_type sbuf(std::begin(src)); + std::istream is(&sbuf); + + char result_buf[5]{}; + is.read(result_buf, 5); + EXPECT_EQ(std::string_view(result_buf, 5), "12345"); + EXPECT_EQ(sbuf.get(), src.end()); + EXPECT_TRUE(is.good()); +} + +TEST(basic_iter_buf, output) +{ + using namespace papilio; + + std::string buf; + + using streambuf_type = iterbuf>; + + streambuf_type sbuf(std::back_inserter(buf)); + std::ostream os(&sbuf); + + os << "hello"; + EXPECT_EQ(buf, "hello"); + EXPECT_TRUE(os.good()); +} + +TEST(basic_iter_buf, winput) +{ + using namespace papilio; + + std::wstring src = L"12345"; + + using streambuf_type = witerbuf; + + streambuf_type sbuf(std::begin(src)); + std::wistream is(&sbuf); + + wchar_t result_buf[5]{}; + is.read(result_buf, 5); + EXPECT_EQ(std::wstring_view(result_buf, 5), L"12345"); + EXPECT_EQ(sbuf.get(), src.end()); + EXPECT_TRUE(is.good()); +} + +TEST(basic_iter_buf, woutput) +{ + using namespace papilio; + + std::wstring buf; + + using streambuf_type = witerbuf>; + + streambuf_type sbuf(std::back_inserter(buf)); + std::wostream os(&sbuf); + + os << L"hello"; + EXPECT_EQ(buf, L"hello"); + EXPECT_TRUE(os.good()); +} + +TEST(basic_oiterstream, char) +{ + using namespace papilio; + + std::string buf; + oiterstream os(std::back_inserter(buf)); + + static_assert(std::is_same_v< + decltype(os)::iterator, + std::back_insert_iterator + >); + + os << "hello"; + os << ' '; + os << 12345; + + EXPECT_EQ(buf, "hello 12345"); + EXPECT_TRUE(os.good()); +} + +TEST(basic_oiterstream, wchar_t) +{ + using namespace papilio; + + std::wstring buf; + woiterstream os(std::back_inserter(buf)); + + static_assert(std::is_same_v< + decltype(os)::iterator, + std::back_insert_iterator + >); + + os << L"hello"; + os << L' '; + os << 12345; + + EXPECT_EQ(buf, L"hello 12345"); + EXPECT_TRUE(os.good()); +} + +int main(int argc, char* argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/test_type.cpp b/test/test_type.cpp index 8b6de80..ae9692a 100644 --- a/test/test_type.cpp +++ b/test/test_type.cpp @@ -84,6 +84,29 @@ TEST(slice, slice) } } +TEST(named_arg, named_arg) +{ + { + using namespace papilio; + + const std::string str_val = "hello world"; + const auto a_0 = arg("string", str_val); + EXPECT_EQ(a_0.name, "string"); + EXPECT_EQ(a_0.value, "hello world"); + EXPECT_EQ(&a_0.get(), &str_val); + EXPECT_EQ(&static_cast(a_0), &str_val); + } + + { + using namespace papilio::literals; + + const int int_val = 1; + const auto a_1 = "integer"_a = int_val; + EXPECT_EQ(a_1.name, "integer"); + EXPECT_EQ(a_1.value, int_val); + } +} + int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv);