summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp')
-rw-r--r--3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp b/3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp
new file mode 100644
index 0000000..402956b
--- /dev/null
+++ b/3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp
@@ -0,0 +1,170 @@
+// Copyright (c) 2001 Daniel C. Nuffer
+// Copyright (c) 2001-2011 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
+#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/assert.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace iterator_policies
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // class split_std_deque
+ //
+ // Implementation of the StoragePolicy used by multi_pass
+ // This stores all data in a std::vector (despite its name), and keeps an
+ // offset to the current position. It stores all the data unless there is
+ // only one iterator using the queue.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ struct split_std_deque
+ {
+ enum { threshold = 16 };
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Value>
+ class unique //: public detail::default_storage_policy
+ {
+ private:
+ typedef std::vector<Value> queue_type;
+
+ protected:
+ unique() : queued_position(0) {}
+
+ unique(unique const& x)
+ : queued_position(x.queued_position) {}
+
+ void swap(unique& x)
+ {
+ boost::swap(queued_position, x.queued_position);
+ }
+
+ // This is called when the iterator is dereferenced. It's a
+ // template method so we can recover the type of the multi_pass
+ // iterator and call advance_input and input_is_valid.
+ template <typename MultiPass>
+ static typename MultiPass::reference
+ dereference(MultiPass const& mp)
+ {
+ queue_type& queue = mp.shared()->queued_elements;
+ typename queue_type::size_type size = queue.size();
+
+ BOOST_ASSERT(mp.queued_position <= size);
+
+ if (mp.queued_position == size)
+ {
+ // check if this is the only iterator
+ if (size >= threshold && MultiPass::is_unique(mp))
+ {
+ // free up the memory used by the queue.
+ queue.clear();
+ mp.queued_position = 0;
+ }
+ return MultiPass::get_input(mp);
+ }
+
+ return queue[mp.queued_position];
+ }
+
+ // This is called when the iterator is incremented. It's a template
+ // method so we can recover the type of the multi_pass iterator
+ // and call is_unique and advance_input.
+ template <typename MultiPass>
+ static void increment(MultiPass& mp)
+ {
+ queue_type& queue = mp.shared()->queued_elements;
+ typename queue_type::size_type size = queue.size();
+
+ BOOST_ASSERT(mp.queued_position <= size);
+
+// // do not increment iterator as long as the current token is
+// // invalid
+// if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
+// return;
+
+ if (mp.queued_position == size)
+ {
+ // check if this is the only iterator
+ if (size >= threshold && MultiPass::is_unique(mp))
+ {
+ // free up the memory used by the queue. we avoid
+ // clearing the queue on every increment, though,
+ // because this would be too time consuming
+ queue.clear();
+ mp.queued_position = 0;
+ }
+ else
+ {
+ queue.push_back(MultiPass::get_input(mp));
+ ++mp.queued_position;
+ }
+ MultiPass::advance_input(mp);
+ }
+ else
+ {
+ ++mp.queued_position;
+ }
+ }
+
+ // called to forcibly clear the queue
+ template <typename MultiPass>
+ static void clear_queue(MultiPass& mp)
+ {
+ mp.shared()->queued_elements.clear();
+ mp.queued_position = 0;
+ }
+
+ // called to determine whether the iterator is an eof iterator
+ template <typename MultiPass>
+ static bool is_eof(MultiPass const& mp)
+ {
+ return mp.queued_position == mp.shared()->queued_elements.size()
+ && MultiPass::input_at_eof(mp);
+ }
+
+ // called by operator==
+ template <typename MultiPass>
+ static bool equal_to(MultiPass const& mp, MultiPass const& x)
+ {
+ return mp.queued_position == x.queued_position;
+ }
+
+ // called by operator<
+ template <typename MultiPass>
+ static bool less_than(MultiPass const& mp, MultiPass const& x)
+ {
+ return mp.queued_position < x.queued_position;
+ }
+
+ template <typename MultiPass>
+ static void destroy(MultiPass&) {}
+
+ protected:
+ mutable typename queue_type::size_type queued_position;
+ };
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Value>
+ struct shared
+ {
+ shared()
+ {
+ queued_elements.reserve(threshold);
+ }
+
+ typedef std::vector<Value> queue_type;
+ queue_type queued_elements;
+ };
+
+ }; // split_std_deque
+
+}}}
+
+#endif
+