blob: 809d6ac3bc5a833628627641c0b7d4a0493a3c41 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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 <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <iostream>
#include <map>
#include <unordered_map>
#include <boost/unordered_map.hpp>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <unordered_set>
#include <boost/unordered_set.hpp>
#include <string>
#include "test.hpp"
namespace x3 = boost::spirit::x3;
// check if we did not break user defined specializations
namespace check_substitute {
template <typename T> struct foo {};
template <typename T> struct bar { using type = T; };
template <typename T> struct is_bar : std::false_type {};
template <typename T> struct is_bar<bar<T>> : std::true_type {};
}
namespace boost { namespace spirit { namespace x3 { namespace traits {
using namespace check_substitute;
template <typename T, typename U>
struct is_substitute<foo<T>, foo<U>> : is_substitute<T, U> {};
template <typename T, typename U>
struct is_substitute<T, U, std::enable_if_t<is_bar<T>::value && is_bar<U>::value>>
: is_substitute<typename T::type, typename U::type> {};
}}}}
namespace check_substitute {
using x3::traits::is_substitute;
static_assert(is_substitute<foo<int>, foo<int>>::value, "is_substitute problem");
static_assert(!is_substitute<foo<int>, foo<long>>::value, "is_substitute problem");
static_assert(is_substitute<bar<int>, bar<int>>::value, "is_substitute problem");
static_assert(!is_substitute<bar<int>, bar<long>>::value, "is_substitute problem");
}
x3::rule<class pair_rule, std::pair<std::string,std::string>> const pair_rule("pair");
x3::rule<class string_rule, std::string> const string_rule("string");
auto const pair_rule_def = string_rule > x3::lit('=') > string_rule;
auto const string_rule_def = x3::lexeme[*x3::alnum];
BOOST_SPIRIT_DEFINE(pair_rule, string_rule)
template <typename Container>
void test_map_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {{"k1", "v1"}, {"k2", "v2"}};
auto const rule = pair_rule % x3::lit(',');
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container));
BOOST_TEST(container.size() == 2);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule;
container.clear();
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container));
// test parsing container into container
auto const cic_rule = pair_rule >> +(',' >> pair_rule);
container.clear();
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container));
}
template <typename Container>
void test_multimap_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {{"k1", "v1"}, {"k2", "v2"}, {"k2", "v3"}};
auto const rule = pair_rule % x3::lit(',');
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", rule, container));
BOOST_TEST(container.size() == 3);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = pair_rule >> ',' >> pair_rule >> ',' >> pair_rule;
container.clear();
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", seq_rule, container));
// test parsing container into container
auto const cic_rule = pair_rule >> +(',' >> pair_rule);
container.clear();
BOOST_TEST(test_attr("k1=v1,k2=v2,k2=v3", cic_rule, container));
}
template <typename Container>
void test_sequence_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {"e1", "e2", "e2"};
auto const rule = string_rule % x3::lit(',');
BOOST_TEST(test_attr("e1,e2,e2", rule, container));
BOOST_TEST(container.size() == 3);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
// test parsing container into container
auto const cic_rule = string_rule >> +(',' >> string_rule);
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
}
template <typename Container>
void test_set_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {"e1", "e2"};
auto const rule = string_rule % x3::lit(',');
BOOST_TEST(test_attr("e1,e2,e2", rule, container));
BOOST_TEST(container.size() == 2);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
// test parsing container into container
auto const cic_rule = string_rule >> +(',' >> string_rule);
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
}
template <typename Container>
void test_multiset_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {"e1", "e2", "e2"};
auto const rule = string_rule % x3::lit(',');
BOOST_TEST(test_attr("e1,e2,e2", rule, container));
BOOST_TEST(container.size() == 3);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
// test parsing container into container
auto const cic_rule = string_rule >> +(',' >> string_rule);
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
}
template <typename Container>
void test_string_support()
{
using spirit_test::test_attr;
Container container;
Container const compare {"e1e2e2"};
auto const rule = string_rule % x3::lit(',');
BOOST_TEST(test_attr("e1,e2,e2", rule, container));
BOOST_TEST(container.size() == 6);
BOOST_TEST(container == compare);
// test sequences parsing into containers
auto const seq_rule = string_rule >> ',' >> string_rule >> ',' >> string_rule;
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", seq_rule, container));
// test parsing container into container
auto const cic_rule = string_rule >> +(',' >> string_rule);
container.clear();
BOOST_TEST(test_attr("e1,e2,e2", cic_rule, container));
}
int
main()
{
using x3::traits::is_associative;
// ------------------------------------------------------------------
static_assert(is_associative<std::set<int>>::value, "is_associative problem");
static_assert(is_associative<std::unordered_set<int>>::value, "is_associative problem");
static_assert(is_associative<boost::unordered_set<int>>::value, "is_associative problem");
static_assert(is_associative<std::multiset<int>>::value, "is_associative problem");
static_assert(is_associative<std::unordered_multiset<int>>::value, "is_associative problem");
static_assert(is_associative<boost::unordered_multiset<int>>::value, "is_associative problem");
static_assert(is_associative<std::map<int,int>>::value, "is_associative problem");
static_assert(is_associative<std::unordered_map<int,int>>::value, "is_associative problem");
static_assert(is_associative<boost::unordered_map<int,int>>::value, "is_associative problem");
static_assert(is_associative<std::multimap<int,int>>::value, "is_associative problem");
static_assert(is_associative<std::unordered_multimap<int,int>>::value, "is_associative problem");
static_assert(is_associative<boost::unordered_multimap<int,int>>::value, "is_associative problem");
static_assert(!is_associative<std::vector<int>>::value, "is_associative problem");
static_assert(!is_associative<std::string>::value, "is_associative problem");
static_assert(!is_associative<std::deque<int>>::value, "is_associative problem");
static_assert(!is_associative<std::list<int>>::value, "is_associative problem");
// ------------------------------------------------------------------
test_string_support<std::string>();
test_sequence_support<std::vector<std::string>>();
test_sequence_support<std::list<std::string>>();
test_sequence_support<std::deque<std::string>>();
test_set_support<std::set<std::string>>();
test_set_support<std::unordered_set<std::string>>();
test_set_support<boost::unordered_set<std::string>>();
test_multiset_support<std::multiset<std::string>>();
test_multiset_support<std::unordered_multiset<std::string>>();
test_multiset_support<boost::unordered_multiset<std::string>>();
test_map_support<std::map<std::string,std::string>>();
test_map_support<std::unordered_map<std::string,std::string>>();
test_map_support<boost::unordered_map<std::string,std::string>>();
test_multimap_support<std::multimap<std::string,std::string>>();
test_multimap_support<std::unordered_multimap<std::string,std::string>>();
test_multimap_support<boost::unordered_multimap<std::string,std::string>>();
return boost::report_errors();
}