| // 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 tags/tagged.hpp |
| /// \brief Defines the tagged class |
| |
| #ifndef BOOST_BIMAP_TAGS_TAGGED_HPP |
| #define BOOST_BIMAP_TAGS_TAGGED_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER>=1200) |
| #pragma once |
| #endif |
| |
| #include <boost/config.hpp> |
| |
| namespace boost { |
| namespace bimaps { |
| |
| /// \brief A light non-invasive idiom to tag a type. |
| /** |
| |
| There are a lot of ways of tagging a type. The standard library for example |
| defines tags (empty structs) that are then inherited by the tagged class. To |
| support built-in types and other types that simple cannot inherit from the |
| tag, the standard builds another level of indirection. An example of this is |
| the type_traits metafunction. This approach is useful if the tags are intended |
| to be used in the library internals, and if the user does not have to create |
| new tagged types often. |
| |
| Boost.MultiIndex is an example of a library that defines a tagged idiom that |
| is better suited to the user. As an option, in the indexed by declaration |
| of a multi-index container a user can \b attach a tag to each index, so it |
| can be referred by it instead of by the index number. It is a very user |
| friendly way of specifying a tag but is very invasive from the library writer's |
| point of view. Each index must now support this additional parameter. Maybe |
| not in the case of the multi-index container, but in simpler classes |
| the information of the tags is used by the father class rather than by the |
| tagged types. |
| |
| \b tagged is a light non-invasive idiom to tag a type. It is very intuitive |
| and user-friendly. With the use of the defined metafunctions the library |
| writer can enjoy the coding too. |
| |
| **/ |
| |
| namespace tags { |
| |
| /// \brief The tag holder |
| /** |
| |
| The idea is to add a level of indirection to the type being tagged. With this |
| class you wrapped a type and apply a tag to it. The only thing to remember is |
| that if you write |
| |
| \code |
| typedef tagged<type,tag> taggedType; |
| \endcode |
| |
| Then instead to use directly the tagged type, in order to access it you have |
| to write \c taggedType::value_type. The tag can be obtained using \c taggedType::tag. |
| The idea is not to use this metadata directly but rather using the metafunctions |
| that are defined in the support namespace. With this metafunctions you can work |
| with tagged and untagged types in a consistent way. For example, the following |
| code is valid: |
| |
| \code |
| BOOST_STATIC_ASSERT( is_same< value_type_of<taggedType>, value_type_of<type> >::value ); |
| \endcode |
| |
| The are other useful metafunctions there too. |
| See also value_type_of, tag_of, is_tagged, apply_to_value_type. |
| |
| \ingroup tagged_group |
| **/ |
| template< class Type, class Tag > |
| struct tagged |
| { |
| typedef Type value_type; |
| typedef Tag tag; |
| }; |
| |
| } // namespace tags |
| } // namespace bimaps |
| } // namespace boost |
| |
| /** \namespace boost::bimaps::tags::support |
| \brief Metafunctions to work with tagged types. |
| |
| This metafunctions aims to make easier the manage of tagged types. They are all mpl |
| compatible metafunctions and can be used with lambda expresions. |
| The metafunction value_type_of and tag_of get the data in a tagged type in a secure |
| and consistent way. |
| default_tagged and overwrite_tagged allows to work with the tag of a tagged type, |
| and apply_to_value_type is a higher order metafunction that allow the user to change |
| the type of a TaggedType. |
| **/ |
| |
| #endif // BOOST_BIMAP_TAGS_TAGGED_HPP |
| |
| |
| |
| |