]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | |
48 | 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 | |
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 | |
110 | at_key(Sequence const& seq) | |
111 | { | |
112 | return result_of::at_key<Sequence const, Key>::call(seq); | |
113 | } | |
114 | }} | |
115 | ||
116 | #endif |