1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2006 Dan Marsden 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(BOOST_FUSION_AT_KEY_20060304_1755) 9 #define BOOST_FUSION_AT_KEY_20060304_1755 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/type_traits/is_const.hpp> 13 #include <boost/fusion/sequence/intrinsic_fwd.hpp> 14 #include <boost/fusion/sequence/intrinsic/has_key.hpp> 15 #include <boost/fusion/algorithm/query/find.hpp> 16 #include <boost/fusion/iterator/deref_data.hpp> 17 #include <boost/fusion/support/tag_of.hpp> 18 #include <boost/fusion/support/category_of.hpp> 19 #include <boost/fusion/support/detail/access.hpp> 20 #include <boost/mpl/empty_base.hpp> 21 #include <boost/mpl/if.hpp> 22 #include <boost/mpl/or.hpp> 23 24 namespace boost { namespace fusion 25 { 26 // Special tags: 27 struct sequence_facade_tag; 28 struct boost_array_tag; // boost::array tag 29 struct mpl_sequence_tag; // mpl sequence tag 30 struct std_pair_tag; // std::pair tag 31 32 namespace extension 33 { 34 template <typename Tag> 35 struct at_key_impl 36 { 37 template <typename Seq, typename Key> 38 struct apply 39 { 40 typedef typename 41 result_of::deref_data< 42 typename result_of::find<Seq, Key>::type 43 >::type 44 type; 45 46 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 47 static type callboost::fusion::extension::at_key_impl::apply48 call(Seq& seq) 49 { 50 return fusion::deref_data(fusion::find<Key>(seq)); 51 } 52 }; 53 }; 54 55 template <> 56 struct at_key_impl<sequence_facade_tag> 57 { 58 template <typename Sequence, typename Key> 59 struct apply : Sequence::template at_key_impl<Sequence, Key> {}; 60 }; 61 62 template <> 63 struct at_key_impl<boost_array_tag>; 64 65 template <> 66 struct at_key_impl<mpl_sequence_tag>; 67 68 template <> 69 struct at_key_impl<std_pair_tag>; 70 } 71 72 namespace detail 73 { 74 template <typename Sequence, typename Key, typename Tag> 75 struct at_key_impl 76 : mpl::if_< 77 mpl::or_< 78 typename extension::has_key_impl<Tag>::template apply<Sequence, Key> 79 , traits::is_unbounded<Sequence> 80 > 81 , typename extension::at_key_impl<Tag>::template apply<Sequence, Key> 82 , mpl::empty_base 83 >::type 84 {}; 85 } 86 87 namespace result_of 88 { 89 template <typename Sequence, typename Key> 90 struct at_key 91 : detail::at_key_impl<Sequence, Key, typename detail::tag_of<Sequence>::type> 92 {}; 93 } 94 95 template <typename Key, typename Sequence> 96 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 97 inline typename 98 lazy_disable_if< 99 is_const<Sequence> 100 , result_of::at_key<Sequence, Key> 101 >::type at_key(Sequence & seq)102 at_key(Sequence& seq) 103 { 104 return result_of::at_key<Sequence, Key>::call(seq); 105 } 106 107 template <typename Key, typename Sequence> 108 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 109 inline typename result_of::at_key<Sequence const, Key>::type at_key(Sequence const & seq)110 at_key(Sequence const& seq) 111 { 112 return result_of::at_key<Sequence const, Key>::call(seq); 113 } 114 }} 115 116 #endif 117