diff options
author | Vlad Voicu <vladv@rosedu.org> | 2012-03-02 10:01:11 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2012-03-09 15:04:05 (GMT) |
commit | 1c8cd160b79b6bbcec72042bdb104ba530508a93 (patch) | |
tree | cff302b81e74c557fbc9e30fd43144d981b613d0 /3rdParty/Boost/src/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp | |
parent | 2944711aefec9a9dd66052440bc4f921910dd780 (diff) | |
download | swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.zip swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.tar.bz2 |
Added spirit to bundled boost
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.hpp | 170 |
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 + |