diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/support/detail/lexer/partition/equivset.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/support/detail/lexer/partition/equivset.hpp | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/support/detail/lexer/partition/equivset.hpp b/3rdParty/Boost/src/boost/spirit/home/support/detail/lexer/partition/equivset.hpp new file mode 100644 index 0000000..b39fb15 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/support/detail/lexer/partition/equivset.hpp @@ -0,0 +1,140 @@ +// equivset.hpp +// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_LEXER_EQUIVSET_HPP +#define BOOST_LEXER_EQUIVSET_HPP + +#include <algorithm> +#include "../parser/tree/node.hpp" +#include <set> +#include "../size_t.hpp" + +namespace boost +{ +namespace lexer +{ +namespace detail +{ +struct equivset +{ + typedef std::set<std::size_t> index_set; + typedef std::vector<std::size_t> index_vector; + // Not owner of nodes: + typedef std::vector<node *> node_vector; + + index_vector _index_vector; + bool _greedy; + std::size_t _id; + node_vector _followpos; + + equivset () : + _greedy (true), + _id (0) + { + } + + equivset (const index_set &index_set_, const bool greedy_, + const std::size_t id_, const node_vector &followpos_) : + _greedy (greedy_), + _id (id_), + _followpos (followpos_) + { + index_set::const_iterator iter_ = index_set_.begin (); + index_set::const_iterator end_ = index_set_.end (); + + for (; iter_ != end_; ++iter_) + { + _index_vector.push_back (*iter_); + } + } + + bool empty () const + { + return _index_vector.empty () && _followpos.empty (); + } + + void intersect (equivset &rhs_, equivset &overlap_) + { + intersect_indexes (rhs_._index_vector, overlap_._index_vector); + + if (!overlap_._index_vector.empty ()) + { + // Note that the LHS takes priority in order to + // respect rule ordering priority in the lex spec. + overlap_._id = _id; + overlap_._greedy = _greedy; + overlap_._followpos = _followpos; + + node_vector::const_iterator overlap_begin_ = + overlap_._followpos.begin (); + node_vector::const_iterator overlap_end_ = + overlap_._followpos.end (); + node_vector::const_iterator rhs_iter_ = + rhs_._followpos.begin (); + node_vector::const_iterator rhs_end_ = + rhs_._followpos.end (); + + for (; rhs_iter_ != rhs_end_; ++rhs_iter_) + { + node *node_ = *rhs_iter_; + + if (std::find (overlap_begin_, overlap_end_, node_) == + overlap_end_) + { + overlap_._followpos.push_back (node_); + overlap_begin_ = overlap_._followpos.begin (); + overlap_end_ = overlap_._followpos.end (); + } + } + + if (_index_vector.empty ()) + { + _followpos.clear (); + } + + if (rhs_._index_vector.empty ()) + { + rhs_._followpos.clear (); + } + } + } + +private: + void intersect_indexes (index_vector &rhs_, index_vector &overlap_) + { + index_vector::iterator iter_ = _index_vector.begin (); + index_vector::iterator end_ = _index_vector.end (); + index_vector::iterator rhs_iter_ = rhs_.begin (); + index_vector::iterator rhs_end_ = rhs_.end (); + + while (iter_ != end_ && rhs_iter_ != rhs_end_) + { + const std::size_t index_ = *iter_; + const std::size_t rhs_index_ = *rhs_iter_; + + if (index_ < rhs_index_) + { + ++iter_; + } + else if (index_ > rhs_index_) + { + ++rhs_iter_; + } + else + { + overlap_.push_back (index_); + iter_ = _index_vector.erase (iter_); + end_ = _index_vector.end (); + rhs_iter_ = rhs_.erase (rhs_iter_); + rhs_end_ = rhs_.end (); + } + } + } +}; +} +} +} + +#endif |