Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // results_cache.hpp
|
Chris@16
|
3 //
|
Chris@16
|
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
5 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
|
Chris@16
|
9 #define BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
|
Chris@16
|
10
|
Chris@16
|
11 // MS compatible compilers support #pragma once
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 # pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <cstddef>
|
Chris@16
|
17 #include <boost/detail/workaround.hpp>
|
Chris@16
|
18 #include <boost/assert.hpp>
|
Chris@16
|
19 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
20 #include <boost/xpressive/detail/core/list.hpp>
|
Chris@16
|
21 #include <boost/xpressive/detail/core/access.hpp>
|
Chris@16
|
22 #include <boost/xpressive/match_results.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 namespace boost { namespace xpressive { namespace detail
|
Chris@16
|
25 {
|
Chris@16
|
26
|
Chris@16
|
27 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
28 // nested_results
|
Chris@16
|
29 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
|
Chris@16
|
30 template<typename BidiIter>
|
Chris@16
|
31 struct nested_results
|
Chris@16
|
32 : detail::list<match_results<BidiIter> >
|
Chris@16
|
33 {
|
Chris@16
|
34 friend struct results_cache<BidiIter>;
|
Chris@16
|
35 friend struct match_results<BidiIter>;
|
Chris@16
|
36 };
|
Chris@16
|
37 #else
|
Chris@16
|
38 template<typename BidiIter>
|
Chris@16
|
39 struct nested_results
|
Chris@16
|
40 : private detail::list<match_results<BidiIter> >
|
Chris@16
|
41 {
|
Chris@16
|
42 friend struct results_cache<BidiIter>;
|
Chris@16
|
43 friend struct xpressive::match_results<BidiIter>;
|
Chris@16
|
44 typedef list<xpressive::match_results<BidiIter> > base_type;
|
Chris@16
|
45
|
Chris@16
|
46 typedef typename base_type::iterator iterator;
|
Chris@16
|
47 typedef typename base_type::const_iterator const_iterator;
|
Chris@16
|
48 typedef typename base_type::pointer pointer;
|
Chris@16
|
49 typedef typename base_type::const_pointer const_pointer;
|
Chris@16
|
50 typedef typename base_type::reference reference;
|
Chris@16
|
51 typedef typename base_type::const_reference const_reference;
|
Chris@16
|
52 typedef typename base_type::size_type size_type;
|
Chris@16
|
53 using base_type::begin;
|
Chris@16
|
54 using base_type::end;
|
Chris@16
|
55 using base_type::size;
|
Chris@16
|
56 using base_type::empty;
|
Chris@16
|
57 using base_type::front;
|
Chris@16
|
58 using base_type::back;
|
Chris@16
|
59 };
|
Chris@16
|
60 #endif
|
Chris@16
|
61
|
Chris@16
|
62 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
63 // results_cache
|
Chris@16
|
64 //
|
Chris@16
|
65 // cache storage for reclaimed match_results structs
|
Chris@16
|
66 template<typename BidiIter>
|
Chris@16
|
67 struct results_cache
|
Chris@16
|
68 {
|
Chris@16
|
69 typedef core_access<BidiIter> access;
|
Chris@16
|
70
|
Chris@16
|
71 match_results<BidiIter> &append_new(nested_results<BidiIter> &out)
|
Chris@16
|
72 {
|
Chris@16
|
73 if(this->cache_.empty())
|
Chris@16
|
74 {
|
Chris@16
|
75 out.push_back(match_results<BidiIter>());
|
Chris@16
|
76 }
|
Chris@16
|
77 else
|
Chris@16
|
78 {
|
Chris@16
|
79 BOOST_ASSERT(access::get_nested_results(this->cache_.back()).empty());
|
Chris@16
|
80 out.splice(out.end(), this->cache_, --this->cache_.end());
|
Chris@16
|
81 }
|
Chris@16
|
82 return out.back();
|
Chris@16
|
83 }
|
Chris@16
|
84
|
Chris@16
|
85 // move the last match_results struct into the cache
|
Chris@16
|
86 void reclaim_last(nested_results<BidiIter> &out)
|
Chris@16
|
87 {
|
Chris@16
|
88 BOOST_ASSERT(!out.empty());
|
Chris@16
|
89 // first, reclaim any nested results
|
Chris@16
|
90 nested_results<BidiIter> &nested = access::get_nested_results(out.back());
|
Chris@16
|
91 if(!nested.empty())
|
Chris@16
|
92 {
|
Chris@16
|
93 this->reclaim_all(nested);
|
Chris@16
|
94 }
|
Chris@16
|
95 // then, reclaim the last match_results
|
Chris@16
|
96 this->cache_.splice(this->cache_.end(), out, --out.end());
|
Chris@16
|
97 }
|
Chris@16
|
98
|
Chris@16
|
99 // move the last n match_results structs into the cache
|
Chris@16
|
100 void reclaim_last_n(nested_results<BidiIter> &out, std::size_t count)
|
Chris@16
|
101 {
|
Chris@16
|
102 for(; 0 != count; --count)
|
Chris@16
|
103 {
|
Chris@16
|
104 this->reclaim_last(out);
|
Chris@16
|
105 }
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 void reclaim_all(nested_results<BidiIter> &out)
|
Chris@16
|
109 {
|
Chris@16
|
110 typedef typename nested_results<BidiIter>::iterator iter_type;
|
Chris@16
|
111
|
Chris@16
|
112 // first, recursively reclaim all the nested results
|
Chris@16
|
113 for(iter_type begin = out.begin(); begin != out.end(); ++begin)
|
Chris@16
|
114 {
|
Chris@16
|
115 nested_results<BidiIter> &nested = access::get_nested_results(*begin);
|
Chris@16
|
116
|
Chris@16
|
117 if(!nested.empty())
|
Chris@16
|
118 {
|
Chris@16
|
119 this->reclaim_all(nested);
|
Chris@16
|
120 }
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 // next, reclaim the results themselves
|
Chris@16
|
124 this->cache_.splice(this->cache_.end(), out);
|
Chris@16
|
125 }
|
Chris@16
|
126
|
Chris@16
|
127 private:
|
Chris@16
|
128
|
Chris@16
|
129 nested_results<BidiIter> cache_;
|
Chris@16
|
130 };
|
Chris@16
|
131
|
Chris@16
|
132 }}} // namespace boost::xpressive::detail
|
Chris@16
|
133
|
Chris@16
|
134 #endif
|