Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:26

0001 #ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED
0002 #define BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED
0003 
0004 // Copyright 2020 Peter Dimov
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <boost/describe/modifiers.hpp>
0009 #include <boost/describe/bases.hpp>
0010 #include <boost/describe/detail/void_t.hpp>
0011 #include <boost/describe/detail/cx_streq.hpp>
0012 #include <boost/describe/detail/config.hpp>
0013 
0014 #if defined(BOOST_DESCRIBE_CXX11)
0015 
0016 #include <boost/mp11/algorithm.hpp>
0017 #include <boost/mp11/utility.hpp>
0018 #include <boost/mp11/integral.hpp>
0019 #include <boost/mp11/list.hpp>
0020 #include <boost/mp11/bind.hpp>
0021 #include <type_traits>
0022 
0023 namespace boost
0024 {
0025 namespace describe
0026 {
0027 namespace detail
0028 {
0029 
0030 // _describe_members<T>
0031 
0032 template<class T> using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast<T**>(0) ) );
0033 template<class T> using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast<T**>(0) ) );
0034 template<class T> using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast<T**>(0) ) );
0035 
0036 template<class T> using _describe_members = mp11::mp_append<_describe_public_members<T>, _describe_protected_members<T>, _describe_private_members<T>>;
0037 
0038 // describe_inherited_members<T>
0039 
0040 // T: type
0041 // V: list of virtual bases visited so far
0042 template<class T, class V> struct describe_inherited_members_impl;
0043 template<class T, class V> using describe_inherited_members = typename describe_inherited_members_impl<T, V>::type;
0044 
0045 // L: list of base class descriptors
0046 // T: derived type
0047 // V: list of virtual bases visited so far
0048 template<class L, class T, class V> struct describe_inherited_members2_impl;
0049 template<class L, class T, class V> using describe_inherited_members2 = typename describe_inherited_members2_impl<L, T, V>::type;
0050 
0051 template<class T, class V> struct describe_inherited_members_impl
0052 {
0053     using R1 = describe_inherited_members2<describe_bases<T, mod_any_access>, T, V>;
0054     using R2 = _describe_members<T>;
0055 
0056     using type = mp11::mp_append<R1, R2>;
0057 };
0058 
0059 template<template<class...> class L, class T, class V> struct describe_inherited_members2_impl<L<>, T, V>
0060 {
0061     using type = L<>;
0062 };
0063 
0064 template<class D1, class D2> using name_matches = mp11::mp_bool< cx_streq( D1::name, D2::name ) >;
0065 
0066 template<class D, class L> using name_is_hidden = mp11::mp_any_of_q<L, mp11::mp_bind_front<name_matches, D>>;
0067 
0068 constexpr unsigned cx_max( unsigned m1, unsigned m2 )
0069 {
0070     return m1 > m2? m1: m2;
0071 }
0072 
0073 template<class T, unsigned Bm> struct update_modifiers
0074 {
0075     template<class D> struct fn
0076     {
0077         using L = _describe_members<T>;
0078         static constexpr unsigned hidden = name_is_hidden<D, L>::value? mod_hidden: 0;
0079 
0080         static constexpr unsigned mods = D::modifiers;
0081         static constexpr unsigned access = cx_max( mods & mod_any_access, Bm & mod_any_access );
0082 
0083         static constexpr decltype(D::pointer) pointer = D::pointer;
0084         static constexpr decltype(D::name) name = D::name;
0085         static constexpr unsigned modifiers = ( mods & ~mod_any_access ) | access | mod_inherited | hidden;
0086     };
0087 };
0088 
0089 #ifndef __cpp_inline_variables
0090 template<class T, unsigned Bm> template<class D> constexpr decltype(D::pointer) update_modifiers<T, Bm>::fn<D>::pointer;
0091 template<class T, unsigned Bm> template<class D> constexpr decltype(D::name) update_modifiers<T, Bm>::fn<D>::name;
0092 template<class T, unsigned Bm> template<class D> constexpr unsigned update_modifiers<T, Bm>::fn<D>::modifiers;
0093 #endif
0094 
0095 template<class D> struct gather_virtual_bases_impl;
0096 template<class D> using gather_virtual_bases = typename gather_virtual_bases_impl<D>::type;
0097 
0098 template<class D> struct gather_virtual_bases_impl
0099 {
0100     using B = typename D::type;
0101     static constexpr unsigned M = D::modifiers;
0102 
0103     using R1 = mp11::mp_transform<gather_virtual_bases, describe_bases<B, mod_any_access>>;
0104     using R2 = mp11::mp_apply<mp11::mp_append, R1>;
0105 
0106     using type = mp11::mp_if_c<(M & mod_virtual) != 0, mp11::mp_push_front<R2, B>, R2>;
0107 };
0108 
0109 template<template<class...> class L, class D1, class... D, class T, class V> struct describe_inherited_members2_impl<L<D1, D...>, T, V>
0110 {
0111     using B = typename D1::type;
0112     static constexpr unsigned M = D1::modifiers;
0113 
0114     using R1 = mp11::mp_if_c<(M & mod_virtual) && mp11::mp_contains<V, B>::value, L<>, describe_inherited_members<B, V>>;
0115 
0116     using R2 = mp11::mp_transform_q<update_modifiers<T, M>, R1>;
0117 
0118     using V2 = mp11::mp_append<V, gather_virtual_bases<D1>>;
0119     using R3 = describe_inherited_members2<L<D...>, T, V2>;
0120 
0121     using type = mp11::mp_append<R2, R3>;
0122 };
0123 
0124 // describe_members<T, M>
0125 
0126 template<class T, unsigned M> using describe_members = mp11::mp_eval_if_c<(M & mod_inherited) == 0, _describe_members<T>, describe_inherited_members, T, mp11::mp_list<>>;
0127 
0128 // member_filter
0129 
0130 template<unsigned M> struct member_filter
0131 {
0132     template<class T> using fn = mp11::mp_bool<
0133         (M & mod_any_access & T::modifiers) != 0 &&
0134         ( (M & mod_any_member) != 0 || (M & mod_static) == (T::modifiers & mod_static) ) &&
0135         ( (M & mod_any_member) != 0 || (M & mod_function) == (T::modifiers & mod_function) ) &&
0136         (M & mod_hidden) >= (T::modifiers & mod_hidden)
0137     >;
0138 };
0139 
0140 // has_describe_members
0141 
0142 template<class T, class En = void> struct has_describe_members: std::false_type
0143 {
0144 };
0145 
0146 template<class T> struct has_describe_members<T, void_t<_describe_members<T>>>: std::true_type
0147 {
0148 };
0149 
0150 } // namespace detail
0151 
0152 template<class T, unsigned M> using describe_members = mp11::mp_copy_if_q<detail::describe_members<T, M>, detail::member_filter<M>>;
0153 
0154 template<class T> using has_describe_members = detail::has_describe_members<T>;
0155 
0156 } // namespace describe
0157 } // namespace boost
0158 
0159 #endif // !defined(BOOST_DESCRIBE_CXX11)
0160 
0161 #endif // #ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED