keyed_element.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*=============================================================================
  2. Copyright (c) 2005-2012 Joel de Guzman
  3. Copyright (c) 2005-2006 Dan Marsden
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #if !defined(BOOST_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330)
  8. #define BOOST_FUSION_DEQUE_DETAIL_KEYED_ELEMENT_26112006_1330
  9. #include <boost/fusion/support/detail/access.hpp>
  10. #include <boost/fusion/iterator/deref.hpp>
  11. #include <boost/fusion/iterator/next.hpp>
  12. namespace boost { namespace fusion
  13. {
  14. struct fusion_sequence_tag;
  15. }}
  16. namespace boost { namespace fusion { namespace detail
  17. {
  18. struct nil_keyed_element
  19. {
  20. typedef fusion_sequence_tag tag;
  21. void get();
  22. template<typename It>
  23. static nil_keyed_element
  24. from_iterator(It const&)
  25. {
  26. return nil_keyed_element();
  27. }
  28. };
  29. template <typename Key, typename Value, typename Rest>
  30. struct keyed_element : Rest
  31. {
  32. typedef Rest base;
  33. typedef fusion_sequence_tag tag;
  34. using Rest::get;
  35. template <typename It>
  36. static keyed_element
  37. from_iterator(It const& it)
  38. {
  39. return keyed_element(
  40. *it, base::from_iterator(fusion::next(it)));
  41. }
  42. keyed_element(keyed_element const& rhs)
  43. : Rest(rhs.get_base()), value_(rhs.value_)
  44. {}
  45. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  46. keyed_element(keyed_element&& rhs)
  47. : Rest(std::forward<Rest>(rhs.forward_base()))
  48. , value_(std::forward<Value>(rhs.value_))
  49. {}
  50. #endif
  51. template <typename U, typename Rst>
  52. keyed_element(keyed_element<Key, U, Rst> const& rhs)
  53. : Rest(rhs.get_base()), value_(rhs.value_)
  54. {}
  55. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  56. #endif
  57. Rest& get_base()
  58. {
  59. return *this;
  60. }
  61. Rest const& get_base() const
  62. {
  63. return *this;
  64. }
  65. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  66. Rest&& forward_base()
  67. {
  68. return std::forward<Rest>(*static_cast<Rest*>(this));
  69. }
  70. #endif
  71. typename cref_result<Value>::type get(Key) const
  72. {
  73. return value_;
  74. }
  75. typename ref_result<Value>::type get(Key)
  76. {
  77. return value_;
  78. }
  79. keyed_element(
  80. typename detail::call_param<Value>::type value
  81. , Rest const& rest)
  82. : Rest(rest), value_(value)
  83. {}
  84. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  85. keyed_element(Value&& value, Rest&& rest)
  86. : Rest(std::forward<Rest>(rest))
  87. , value_(std::forward<Value>(value))
  88. {}
  89. #endif
  90. keyed_element()
  91. : Rest(), value_()
  92. {}
  93. template<typename U, typename Rst>
  94. keyed_element& operator=(keyed_element<Key, U, Rst> const& rhs)
  95. {
  96. base::operator=(static_cast<Rst const&>(rhs)); // cast for msvc-7.1
  97. value_ = rhs.value_;
  98. return *this;
  99. }
  100. keyed_element& operator=(keyed_element const& rhs)
  101. {
  102. base::operator=(rhs);
  103. value_ = rhs.value_;
  104. return *this;
  105. }
  106. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  107. keyed_element& operator=(keyed_element&& rhs)
  108. {
  109. base::operator=(std::forward<keyed_element>(rhs));
  110. value_ = std::forward<Value>(rhs.value_);
  111. return *this;
  112. }
  113. #endif
  114. Value value_;
  115. };
  116. template<typename Elem, typename Key>
  117. struct keyed_element_value_at
  118. : keyed_element_value_at<typename Elem::base, Key>
  119. {};
  120. template<typename Key, typename Value, typename Rest>
  121. struct keyed_element_value_at<keyed_element<Key, Value, Rest>, Key>
  122. {
  123. typedef Value type;
  124. };
  125. }}}
  126. #endif