16 #include <initializer_list> 23 #include <hilti/rt/extension-points.h> 24 #include <hilti/rt/iterator.h> 25 #include <hilti/rt/util.h> 29 template<
typename K,
typename V>
34 template<
typename K,
typename V>
38 std::weak_ptr<M*> _control;
39 typename M::M::iterator _iterator;
44 friend class Map<K, V>;
47 if ( a._control.lock() != b._control.lock() )
48 throw InvalidArgument(
"cannot compare iterators into different maps");
50 return a._iterator == b._iterator;
53 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
56 if ( ! _control.lock() ) {
57 throw IndexError(
"iterator is invalid");
70 const typename M::M::value_type* operator->()
const {
return &operator*(); }
72 typename M::M::const_reference operator*()
const {
73 if (
auto&& l = _control.lock() ) {
75 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
76 throw IndexError(
"iterator is invalid");
81 throw IndexError(
"iterator is invalid");
85 friend class Map<K, V>;
87 Iterator(
typename M::M::iterator iterator,
const typename M::C& control)
88 : _control(control), _iterator(std::move(iterator)) {}
91 template<
typename K,
typename V>
95 std::weak_ptr<M*> _control;
96 typename M::M::const_iterator _iterator;
102 if ( a._control.lock() != b._control.lock() )
103 throw InvalidArgument(
"cannot compare iterators into different sets");
105 return a._iterator == b._iterator;
111 if ( ! _control.lock() ) {
112 throw IndexError(
"iterator is invalid");
125 const typename M::M::value_type* operator->()
const {
return &operator*(); }
127 typename M::M::const_reference operator*()
const {
128 if (
auto&& l = _control.lock() ) {
130 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
131 throw IndexError(
"iterator is invalid");
136 throw IndexError(
"iterator is invalid");
140 friend class Map<K, V>;
142 ConstIterator(
typename M::M::const_iterator iterator,
const typename M::C& control)
143 : _control(control), _iterator(std::move(iterator)) {}
169 template<
typename K,
typename V>
170 class Map :
protected std::map<K, V> {
172 using M = std::map<K, V>;
173 using C = std::shared_ptr<Map<K, V>*>;
175 C _control = std::make_shared<Map<K, V>*>(
this);
177 using key_type =
typename M::key_type;
178 using value_type =
typename M::value_type;
179 using size_type = uint64_t;
185 Map(std::initializer_list<value_type>
init) :
M(std::move(init)) {}
192 bool contains(
const K& k)
const {
return this->find(k) !=
static_cast<const M&
>(*this).end(); }
201 const V&
get(
const K& k)
const& {
204 }
catch (
const std::out_of_range& ) {
205 throw IndexError(
"key is unset");
216 V&
get(
const K& k) & {
219 }
catch (
const std::out_of_range& ) {
220 throw IndexError(
"key is unset");
238 const auto&
operator[](
const K& k)
const& {
return this->
get(k); }
250 void index_assign(
const K& key, V value) {
251 if ( ! contains(key) )
252 this->invalidateIterators();
254 this->insert_or_assign(key, std::move(value));
257 auto begin()
const {
return this->cbegin(); }
258 auto end()
const {
return this->cend(); }
260 auto begin() {
return iterator(static_cast<M&>(*this).begin(), _control); }
261 auto end() {
return iterator(static_cast<M&>(*this).end(), _control); }
263 auto cbegin()
const {
return const_iterator(static_cast<const M&>(*this).begin(), _control); }
264 auto cend()
const {
return const_iterator(static_cast<const M&>(*this).end(), _control); }
266 size_type size()
const {
return M::size(); }
273 this->invalidateIterators();
275 return static_cast<M&
>(*this).clear();
286 auto removed =
static_cast<M&
>(*this).erase(key);
289 this->invalidateIterators();
295 friend bool operator==(
const Map& a,
const Map& b) {
return static_cast<const M&
>(a) == static_cast<const M&>(b); }
296 friend bool operator!=(
const Map& a,
const Map& b) {
return ! (a == b); }
302 void invalidateIterators() {
304 _control = std::make_shared<Map<K, V>*>(
this);
312 template<
typename K,
typename V>
316 template<
typename K,
typename V>
320 template<
typename K,
typename V>
324 template<
typename K,
typename V>
329 template<
typename K,
typename V>
330 inline std::ostream& operator<<(std::ostream& out, const map::Iterator<K, V>& it) {
334 template<
typename K,
typename V>
335 inline std::ostream& operator<<(std::ostream& out, const map::ConstIterator<K, V>& it) {
340 namespace detail::adl {
341 template<
typename K,
typename V>
343 std::vector<std::string> r;
345 for (
const auto& i : x )
353 template<
typename K,
typename V>
355 return "<map iterator>";
358 template<
typename K,
typename V>
360 return "<const map iterator>";
365 template<
typename K,
typename V>
366 inline std::ostream& operator<<(std::ostream& out, const Map<K, V>& x) {
370 inline std::ostream& operator<<(std::ostream& out,
const map::Empty& x) {
return out <<
to_string(x); }
std::string to_string(T &&x)
Definition: extension-points.h:26
void init()
Definition: init.cc:19
auto & operator[](const K &k) &
Definition: map.h:230
auto erase(const key_type &key)
Definition: map.h:285
bool contains(const K &k) const
Definition: map.h:192
auto clear()
Definition: map.h:272
std::string join(const T &l, const std::string &delim="")
Definition: util.h:281
auto operator[](const K &k) &&
Definition: map.h:248
const auto & operator[](const K &k) const &
Definition: map.h:238
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13