/*============================================================================= Copyright (c) 2001-2015 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser 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 #include #include #include #include #include #include #include #include #include #include #include #include #include namespace x4 = boost::spirit::x4; // check if we did not break user defined specializations namespace check_substitute { template struct foo {}; template struct bar { using type = T; }; template struct is_bar : std::false_type {}; template struct is_bar> : std::true_type {}; } // check_substitute namespace boost::spirit::x4::traits { using namespace check_substitute; template struct is_substitute, foo> : is_substitute {}; template requires is_bar::value && is_bar::value struct is_substitute : is_substitute {}; } // boost::spirit::x4::traits namespace check_substitute { using x4::traits::is_substitute_v; static_assert( is_substitute_v, foo>); static_assert(!is_substitute_v, foo>); static_assert( is_substitute_v, bar>); static_assert(!is_substitute_v, bar>); } // check_substitute namespace { constexpr x4::rule> pair_rule("pair"); constexpr x4::rule string_rule("string"); constexpr auto pair_rule_def = string_rule >> x4::lit('=') >> string_rule; constexpr auto string_rule_def = x4::lexeme[*x4::standard::alnum]; BOOST_SPIRIT_X4_DEFINE(pair_rule) BOOST_SPIRIT_X4_DEFINE(string_rule) template void test_map_support() { { constexpr auto rule = pair_rule % x4::lit(','); Container actual; REQUIRE(parse("k1=v1,k2=v2,k2=v3", rule, actual)); CHECK(actual.size() == 2); CHECK(actual == Container{{"k1", "v1"}, {"k2", "v2"}}); } { // test sequences parsing into containers constexpr auto seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule; Container container; CHECK(parse("k1=v1,k2=v2,k2=v3", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = pair_rule >> +(',' >> pair_rule); Container container; CHECK(parse("k1=v1,k2=v2,k2=v3", cic_rule, container)); } } template void test_multimap_support() { { constexpr auto rule = pair_rule % x4::lit(','); Container actual; REQUIRE(parse("k1=v1,k2=v2,k2=v3", rule, actual)); CHECK(actual.size() == 3); CHECK(actual == Container{{"k1", "v1"}, {"k2", "v2"}, {"k2", "v3"}}); } { // test sequences parsing into containers constexpr auto seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule; Container container; CHECK(parse("k1=v1,k2=v2,k2=v3", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = pair_rule >> +(',' >> pair_rule); Container container; CHECK(parse("k1=v1,k2=v2,k2=v3", cic_rule, container)); } } template void test_sequence_support() { { constexpr auto rule = string_rule % x4::lit(','); Container actual; REQUIRE(parse("e1,e2,e2", rule, actual)); CHECK(actual.size() == 3); CHECK(actual == Container{"e1", "e2", "e2"}); } { // test sequences parsing into containers constexpr auto seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; Container container; CHECK(parse("e1,e2,e2", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = string_rule >> +(',' >> string_rule); Container container; CHECK(parse("e1,e2,e2", cic_rule, container)); } } template void test_set_support() { { constexpr auto rule = string_rule % x4::lit(','); Container actual; REQUIRE(parse("e1,e2,e2", rule, actual)); CHECK(actual.size() == 2); CHECK(actual == Container{"e1", "e2"}); } { // test sequences parsing into containers constexpr auto seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; Container container; CHECK(parse("e1,e2,e2", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = string_rule >> +(',' >> string_rule); Container container; CHECK(parse("e1,e2,e2", cic_rule, container)); } } template void test_multiset_support() { { constexpr auto rule = string_rule % x4::lit(','); Container actual; REQUIRE(parse("e1,e2,e2", rule, actual)); CHECK(actual.size() == 3); CHECK(actual == Container{"e1", "e2", "e2"}); } { // test sequences parsing into containers constexpr auto seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; Container container; CHECK(parse("e1,e2,e2", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = string_rule >> +(',' >> string_rule); Container container; CHECK(parse("e1,e2,e2", cic_rule, container)); } } template void test_string_support() { { constexpr auto rule = string_rule % x4::lit(','); Container container; REQUIRE(parse("e1,e2,e2", rule, container)); CHECK(container.size() == 6); CHECK(container == Container{"e1e2e2"}); } { // test sequences parsing into containers constexpr auto seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule; Container container; CHECK(parse("e1,e2,e2", seq_rule, container)); } { // test parsing container into container constexpr auto cic_rule = string_rule >> +(',' >> string_rule); Container container; CHECK(parse("e1,e2,e2", cic_rule, container)); } } } // anonymous TEST_CASE("container_support") { using x4::traits::is_container_v; using x4::traits::is_associative_v; // ------------------------------------------------------------------ STATIC_CHECK(is_container_v); STATIC_CHECK(!is_associative_v); STATIC_CHECK(is_container_v>); STATIC_CHECK(!is_associative_v>); STATIC_CHECK(is_container_v>); STATIC_CHECK(!is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(!is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(!is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(!is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(!is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(!is_associative_v>>); // ------------------------------------------------------------------ STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); STATIC_CHECK(is_container_v>); STATIC_CHECK(is_associative_v>); STATIC_CHECK(is_container_v>>); STATIC_CHECK(is_associative_v>>); // ------------------------------------------------------------------ test_string_support(); test_sequence_support>(); test_sequence_support>(); test_sequence_support>(); test_set_support>(); test_set_support>(); test_multiset_support>(); test_multiset_support>(); test_map_support>(); test_map_support>(); test_multimap_support>(); test_multimap_support>(); }