diff options
Diffstat (limited to 'boost/xpressive/regex_actions.hpp')
-rw-r--r-- | boost/xpressive/regex_actions.hpp | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/boost/xpressive/regex_actions.hpp b/boost/xpressive/regex_actions.hpp index e22b164a88..1f9617ba31 100644 --- a/boost/xpressive/regex_actions.hpp +++ b/boost/xpressive/regex_actions.hpp @@ -20,14 +20,17 @@ #include <boost/mpl/if.hpp> #include <boost/mpl/or.hpp> #include <boost/mpl/int.hpp> +#include <boost/mpl/assert.hpp> #include <boost/noncopyable.hpp> #include <boost/lexical_cast.hpp> #include <boost/throw_exception.hpp> #include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_reference.hpp> +#include <boost/range/iterator_range.hpp> #include <boost/xpressive/detail/detail_fwd.hpp> #include <boost/xpressive/detail/core/state.hpp> #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp> @@ -35,6 +38,7 @@ #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp> #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp> #include <boost/xpressive/detail/utility/ignore_unused.hpp> +#include <boost/xpressive/detail/static/type_traits.hpp> // These are very often needed by client code. #include <boost/typeof/std/map.hpp> @@ -62,21 +66,6 @@ #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required #endif -namespace boost -{ - namespace detail - { - // Bit of a hack to make lexical_cast work with wide sub_match - template<typename T> - struct stream_char; - - template<typename BidiIter> - struct stream_char<xpressive::sub_match<BidiIter> > - : boost::iterator_value<BidiIter> - {}; - } -} - namespace boost { namespace xpressive { @@ -572,7 +561,53 @@ namespace boost { namespace xpressive template<typename Value> T operator()(Value const &val) const { - return lexical_cast<T>(val); + return boost::lexical_cast<T>(val); + } + + // Hack around some limitations in boost::lexical_cast + T operator()(csub_match const &val) const + { + return val.matched + ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second)) + : boost::lexical_cast<T>(""); + } + + #ifndef BOOST_XPRESSIVE_NO_WREGEX + T operator()(wcsub_match const &val) const + { + return val.matched + ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second)) + : boost::lexical_cast<T>(""); + } + #endif + + template<typename BidiIter> + T operator()(sub_match<BidiIter> const &val) const + { + // If this assert fires, you're trying to coerce a sequences of non-characters + // to some other type. Xpressive doesn't know how to do that. + typedef typename iterator_value<BidiIter>::type char_type; + BOOST_MPL_ASSERT_MSG( + (xpressive::detail::is_char<char_type>::value) + , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES + , (char_type) + ); + return this->impl(val, xpressive::detail::is_string_iterator<BidiIter>()); + } + + private: + template<typename RandIter> + T impl(sub_match<RandIter> const &val, mpl::true_) const + { + return val.matched + ? boost::lexical_cast<T>(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first))) + : boost::lexical_cast<T>(""); + } + + template<typename BidiIter> + T impl(sub_match<BidiIter> const &val, mpl::false_) const + { + return boost::lexical_cast<T>(val.str()); } }; |