11#include <Sawyer/Interval.h> 
   12#include <Sawyer/Optional.h> 
   13#include <Sawyer/Sawyer.h> 
   14#include <boost/range/iterator_range.hpp> 
   16#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   17#include <boost/serialization/map.hpp> 
   20#ifdef SAWYER_HAVE_CEREAL 
   21#include <cereal/types/map.hpp> 
   70         class Cmp = std::less<K>,
 
   71         class Alloc = std::allocator<std::pair<const K, T> > >
 
   80    typedef std::map<Key, Value, Comparator, Alloc> StlMap;
 
   83#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   85    friend class boost::serialization::access;
 
   88    void serialize(S &s, 
const unsigned ) {
 
   89        s & BOOST_SERIALIZATION_NVP(map_);
 
   93#ifdef SAWYER_HAVE_CEREAL 
   95    friend class cereal::access;
 
   97    template<
class Archive>
 
   98    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
   99        archive(CEREAL_NVP(map_));
 
  107    class Node: 
private std::pair<const Key, Value> {
 
  110        explicit Node(
const std::pair<const Key, Value> &pair): std::pair<const Key, Value>(pair) {}
 
  116        const Key& 
key()
 const { 
return this->first; }
 
 
  132    template<
class Derived, 
class Value, 
class BaseIterator>
 
  133    class BidirectionalIterator {
 
  137        using iterator_category = std::bidirectional_iterator_tag;
 
  138        using value_type = 
Value;
 
  139        using difference_type = std::ptrdiff_t;
 
  140        using pointer = 
Value*;
 
  141        using reference = 
Value&;
 
  145        BidirectionalIterator() {}
 
  146        BidirectionalIterator(
const BaseIterator &base): base_(base) {}
 
  147        BidirectionalIterator(
const BidirectionalIterator &other): base_(other.base_) {}
 
  150        Derived& operator=(
const Derived &other) { base_ = other.base(); 
return *derived(); }
 
  151        BidirectionalIterator& operator=(
const BidirectionalIterator &other) { base_ = other.base(); 
return *
this; }
 
  154        Derived& operator++() { ++base_; 
return *derived(); }
 
  157        Derived operator++(
int) { Derived old=*derived(); ++*
this; 
return old; }
 
  160        Derived& operator--() { --base_; 
return *derived(); }
 
  163        Derived operator--(
int) { Derived old=*derived(); --*
this; 
return old; }
 
  169        template<
class OtherIter> 
bool operator==(
const OtherIter &other)
 const { 
return base_ == other.base(); }
 
  174        template<
class OtherIter> 
bool operator!=(
const OtherIter &other)
 const { 
return base_ != other.base(); }
 
  176        const BaseIterator& base()
 const { 
return base_; }
 
  178        Derived* derived() { 
return static_cast<Derived*
>(
this); }
 
  179        const Derived* derived()
 const { 
return static_cast<const Derived*
>(
this); }
 
  187    class NodeIterator: 
public BidirectionalIterator<NodeIterator, Node, typename StlMap::iterator> {
 
  188        typedef                BidirectionalIterator<NodeIterator, Node, typename StlMap::iterator> Super;
 
  206        NodeIterator(
const typename StlMap::iterator &base): Super(base) {}
 
 
  213    class ConstNodeIterator: 
public BidirectionalIterator<ConstNodeIterator, const Node, typename StlMap::const_iterator> {
 
  214        typedef                     BidirectionalIterator<ConstNodeIterator, const Node, typename StlMap::const_iterator> Super;
 
  236        ConstNodeIterator(
const typename StlMap::iterator &base): Super(typename StlMap::const_iterator(base)) {}
 
 
  243    class ConstKeyIterator: 
public BidirectionalIterator<ConstKeyIterator, const Key, typename StlMap::const_iterator> {
 
  244        typedef                    BidirectionalIterator<ConstKeyIterator, const Key, typename StlMap::const_iterator> Super;
 
 
  271    class ValueIterator: 
public BidirectionalIterator<ValueIterator, Value, typename StlMap::iterator> {
 
  272        typedef                 BidirectionalIterator<ValueIterator, Value, typename StlMap::iterator> Super;
 
 
  296    class ConstValueIterator: 
public BidirectionalIterator<ConstValueIterator, const Value, typename StlMap::const_iterator> {
 
  297        typedef BidirectionalIterator<ConstValueIterator, const Value, typename StlMap::const_iterator> Super;
 
 
  338        : map_(comparator, allocator) {}
 
 
  349    template<
class Key2, 
class T2, 
class Cmp2, 
class Alloc2>
 
  352        boost::iterator_range<OtherIterator> otherNodes = other.
nodes();
 
  353        for (OtherIterator otherIter=otherNodes.begin(); otherIter!=otherNodes.end(); ++otherIter)
 
  354            map_.insert(map_.end(), std::make_pair(
Key(otherIter->key()), 
Value(otherIter->value())));
 
 
  357    Map& operator=(
const Map &other) {
 
  359        for (
const auto &node: other.
nodes())
 
  360            map_.
insert(map_.end(), std::make_pair(node.key(), node.value()));
 
  367    template<
class Key2, 
class T2, 
class Cmp2, 
class Alloc2>
 
  371        boost::iterator_range<OtherIterator> otherNodes = other.
nodes();
 
  372        for (OtherIterator otherIter=otherNodes.begin(); otherIter!=otherNodes.end(); ++otherIter)
 
  373            map_.insert(map_.end(), std::make_pair(
Key(otherIter->key()), 
Value(otherIter->value())));
 
 
  387    boost::iterator_range<NodeIterator> 
nodes() {
 
 
  390    boost::iterator_range<ConstNodeIterator> 
nodes()
 const {
 
 
  400    boost::iterator_range<ConstKeyIterator> 
keys() {
 
 
  403    boost::iterator_range<ConstKeyIterator> 
keys()
 const {
 
 
  414    boost::iterator_range<ValueIterator> 
values() {
 
 
  417    boost::iterator_range<ConstValueIterator> 
values()
 const {
 
 
  445        return map_.begin()->first;
 
 
  451        typename StlMap::const_iterator last = map_.end();
 
 
  481        return map_.find(key);
 
 
  484        return map_.find(key);
 
 
  494        return map_.find(key)!=map_.end();
 
 
  507        return map_.lower_bound(key);
 
 
  510        return map_.lower_bound(key);
 
 
  524        return map_.upper_bound(key);
 
 
  527        return map_.upper_bound(key);
 
 
  566        typename StlMap::iterator found = map_.find(key);
 
  567        if (found==map_.end())
 
  568            throw std::domain_error(
"key lookup failure; key is not in map domain");
 
  569        return found->second;
 
 
  572        typename StlMap::const_iterator found = map_.find(key);
 
  573        if (found==map_.end())
 
  574            throw std::domain_error(
"key lookup failure; key is not in map domain");
 
  575        return found->second;
 
 
  603        typename StlMap::const_iterator found = map_.find(key);
 
 
  615        typename StlMap::iterator found = map_.find(key);
 
  616        return found == map_.end() ? dflt : found->second;
 
 
  619        typename StlMap::const_iterator found = map_.find(key);
 
  620        return found == map_.end() ? dflt : found->second;
 
 
  630        static const Value dflt;
 
  631        typename StlMap::const_iterator found = map_.find(key);
 
  632        return found==map_.end() ? dflt : found->second;
 
 
  647        std::pair<typename StlMap::iterator, bool> inserted = map_.
insert(std::make_pair(key, value));
 
  648        if (!inserted.second)
 
  649            inserted.first->second = value;
 
 
  681    template<
class OtherNodeIterator>
 
  683        for (OtherNodeIterator otherIter=begin; otherIter!=end; ++otherIter)
 
 
  687    template<
class OtherNodeIterator>
 
  701        return map_.insert(std::make_pair(key, value)).first->second;
 
 
  712        return map_.insert(std::make_pair(key, T())).first->second;
 
 
  721    template<
class OtherNodeIterator>
 
  723        for (OtherNodeIterator otherIter=range.begin(); otherIter!=range.end(); ++otherIter)
 
 
  757    template<
class OtherKeyIterator>
 
  759        for (OtherKeyIterator otherIter=range.begin(); otherIter!=range.end(); ++otherIter)
 
 
  772        map_.
erase(iter.base());
 
 
  777        ASSERT_require(iter != 
keys().end());
 
  778        typename StlMap::iterator stdIter = map_.find(*iter);
 
  779        ASSERT_require(stdIter != map_.end());
 
 
  784        map_.
erase(iter.base());
 
 
  798        map_.
erase(begin.base(), end.base());
 
 
  803        map_.
erase(range.begin().base(), range.end().base());
 
 
 
Range of values delimited by endpoints.
 
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
 
Bidirectional iterator over keys.
 
ConstKeyIterator(const ConstNodeIterator &other)
Copy constructor.
 
ConstKeyIterator(const NodeIterator &other)
Copy constructor.
 
const Key * operator->() const
Returns a pointer to the interval of the storage node.
 
ConstKeyIterator(const ConstKeyIterator &other)
Copy constructor.
 
ConstKeyIterator & operator=(const ConstKeyIterator &other)
Assignment.
 
const Key & operator*() const
Dereference iterator to return the interval of the storage node.
 
Bidirectional iterator over key/value nodes.
 
const Node & operator*() const
Dereference iterator to return a storage node.
 
ConstNodeIterator(const NodeIterator &other)
Copy constructor.
 
const Node * operator->() const
Returns a pointer to a storage node.
 
ConstNodeIterator & operator=(const ConstNodeIterator &other)
Assignment.
 
ConstNodeIterator(const ConstNodeIterator &other)
Copy constructor.
 
Bidirectional iterator over values.
 
ConstValueIterator(const ConstValueIterator &other)
Copy constructor.
 
ConstValueIterator(const ConstNodeIterator &other)
Copy constructor.
 
ConstValueIterator & operator=(const ConstValueIterator &other)
Assignment.
 
ConstValueIterator(const ValueIterator &other)
Copy constructor.
 
const Value & operator*() const
Dereference iterator to return the value of the storage node.
 
ConstValueIterator(const NodeIterator &other)
Copy constructor.
 
const Value * operator->() const
Returns a pointer to the value of the storage node.
 
Bidirectional iterator over key/value nodes.
 
NodeIterator(const NodeIterator &other)
Copy constructor.
 
NodeIterator & operator=(const NodeIterator &other)
Assignment.
 
Node * operator->() const
Returns a pointer to a storage node.
 
Node & operator*() const
Dereference iterator to return a storage node.
 
const Key & key() const
Key part of key/value node.
 
const Value & value() const
Value part of key/value node.
 
Value & value()
Value part of key/value node.
 
Bidirectional iterator over values.
 
ValueIterator(const ValueIterator &other)
Copy constructor.
 
Value & operator*() const
Dereference iterator to return the value of the storage node.
 
ValueIterator & operator=(const ValueIterator &other)
Assignment.
 
ValueIterator(const NodeIterator &other)
Copy constructor.
 
Value * operator->() const
Returns a pointer to the value of the storage node.
 
Container associating values with keys.
 
NodeIterator upperBound(const Key &key)
Find a node close to a key.
 
Map & insertDefault(const Key &key)
Insert or update a key with a default value.
 
NodeIterator find(const Key &key)
Find a node by key.
 
const Value & get(const Key &key) const
Lookup and return an existing value.
 
Map & eraseAt(const NodeIterator &iter)
Remove a node by iterator.
 
Map & eraseAtMultiple(const boost::iterator_range< Iter > &range)
Remove multiple nodes by iterator range.
 
boost::iterator_range< ConstNodeIterator > nodes() const
Iterators for container nodes.
 
Map & eraseAt(const ValueIterator &iter)
Remove a node by iterator.
 
boost::iterator_range< ConstKeyIterator > keys() const
Iterators for container keys.
 
Value & operator[](const Key &key)
Return a reference to an existing value.
 
bool exists(const Key &key) const
Determine if a key exists.
 
Map & eraseMultiple(const boost::iterator_range< OtherKeyIterator > &range)
Remove keys stored in another Map.
 
Map & insertMaybeMultiple(const boost::iterator_range< OtherNodeIterator > &range)
Conditionally insert multiple key/value pairs.
 
Key greatest() const
Returns the maximum key.
 
const Value & operator[](const Key &key) const
Return a reference to an existing value.
 
Map & operator=(const Map< Key2, T2, Cmp2, Alloc2 > &other)
Make this map be a copy of another map.
 
boost::iterator_range< ValueIterator > values()
Iterators for container values.
 
Map(const Map &other)
Copy constructor.
 
Map & insertMultiple(const boost::iterator_range< OtherNodeIterator > &range)
Insert multiple values.
 
ConstNodeIterator find(const Key &key) const
Find a node by key.
 
size_t size() const
Number of nodes, keys, or values in this container.
 
Cmp Comparator
Type of comparator, third template argument.
 
Value & get(const Key &key)
Lookup and return an existing value.
 
bool isEmpty() const
Determines whether this container is empty.
 
Optional< Value > getOptional(const Key &key) const
Lookup and return a value or nothing.
 
Alloc Allocator
Type of allocator, fourth template argument.
 
Map & erase(const Key &key)
Remove a node with specified key.
 
const Value & getOrElse(const Key &key, const Value &dflt) const
Lookup and return a value or something else.
 
NodeIterator lowerBound(const Key &key)
Find a node close to a key.
 
Value & insertMaybeDefault(const Key &key)
Conditionally insert a new key with default value.
 
ConstNodeIterator lowerBound(const Key &key) const
Find a node close to a key.
 
boost::iterator_range< NodeIterator > nodes()
Iterators for container nodes.
 
Map & eraseAtMultiple(const Iter &begin, const Iter &end)
Remove multiple nodes by iterator range.
 
Value & insertMaybe(const Key &key, const Value &value)
Conditionally insert a new key/value pair.
 
Map(const Map< Key2, T2, Cmp2, Alloc2 > &other)
Copy constructor.
 
boost::iterator_range< ConstKeyIterator > keys()
Iterators for container keys.
 
Map & insert(const Key &key, const Value &value)
Insert or update a key/value pair.
 
ConstNodeIterator upperBound(const Key &key) const
Find a node close to a key.
 
Map & clear()
Remove all nodes.
 
Value & getOrElse(const Key &key, Value &dflt)
Lookup and return a value or something else.
 
Map & insertMultiple(const OtherNodeIterator &begin, const OtherNodeIterator &end)
Insert multiple values.
 
Map(const Comparator &comparator, const Allocator &allocator=Allocator())
Constructs an empty map.
 
const Value & getOrDefault(const Key &key) const
Lookup and return a value or a default.
 
Key least() const
Returns the minimum key.
 
T Value
Type for values associated with each key.
 
Interval< Key > hull() const
Returns the range of keys in this map.
 
Map()
Default constructor.
 
boost::iterator_range< ConstValueIterator > values() const
Iterators for container values.
 
Map & eraseAt(const ConstKeyIterator &iter)
Remove a node by iterator.
 
Holds a value or nothing.