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