From f8bb69dc9a54e18bfc66fd445e84b139bf189964 Mon Sep 17 00:00:00 2001 From: Dan Marsden Date: Tue, 8 May 2007 22:14:58 +0000 Subject: [PATCH] adding struct associative adaptor [SVN r37638] --- .../adapted/struct/adapt_assoc_struct.hpp | 94 +++++++++++++++++++ .../adapted/struct/detail/at_key_impl.hpp | 54 +++++++++++ .../adapted/struct/detail/has_key_impl.hpp | 40 ++++++++ .../struct/detail/value_at_key_impl.hpp | 39 ++++++++ .../sequence/adapted/struct/extension.hpp | 24 +++++ 5 files changed, 251 insertions(+) create mode 100644 include/boost/fusion/sequence/adapted/struct/adapt_assoc_struct.hpp create mode 100644 include/boost/fusion/sequence/adapted/struct/detail/at_key_impl.hpp create mode 100644 include/boost/fusion/sequence/adapted/struct/detail/has_key_impl.hpp create mode 100644 include/boost/fusion/sequence/adapted/struct/detail/value_at_key_impl.hpp diff --git a/include/boost/fusion/sequence/adapted/struct/adapt_assoc_struct.hpp b/include/boost/fusion/sequence/adapted/struct/adapt_assoc_struct.hpp new file mode 100644 index 00000000..44357c00 --- /dev/null +++ b/include/boost/fusion/sequence/adapted/struct/adapt_assoc_struct.hpp @@ -0,0 +1,94 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2007 Dan Marsden + + 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) +==============================================================================*/ +#if !defined(BOOST_FUSION_ADAPT_ASSOC_STRUCT_20070508_2207) +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_20070508_2207 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace fusion { namespace extension { + template + struct struct_assoc_member; +}}} + + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT(name, bseq) \ + BOOST_FUSION_ADAPT_ASSOC_STRUCT_I( \ + name, BOOST_PP_CAT(BOOST_FUSION_ADAPT_ASSOC_STRUCT_X bseq, 0)) \ + /***/ + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_X(x, y, z) ((x, y, z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y(x, y, z) ((x, y, z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_X +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_X0 +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_Y0 + +// BOOST_FUSION_ADAPT_ASSOC_STRUCT_I generates the overarching structure and uses +// SEQ_FOR_EACH_I to generate the "linear" substructures. +// Thanks to Paul Mensonides for the PP macro help + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_I(name, seq) \ + namespace boost { namespace fusion { namespace traits \ + { \ + template <> \ + struct tag_of \ + { \ + typedef struct_tag type; \ + }; \ + }}} \ + namespace boost { namespace fusion { namespace extension \ + { \ + template <> \ + struct struct_size : mpl::int_ {}; \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_FUSION_ADAPT_ASSOC_STRUCT_C, name, seq) \ + }}} \ + /***/ + +#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C(r, name, i, xy) \ + template <> \ + struct struct_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(3, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(3, 1, xy); \ + }; \ + }; \ + template<> \ + struct struct_assoc_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(3, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(3, 1, xy); \ + }; \ + }; + /***/ + +#endif diff --git a/include/boost/fusion/sequence/adapted/struct/detail/at_key_impl.hpp b/include/boost/fusion/sequence/adapted/struct/detail/at_key_impl.hpp new file mode 100644 index 00000000..4ce0fce9 --- /dev/null +++ b/include/boost/fusion/sequence/adapted/struct/detail/at_key_impl.hpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + 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) +==============================================================================*/ +#if !defined(BOOST_FUSION_AT_KEY_IMPL_20070508_2248) +#define BOOST_FUSION_AT_KEY_IMPL_20070508_2248 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct at_key_impl; + + template + struct struct_assoc_member; + + template <> + struct at_key_impl + { + template + struct apply + { + typedef typename + extension::struct_assoc_member + element; + + typedef typename + mpl::eval_if< + is_const + , detail::cref_result + , detail::ref_result + >::type + type; + + static type + call(Sequence& seq) + { + return extension:: + struct_assoc_member::call(seq); + } + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/sequence/adapted/struct/detail/has_key_impl.hpp b/include/boost/fusion/sequence/adapted/struct/detail/has_key_impl.hpp new file mode 100644 index 00000000..8972f5df --- /dev/null +++ b/include/boost/fusion/sequence/adapted/struct/detail/has_key_impl.hpp @@ -0,0 +1,40 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + 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) +==============================================================================*/ +#if !defined(BOOST_FUSION_HAS_KEY_IMPL_20070508_2231) +#define BOOST_FUSION_HAS_KEY_IMPL_20070508_2231 + +#include +#include + +namespace boost { namespace fusion { + + struct struct_tag; + + namespace extension + { + struct no_such_member; + + template + struct has_key_impl; + + template + struct struct_assoc_member; + + template<> + struct has_key_impl + { + template + struct apply + : mpl::not_::type> > + { + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/sequence/adapted/struct/detail/value_at_key_impl.hpp b/include/boost/fusion/sequence/adapted/struct/detail/value_at_key_impl.hpp new file mode 100644 index 00000000..b1b3dcfb --- /dev/null +++ b/include/boost/fusion/sequence/adapted/struct/detail/value_at_key_impl.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2005-2007 Dan Marsden + + 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) +==============================================================================*/ +#if !defined(BOOST_FUSION_VALUE_AT_KEY_IMPL_20070508_2300) +#define BOOST_FUSION_VALUE_AT_KEY_IMPL_20070508_2300 + +#include + +namespace boost { namespace fusion +{ + struct struct_tag; + + namespace extension + { + template + struct value_at_key_impl; + + template + struct struct_assoc_member; + + template <> + struct value_at_key_impl + { + template + struct apply + { + typedef typename + extension::struct_assoc_member::type + type; + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/sequence/adapted/struct/extension.hpp b/include/boost/fusion/sequence/adapted/struct/extension.hpp index f0af1baa..c5516ae5 100644 --- a/include/boost/fusion/sequence/adapted/struct/extension.hpp +++ b/include/boost/fusion/sequence/adapted/struct/extension.hpp @@ -37,6 +37,30 @@ namespace boost { namespace fusion { namespace extension struct struct_size : struct_size {}; + + struct no_such_member; + + template + struct struct_assoc_member + { + typedef no_such_member type; + }; + + template + struct struct_assoc_member + { + typedef typename + add_const::type>::type + type; + + static type& + call(Struct const& struct_) + { + return struct_member::call( + const_cast(struct_)); + } + }; + }}} #endif