summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/proto/test/matches.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/proto/test/matches.cpp')
-rw-r--r--src/boost/libs/proto/test/matches.cpp319
1 files changed, 319 insertions, 0 deletions
diff --git a/src/boost/libs/proto/test/matches.cpp b/src/boost/libs/proto/test/matches.cpp
new file mode 100644
index 00000000..60b8f725
--- /dev/null
+++ b/src/boost/libs/proto/test/matches.cpp
@@ -0,0 +1,319 @@
+///////////////////////////////////////////////////////////////////////////////
+// matches.hpp
+//
+// Copyright 2008 Eric Niebler. 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 <string>
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/debug.hpp>
+#include <boost/proto/transform/arg.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+namespace fusion = boost::fusion;
+
+struct int_convertible
+{
+ int_convertible() {}
+ operator int() const { return 0; }
+};
+
+struct Input
+ : proto::or_<
+ proto::shift_right< proto::terminal< std::istream & >, proto::_ >
+ , proto::shift_right< Input, proto::_ >
+ >
+{};
+
+struct Output
+ : proto::or_<
+ proto::shift_left< proto::terminal< std::ostream & >, proto::_ >
+ , proto::shift_left< Output, proto::_ >
+ >
+{};
+
+proto::terminal< std::istream & >::type const cin_ = {std::cin};
+proto::terminal< std::ostream & >::type const cout_ = {std::cout};
+
+struct Anything
+ : proto::or_<
+ proto::terminal<proto::_>
+ , proto::nary_expr<proto::_, proto::vararg<Anything> >
+ >
+{};
+
+void a_function() {}
+
+struct MyCases
+{
+ template<typename Tag>
+ struct case_
+ : proto::not_<proto::_>
+ {};
+};
+
+template<>
+struct MyCases::case_<proto::tag::shift_right>
+ : proto::_
+{};
+
+template<>
+struct MyCases::case_<proto::tag::plus>
+ : proto::_
+{};
+
+enum binary_representation_enum
+{
+ magnitude
+ , two_complement
+};
+
+typedef
+ mpl::integral_c<binary_representation_enum, magnitude>
+magnitude_c;
+
+typedef
+ mpl::integral_c<binary_representation_enum, two_complement>
+two_complement_c;
+
+template<typename Type, typename Representation>
+struct number
+{};
+
+struct NumberGrammar
+ : proto::or_ <
+ proto::terminal<number<proto::_, two_complement_c> >
+ , proto::terminal<number<proto::_, magnitude_c> >
+ >
+{};
+
+struct my_terminal
+{};
+
+template<typename T>
+struct a_template
+{};
+
+template<typename Expr>
+struct my_expr;
+
+struct my_domain
+ : proto::domain<proto::pod_generator<my_expr> >
+{};
+
+template<typename Expr>
+struct my_expr
+{
+ BOOST_PROTO_BASIC_EXTENDS(Expr, my_expr, my_domain)
+};
+
+void test_matches()
+{
+ proto::assert_matches< proto::_ >( proto::lit(1) );
+ proto::assert_matches< proto::_ >( proto::as_child(1) );
+ proto::assert_matches< proto::_ >( proto::as_expr(1) );
+
+ proto::assert_matches< proto::terminal<int> >( proto::lit(1) );
+ proto::assert_matches< proto::terminal<int> >( proto::as_child(1) );
+ proto::assert_matches< proto::terminal<int> >( proto::as_expr(1) );
+
+ proto::assert_matches_not< proto::terminal<int> >( proto::lit('a') );
+ proto::assert_matches_not< proto::terminal<int> >( proto::as_child('a') );
+ proto::assert_matches_not< proto::terminal<int> >( proto::as_expr('a') );
+
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::lit('a') );
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_child('a') );
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_expr('a') );
+
+ proto::assert_matches_not< proto::terminal<int> >( proto::lit((int_convertible())) );
+ proto::assert_matches_not< proto::terminal<int> >( proto::as_child((int_convertible())) );
+ proto::assert_matches_not< proto::terminal<int> >( proto::as_expr((int_convertible())) );
+
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::lit((int_convertible())) );
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_child((int_convertible())) );
+ proto::assert_matches< proto::terminal<proto::convertible_to<int> > >( proto::as_expr((int_convertible())) );
+
+ proto::assert_matches< proto::if_<boost::is_same<proto::_value, int>() > >( proto::lit(1) );
+ proto::assert_matches_not< proto::if_<boost::is_same<proto::_value, int>() > >( proto::lit('a') );
+
+ proto::assert_matches<
+ proto::and_<
+ proto::terminal<proto::_>
+ , proto::if_<boost::is_same<proto::_value, int>() >
+ >
+ >( proto::lit(1) );
+
+ proto::assert_matches_not<
+ proto::and_<
+ proto::terminal<proto::_>
+ , proto::if_<boost::is_same<proto::_value, int>() >
+ >
+ >( proto::lit('a') );
+
+ proto::assert_matches< proto::terminal<char const *> >( proto::lit("hello") );
+ proto::assert_matches< proto::terminal<char const *> >( proto::as_child("hello") );
+ proto::assert_matches< proto::terminal<char const *> >( proto::as_expr("hello") );
+
+ proto::assert_matches< proto::terminal<char const[6]> >( proto::lit("hello") );
+ proto::assert_matches< proto::terminal<char const (&)[6]> >( proto::as_child("hello") );
+ proto::assert_matches< proto::terminal<char const[6]> >( proto::as_expr("hello") );
+
+ proto::assert_matches< proto::terminal<char [6]> >( proto::lit("hello") );
+ proto::assert_matches< proto::terminal<char [6]> >( proto::as_child("hello") );
+ proto::assert_matches< proto::terminal<char [6]> >( proto::as_expr("hello") );
+
+ proto::assert_matches< proto::terminal<char const[proto::N]> >( proto::lit("hello") );
+ proto::assert_matches< proto::terminal<char const (&)[proto::N]> >( proto::as_child("hello") );
+ proto::assert_matches< proto::terminal<char const[proto::N]> >( proto::as_expr("hello") );
+
+ proto::assert_matches< proto::terminal<char [proto::N]> >( proto::lit("hello") );
+ proto::assert_matches< proto::terminal<char [proto::N]> >( proto::as_child("hello") );
+ proto::assert_matches< proto::terminal<char [proto::N]> >( proto::as_expr("hello") );
+
+ proto::assert_matches< proto::terminal<wchar_t const[proto::N]> >( proto::lit(L"hello") );
+ proto::assert_matches< proto::terminal<wchar_t const (&)[proto::N]> >( proto::as_child(L"hello") );
+ proto::assert_matches< proto::terminal<wchar_t const[proto::N]> >( proto::as_expr(L"hello") );
+
+ proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::lit(L"hello") );
+ proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::as_child(L"hello") );
+ proto::assert_matches< proto::terminal<wchar_t [proto::N]> >( proto::as_expr(L"hello") );
+
+ proto::assert_matches_not< proto::if_<boost::is_same<proto::_value, int>()> >( proto::lit("hello") );
+
+ proto::assert_matches< proto::terminal<std::string> >( proto::lit(std::string("hello")) );
+ proto::assert_matches< proto::terminal<std::string> >( proto::as_child(std::string("hello")) );
+ proto::assert_matches< proto::terminal<std::string> >( proto::as_expr(std::string("hello")) );
+
+ proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::lit(std::string("hello")) );
+ proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::as_child(std::string("hello")) );
+ proto::assert_matches< proto::terminal<std::basic_string<proto::_> > >( proto::as_expr(std::string("hello")) );
+
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::lit(1) );
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::as_child(1) );
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> > >( proto::as_expr(1) );
+
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::lit(1) );
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::as_child(1) );
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_,proto::_,proto::_> > >( proto::as_expr(1) );
+
+ #if BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(61700))
+ typedef std::string const const_string;
+ #else
+ typedef std::string const_string;
+ #endif
+
+ proto::assert_matches< proto::terminal<std::basic_string<proto::_> const & > >( proto::lit(const_string("hello")) );
+ proto::assert_matches< proto::terminal<std::basic_string<proto::_> const & > >( proto::as_child(const_string("hello")) );
+ proto::assert_matches_not< proto::terminal<std::basic_string<proto::_> const & > >( proto::as_expr(const_string("hello")) );
+
+ proto::assert_matches< proto::terminal< void(&)() > >( proto::lit(a_function) );
+ proto::assert_matches< proto::terminal< void(&)() > >( proto::as_child(a_function) );
+ proto::assert_matches< proto::terminal< void(&)() > >( proto::as_expr(a_function) );
+
+ proto::assert_matches_not< proto::terminal< void(*)() > >( proto::lit(a_function) );
+ proto::assert_matches_not< proto::terminal< void(*)() > >( proto::as_child(a_function) );
+ proto::assert_matches_not< proto::terminal< void(*)() > >( proto::as_expr(a_function) );
+
+ proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::lit(a_function) );
+ proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::as_child(a_function) );
+ proto::assert_matches< proto::terminal< proto::convertible_to<void(*)()> > >( proto::as_expr(a_function) );
+
+ proto::assert_matches< proto::terminal< void(*)() > >( proto::lit(&a_function) );
+ proto::assert_matches< proto::terminal< void(*)() > >( proto::as_child(&a_function) );
+ proto::assert_matches< proto::terminal< void(*)() > >( proto::as_expr(&a_function) );
+
+ proto::assert_matches< proto::terminal< void(* const &)() > >( proto::lit(&a_function) );
+ proto::assert_matches< proto::terminal< void(* const &)() > >( proto::as_child(&a_function) );
+ proto::assert_matches_not< proto::terminal< void(* const &)() > >( proto::as_expr(&a_function) );
+
+ proto::assert_matches<
+ proto::or_<
+ proto::if_<boost::is_same<proto::_value, char>() >
+ , proto::if_<boost::is_same<proto::_value, int>() >
+ >
+ >( proto::lit(1) );
+
+ proto::assert_matches_not<
+ proto::or_<
+ proto::if_<boost::is_same<proto::_value, char>() >
+ , proto::if_<boost::is_same<proto::_value, int>() >
+ >
+ >( proto::lit(1u) );
+
+ proto::assert_matches< Input >( cin_ >> 1 >> 2 >> 3 );
+ proto::assert_matches_not< Output >( cin_ >> 1 >> 2 >> 3 );
+
+ proto::assert_matches< Output >( cout_ << 1 << 2 << 3 );
+ proto::assert_matches_not< Input >( cout_ << 1 << 2 << 3 );
+
+ proto::assert_matches< proto::function< proto::terminal<int>, proto::vararg< proto::terminal<char> > > >( proto::lit(1)('a','b','c','d') );
+ proto::assert_matches_not< proto::function< proto::terminal<int>, proto::vararg< proto::terminal<char> > > >( proto::lit(1)('a','b','c',"d") );
+
+ proto::assert_matches< Anything >( cout_ << 1 << +proto::lit('a') << proto::lit(1)('a','b','c',"d") );
+
+ proto::assert_matches< proto::switch_<MyCases> >( proto::lit(1) >> 'a' );
+ proto::assert_matches< proto::switch_<MyCases> >( proto::lit(1) + 'a' );
+ proto::assert_matches_not< proto::switch_<MyCases> >( proto::lit(1) << 'a' );
+
+ number<int, two_complement_c> num;
+ proto::assert_matches<NumberGrammar>(proto::as_expr(num));
+
+ // check custom terminal types
+ {
+ proto::nullary_expr<my_terminal, int>::type i = {0};
+
+ proto::assert_matches<proto::nullary_expr<my_terminal, proto::_> >( i );
+ proto::assert_matches_not<proto::terminal<proto::_> >( i );
+
+ proto::terminal<int>::type j = {0};
+ proto::assert_matches<proto::terminal<proto::_> >( j );
+ proto::assert_matches_not<proto::nullary_expr<my_terminal, proto::_> >( j );
+
+ proto::assert_matches<proto::nullary_expr<proto::_, proto::_> >( i );
+ }
+
+ // check 0 and 1 arg forms or or_ and and_
+ {
+ proto::assert_matches< proto::and_<> >( proto::lit(1) );
+ proto::assert_matches_not< proto::or_<> >( proto::lit(1) );
+
+ proto::assert_matches< proto::and_<proto::terminal<int> > >( proto::lit(1) );
+ proto::assert_matches< proto::or_<proto::terminal<int> > >( proto::lit(1) );
+ }
+
+ // Test lambda matches with arrays, a corner case that had
+ // a bug that was reported by Antoine de Maricourt on boost@lists.boost.org
+ {
+ a_template<int[3]> a;
+ proto::assert_matches< proto::terminal< a_template<proto::_> > >( proto::lit(a) );
+ }
+
+ // Test that the actual derived expression type makes it through to proto::if_
+ {
+ my_expr<proto::terminal<int>::type> e = {{1}};
+ proto::assert_matches< proto::if_<boost::is_same<proto::domain_of<proto::_>, my_domain>()> >( e );
+ }
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto::matches<>");
+
+ test->add(BOOST_TEST_CASE(&test_matches));
+
+ return test;
+}
+