faster, better use_simple_repeat<> trait

[SVN r37835]
This commit is contained in:
Eric Niebler 2007-05-31 18:51:51 +00:00
parent f51effb483
commit f13bde65cb
9 changed files with 213 additions and 244 deletions

View File

@ -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>

View File

@ -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
{

View File

@ -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>

View File

@ -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; }\

View File

@ -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_()

View File

@ -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>
>

View File

@ -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

View File

@ -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

View File

@ -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");
}
///////////////////////////////////////////////////////////////////////////////