16 #include <initializer_list> 20 #include <type_traits> 24 #include <hilti/rt/extension-points.h> 25 #include <hilti/rt/iterator.h> 26 #include <hilti/rt/safe-int.h> 27 #include <hilti/rt/util.h> 31 template<
typename K,
typename V>
36 template<
typename K,
typename V>
40 std::weak_ptr<M*> _control;
41 typename M::M::iterator _iterator;
46 friend class Map<K, V>;
49 if ( a._control.lock() != b._control.lock() )
50 throw InvalidArgument(
"cannot compare iterators into different maps");
52 return a._iterator == b._iterator;
55 friend bool operator!=(
const Iterator& a,
const Iterator& b) {
return ! (a == b); }
58 if ( ! _control.lock() ) {
59 throw IndexError(
"iterator is invalid");
72 const typename M::M::value_type* operator->()
const {
return &operator*(); }
74 typename M::M::const_reference operator*()
const {
75 if (
auto&& l = _control.lock() ) {
77 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
78 throw IndexError(
"iterator is invalid");
83 throw IndexError(
"iterator is invalid");
87 friend class Map<K, V>;
89 Iterator(
typename M::M::iterator iterator,
const typename M::C& control)
90 : _control(control), _iterator(std::move(iterator)) {}
93 template<
typename K,
typename V>
97 std::weak_ptr<M*> _control;
98 typename M::M::const_iterator _iterator;
104 if ( a._control.lock() != b._control.lock() )
105 throw InvalidArgument(
"cannot compare iterators into different sets");
107 return a._iterator == b._iterator;
113 if ( ! _control.lock() ) {
114 throw IndexError(
"iterator is invalid");
127 const typename M::M::value_type* operator->()
const {
return &operator*(); }
129 typename M::M::const_reference operator*()
const {
130 if (
auto&& l = _control.lock() ) {
132 if ( _iterator == static_cast<const typename M::M&>(**l).cend() )
133 throw IndexError(
"iterator is invalid");
138 throw IndexError(
"iterator is invalid");
142 friend class Map<K, V>;
144 ConstIterator(
typename M::M::const_iterator iterator,
const typename M::C& control)
145 : _control(control), _iterator(std::move(iterator)) {}
171 template<
typename K,
typename V>
172 class Map :
protected std::map<K, V> {
174 using M = std::map<K, V>;
175 using C = std::shared_ptr<Map<K, V>*>;
177 C _control = std::make_shared<Map<K, V>*>(
this);
179 using key_type =
typename M::key_type;
180 using value_type =
typename M::value_type;
181 using size_type = integer::safe<uint64_t>;
187 Map(std::initializer_list<value_type>
init) :
M(std::move(init)) {}
194 bool contains(
const K& k)
const {
return this->find(k) !=
static_cast<const M&
>(*this).end(); }
203 const V&
get(
const K& k)
const& {
206 }
catch (
const std::out_of_range& ) {
207 throw IndexError(
"key is unset");
218 V&
get(
const K& k) & {
221 }
catch (
const std::out_of_range& ) {
222 throw IndexError(
"key is unset");
240 const auto&
operator[](
const K& k)
const& {
return this->
get(k); }
252 void index_assign(
const K& key, V value) {
253 if ( ! contains(key) )
254 this->invalidateIterators();
256 this->insert_or_assign(key, std::move(value));
259 auto begin()
const {
return this->cbegin(); }
260 auto end()
const {
return this->cend(); }
262 auto begin() {
return iterator(static_cast<M&>(*this).begin(), _control); }
263 auto end() {
return iterator(static_cast<M&>(*this).end(), _control); }
265 auto cbegin()
const {
return const_iterator(static_cast<const M&>(*this).begin(), _control); }
266 auto cend()
const {
return const_iterator(static_cast<const M&>(*this).end(), _control); }
268 size_type size()
const {
return M::size(); }
275 this->invalidateIterators();
277 return static_cast<M&
>(*this).clear();
288 auto removed =
static_cast<M&
>(*this).erase(key);
291 this->invalidateIterators();
297 friend bool operator==(
const Map& a,
const Map& b) {
return static_cast<const M&
>(a) == static_cast<const M&>(b); }
298 friend bool operator!=(
const Map& a,
const Map& b) {
return ! (a == b); }
304 void invalidateIterators() {
306 _control = std::make_shared<Map<K, V>*>(
this);
314 template<
typename K,
typename V>
318 template<
typename K,
typename V>
322 template<
typename K,
typename V>
326 template<
typename K,
typename V>
331 template<
typename K,
typename V>
332 inline std::ostream& operator<<(std::ostream& out, const map::Iterator<K, V>& it) {
336 template<
typename K,
typename V>
337 inline std::ostream& operator<<(std::ostream& out, const map::ConstIterator<K, V>& it) {
342 namespace detail::adl {
343 template<
typename K,
typename V>
345 std::vector<std::string> r;
347 for (
const auto& i : x )
353 template<
typename K,
typename V>
354 inline std::string
to_string(
const std::pair<const K, V>& x, adl::tag ) {
356 static_assert(std::is_same_v<
typename Map<K, V>::value_type, std::pair<const K, V>>);
362 template<
typename K,
typename V>
364 return "<map iterator>";
367 template<
typename K,
typename V>
369 return "<const map iterator>";
374 template<
typename K,
typename V>
375 inline std::ostream& operator<<(std::ostream& out, const Map<K, V>& x) {
379 template<
typename K,
typename V>
380 inline std::ostream& operator<<(std::ostream& out, const std::pair<K, V>& x) {
382 static_assert(std::is_same_v<
typename Map<K, V>::value_type, std::pair<const K, V>>);
386 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:20
auto & operator[](const K &k) &
Definition: map.h:232
auto erase(const key_type &key)
Definition: map.h:287
bool contains(const K &k) const
Definition: map.h:194
auto clear()
Definition: map.h:274
std::string join(const T &l, const std::string &delim="")
Definition: util.h:279
auto operator[](const K &k) &&
Definition: map.h:250
const auto & operator[](const K &k) const &
Definition: map.h:240
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13