| /////////////////////////////////////////////////////////////////////////////// |
| // sub_match_vector.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_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005 |
| #define BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005 |
| |
| // MS compatible compilers support #pragma once |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| # pragma once |
| #endif |
| |
| #include <boost/noncopyable.hpp> |
| #include <boost/iterator_adaptors.hpp> |
| #include <boost/xpressive/detail/detail_fwd.hpp> |
| #include <boost/xpressive/detail/core/sub_match_impl.hpp> |
| |
| namespace boost { namespace xpressive { namespace detail |
| { |
| |
| #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200 |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // sub_match_iterator |
| // |
| template<typename Value, typename MainIter> |
| struct sub_match_iterator |
| : iterator_adaptor |
| < |
| sub_match_iterator<Value, MainIter> |
| , MainIter |
| , Value |
| , std::random_access_iterator_tag |
| > |
| { |
| typedef iterator_adaptor |
| < |
| sub_match_iterator<Value, MainIter> |
| , MainIter |
| , Value |
| , std::random_access_iterator_tag |
| > base_t; |
| |
| sub_match_iterator(MainIter baseiter) |
| : base_t(baseiter) |
| { |
| } |
| }; |
| |
| #endif |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // sub_match_vector |
| // |
| template<typename BidiIter> |
| struct sub_match_vector |
| : private noncopyable |
| { |
| private: |
| struct dummy { int i_; }; |
| typedef int dummy::*bool_type; |
| |
| public: |
| typedef sub_match<BidiIter> value_type; |
| typedef std::size_t size_type; |
| typedef value_type const &const_reference; |
| typedef const_reference reference; |
| typedef typename iterator_difference<BidiIter>::type difference_type; |
| typedef typename iterator_value<BidiIter>::type char_type; |
| typedef typename sub_match<BidiIter>::string_type string_type; |
| |
| #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200 |
| |
| typedef sub_match_iterator |
| < |
| value_type const |
| , sub_match_impl<BidiIter> const * |
| > const_iterator; |
| |
| #else |
| |
| typedef iterator_adaptor |
| < |
| sub_match_impl<BidiIter> const * |
| , default_iterator_policies |
| , value_type |
| , value_type const & |
| , value_type const * |
| > const_iterator; |
| |
| #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 |
| |
| typedef const_iterator iterator; |
| |
| sub_match_vector() |
| : size_(0) |
| , sub_matches_(0) |
| { |
| } |
| |
| const_reference operator [](size_type index) const |
| { |
| static value_type const s_null; |
| return (index >= this->size_) |
| ? s_null |
| : *static_cast<value_type const *>(&this->sub_matches_[ index ]); |
| } |
| |
| size_type size() const |
| { |
| return this->size_; |
| } |
| |
| bool empty() const |
| { |
| return 0 == this->size(); |
| } |
| |
| const_iterator begin() const |
| { |
| return const_iterator(this->sub_matches_); |
| } |
| |
| const_iterator end() const |
| { |
| return const_iterator(this->sub_matches_ + this->size_); |
| } |
| |
| operator bool_type() const |
| { |
| return (!this->empty() && (*this)[0].matched) ? &dummy::i_ : 0; |
| } |
| |
| bool operator !() const |
| { |
| return this->empty() || !(*this)[0].matched; |
| } |
| |
| void swap(sub_match_vector<BidiIter> &that) |
| { |
| std::swap(this->size_, that.size_); |
| std::swap(this->sub_matches_, that.sub_matches_); |
| } |
| |
| private: |
| friend struct detail::core_access<BidiIter>; |
| |
| void init_(sub_match_impl<BidiIter> *sub_matches, size_type size) |
| { |
| this->size_ = size; |
| this->sub_matches_ = sub_matches; |
| } |
| |
| void init_(sub_match_impl<BidiIter> *sub_matches, size_type size, sub_match_vector<BidiIter> const &that) |
| { |
| BOOST_ASSERT(size == that.size_); |
| this->size_ = size; |
| this->sub_matches_ = sub_matches; |
| std::copy(that.sub_matches_, that.sub_matches_ + that.size_, this->sub_matches_); |
| } |
| |
| size_type size_; |
| sub_match_impl<BidiIter> *sub_matches_; |
| }; |
| |
| }}} // namespace boost::xpressive::detail |
| |
| #endif |