1 /////////////////////////////////////////////////////////////////////////////// 2 // sub_match_vector.hpp 3 // 4 // Copyright 2008 Eric Niebler. Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005 9 #define BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/noncopyable.hpp> 17 #include <boost/iterator_adaptors.hpp> 18 #include <boost/xpressive/detail/detail_fwd.hpp> 19 #include <boost/xpressive/detail/core/sub_match_impl.hpp> 20 21 namespace boost { namespace xpressive { namespace detail 22 { 23 24 #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200 25 26 ////////////////////////////////////////////////////////////////////////// 27 // sub_match_iterator 28 // 29 template<typename Value, typename MainIter> 30 struct sub_match_iterator 31 : iterator_adaptor 32 < 33 sub_match_iterator<Value, MainIter> 34 , MainIter 35 , Value 36 , std::random_access_iterator_tag 37 > 38 { 39 typedef iterator_adaptor 40 < 41 sub_match_iterator<Value, MainIter> 42 , MainIter 43 , Value 44 , std::random_access_iterator_tag 45 > base_t; 46 sub_match_iteratorboost::xpressive::detail::sub_match_iterator47 sub_match_iterator(MainIter baseiter) 48 : base_t(baseiter) 49 { 50 } 51 }; 52 53 #endif 54 55 ////////////////////////////////////////////////////////////////////////// 56 // sub_match_vector 57 // 58 template<typename BidiIter> 59 struct sub_match_vector 60 : private noncopyable 61 { 62 private: 63 struct dummy { int i_; }; 64 typedef int dummy::*bool_type; 65 66 public: 67 typedef sub_match<BidiIter> value_type; 68 typedef std::size_t size_type; 69 typedef value_type const &const_reference; 70 typedef const_reference reference; 71 typedef typename iterator_difference<BidiIter>::type difference_type; 72 typedef typename iterator_value<BidiIter>::type char_type; 73 typedef typename sub_match<BidiIter>::string_type string_type; 74 75 #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200 76 77 typedef sub_match_iterator 78 < 79 value_type const 80 , sub_match_impl<BidiIter> const * 81 > const_iterator; 82 83 #else 84 85 typedef iterator_adaptor 86 < 87 sub_match_impl<BidiIter> const * 88 , default_iterator_policies 89 , value_type 90 , value_type const & 91 , value_type const * 92 > const_iterator; 93 94 #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200 95 96 typedef const_iterator iterator; 97 sub_match_vectorboost::xpressive::detail::sub_match_vector98 sub_match_vector() 99 : size_(0) 100 , sub_matches_(0) 101 { 102 } 103 operator []boost::xpressive::detail::sub_match_vector104 const_reference operator [](size_type index) const 105 { 106 static value_type const s_null; 107 return (index >= this->size_) 108 ? s_null 109 : *static_cast<value_type const *>(&this->sub_matches_[ index ]); 110 } 111 sizeboost::xpressive::detail::sub_match_vector112 size_type size() const 113 { 114 return this->size_; 115 } 116 emptyboost::xpressive::detail::sub_match_vector117 bool empty() const 118 { 119 return 0 == this->size(); 120 } 121 beginboost::xpressive::detail::sub_match_vector122 const_iterator begin() const 123 { 124 return const_iterator(this->sub_matches_); 125 } 126 endboost::xpressive::detail::sub_match_vector127 const_iterator end() const 128 { 129 return const_iterator(this->sub_matches_ + this->size_); 130 } 131 operator bool_typeboost::xpressive::detail::sub_match_vector132 operator bool_type() const 133 { 134 return (!this->empty() && (*this)[0].matched) ? &dummy::i_ : 0; 135 } 136 operator !boost::xpressive::detail::sub_match_vector137 bool operator !() const 138 { 139 return this->empty() || !(*this)[0].matched; 140 } 141 swapboost::xpressive::detail::sub_match_vector142 void swap(sub_match_vector<BidiIter> &that) 143 { 144 std::swap(this->size_, that.size_); 145 std::swap(this->sub_matches_, that.sub_matches_); 146 } 147 148 private: 149 friend struct detail::core_access<BidiIter>; 150 init_boost::xpressive::detail::sub_match_vector151 void init_(sub_match_impl<BidiIter> *sub_matches, size_type size) 152 { 153 this->size_ = size; 154 this->sub_matches_ = sub_matches; 155 } 156 init_boost::xpressive::detail::sub_match_vector157 void init_(sub_match_impl<BidiIter> *sub_matches, size_type size, sub_match_vector<BidiIter> const &that) 158 { 159 BOOST_ASSERT(size == that.size_); 160 this->size_ = size; 161 this->sub_matches_ = sub_matches; 162 std::copy(that.sub_matches_, that.sub_matches_ + that.size_, this->sub_matches_); 163 } 164 165 size_type size_; 166 sub_match_impl<BidiIter> *sub_matches_; 167 }; 168 169 }}} // namespace boost::xpressive::detail 170 171 #endif 172