// 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 relation/support/member_with_tag.hpp | |
/// \brief member_with_tag<tag,relation> metafunction | |
#ifndef BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP | |
#define BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP | |
#if defined(_MSC_VER) && (_MSC_VER>=1200) | |
#pragma once | |
#endif | |
#include <boost/config.hpp> | |
#include <boost/bimap/relation/member_at.hpp> | |
#include <boost/bimap/detail/debug/static_error.hpp> | |
#include <boost/utility/enable_if.hpp> | |
#include <boost/type_traits/is_same.hpp> | |
#include <boost/mpl/bool.hpp> | |
#include <boost/mpl/not.hpp> | |
#include <boost/mpl/and.hpp> | |
/** \struct boost::bimaps::relation::support::member_with_tag | |
\brief Metafunction to convert user tags to the member_at idiom. | |
\code | |
template< class Tag, class Relation > | |
struct member_with_tag | |
{ | |
typedef member_at::{side} type; | |
}; | |
\endcode | |
We have to allow that all the metafunctions that works with tags | |
and retrieves data from a Relation will work with member_at idiom | |
even if the type was tagged. This will be great for the user, | |
because he can choose to tag a member after he is using the | |
relation and the code will still work. | |
If we perform this check in every metafunction it will be very | |
tedious and error prone, so instead of that all metafunctions | |
that works with relations first call this metafunction that | |
convert the tag to a member_at tag. | |
See also member_at, is_tag_of_member_at_left, is_tag_of_member_at_right. | |
\ingroup relation_group | |
**/ | |
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES | |
namespace boost { | |
namespace bimaps { | |
namespace relation { | |
namespace support { | |
template | |
< | |
class Tag, | |
class Relation, | |
class Enable = void | |
> | |
struct member_with_tag | |
{ | |
BOOST_BIMAP_STATIC_ERROR( MEMBER_WITH_TAG_FAILURE, (Relation,Tag) ); | |
}; | |
template< class Relation > | |
struct member_with_tag | |
< | |
member_at::left, Relation, void | |
> | |
{ | |
typedef member_at::left type; | |
}; | |
template< class Relation > | |
struct member_with_tag | |
< | |
member_at::right, Relation, void | |
> | |
{ | |
typedef member_at::right type; | |
}; | |
template< class Relation > | |
struct member_with_tag | |
< | |
member_at::info, Relation, void | |
> | |
{ | |
typedef member_at::info type; | |
}; | |
template< class Tag, class Relation > | |
struct member_with_tag | |
< | |
Tag, Relation, | |
BOOST_DEDUCED_TYPENAME enable_if | |
< | |
mpl::and_ | |
< | |
mpl::not_< is_same<Tag,member_at::left> >, | |
is_same | |
< | |
Tag, | |
BOOST_DEDUCED_TYPENAME Relation::left_tag | |
> | |
> | |
>::type | |
> | |
{ | |
typedef member_at::left type; | |
}; | |
template< class Tag, class Relation > | |
struct member_with_tag | |
< | |
Tag, | |
Relation, | |
BOOST_DEDUCED_TYPENAME enable_if | |
< | |
mpl::and_ | |
< | |
mpl::not_< is_same<Tag,member_at::right> >, | |
is_same | |
< | |
Tag, | |
BOOST_DEDUCED_TYPENAME Relation::right_tag | |
> | |
> | |
>::type | |
> | |
{ | |
typedef member_at::right type; | |
}; | |
template< class Tag, class Relation > | |
struct member_with_tag | |
< | |
Tag, Relation, | |
BOOST_DEDUCED_TYPENAME enable_if | |
< | |
mpl::and_ | |
< | |
mpl::not_< is_same<Tag,member_at::info> >, | |
is_same | |
< | |
Tag, | |
BOOST_DEDUCED_TYPENAME Relation::info_tag | |
> | |
> | |
>::type | |
> | |
{ | |
typedef member_at::info type; | |
}; | |
} // namespace support | |
} // namespace relation | |
} // namespace bimaps | |
} // namespace boost | |
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES | |
#endif // BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP | |