/** @file

    $Id$

    $Date$
    $Author$

    @copy &copy; Marc W&auml;ckerlin
    @license LGPL, see file <a href="license.html">COPYING</a>

    $Log$
    Revision 1.4  2005/11/29 12:39:42  marc
    make it compilable with gcc 4.0.2 and newer doxygen

    Revision 1.3  2005/04/07 20:48:20  marc
    docu: new doxygen, new grouping

    Revision 1.2  2004/12/20 07:40:35  marc
    documentation improved, new grouping

    Revision 1.1  2004/10/07 09:31:30  marc
    new feature


*/
#ifndef __MRW__MAP__HPP__
#define __MRW__MAP__HPP__

#include <map>
#include <mrw/exception.hpp>
#include <mrw/string.hpp>

/** @addtogroup StdExtSTL
 */
//@{
/** @defgroup StdExtmap map
 */
//@{

/** @brief insert a value in a map

    @code
    std::map<int, std::string> test;
    test<<std::make_pair(1, std::string("one"))
        <<std::make_pair(2, std::string("two"));
    @endcode

    @throw mrw::invalid_argument, if element is already in map
    @param l a map of values
    @param o a value to be inserted into map @c l
    @pre \#include <mrw/map.hpp>
*/
template <typename K, typename T, class C, typename A>
std::map<K, T, C, A>& operator<<(std::map<K, T, C, A>& l, const std::pair<K, T>& o)
  throw(std::exception) {
  if (!l.insert(o).second)
    throw mrw::invalid_argument(std::string(__FILE__ ":")+__LINE__+
                                ": std::map<>&"
                                " operator<<(std::map<>&, const T&),"
                                "map element already exists");
  return l;
}

/** @brief extract the first value of a map

    @code
    std::map<int, std::string> test;
    test<<std::make_pair(1, std::string("one"))
        <<std::make_pair(2, std::string("two"));
    std::pair<int, std::string> i1, i2;
    test>>i1>>i2;
    // now: i1==(1, "one") i2==(2, "two") test=={}
    @endcode

    @param l a map of values
    @param o a value to be extracted from map @c l
    @throw mrw::length_error, if map was empty on entry
    @note when something is extracted from a map, it is removed
    from the map, that means after every shift the map is
    shortened by the shifted element
    @pre \#include <mrw/map.hpp>
*/
template <typename K, typename T, class C, typename A>
std::map<K, T, C, A>& operator>>(std::map<K, T, C, A>& l, std::pair<K, T>& o)
  throw(std::exception) {
  typename std::map<K, T, C, A>::iterator it(l.begin());
  if (it==l.end())
    throw mrw::length_error(std::string(__FILE__ ":")+__LINE__+
                            ": std::map<>& operator>>(std::map<>&, T&),"
                            " map is empty");
  o = *it;
  l.erase(it);
  return l;
}

//@}
//@}

#endif
