11 #include <Sawyer/Interval.h>
12 #include <Sawyer/Optional.h>
13 #include <Sawyer/Sawyer.h>
14 #include <boost/range/iterator_range.hpp>
15 #include <boost/serialization/access.hpp>
16 #include <boost/serialization/nvp.hpp>
17 #include <boost/serialization/map.hpp>
64 class Cmp = std::less<K>,
65 class Alloc = std::allocator<std::pair<const K, T> > >
74 typedef std::map<Key, Value, Comparator, Alloc> StlMap;
78 friend class boost::serialization::access;
81 void serialize(S &s,
const unsigned ) {
82 s & BOOST_SERIALIZATION_NVP(map_);
89 class Node:
private std::pair<const Key, Value> {
92 explicit Node(
const std::pair<const Key, Value> &pair): std::pair<const Key, Value>(pair) {}
98 const Key&
key()
const {
return this->first; }
114 template<
class Derived,
class Value,
class BaseIterator>
115 class BidirectionalIterator {
119 using iterator_category = std::bidirectional_iterator_tag;
120 using value_type =
Value;
121 using difference_type = std::ptrdiff_t;
122 using pointer =
Value*;
123 using reference =
Value&;
127 BidirectionalIterator() {}
128 BidirectionalIterator(
const BaseIterator &base): base_(base) {}
130 Derived&
operator=(
const Derived &other) { base_ = other.base_;
return *derived(); }
133 Derived& operator++() { ++base_;
return *derived(); }
136 Derived operator++(
int) { Derived old=*derived(); ++*
this;
return old; }
139 Derived& operator--() { --base_;
return *derived(); }
142 Derived operator--(
int) { Derived old=*derived(); --*
this;
return old; }
148 template<
class OtherIter>
bool operator==(
const OtherIter &other)
const {
return base_ == other.base(); }
153 template<
class OtherIter>
bool operator!=(
const OtherIter &other)
const {
return base_ != other.base(); }
155 const BaseIterator& base()
const {
return base_; }
157 Derived* derived() {
return static_cast<Derived*
>(
this); }
158 const Derived* derived()
const {
return static_cast<const Derived*
>(
this); }
166 class NodeIterator:
public BidirectionalIterator<NodeIterator, Node, typename StlMap::iterator> {
167 typedef BidirectionalIterator<NodeIterator, Node, typename StlMap::iterator> Super;
182 NodeIterator(
const typename StlMap::iterator &base): Super(base) {}
189 class ConstNodeIterator:
public BidirectionalIterator<ConstNodeIterator, const Node, typename StlMap::const_iterator> {
190 typedef BidirectionalIterator<ConstNodeIterator, const Node, typename StlMap::const_iterator> Super;
209 ConstNodeIterator(
const typename StlMap::iterator &base): Super(typename StlMap::const_iterator(base)) {}
216 class ConstKeyIterator:
public BidirectionalIterator<ConstKeyIterator, const Key, typename StlMap::const_iterator> {
217 typedef BidirectionalIterator<ConstKeyIterator, const Key, typename StlMap::const_iterator> Super;
241 class ValueIterator:
public BidirectionalIterator<ValueIterator, Value, typename StlMap::iterator> {
242 typedef BidirectionalIterator<ValueIterator, Value, typename StlMap::iterator> Super;
263 class ConstValueIterator:
public BidirectionalIterator<ConstValueIterator, const Value, typename StlMap::const_iterator> {
264 typedef BidirectionalIterator<ConstValueIterator, const Value, typename StlMap::const_iterator> Super;
302 : map_(comparator, allocator) {}
313 template<
class Key2,
class T2,
class Cmp2,
class Alloc2>
316 boost::iterator_range<OtherIterator> otherNodes = other.
nodes();
317 for (OtherIterator otherIter=otherNodes.begin(); otherIter!=otherNodes.end(); ++otherIter)
318 map_.insert(map_.end(), std::make_pair(
Key(otherIter->key()),
Value(otherIter->value())));
324 template<
class Key2,
class T2,
class Cmp2,
class Alloc2>
328 boost::iterator_range<OtherIterator> otherNodes = other.
nodes();
329 for (OtherIterator otherIter=otherNodes.begin(); otherIter!=otherNodes.end(); ++otherIter)
330 map_.insert(map_.end(), std::make_pair(
Key(otherIter->key()),
Value(otherIter->value())));
344 boost::iterator_range<NodeIterator>
nodes() {
345 return boost::iterator_range<NodeIterator>(NodeIterator(map_.begin()), NodeIterator(map_.end()));
347 boost::iterator_range<ConstNodeIterator>
nodes()
const {
348 return boost::iterator_range<ConstNodeIterator>(ConstNodeIterator(map_.begin()), ConstNodeIterator(map_.end()));
357 boost::iterator_range<ConstKeyIterator>
keys() {
358 return boost::iterator_range<ConstKeyIterator>(NodeIterator(map_.begin()), NodeIterator(map_.end()));
360 boost::iterator_range<ConstKeyIterator>
keys()
const {
361 return boost::iterator_range<ConstKeyIterator>(ConstNodeIterator(map_.begin()), ConstNodeIterator(map_.end()));
371 boost::iterator_range<ValueIterator>
values() {
372 return boost::iterator_range<ValueIterator>(NodeIterator(map_.begin()), NodeIterator(map_.end()));
374 boost::iterator_range<ConstValueIterator>
values()
const {
375 return boost::iterator_range<ConstValueIterator>(ConstNodeIterator(map_.begin()), ConstNodeIterator(map_.end()));
402 return map_.begin()->first;
408 typename StlMap::const_iterator last = map_.end();
438 return map_.find(key);
440 ConstNodeIterator
find(
const Key &key)
const {
441 return map_.find(key);
451 return map_.find(key)!=map_.end();
464 return map_.lower_bound(key);
467 return map_.lower_bound(key);
481 return map_.upper_bound(key);
484 return map_.upper_bound(key);
523 typename StlMap::iterator found = map_.find(key);
524 if (found==map_.end())
525 throw std::domain_error(
"key lookup failure; key is not in map domain");
526 return found->second;
529 typename StlMap::const_iterator found = map_.find(key);
530 if (found==map_.end())
531 throw std::domain_error(
"key lookup failure; key is not in map domain");
532 return found->second;
560 typename StlMap::const_iterator found = map_.find(key);
572 typename StlMap::iterator found = map_.find(key);
573 return found == map_.end() ? dflt : found->second;
576 typename StlMap::const_iterator found = map_.find(key);
577 return found == map_.end() ? dflt : found->second;
587 static const Value dflt;
588 typename StlMap::const_iterator found = map_.find(key);
589 return found==map_.end() ? dflt : found->second;
604 std::pair<typename StlMap::iterator, bool> inserted = map_.
insert(std::make_pair(key, value));
605 if (!inserted.second)
606 inserted.first->second = value;
638 template<
class OtherNodeIterator>
640 for (OtherNodeIterator otherIter=begin; otherIter!=end; ++otherIter)
644 template<
class OtherNodeIterator>
658 return map_.insert(std::make_pair(key, value)).first->second;
669 return map_.insert(std::make_pair(key, T())).first->second;
678 template<
class OtherNodeIterator>
680 for (OtherNodeIterator otherIter=range.begin(); otherIter!=range.end(); ++otherIter)
714 template<
class OtherKeyIterator>
716 for (OtherKeyIterator otherIter=range.begin(); otherIter!=range.end(); ++otherIter)
729 map_.
erase(iter.base());
734 ASSERT_require(iter !=
keys().end());
735 typename StlMap::iterator stdIter = map_.find(*iter);
736 ASSERT_require(stdIter != map_.end());
741 map_.
erase(iter.base());
755 map_.
erase(begin.base(), end.base());
760 map_.
erase(range.begin().base(), range.end().base());