]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // results_cache.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_RESULTS_CACHE_HPP_EAN_10_04_2005 | |
9 | #define BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_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 <cstddef> | |
17 | #include <boost/detail/workaround.hpp> | |
18 | #include <boost/assert.hpp> | |
19 | #include <boost/xpressive/detail/detail_fwd.hpp> | |
20 | #include <boost/xpressive/detail/core/list.hpp> | |
21 | #include <boost/xpressive/detail/core/access.hpp> | |
22 | #include <boost/xpressive/match_results.hpp> | |
23 | ||
24 | namespace boost { namespace xpressive { namespace detail | |
25 | { | |
26 | ||
27 | /////////////////////////////////////////////////////////////////////////////// | |
28 | // nested_results | |
29 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) | |
30 | template<typename BidiIter> | |
31 | struct nested_results | |
32 | : detail::list<match_results<BidiIter> > | |
33 | { | |
34 | friend struct results_cache<BidiIter>; | |
35 | friend struct match_results<BidiIter>; | |
36 | }; | |
37 | #else | |
38 | template<typename BidiIter> | |
39 | struct nested_results | |
40 | : private detail::list<match_results<BidiIter> > | |
41 | { | |
42 | friend struct results_cache<BidiIter>; | |
43 | friend struct xpressive::match_results<BidiIter>; | |
44 | typedef list<xpressive::match_results<BidiIter> > base_type; | |
45 | ||
46 | typedef typename base_type::iterator iterator; | |
47 | typedef typename base_type::const_iterator const_iterator; | |
48 | typedef typename base_type::pointer pointer; | |
49 | typedef typename base_type::const_pointer const_pointer; | |
50 | typedef typename base_type::reference reference; | |
51 | typedef typename base_type::const_reference const_reference; | |
52 | typedef typename base_type::size_type size_type; | |
53 | using base_type::begin; | |
54 | using base_type::end; | |
55 | using base_type::size; | |
56 | using base_type::empty; | |
57 | using base_type::front; | |
58 | using base_type::back; | |
59 | }; | |
60 | #endif | |
61 | ||
62 | /////////////////////////////////////////////////////////////////////////////// | |
63 | // results_cache | |
64 | // | |
65 | // cache storage for reclaimed match_results structs | |
66 | template<typename BidiIter> | |
67 | struct results_cache | |
68 | { | |
69 | typedef core_access<BidiIter> access; | |
70 | ||
71 | match_results<BidiIter> &append_new(nested_results<BidiIter> &out) | |
72 | { | |
73 | if(this->cache_.empty()) | |
74 | { | |
75 | out.push_back(match_results<BidiIter>()); | |
76 | } | |
77 | else | |
78 | { | |
79 | BOOST_ASSERT(access::get_nested_results(this->cache_.back()).empty()); | |
80 | out.splice(out.end(), this->cache_, --this->cache_.end()); | |
81 | } | |
82 | return out.back(); | |
83 | } | |
84 | ||
85 | // move the last match_results struct into the cache | |
86 | void reclaim_last(nested_results<BidiIter> &out) | |
87 | { | |
88 | BOOST_ASSERT(!out.empty()); | |
89 | // first, reclaim any nested results | |
90 | nested_results<BidiIter> &nested = access::get_nested_results(out.back()); | |
91 | if(!nested.empty()) | |
92 | { | |
93 | this->reclaim_all(nested); | |
94 | } | |
95 | // then, reclaim the last match_results | |
96 | this->cache_.splice(this->cache_.end(), out, --out.end()); | |
97 | } | |
98 | ||
99 | // move the last n match_results structs into the cache | |
100 | void reclaim_last_n(nested_results<BidiIter> &out, std::size_t count) | |
101 | { | |
102 | for(; 0 != count; --count) | |
103 | { | |
104 | this->reclaim_last(out); | |
105 | } | |
106 | } | |
107 | ||
108 | void reclaim_all(nested_results<BidiIter> &out) | |
109 | { | |
110 | typedef typename nested_results<BidiIter>::iterator iter_type; | |
111 | ||
112 | // first, recursively reclaim all the nested results | |
113 | for(iter_type begin = out.begin(); begin != out.end(); ++begin) | |
114 | { | |
115 | nested_results<BidiIter> &nested = access::get_nested_results(*begin); | |
116 | ||
117 | if(!nested.empty()) | |
118 | { | |
119 | this->reclaim_all(nested); | |
120 | } | |
121 | } | |
122 | ||
123 | // next, reclaim the results themselves | |
124 | this->cache_.splice(this->cache_.end(), out); | |
125 | } | |
126 | ||
127 | private: | |
128 | ||
129 | nested_results<BidiIter> cache_; | |
130 | }; | |
131 | ||
132 | }}} // namespace boost::xpressive::detail | |
133 | ||
134 | #endif |