| /////////////////////////////////////////////////////////////////////////////// |
| // adaptor.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) |
| |
| #ifndef BOOST_XPRESSIVE_DETAIL_CORE_ADAPTOR_HPP_EAN_10_04_2005 |
| #define BOOST_XPRESSIVE_DETAIL_CORE_ADAPTOR_HPP_EAN_10_04_2005 |
| |
| // MS compatible compilers support #pragma once |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| #include <boost/ref.hpp> |
| #include <boost/implicit_cast.hpp> |
| #include <boost/intrusive_ptr.hpp> |
| #include <boost/xpressive/detail/detail_fwd.hpp> |
| #include <boost/xpressive/detail/dynamic/matchable.hpp> |
| |
| namespace boost { namespace xpressive { namespace detail |
| { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // xpression_adaptor |
| // |
| // wrap a static xpression in a matchable interface so it can be stored |
| // in and invoked from a basic_regex object. |
| template<typename Xpr, typename Base> |
| struct xpression_adaptor |
| : Base // either matchable or matchable_ex |
| { |
| typedef typename Base::iterator_type iterator_type; |
| typedef typename iterator_value<iterator_type>::type char_type; |
| |
| Xpr xpr_; |
| |
| xpression_adaptor(Xpr const &xpr) |
| #if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4)) \ |
| && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) |
| // Ugh, gcc has an optimizer bug which elides this c'tor call |
| // resulting in pure virtual function calls. |
| __attribute__((noinline)) |
| #endif |
| : xpr_(xpr) |
| { |
| } |
| |
| virtual bool match(match_state<iterator_type> &state) const |
| { |
| typedef typename unwrap_reference<Xpr const>::type xpr_type; |
| return implicit_cast<xpr_type &>(this->xpr_).match(state); |
| } |
| |
| void link(xpression_linker<char_type> &linker) const |
| { |
| this->xpr_.link(linker); |
| } |
| |
| void peek(xpression_peeker<char_type> &peeker) const |
| { |
| this->xpr_.peek(peeker); |
| } |
| |
| private: |
| xpression_adaptor &operator =(xpression_adaptor const &); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // make_adaptor |
| // |
| template<typename Base, typename Xpr> |
| inline intrusive_ptr<Base const> make_adaptor(Xpr const &xpr) |
| { |
| return intrusive_ptr<Base const>(new xpression_adaptor<Xpr, Base>(xpr)); |
| } |
| |
| }}} // namespace boost::xpressive::detail |
| |
| #endif |