16 #include <initializer_list> 23 #include <hilti/rt/extension-points.h> 24 #include <hilti/rt/iterator.h> 25 #include <hilti/rt/safe-int.h> 26 #include <hilti/rt/util.h> 30 template<
typename K,
typename V>
35 template<
typename K,
typename V>
39 std::weak_ptr<M*> _control;
40 typename M::M::iterator _iterator;
45 friend class Map<K, V>;
48 if ( a._control.lock() != b._control.lock() )
49 throw InvalidArgument(
"cannot compare iterators into different maps");
51 return a._iterator == b._iterator;
54 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
57 if ( ! _control.lock() ) {
58 throw IndexError(
"iterator is invalid");
71 const typename M::M::value_type* operator->()
const {
return &operator*(); }
73 typename M::M::const_reference operator*()
const {
74 if (
auto&& l = _control.lock() ) {
76 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
77 throw IndexError(
"iterator is invalid");
82 throw IndexError(
"iterator is invalid");
86 friend class Map<K, V>;
88 Iterator(
typename M::M::iterator iterator,
const typename M::C& control)
89 : _control(control), _iterator(std::move(iterator)) {}
92 template<
typename K,
typename V>
96 std::weak_ptr<M*> _control;
97 typename M::M::const_iterator _iterator;
103 if ( a._control.lock() != b._control.lock() )
104 throw InvalidArgument(
"cannot compare iterators into different sets");
106 return a._iterator == b._iterator;
112 if ( ! _control.lock() ) {
113 throw IndexError(
"iterator is invalid");
126 const typename M::M::value_type* operator->()
const {
return &operator*(); }
128 typename M::M::const_reference operator*()
const {
129 if (
auto&& l = _control.lock() ) {
131 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
132 throw IndexError(
"iterator is invalid");
137 throw IndexError(
"iterator is invalid");
141 friend class Map<K, V>;
143 ConstIterator(
typename M::M::const_iterator iterator,
const typename M::C& control)
144 : _control(control), _iterator(std::move(iterator)) {}
170 template<
typename K,
typename V>
171 class Map :
protected std::map<K, V> {
173 using M = std::map<K, V>;
174 using C = std::shared_ptr<Map<K, V>*>;
176 C _control = std::make_shared<Map<K, V>*>(
this);
178 using key_type =
typename M::key_type;
179 using value_type =
typename M::value_type;
180 using size_type = integer::safe<uint64_t>;
186 Map(std::initializer_list<value_type>
init) :
M(std::move(init)) {}
193 bool contains(
const K& k)
const {
return this->find(k) !=
static_cast<const M&
>(*this).end(); }
202 const V&
get(
const K& k)
const& {
205 }
catch (
const std::out_of_range& ) {
206 throw IndexError(
"key is unset");
217 V&
get(
const K& k) & {
220 }
catch (
const std::out_of_range& ) {
221 throw IndexError(
"key is unset");
239 const auto&
operator[](
const K& k)
const& {
return this->
get(k); }
251 void index_assign(
const K& key, V value) {
252 if ( ! contains(key) )
253 this->invalidateIterators();
255 this->insert_or_assign(key, std::move(value));
258 auto begin()
const {
return this->cbegin(); }
259 auto end()
const {
return this->cend(); }
261 auto begin() {
return iterator(static_cast<M&>(*this).begin(), _control); }
262 auto end() {
return iterator(static_cast<M&>(*this).end(), _control); }
264 auto cbegin()
const {
return const_iterator(static_cast<const M&>(*this).begin(), _control); }
265 auto cend()
const {
return const_iterator(static_cast<const M&>(*this).end(), _control); }
267 size_type size()
const {
return M::size(); }
274 this->invalidateIterators();
276 return static_cast<M&
>(*this).clear();
287 auto removed =
static_cast<M&
>(*this).erase(key);
290 this->invalidateIterators();
296 friend bool operator==(
const Map& a,
const Map& b) {
return static_cast<const M&
>(a) == static_cast<const M&>(b); }
297 friend bool operator!=(
const Map& a,
const Map& b) {
return ! (a == b); }
303 void invalidateIterators() {
305 _control = std::make_shared<Map<K, V>*>(
this);
313 template<
typename K,
typename V>
317 template<
typename K,
typename V>
321 template<
typename K,
typename V>
325 template<
typename K,
typename V>
330 template<
typename K,
typename V>
331 inline std::ostream& operator<<(std::ostream& out, const map::Iterator<K, V>& it) {
335 template<
typename K,
typename V>
336 inline std::ostream& operator<<(std::ostream& out, const map::ConstIterator<K, V>& it) {
341 namespace detail::adl {
342 template<
typename K,
typename V>
344 std::vector<std::string> r;
346 for (
const auto& i : x )
354 template<
typename K,
typename V>
356 return "<map iterator>";
359 template<
typename K,
typename V>
361 return "<const map iterator>";
366 template<
typename K,
typename V>
367 inline std::ostream& operator<<(std::ostream& out, const Map<K, V>& x) {
371 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:18
auto & operator[](const K &k) &
Definition: map.h:231
auto erase(const key_type &key)
Definition: map.h:286
bool contains(const K &k) const
Definition: map.h:193
auto clear()
Definition: map.h:273
std::string join(const T &l, const std::string &delim="")
Definition: util.h:281
auto operator[](const K &k) &&
Definition: map.h:249
const auto & operator[](const K &k) const &
Definition: map.h:239
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13