mirror of
https://github.com/boostorg/xpressive.git
synced 2025-05-11 13:23:56 +00:00
faster, better use_simple_repeat<> trait
[SVN r37835]
This commit is contained in:
parent
f51effb483
commit
f13bde65cb
@ -26,8 +26,6 @@ namespace boost { namespace fusion
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
|
||||
#include <boost/xpressive/detail/utility/algorithm.hpp>
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
#include <boost/xpressive/detail/utility/save_restore.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
|
||||
|
@ -54,7 +54,7 @@ struct quant_style
|
||||
typedef void is_boost_xpressive_xpression_;
|
||||
|
||||
// Which quantification strategy to use?
|
||||
BOOST_STATIC_CONSTANT(quant_enum, quant = QuantStyle);
|
||||
BOOST_STATIC_CONSTANT(int, quant = QuantStyle);
|
||||
|
||||
// how many characters this matcher consumes
|
||||
BOOST_STATIC_CONSTANT(std::size_t, width = Width);
|
||||
@ -70,7 +70,7 @@ struct quant_style
|
||||
|
||||
#define BOOST_XPR_QUANT_STYLE(Style, Width, Pure)\
|
||||
typedef void is_boost_xpressive_xpression_;\
|
||||
BOOST_STATIC_CONSTANT(quant_enum, quant = Style);\
|
||||
BOOST_STATIC_CONSTANT(int, quant = Style);\
|
||||
BOOST_STATIC_CONSTANT(std::size_t, width = Width);\
|
||||
BOOST_STATIC_CONSTANT(bool, pure = Pure);\
|
||||
static detail::width get_width() { return width; }\
|
||||
|
@ -41,7 +41,7 @@ struct sequence
|
||||
sequence(intrusive_ptr<dynamic_xpression<Matcher, BidiIter> > const &xpr)
|
||||
: pure_(Matcher::pure)
|
||||
, width_(xpr->Matcher::get_width())
|
||||
, quant_(Matcher::quant)
|
||||
, quant_(static_cast<quant_enum>(Matcher::quant))
|
||||
, head_(xpr)
|
||||
, tail_(&xpr->next_)
|
||||
, alt_end_xpr_()
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/transform/arg.hpp>
|
||||
#include <boost/xpressive/proto/transform/fold.hpp>
|
||||
@ -64,7 +65,7 @@ namespace boost { namespace xpressive
|
||||
template<typename Char, typename Tag, bool Greedy>
|
||||
struct as_repeat
|
||||
: proto::trans::conditional<
|
||||
use_simple_repeat<proto::result_of::arg<mpl::_> >
|
||||
use_simple_repeat<proto::result_of::arg<mpl::_>, Char>
|
||||
, as_simple_quantifier<proto::unary_expr<Tag, Grammar<Char> >, Greedy>
|
||||
, as_default_quantifier<proto::unary_expr<Tag, Grammar<Char> >, Greedy>
|
||||
>
|
||||
|
@ -17,198 +17,181 @@
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// equivalent to mpl::and_<X, Y>
|
||||
#define BOOST_XPR_AND_PURE_(X, Y) \
|
||||
mpl::and_<X, Y >
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// use_simple_repeat
|
||||
// use_simple_repeat_terminal
|
||||
//
|
||||
template<typename Expr>
|
||||
struct use_simple_repeat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_terminal_pure
|
||||
//
|
||||
template<typename Expr, bool IsXpr = is_xpr<Expr>::value>
|
||||
struct is_terminal_pure
|
||||
: mpl::bool_<Expr::pure> // xpression types
|
||||
template<typename Expr, typename Char, bool IsXpr = is_xpr<Expr>::value>
|
||||
struct use_simple_repeat_terminal
|
||||
: mpl::bool_<
|
||||
Expr::quant == quant_fixed_width
|
||||
|| (Expr::width != unknown_width::value && Expr::pure)
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_terminal_pure<Expr, false>
|
||||
: mpl::true_ // char literals
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_terminal<Expr, Char, false>
|
||||
: mpl::true_ // char literals, string literals, etc.
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_terminal_pure<Expr *, false>
|
||||
: mpl::true_ // string literals
|
||||
template<typename BidiIter, typename Char>
|
||||
struct use_simple_repeat_terminal<tracking_ptr<regex_impl<BidiIter> >, Char, false>
|
||||
: mpl::false_ // basic_regex
|
||||
{};
|
||||
|
||||
template<typename Char, std::size_t N>
|
||||
struct is_terminal_pure<Char (&) [N], false>
|
||||
: mpl::true_ // string literals
|
||||
template<typename BidiIter, typename Char>
|
||||
struct use_simple_repeat_terminal<reference_wrapper<basic_regex<BidiIter> >, Char, false>
|
||||
: mpl::false_ // basic_regex
|
||||
{};
|
||||
|
||||
template<typename Char, std::size_t N>
|
||||
struct is_terminal_pure<Char const (&) [N], false>
|
||||
: mpl::true_ // string literals
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct is_terminal_pure<tracking_ptr<regex_impl<BidiIter> >, false>
|
||||
: mpl::false_ // basic_regex
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct is_terminal_pure<reference_wrapper<basic_regex<BidiIter> >, false>
|
||||
: mpl::false_ // basic_regex
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct is_terminal_pure<reference_wrapper<basic_regex<BidiIter> const>, false>
|
||||
: mpl::false_ // basic_regex
|
||||
template<typename BidiIter, typename Char>
|
||||
struct use_simple_repeat_terminal<reference_wrapper<basic_regex<BidiIter> const>, Char, false>
|
||||
: mpl::false_ // basic_regex
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_pure
|
||||
// use_simple_repeat_
|
||||
//
|
||||
template<typename Expr, typename Tag = typename Expr::tag_type>
|
||||
struct is_pure {};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::terminal>
|
||||
: is_terminal_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char, typename Tag = typename Expr::tag_type>
|
||||
struct use_simple_repeat_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::shift_right>
|
||||
: BOOST_XPR_AND_PURE_(
|
||||
is_pure<typename proto::result_of::left<Expr>::type>
|
||||
, is_pure<typename proto::result_of::right<Expr>::type>
|
||||
)
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::terminal>
|
||||
: use_simple_repeat_terminal<typename proto::result_of::arg<Expr>::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::bitwise_or>
|
||||
: BOOST_XPR_AND_PURE_(
|
||||
is_pure<typename proto::result_of::left<Expr>::type>
|
||||
, is_pure<typename proto::result_of::right<Expr>::type>
|
||||
)
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::shift_right>
|
||||
: mpl::and_<
|
||||
use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
, use_simple_repeat_<typename Expr::arg1_type::type, Char>
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::bitwise_or>
|
||||
: mpl::and_<
|
||||
use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
, use_simple_repeat_<typename Expr::arg1_type::type, Char>
|
||||
, mpl::not_equal_to<unknown_width, width_of<Expr, Char> >
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename Left>
|
||||
struct is_pure_assign {};
|
||||
struct use_simple_repeat_assign
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_pure_assign<basic_mark_tag>
|
||||
struct use_simple_repeat_assign<basic_mark_tag>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_pure_assign<set_initializer_type>
|
||||
struct use_simple_repeat_assign<set_initializer_type>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
// either (s1 = ...) or (set = ...)
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::assign>
|
||||
: is_pure_assign<typename proto::result_of::left<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::assign>
|
||||
: use_simple_repeat_assign<typename Expr::arg0_type::type>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, modifier_tag>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, modifier_tag>
|
||||
: use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, lookahead_tag>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, lookahead_tag>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, lookbehind_tag>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, lookbehind_tag>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, keeper_tag>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, keeper_tag>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
// when complementing a set or an assertion, the purity is that of the set (true) or the assertion
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::complement>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::complement>
|
||||
: use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
// The comma is used in list-initialized sets, which are pure
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::comma>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::comma>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
// The subscript operator[] is used for sets, as in set['a' | range('b','h')]
|
||||
// It is also used for actions, which by definition have side-effects and thus are impure
|
||||
template<typename Expr, typename Left>
|
||||
struct is_pure_subscript
|
||||
template<typename Expr, typename Char, typename Left>
|
||||
struct use_simple_repeat_subscript
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure_subscript<Expr, set_initializer_type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_subscript<Expr, Char, set_initializer_type>
|
||||
: mpl::true_
|
||||
{
|
||||
// If Left is "set" then make sure that Right is pure
|
||||
BOOST_MPL_ASSERT((is_pure<typename proto::result_of::right<Expr>::type>));
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::subscript>
|
||||
: is_pure_subscript<Expr, typename proto::result_of::left<Expr>::type>
|
||||
{};
|
||||
|
||||
// Quantified expressions are pure IFF they use the simple_repeat_matcher
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::posit>
|
||||
: use_simple_repeat<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::subscript>
|
||||
: use_simple_repeat_subscript<Expr, Char, typename Expr::arg0_type::type>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::dereference>
|
||||
: use_simple_repeat<typename proto::result_of::arg<Expr>::type>
|
||||
// Quantified expressions are variable-width and cannot use the simple quantifier
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::posit>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::logical_not>
|
||||
: use_simple_repeat<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::dereference>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr, uint_t Min, uint_t Max>
|
||||
struct is_pure<Expr, generic_quant_tag<Min, Max> >
|
||||
: use_simple_repeat<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::logical_not>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct is_pure<Expr, proto::tag::negate>
|
||||
: is_pure<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char, uint_t Min, uint_t Max>
|
||||
struct use_simple_repeat_<Expr, Char, generic_quant_tag<Min, Max> >
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Char, uint_t Count>
|
||||
struct use_simple_repeat_<Expr, Char, generic_quant_tag<Count, Count> >
|
||||
: use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat_<Expr, Char, proto::tag::negate>
|
||||
: use_simple_repeat_<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// use_simple_repeat
|
||||
//
|
||||
template<typename Expr>
|
||||
template<typename Expr, typename Char>
|
||||
struct use_simple_repeat
|
||||
: mpl::bool_<width_of<Expr>::value != unknown_width::value && is_pure<Expr>::value>
|
||||
: use_simple_repeat_<Expr, Char>
|
||||
{
|
||||
// should never try to repeat something of 0-width
|
||||
BOOST_MPL_ASSERT_RELATION(0, !=, width_of<Expr>::value);
|
||||
BOOST_MPL_ASSERT_RELATION(0, !=, (width_of<Expr, Char>::value));
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
@ -25,212 +25,201 @@
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/traits.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// add widths
|
||||
#define BOOST_XPR_ADD_WIDTH_(X, Y) \
|
||||
mpl::if_< \
|
||||
mpl::or_<mpl::equal_to<X, unknown_width>, mpl::equal_to<Y, unknown_width> > \
|
||||
, unknown_width \
|
||||
, mpl::plus<X, Y > \
|
||||
>::type
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// multiply widths
|
||||
#define BOOST_XPR_MULT_WIDTH_(X, Y) \
|
||||
mpl::if_< \
|
||||
mpl::or_<mpl::equal_to<X, unknown_width>, mpl::equal_to<Y, unknown_width> > \
|
||||
, unknown_width \
|
||||
, mpl::times<X, Y > \
|
||||
>::type
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// check widths for equality
|
||||
#define BOOST_XPR_EQUAL_WIDTH_(X, Y) \
|
||||
mpl::if_< \
|
||||
mpl::equal_to<X, Y > \
|
||||
, X \
|
||||
, unknown_width \
|
||||
>::type
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// width_of_terminal
|
||||
//
|
||||
template<typename Expr, bool IsXpr = is_xpr<Expr>::value>
|
||||
template<typename Expr, typename Char, bool IsXpr = is_xpr<Expr>::value>
|
||||
struct width_of_terminal
|
||||
: mpl::size_t<Expr::width> // char literals
|
||||
: mpl::size_t<Expr::width> // xpressive literals
|
||||
{};
|
||||
|
||||
// BUGBUG this is wrong!!!
|
||||
template<typename Expr>
|
||||
struct width_of_terminal<Expr, false>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of_terminal<Expr, Char, false>
|
||||
: unknown_width // unknown literals (eg, basic_string, basic_regex, etc.)
|
||||
{};
|
||||
|
||||
template<typename Char>
|
||||
struct width_of_terminal<Char, Char, false>
|
||||
: mpl::size_t<1> // char literals
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of_terminal<Expr *, false>
|
||||
: unknown_width // string literals
|
||||
template<typename Char>
|
||||
struct width_of_terminal<char, Char, false>
|
||||
: mpl::size_t<1> // char literals
|
||||
{};
|
||||
|
||||
template<typename Char, std::size_t N>
|
||||
struct width_of_terminal<Char (&) [N], false>
|
||||
template<>
|
||||
struct width_of_terminal<char, char, false>
|
||||
: mpl::size_t<1> // char literals
|
||||
{};
|
||||
|
||||
template<typename Elem, std::size_t N, typename Char>
|
||||
struct width_of_terminal<Elem (&) [N], Char, false>
|
||||
: mpl::size_t<N-1> // string literals
|
||||
{};
|
||||
|
||||
template<typename Char, std::size_t N>
|
||||
struct width_of_terminal<Char const (&) [N], false>
|
||||
template<typename Elem, std::size_t N, typename Char>
|
||||
struct width_of_terminal<Elem const (&) [N], Char, false>
|
||||
: mpl::size_t<N-1> // string literals
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct width_of_terminal<tracking_ptr<regex_impl<BidiIter> >, false>
|
||||
: unknown_width // basic_regex
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct width_of_terminal<reference_wrapper<basic_regex<BidiIter> >, false>
|
||||
: unknown_width // basic_regex
|
||||
{};
|
||||
|
||||
template<typename BidiIter>
|
||||
struct width_of_terminal<reference_wrapper<basic_regex<BidiIter> const>, false>
|
||||
: unknown_width // basic_regex
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// width_of
|
||||
//
|
||||
template<typename Expr, typename Tag = typename Expr::tag_type>
|
||||
struct width_of;
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::terminal>
|
||||
: width_of_terminal<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char, typename Tag = typename Expr::tag_type>
|
||||
struct width_of
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::shift_right>
|
||||
: BOOST_XPR_ADD_WIDTH_(
|
||||
width_of<typename proto::result_of::left<Expr>::type>
|
||||
, width_of<typename proto::result_of::right<Expr>::type>
|
||||
)
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::terminal>
|
||||
: width_of_terminal<typename proto::result_of::arg<Expr>::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::bitwise_or>
|
||||
: BOOST_XPR_EQUAL_WIDTH_(
|
||||
width_of<typename proto::result_of::left<Expr>::type>
|
||||
, width_of<typename proto::result_of::right<Expr>::type>
|
||||
)
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::shift_right>
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
mpl::equal_to<unknown_width, width_of<typename Expr::arg0_type::type, Char> >
|
||||
, mpl::equal_to<unknown_width, width_of<typename Expr::arg1_type::type, Char> >
|
||||
>
|
||||
, unknown_width
|
||||
, mpl::plus<
|
||||
width_of<typename Expr::arg0_type::type, Char>
|
||||
, width_of<typename Expr::arg1_type::type, Char>
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Left>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::bitwise_or>
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
mpl::equal_to<unknown_width, width_of<typename Expr::arg0_type::type, Char> >
|
||||
, mpl::not_equal_to<
|
||||
width_of<typename Expr::arg0_type::type, Char>
|
||||
, width_of<typename Expr::arg1_type::type, Char>
|
||||
>
|
||||
>
|
||||
, unknown_width
|
||||
, width_of<typename Expr::arg0_type::type, Char>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<typename Expr, typename Char, typename Left>
|
||||
struct width_of_assign;
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of_assign<Expr, basic_mark_tag>
|
||||
: width_of<typename proto::result_of::right<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of_assign<Expr, Char, basic_mark_tag>
|
||||
: width_of<typename Expr::arg1_type::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of_assign<Expr, set_initializer_type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of_assign<Expr, Char, set_initializer_type>
|
||||
: mpl::size_t<1>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::assign>
|
||||
: width_of_assign<Expr, typename proto::result_of::left<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::assign>
|
||||
: width_of_assign<Expr, Char, typename Expr::arg0_type::type>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, modifier_tag>
|
||||
: width_of<typename proto::result_of::right<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, modifier_tag>
|
||||
: width_of<typename Expr::arg1_type::type, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, lookahead_tag>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, lookahead_tag>
|
||||
: mpl::size_t<0>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, lookbehind_tag>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, lookbehind_tag>
|
||||
: mpl::size_t<0>
|
||||
{};
|
||||
|
||||
// keep() is used to turn off backtracking, so they should only be used
|
||||
// for things that are variable-width (eg. quantified)
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, keeper_tag>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, keeper_tag>
|
||||
: unknown_width
|
||||
{
|
||||
// If this assert fires, you put something that doesn't require backtracking
|
||||
// in a keep(). In that case, the keep() is not necessary and you should just
|
||||
// remove it.
|
||||
BOOST_MPL_ASSERT_RELATION(width_of<typename proto::result_of::arg<Expr>::type>::value, ==, unknown_width::value);
|
||||
BOOST_MPL_ASSERT_RELATION((width_of<typename Expr::arg0_type::type, Char>::value), ==, unknown_width::value);
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::posit>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::posit>
|
||||
: unknown_width
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::dereference>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::dereference>
|
||||
: unknown_width
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::logical_not>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::logical_not>
|
||||
: unknown_width
|
||||
{};
|
||||
|
||||
template<typename Expr, uint_t Min, uint_t Max>
|
||||
struct width_of<Expr, generic_quant_tag<Min, Max> >
|
||||
template<typename Expr, typename Char, uint_t Min, uint_t Max>
|
||||
struct width_of<Expr, Char, generic_quant_tag<Min, Max> >
|
||||
: unknown_width
|
||||
{};
|
||||
|
||||
template<typename Expr, uint_t Count>
|
||||
struct width_of<Expr, generic_quant_tag<Count, Count> >
|
||||
: BOOST_XPR_MULT_WIDTH_(width_of<typename proto::result_of::arg<Expr>::type>, mpl::size_t<Count>)
|
||||
template<typename Expr, typename Char, uint_t Count>
|
||||
struct width_of<Expr, Char, generic_quant_tag<Count, Count> >
|
||||
: mpl::if_<
|
||||
mpl::equal_to<unknown_width, width_of<typename Expr::arg0_type::type, Char> >
|
||||
, unknown_width
|
||||
, mpl::times<
|
||||
width_of<typename Expr::arg0_type::type, Char>
|
||||
, mpl::size_t<Count>
|
||||
>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::negate>
|
||||
: width_of<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::negate>
|
||||
: width_of<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
// when complementing a set or an assertion, the width is that of the set (1) or the assertion (0)
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::complement>
|
||||
: width_of<typename proto::result_of::arg<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::complement>
|
||||
: width_of<typename Expr::arg0_type::type, Char>
|
||||
{};
|
||||
|
||||
// The comma is used in list-initialized sets, and the width of sets are 1
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::comma>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::comma>
|
||||
: mpl::size_t<1>
|
||||
{};
|
||||
|
||||
// The subscript operator[] is used for sets, as in set['a' | range('b','h')],
|
||||
// or for actions as in (any >> expr)[ action ]
|
||||
template<typename Expr, typename Left>
|
||||
template<typename Expr, typename Char, typename Left>
|
||||
struct width_of_subscript
|
||||
: width_of<Left>
|
||||
: width_of<Left, Char>
|
||||
{};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of_subscript<Expr, set_initializer_type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of_subscript<Expr, Char, set_initializer_type>
|
||||
: mpl::size_t<1>
|
||||
{
|
||||
// If Left is "set" then make sure that Right has a width_of 1
|
||||
BOOST_MPL_ASSERT_RELATION(1, ==, width_of<typename proto::result_of::right<Expr>::type>::value);
|
||||
BOOST_MPL_ASSERT_RELATION(1, ==, (width_of<typename Expr::arg1_type::type, Char>::value));
|
||||
};
|
||||
|
||||
template<typename Expr>
|
||||
struct width_of<Expr, proto::tag::subscript>
|
||||
: width_of_subscript<Expr, typename proto::result_of::left<Expr>::type>
|
||||
template<typename Expr, typename Char>
|
||||
struct width_of<Expr, Char, proto::tag::subscript>
|
||||
: width_of_subscript<Expr, Char, typename Expr::arg0_type::type>
|
||||
{};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
@ -170,9 +170,9 @@ inline void display_type2()
|
||||
string_remove(str, "fusion::");
|
||||
|
||||
//std::printf("%s\n\n", str.c_str());
|
||||
std::printf("%s\nwdith=%d\nis_pure=%s\n\n", str.c_str()
|
||||
, detail::width_of<T>::value
|
||||
, detail::is_pure<T>::value ? "true" : "false");
|
||||
std::printf("%s\nwdith=%d\nuse_simple_repeat=%s\n\n", str.c_str()
|
||||
, detail::width_of<T, char>::value
|
||||
, detail::use_simple_repeat<T, char>::value ? "true" : "false");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user