mirror of
https://github.com/boostorg/xpressive.git
synced 2026-01-19 04:52:07 +00:00
179 lines
6.4 KiB
C++
179 lines
6.4 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// test_typeof2.cpp
|
|
//
|
|
// Copyright 2008 David Jenkins. 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)
|
|
|
|
#define BOOST_TYPEOF_LIMIT_SIZE 200
|
|
#define BOOST_TYPEOF_EMULATION 1
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <list>
|
|
#include <stack>
|
|
#include <boost/version.hpp>
|
|
#include <boost/xpressive/xpressive_static.hpp>
|
|
#include <boost/xpressive/regex_actions.hpp>
|
|
#include <boost/xpressive/xpressive_typeof.hpp>
|
|
#include <boost/typeof/std/stack.hpp>
|
|
#include <boost/typeof/std/list.hpp>
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
|
|
// I couldn't find these registrations anywhere else, so I put them here
|
|
// They are necessary for this program to compile
|
|
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
|
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::mpl::int_, (int))
|
|
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::reference_wrapper, (typename))
|
|
|
|
// Here's the test for typeof registration, to be used on static regular expressions
|
|
#define TYPEOF_TEST(Expr) { BOOST_PROTO_AUTO(Dummy, Expr); }
|
|
|
|
namespace xp = boost::xpressive;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// test_actions
|
|
// regular expressions from test_actions.cpp
|
|
void test_actions()
|
|
{
|
|
using namespace boost::xpressive;
|
|
// regexes from test_actions.cpp
|
|
std::string result;
|
|
TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]));
|
|
TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]) >> repeat<4>(_));
|
|
std::list<int> result2;
|
|
TYPEOF_TEST((+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ]
|
|
>> *(' ' >> (+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ]));
|
|
std::map<std::string, int> result3;
|
|
TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ xp::ref(result3)[s1] = as<int>(s2) ]);
|
|
placeholder< std::map<std::string, int> > const _map5 = {{}};
|
|
TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ _map5[s1] = as<int>(s2) ]);
|
|
|
|
smatch what;
|
|
placeholder< std::map<std::string, int> > const _map6 = {{}};
|
|
std::map<std::string, int> result6;
|
|
what.let(_map6 = result6); // bind the argument!
|
|
|
|
local<int> left, right;
|
|
std::stack<int> stack_;
|
|
reference<std::stack<int> > stack(stack_);
|
|
cregex expression2, factor2, term2, group2;
|
|
TYPEOF_TEST( '(' >> by_ref(expression2) >> ')');
|
|
TYPEOF_TEST( (+_d)[ push(stack, as<int>(_)) ] | group2);
|
|
TYPEOF_TEST(factor2 >> *(
|
|
('*' >> factor2)
|
|
[ right = top(stack)
|
|
, pop(stack)
|
|
, left = top(stack)
|
|
, pop(stack)
|
|
, push(stack, left * right)
|
|
]
|
|
));
|
|
TYPEOF_TEST(term2 >> *(
|
|
('+' >> term2)
|
|
[ right = top(stack)
|
|
, pop(stack)
|
|
, left = top(stack)
|
|
, pop(stack)
|
|
, push(stack, left + right)
|
|
]
|
|
));
|
|
}
|
|
|
|
|
|
#ifndef BOOST_XPRESSIVE_NO_WREGEX
|
|
struct City
|
|
{
|
|
std::wstring name;
|
|
char const* nickname;
|
|
int population;
|
|
};
|
|
BOOST_TYPEOF_REGISTER_TYPE(City)
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// test_symbols
|
|
// regular expressions from test_symbols.cpp
|
|
void test_symbols()
|
|
{
|
|
using namespace boost::xpressive;
|
|
std::string result;
|
|
std::map<std::string,std::string> map10;
|
|
TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ] >> *(' ' >> (a1=map10)[ xp::ref(result) += ',' + a1 ]));
|
|
TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ]
|
|
>> *((a1=map10)[ xp::ref(result) += ',', xp::ref(result) += a1 ]));
|
|
std::list<int> result12;
|
|
std::map<std::string,int> map12;
|
|
TYPEOF_TEST((a1=map12)[ xp::ref(result12)->*push_back( a1 ) ]
|
|
>> *(' ' >> (a1=map12)[ xp::ref(result12)->*push_back( a1 ) ]));
|
|
|
|
placeholder< std::map<std::string, int> > const _map13 = {};
|
|
BOOST_PROTO_AUTO(pair13, ( (a1=map10) >> "=>" >> (a2= map12) )[ _map13[a1] = a2 ]);
|
|
smatch what;
|
|
std::map<std::string, int> result13;
|
|
what.let(_map13 = result13);
|
|
TYPEOF_TEST(pair13 >> *(+_s >> pair13));
|
|
|
|
int result14 = 0;
|
|
std::map<std::string,int> map1a;
|
|
std::map<std::string,int> map2a;
|
|
std::map<std::string,int> map3a;
|
|
TYPEOF_TEST((a1=map1a)[ xp::ref(result14) += a1 ]
|
|
>> (a2=map2a)[ xp::ref(result) += a2 ]
|
|
>> (a3=map3a)[ xp::ref(result) += a3 ]
|
|
);
|
|
{
|
|
TYPEOF_TEST(icase(a1= map10) [ xp::ref(result) = a1 ]
|
|
>> repeat<3>( (' ' >> icase(a1= map10) [ xp::ref(result) += ',', xp::ref(result) += a1 ]) )
|
|
);
|
|
TYPEOF_TEST(*((a1= map1a) | (a1= map2a) | 'e') [ xp::ref(result) += (a1 | "9") ]);
|
|
}
|
|
#ifndef BOOST_XPRESSIVE_NO_WREGEX
|
|
City result17a, result17b;
|
|
std::map<std::wstring, City> map17;
|
|
TYPEOF_TEST((a1= map17)[ xp::ref(result17a) = a1 ] >> +_s
|
|
>> (a1= map17)[ xp::ref(result17b) = a1 ]);
|
|
#else
|
|
// This test is empty
|
|
#endif
|
|
|
|
}
|
|
|
|
bool three_or_six(xp::csub_match const &sub)
|
|
{
|
|
return sub.length() == 3 || sub.length() == 6;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// test_assert
|
|
// regular expressions from test_assert.cpp
|
|
void test_assert()
|
|
{
|
|
using namespace boost::xpressive;
|
|
std::string result;
|
|
TYPEOF_TEST((bow >> +_w >> eow)[ check(&three_or_six) ]);
|
|
TYPEOF_TEST((bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ]);
|
|
int const days_per_month[] =
|
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 31, 31};
|
|
mark_tag month(1), day(2);
|
|
// Note: if you uncomment the lines below,
|
|
// the BOOST_TYPEOF_LIMIT_SIZE is exceeded
|
|
TYPEOF_TEST((
|
|
// Month must be between 1 and 12 inclusive
|
|
(month= _d >> !_d) [ check(as<int>(_) >= 1
|
|
&& as<int>(_) <= 12) ]
|
|
//>> '/'
|
|
// // Day must be between 1 and 31 inclusive
|
|
//>> (day= _d >> !_d) [ check(as<int>(_) >= 1
|
|
// && as<int>(_) <= 31) ]
|
|
//>> '/'
|
|
// // Only consider years between 1970 and 2038
|
|
//>> (_d >> _d >> _d >> _d) [ check(as<int>(_) >= 1970
|
|
// && as<int>(_) <= 2038) ]
|
|
)
|
|
// Ensure the month actually has that many days.
|
|
[ check( ref(days_per_month)[as<int>(month)-1] >= as<int>(day) ) ]);
|
|
}
|
|
|