# Multimap Value-Type Utilities

In `pb_assoc`, associative containers have a unique-key design. Multimaps, consequently are maps of sets, e.g., a `cc_ht_multimap`<int, char> object maps `int`s to sets of `char`s. It is often convenient to perform value-type operations on multimaps, e.g., in this case, to find a specific `std::pair<int, char>` object (say, `std::make_pair(2, 'b')`) in a multimap object. These types of operations involve typically two steps: in the first step, some operation is performed on the multimap object itself, and in the second step, some operation is performed on the multimap's pertinent set object. (This is true for the STL's multimaps as well, except that the "set" is an implicit list.)

Coding these two-step operations is repetitious and error prone. `pb_assoc` containers already maintain the invariant that they support a value-type method for any mapped-value-type method they support (hence any multimap of the above type supporsts a method for inserting `std::make_pair(2, 'b')`). Following are some utility functions for other common operations.

    template<
      class MMap_Cntnr>
    inline std::pair<
        typename MMap_Cntnr::mapped_data_type::find_iterator,
        bool>
      mmap_value_find
      (const MMap_Cntnr &r_mmap_cntnr,
        typename MMap_Cntnr::const_reference r_val);

Finds the (const reference to a) value-type `r_val` in the multimap object `r_mmap_cntnr`.

It returns a pair whose first entry is a find-type iterator of the multimap's set type, and whose second entry is a boolean indicating whether the value type was found (only in this case is the first entry in the pair valid).

    template<
      class MMap_Cntnr<
    inline typename MMap_Cntnr::size_type
      mmap_value_erase
      (MMap_Cntnr &r_mmap_cntnr,
        typename MMap_Cntnr::const_reference r_val,
        bool erase_entry_if_last);

Transactionally erases the (const reference to the) value-type `r_val` from the multimap object `r_mmap_cntnr`, and erases the mapped value type with `r_val`'s key if there are no more value types with this given key and `erase_entry_if_last` `= true`.

It returns 1 if a value type was actually erased, or 0 otherwise.

    template<
      class MMap_Cntnr>
    inline std::pair<
        typename MMap_Cntnr::mapped_data_type::find_iterator,
        bool>
      mmap_value_replace
      (MMap_Cntnr &r_mmap_cntnr,
        typename MMap_Cntnr::const_reference r_val,
        typename MMap_Cntnr::const_data_reference r_data);

Transactionally erases `r_val` from `r_mmap_cntnr` (if it such a value type exists) and inserts instead a value type whose key is `r_val``.first` and whose data is `r_data`.

It returns a pair whose first entry is a find-type iterator of the multimap's set type, and whose second entry is a boolean indicating whether the new value type was inserted (it might have existed previously).

(If the multimap type or its set type do not guarantee exception free erases, `mmap_value_erase` and `mmap_value_replace` will invalidate pointers, references, and iterators).