// Boost.Bimap
//
// Copyright (c) 2006-2007 Matias Capeletto
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

/// \file bimap.hpp
/// \brief Includes the basic bimap container

/** \mainpage notitle
\n
\image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png

\section Introduction

This is the complete reference of Boost.Bimap.

After getting a good understanding of the library from a user perspective
the next step will be:

    - Understand the tagged idiom. (boost::bimaps::tags)
    - Understand the internals of the relation class (boost::bimaps::relation)
    - Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor)
    - Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views
      and boost::bimaps::detail)


                                                                        **/

/** \defgroup mutant_group mutant idiom
\brief A safe wrapper around reinterpret_cast
                                                                        **/

/** \defgroup relation_group relation
\brief The relation
                                                                        **/

/** \defgroup tags_group tagged idiom
\brief The tagged idiom
                                                                        **/


#ifndef BOOST_BIMAP_BIMAP_HPP
#define BOOST_BIMAP_BIMAP_HPP

#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif

#include <boost/config.hpp>
#include <boost/bimap/detail/user_interface_config.hpp>
#include <boost/mpl/aux_/na.hpp>

#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
    #include <boost/serialization/nvp.hpp>
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION

// Boost.Bimap
#include <boost/bimap/detail/bimap_core.hpp>
#include <boost/bimap/detail/map_view_base.hpp>
#include <boost/bimap/detail/modifier_adaptor.hpp>
#include <boost/bimap/relation/support/data_extractor.hpp>
#include <boost/bimap/relation/support/member_with_tag.hpp>

#include <boost/bimap/support/map_type_by.hpp>
#include <boost/bimap/support/map_by.hpp>
#include <boost/bimap/support/iterator_type_by.hpp>

/// \brief The namespace where all the boost libraries lives.

namespace boost {

/// \brief Boost.Bimap library namespace
/**
All the entities in the library are defined in this namespace.
                                                                    **/
namespace bimaps {

/// \brief The bimap class is the entry point to the library.
/**
This class manages the instantiation of the desired bimap type.
As there are several types of bidirectional maps that can be
created using it. the main job of it is to find the desired
type. This is done using metaprogramming to obtain the relation
type that will be stored, the map_view type of each side and
the set_view type of the general relationship. The instantiation
is kept simple using an extended standard set theory, where a
bidirectional map type is defined by the set types it relates.
For example, a bidirectional map that has multimap semantics
viewed from both sides is defined by specifying that the two
keys sets are of \c multiset_of<Key> type.
This allows the bimap class to support seamingless N-N, 1-N,
ordered/unordered and even vector-list types of mapping.
The three last parameters are used to specify the set type of
the relation, an inplace hooked data class and the allocator
type. As a help to the bimap user, these parameters support
default types but use a special idiom that allow them to be
specified without interleaving the usual use_default keyword.
The possible bimap instantiation are enumerated here:
\c {Side}KeyType can be directly a type, this is default to
\c set_of<{Side}KeyType>, or can be a \c {SetType}_of<Type>
specification. Additionally this two parameters can be tagged
to specify others tags instead of the usual \c member_at::{Side}
ones.


\code

    typedef bimap
    <
        LeftCollectionType, RightCollectionType

        [ , SetTypeOfRelation  ]  // Default to left_based
        [ , info_hook< Info >  ]  // Default to no info
        [ , Allocator          ]  // Default to std::allocator<>

    > bm;

\endcode

                                                                       **/


template
<
    class KeyTypeA, class KeyTypeB,
    class AP1 = ::boost::mpl::na,
    class AP2 = ::boost::mpl::na,
    class AP3 = ::boost::mpl::na
>
class bimap
:
    // Bimap Core, use mpl magic to find the desired bimap type

    public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>,

    // You can use bimap as a collection of relations

    public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
                ::relation_set,

    // Include extra typedefs (i.e. left_local_iterator for unordered_map)

    public ::boost::bimaps::detail:: left_map_view_extra_typedefs<
        BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::left_map_view_type<
            ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
        >::type
    >,
    public ::boost::bimaps::detail::right_map_view_extra_typedefs< 
        BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::right_map_view_type<
            ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
        >::type
    >
{
    typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
        bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> base_;

    BOOST_DEDUCED_TYPENAME base_::core_type core;

    public:

    // metadata --------------------------------------------------------

    /*
    // The rest is computed in the core, because it is quite difficult to
    // expose a nice interface with so many metaprogramming stuff.
    // Here it is the complete metadat list.

    // Map by {side} metadata

    typedef -unspecified- {side}_tag;
    typedef -unspecified- {side}_data_type;
    typedef -unspecified- {side}_value_type;
    typedef -unspecified- {side}_key_type;
    typedef -unspecified- {side}_iterator;
    typedef -unspecified- {side}_const_iterator;

    ------------------------------------------------------------------*/

    typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
          left_map_view_type<base_>::type  left_map;
    typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
         right_map_view_type<base_>::type right_map;

    typedef BOOST_DEDUCED_TYPENAME
         left_map::reference        left_reference;
    typedef BOOST_DEDUCED_TYPENAME
         left_map::const_reference  left_const_reference;

    typedef BOOST_DEDUCED_TYPENAME
        right_map::reference       right_reference;
    typedef BOOST_DEDUCED_TYPENAME
        right_map::const_reference right_const_reference;

    typedef BOOST_DEDUCED_TYPENAME base_::relation::info_type info_type;

    typedef BOOST_DEDUCED_TYPENAME base_::core_type::allocator_type allocator_type; 
    
    /// Left map view
    left_map  left;

    /// Right map view
    right_map right;

    typedef BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag 
                                          logic_relation_set_tag;
    typedef BOOST_DEDUCED_TYPENAME base_::logic_left_tag logic_left_tag;
    typedef BOOST_DEDUCED_TYPENAME base_::logic_right_tag logic_right_tag;
    typedef BOOST_DEDUCED_TYPENAME base_::core_type::ctor_args_list 
                                                     ctor_args_list;

   bimap(const allocator_type& al = allocator_type()) :

       base_::relation_set(
           ::boost::multi_index::get<
               logic_relation_set_tag
           >(core)
       ),

       core(al),

       left (
           ::boost::multi_index::get<
               logic_left_tag
           >(core)
       ),
       right (
           ::boost::multi_index::get<
               logic_right_tag
           >(core)
       )

   {}

   template< class InputIterator >
   bimap(InputIterator first,InputIterator last,
         const allocator_type& al = allocator_type()) :

       base_::relation_set(
           ::boost::multi_index::get<logic_relation_set_tag>(core)
       ),

       core(first,last,ctor_args_list(),al),

       left (
           ::boost::multi_index::get<logic_left_tag>(core)
       ),
       right (
           ::boost::multi_index::get<logic_right_tag>(core)
       )

   {}

   bimap(const bimap& x) :

       base_::relation_set(
           ::boost::multi_index::get<logic_relation_set_tag>(core)
       ),

       core(x.core),

       left (
           ::boost::multi_index::get<logic_left_tag>(core)
       ),
       right (
           ::boost::multi_index::get<logic_right_tag>(core)
       )

   {}

    bimap& operator=(const bimap& x)
    {
        core = x.core;
        return *this;
    }

    // Projection of iterators

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::left_iterator
        project_left(IteratorType iter)
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
    }

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::left_const_iterator
        project_left(IteratorType iter) const
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
    }

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::right_iterator
        project_right(IteratorType iter)
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
    }

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::right_const_iterator
        project_right(IteratorType iter) const
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
    }

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::relation_set::iterator
        project_up(IteratorType iter)
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
    }

    template< class IteratorType >
    BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator
        project_up(IteratorType iter) const
    {
        return core.template project<
            BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
    }

    // Support for tags

    template< class Tag, class IteratorType >
    BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
    iterator_type_by<Tag,bimap>::type
        project(IteratorType iter
                BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
    {
        return core.template project<Tag>(iter.base());
    }

    template< class Tag, class IteratorType >
    BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
    const_iterator_type_by<Tag,bimap>::type
        project(IteratorType iter
                BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const
    {
        return core.template project<Tag>(iter.base());
    }

    template< class Tag >
    struct map_by :
        public ::boost::bimaps::support::map_type_by<Tag,bimap>::type
    {
        typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
            map_type_by<Tag,bimap>::type type;

        private: map_by() {}
    };

    template< class Tag >
    BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
    map_type_by<Tag,bimap>::type &
        by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
    {
        return ::boost::bimaps::support::map_by<Tag>(*this);
    }

    template< class Tag >
    const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
    map_type_by<Tag,bimap>::type &
        by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const
    {
        return ::boost::bimaps::support::map_by<Tag>(*this);
    }


    #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION

    // Serialization support

    private:

    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & serialization::make_nvp("mi_core",core);
    }

    #endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};

} // namespace bimaps
} // namespace boost


/** \namespace boost::bimaps::support
\brief Metafunctions to help working with bimaps.
                                                            **/

/** \namespace boost::bimaps::views
\brief Bimap views.
                                                            **/

/** \namespace boost::bimaps::views::detail
\brief Bimap views details.
                                                            **/



// Include basic tools for user commodity

#include <boost/bimap/tags/tagged.hpp>
#include <boost/bimap/relation/member_at.hpp>
#include <boost/multi_index/detail/unbounded.hpp>

// Bring the most used namespaces directly to the user main namespace
namespace boost {
namespace bimaps {

using ::boost::bimaps::tags::tagged;

namespace member_at = ::boost::bimaps::relation::member_at;

using ::boost::multi_index::unbounded;

} // namespace bimaps
} // namespace boost


#endif // BOOST_BIMAP_BIMAP_HPP
