/*============================================================================= Copyright (c) 2025 Nana Sakisaka Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "test.hpp" #include #include #include #include #include namespace { struct minimal_parser : x4::parser { constexpr minimal_parser() = default; constexpr minimal_parser(minimal_parser const&) = delete; constexpr minimal_parser& operator=(minimal_parser const&) = delete; constexpr minimal_parser(minimal_parser&&) = default; constexpr minimal_parser& operator=(minimal_parser&&) = default; template Se, class Context, x4::X4Attribute Attr> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, Attr&) const { return true; } }; struct minimal_unary_parser : x4::unary_parser { template Se, class Context, x4::X4Attribute Attr> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, Attr&) const { return true; } }; struct minimal_binary_parser : x4::binary_parser { template Se, class Context, x4::X4Attribute Attr> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, Attr&) const { return true; } }; struct minimal_unused_parser : x4::parser { template Se, class Context> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, unused_type const&) const { return true; } }; struct minimal_unary_unused_parser : x4::unary_parser { template Se, class Context> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, unused_type const&) const { return true; } }; struct minimal_binary_unused_parser : x4::binary_parser { template Se, class Context> [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, unused_type const&) const { return true; } }; } // anonymous TEST_CASE("parser") { using x4::blank; { using It = std::string_view::const_iterator; using Se = It; static_assert(std::forward_iterator); static_assert(std::sentinel_for); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); // parse { // str STATIC_CHECK(x4::parse("", minimal_parser{}, unused)); // str + res STATIC_CHECK([] { x4::parse_result res{}; x4::parse(res, "", minimal_parser{}, unused); return res; }()); // It/Se STATIC_CHECK(x4::parse(It{}, Se{}, minimal_parser{}, unused)); // It/Se + res STATIC_CHECK([] { x4::parse_result res{}; x4::parse(res, It{}, Se{}, minimal_parser{}, unused); return res; }()); } // phrase_parse { // str STATIC_CHECK(x4::parse("", minimal_parser{}, blank, unused)); // str + res STATIC_CHECK([] { x4::parse_result res{}; x4::parse(res, "", minimal_parser{}, blank, unused); return res; }()); // It/Se STATIC_CHECK(x4::parse(It{}, Se{}, minimal_parser{}, blank, unused)); // It/Se + res STATIC_CHECK([] { x4::parse_result res{}; x4::parse(res, It{}, Se{}, minimal_parser{}, blank, unused); return res; }()); } // expectation STATIC_CHECK(x4::parse("", minimal_parser{} > minimal_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unary_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unary_parser{} > minimal_unary_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_binary_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_binary_parser{} > minimal_binary_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unused_parser{} > minimal_unused_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unary_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unary_unused_parser{} > minimal_unary_unused_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_binary_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_binary_unused_parser{} > minimal_binary_unused_parser{}, unused)); } { using It = std::counted_iterator; using Se = std::default_sentinel_t; static_assert(std::forward_iterator); static_assert(std::sentinel_for); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_parser{} > minimal_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unary_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unary_parser{} > minimal_unary_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_binary_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_binary_parser{} > minimal_binary_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unused_parser{} > minimal_unused_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_unary_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_unary_unused_parser{} > minimal_unary_unused_parser{}, unused)); STATIC_CHECK(x4::X4Subject); STATIC_CHECK(x4::X4ExplicitSubject); STATIC_CHECK(x4::is_parsable_v); STATIC_CHECK(!x4::is_nothrow_parsable_v); STATIC_CHECK(x4::X4Parser); STATIC_CHECK(x4::X4ExplicitParser); STATIC_CHECK(x4::parse("", minimal_binary_unused_parser{}, unused)); STATIC_CHECK(x4::parse("", minimal_binary_unused_parser{} > minimal_binary_unused_parser{}, unused)); } }