member_with_tag.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Boost.Bimap
  2. //
  3. // Copyright (c) 2006-2007 Matias Capeletto
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. /// \file relation/support/member_with_tag.hpp
  9. /// \brief member_with_tag<tag,relation> metafunction
  10. #ifndef BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP
  11. #define BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/config.hpp>
  16. #include <boost/bimap/relation/member_at.hpp>
  17. #include <boost/bimap/detail/debug/static_error.hpp>
  18. #include <boost/utility/enable_if.hpp>
  19. #include <boost/type_traits/is_same.hpp>
  20. #include <boost/mpl/bool.hpp>
  21. #include <boost/mpl/not.hpp>
  22. #include <boost/mpl/and.hpp>
  23. /** \struct boost::bimaps::relation::support::member_with_tag
  24. \brief Metafunction to convert user tags to the member_at idiom.
  25. \code
  26. template< class Tag, class Relation >
  27. struct member_with_tag
  28. {
  29. typedef member_at::{side} type;
  30. };
  31. \endcode
  32. We have to allow that all the metafunctions that works with tags
  33. and retrieves data from a Relation will work with member_at idiom
  34. even if the type was tagged. This will be great for the user,
  35. because he can choose to tag a member after he is using the
  36. relation and the code will still work.
  37. If we perform this check in every metafunction it will be very
  38. tedious and error prone, so instead of that all metafunctions
  39. that works with relations first call this metafunction that
  40. convert the tag to a member_at tag.
  41. See also member_at, is_tag_of_member_at_left, is_tag_of_member_at_right.
  42. \ingroup relation_group
  43. **/
  44. #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
  45. namespace boost {
  46. namespace bimaps {
  47. namespace relation {
  48. namespace support {
  49. template
  50. <
  51. class Tag,
  52. class Relation,
  53. class Enable = void
  54. >
  55. struct member_with_tag
  56. {
  57. BOOST_BIMAP_STATIC_ERROR( MEMBER_WITH_TAG_FAILURE, (Relation,Tag) );
  58. };
  59. template< class Relation >
  60. struct member_with_tag
  61. <
  62. member_at::left, Relation, void
  63. >
  64. {
  65. typedef member_at::left type;
  66. };
  67. template< class Relation >
  68. struct member_with_tag
  69. <
  70. member_at::right, Relation, void
  71. >
  72. {
  73. typedef member_at::right type;
  74. };
  75. template< class Relation >
  76. struct member_with_tag
  77. <
  78. member_at::info, Relation, void
  79. >
  80. {
  81. typedef member_at::info type;
  82. };
  83. template< class Tag, class Relation >
  84. struct member_with_tag
  85. <
  86. Tag, Relation,
  87. BOOST_DEDUCED_TYPENAME enable_if
  88. <
  89. mpl::and_
  90. <
  91. mpl::not_< is_same<Tag,member_at::left> >,
  92. is_same
  93. <
  94. Tag,
  95. BOOST_DEDUCED_TYPENAME Relation::left_tag
  96. >
  97. >
  98. >::type
  99. >
  100. {
  101. typedef member_at::left type;
  102. };
  103. template< class Tag, class Relation >
  104. struct member_with_tag
  105. <
  106. Tag,
  107. Relation,
  108. BOOST_DEDUCED_TYPENAME enable_if
  109. <
  110. mpl::and_
  111. <
  112. mpl::not_< is_same<Tag,member_at::right> >,
  113. is_same
  114. <
  115. Tag,
  116. BOOST_DEDUCED_TYPENAME Relation::right_tag
  117. >
  118. >
  119. >::type
  120. >
  121. {
  122. typedef member_at::right type;
  123. };
  124. template< class Tag, class Relation >
  125. struct member_with_tag
  126. <
  127. Tag, Relation,
  128. BOOST_DEDUCED_TYPENAME enable_if
  129. <
  130. mpl::and_
  131. <
  132. mpl::not_< is_same<Tag,member_at::info> >,
  133. is_same
  134. <
  135. Tag,
  136. BOOST_DEDUCED_TYPENAME Relation::info_tag
  137. >
  138. >
  139. >::type
  140. >
  141. {
  142. typedef member_at::info type;
  143. };
  144. } // namespace support
  145. } // namespace relation
  146. } // namespace bimaps
  147. } // namespace boost
  148. #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
  149. #endif // BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP