| 316 | // Base class for btree_map. |
| 317 | template <typename Tree> |
| 318 | class btree_map_container : public btree_set_container<Tree> { |
| 319 | using super_type = btree_set_container<Tree>; |
| 320 | using params_type = typename Tree::params_type; |
| 321 | |
| 322 | protected: |
| 323 | template <class K> |
| 324 | using key_arg = typename super_type::template key_arg<K>; |
| 325 | |
| 326 | public: |
| 327 | using key_type = typename Tree::key_type; |
| 328 | using mapped_type = typename params_type::mapped_type; |
| 329 | using value_type = typename Tree::value_type; |
| 330 | using key_compare = typename Tree::key_compare; |
| 331 | using allocator_type = typename Tree::allocator_type; |
| 332 | using iterator = typename Tree::iterator; |
| 333 | using const_iterator = typename Tree::const_iterator; |
| 334 | |
| 335 | // Inherit constructors. |
| 336 | using super_type::super_type; |
| 337 | btree_map_container() {} |
| 338 | |
| 339 | // Insertion routines. |
| 340 | template <typename... Args> |
| 341 | std::pair<iterator, bool> try_emplace(const key_type &k, Args &&... args) { |
| 342 | return this->tree_.insert_unique( |
| 343 | k, std::piecewise_construct, std::forward_as_tuple(k), |
| 344 | std::forward_as_tuple(std::forward<Args>(args)...)); |
| 345 | } |
| 346 | template <typename... Args> |
| 347 | std::pair<iterator, bool> try_emplace(key_type &&k, Args &&... args) { |
| 348 | // Note: `key_ref` exists to avoid a ClangTidy warning about moving from `k` |
| 349 | // and then using `k` unsequenced. This is safe because the move is into a |
| 350 | // forwarding reference and insert_unique guarantees that `key` is never |
| 351 | // referenced after consuming `args`. |
| 352 | const key_type& key_ref = k; |
| 353 | return this->tree_.insert_unique( |
| 354 | key_ref, std::piecewise_construct, std::forward_as_tuple(std::move(k)), |
| 355 | std::forward_as_tuple(std::forward<Args>(args)...)); |
| 356 | } |
| 357 | template <typename... Args> |
| 358 | iterator try_emplace(const_iterator hint, const key_type &k, |
| 359 | Args &&... args) { |
| 360 | return this->tree_ |
| 361 | .insert_hint_unique(iterator(hint), k, std::piecewise_construct, |
| 362 | std::forward_as_tuple(k), |
| 363 | std::forward_as_tuple(std::forward<Args>(args)...)) |
| 364 | .first; |
| 365 | } |
| 366 | template <typename... Args> |
| 367 | iterator try_emplace(const_iterator hint, key_type &&k, Args &&... args) { |
| 368 | // Note: `key_ref` exists to avoid a ClangTidy warning about moving from `k` |
| 369 | // and then using `k` unsequenced. This is safe because the move is into a |
| 370 | // forwarding reference and insert_hint_unique guarantees that `key` is |
| 371 | // never referenced after consuming `args`. |
| 372 | const key_type& key_ref = k; |
| 373 | return this->tree_ |
| 374 | .insert_hint_unique(iterator(hint), key_ref, std::piecewise_construct, |
| 375 | std::forward_as_tuple(std::move(k)), |