Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:25:44

0001 // Copyright 2015-2018 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt
0005 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
0008 #define BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_
0009 
0010 
0011 #include <type_traits>
0012 
0013 
0014 #ifdef BOOST_HAS_PRAGMA_ONCE
0015 # pragma once
0016 #endif
0017 
0018 namespace boost { namespace dll { namespace experimental { namespace detail {
0019 
0020 //the following could be done by fusion, though it's simple enough to just declare it here.
0021 template<class ...Args>
0022 struct sequence {};
0023 
0024 template<class Value, class Seq> struct push_front;
0025 template<class Value, class ...Args>
0026 struct push_front<Value, sequence<Args...>>
0027 {
0028     typedef sequence<Value, Args...> type;
0029 };
0030 
0031 template<class Lhs, class Rhs>
0032 struct unqalified_is_same :
0033         std::is_same<
0034             typename std::remove_cv<Lhs>::type,
0035             typename std::remove_cv<Rhs>::type
0036         >
0037 {
0038 };
0039 
0040 /* ********************************** function sequence type traits ******************************/
0041 
0042 //determine if it's a sequence of functions.
0043 template<class T> struct is_function_seq;
0044 
0045 //type-trait for function overloads
0046 template<class Class, class...Args> struct is_function_seq<sequence<Class, Args...>>
0047             : std::conditional<
0048                 std::is_function<Class>::value,
0049                 is_function_seq<sequence<Args...>>,
0050                 std::false_type>::type
0051 {};
0052 
0053 template<class Class>
0054 struct is_function_seq<sequence<Class>> : std::is_function<Class>
0055 {
0056 };
0057 
0058 template<>
0059 struct is_function_seq<sequence<>> : std::false_type
0060 {
0061 };
0062 
0063 /* ********************************* Function Tuple ***************************  */
0064 
0065 //a tuple of plain functions.
0066 template <class ...Ts>
0067 struct function_tuple;
0068 
0069 template <class Return, class...Args, class T2, class ...Ts>
0070 struct function_tuple<Return(Args...), T2, Ts...>
0071     : function_tuple<T2, Ts...>
0072 {
0073     Return(*f_)(Args...);
0074 
0075     constexpr function_tuple(Return(* t)(Args...), T2* t2, Ts* ... ts)
0076         : function_tuple<T2, Ts...>(t2, ts...)
0077         , f_(t)
0078     {}
0079 
0080     Return operator()(Args...args) const {
0081         return (*f_)(static_cast<Args>(args)...);
0082     }
0083     using function_tuple<T2, Ts...>::operator();
0084 };
0085 
0086 template <class Return, class...Args>
0087 struct function_tuple<Return(Args...)> {
0088     Return(*f_)(Args...);
0089 
0090     constexpr function_tuple(Return(* t)(Args...))
0091         : f_(t)
0092     {}
0093 
0094     Return operator()(Args...args) const {
0095         return (*f_)(static_cast<Args>(args)...);
0096     }
0097 };
0098 
0099 
0100 /* ********************************** MemFn sequence type traits ******************************/
0101 
0102 template<class Class, class Func>
0103 struct mem_fn_def
0104 {
0105     typedef Class class_type;
0106     typedef Func  func_type;
0107     typedef typename boost::dll::detail::get_mem_fn_type<Class, Func>::mem_fn mem_fn;
0108 };
0109 
0110 template<class ...Args>
0111 struct make_mem_fn_seq;
0112 
0113 // B: is T1 another version of T0?
0114 template<bool, class T0, class T1, class T2>
0115 struct make_mem_fn_seq_getter;
0116 
0117 template<class T0, class T1, class T2>
0118 struct make_mem_fn_seq_getter<true, T0, T1, T2>
0119 {
0120     typedef mem_fn_def<T1, T2> type;
0121 };
0122 
0123 template<class T0, class T1, class T2>
0124 struct make_mem_fn_seq_getter<false, T0, T1, T2>
0125 {
0126     typedef mem_fn_def<T0, T1> type;
0127 };
0128 
0129 template<class Class, class Signature>
0130 struct make_mem_fn_seq<Class, Signature>
0131 {
0132     typedef mem_fn_def<Class, Signature> mem_fn;
0133     typedef sequence<mem_fn>   type;
0134 };
0135 
0136 template<class Class>
0137 struct make_mem_fn_seq<Class>
0138 {
0139     typedef sequence<>   type;
0140 };
0141 
0142 template<class T0, class T1, class T2, class ... Args>
0143 struct make_mem_fn_seq<T0, T1, T2, Args...>
0144 {
0145     /* Since we might have ovls, it might be :
0146      * Class, void(int), void(int, int) //--> just us class for both
0147      * Class, const Class, void(int)//--> ovl class.
0148      *
0149      */
0150     static_assert(std::is_object<T0>::value, "");
0151     typedef typename make_mem_fn_seq_getter<
0152            unqalified_is_same<T0, T1>::value, T0, T1, T2>::type mem_fn_type;
0153 
0154     typedef typename std::conditional<
0155         unqalified_is_same<T0, T1>::value,
0156         make_mem_fn_seq<T1, Args...>,
0157         make_mem_fn_seq<T0, T2, Args...>> ::type next;
0158 
0159     typedef typename push_front<mem_fn_type, typename next::type>::type type;
0160 };
0161 
0162 
0163 
0164 
0165 /* Ok, this needs to be documented, so here's some pseudo-code:
0166  *
0167  * @code
0168  *
0169  * bool unqalified_is_same(lhs, rhs)
0170  * {
0171  *    return remove_cv(lhs) == remove_cv(rhs);
0172  * }
0173  *
0174  * mem_fn make_mem_fn_seq_getter(b, cl, T2, T3)
0175  * {
0176  *    if (b) //b means, that T2 is another version of cl, i.e. qualified
0177  *       return get_mem_fn_type(T2, T3);
0178  *    else //means that T2 is a function.
0179  *       return get_mem_fn_type(cl, T2);
0180  * }
0181  *
0182  * sequence make_mem_fn_seq(type cl, type T2, type T3, types...)
0183  * {
0184  *     mem_fn = make_mem_fn_seq_getter(
0185  *               unqalified_is_same(cl, T2), cl, T2, T3);
0186  *
0187  *     next = unqalified_is_same(cl, T2) ?
0188  *              make_mem_fn_seq(T2, types...) //because: T2 is another version of cl, hence i use this. T3 was already consumed.
0189  *              :
0190  *              make_mem_fn_seq(Class, T3, types...) //because: T2 was a function, hence it is consumed and class remains unchanged.
0191  *              ;
0192  *     return push_front(mem_fn, next) ;
0193  * };
0194  * @endcode
0195  */
0196 
0197 
0198 
0199 template<class T, class U, class ...Args>
0200 struct is_mem_fn_seq_impl
0201 {
0202     typedef typename std::conditional<
0203                  std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value,
0204                  typename is_mem_fn_seq_impl<T, Args...>::type,
0205                  std::false_type>::type type;
0206 };
0207 
0208 template<class T, class U>
0209 struct is_mem_fn_seq_impl<T, U>
0210 {
0211     typedef typename std::conditional<
0212                  std::is_function<U>::value && std::is_object<T>::value,
0213                  std::true_type, std::false_type>::type type;
0214 };
0215 
0216 template<class T, class U, class Last>
0217 struct is_mem_fn_seq_impl<T, U, Last>
0218 {
0219     typedef typename std::conditional<
0220                  (std::is_function<U>::value || boost::dll::experimental::detail::unqalified_is_same<T, U>::value)
0221                  && std::is_function<Last>::value,
0222                  std::true_type, std::false_type>::type type;
0223 };
0224 
0225 template<class T> struct is_mem_fn_seq : std::false_type {};
0226 
0227 //If only two arguments are provided at all.
0228 template<class T, class U>
0229 struct is_mem_fn_seq<sequence<T, U>> : std::conditional<
0230                  std::is_object<T>::value && std::is_function<U>::value,
0231                  std::true_type, std::false_type>::type
0232 {
0233 };
0234 
0235 
0236 template<class T, class Func, class ...Args>
0237 struct is_mem_fn_seq<sequence<T, Func, Args...>> :
0238         std::conditional<
0239             std::is_class<T>::value && std::is_function<Func>::value,
0240             typename is_mem_fn_seq_impl<T, Args...>::type,
0241             std::false_type>::type {};
0242 
0243 
0244 /* ********************************** mem fn sequence tuple ******************************/
0245 
0246 /* A tuple of member functions
0247  * Unlike for plain functions a sequence here might contain classes as well as functions.
0248  */
0249 template <class ...Ts>
0250 struct mem_fn_tuple;
0251 
0252 template <class Class, class Return, class...Args, class T2, class ...Ts>
0253 struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>, T2, Ts...>
0254     : mem_fn_tuple<T2, Ts...>
0255 {
0256     typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
0257     mem_fn f_;
0258 
0259     constexpr mem_fn_tuple(mem_fn f, typename T2::mem_fn t2, typename Ts::mem_fn ... ts)
0260         : mem_fn_tuple<T2, Ts...>(t2, ts...)
0261         , f_(f)
0262     {}
0263 
0264     Return operator()(Class* const cl, Args...args) const {
0265         return (cl->*f_)(static_cast<Args>(args)...);
0266     }
0267     using mem_fn_tuple<T2, Ts...>::operator();
0268 
0269 };
0270 
0271 template <class Class, class Return, class...Args>
0272 struct mem_fn_tuple<mem_fn_def<Class, Return(Args...)>> {
0273     typedef typename boost::dll::detail::get_mem_fn_type<Class, Return(Args...)>::mem_fn mem_fn;
0274     mem_fn f_;
0275 
0276     constexpr mem_fn_tuple(mem_fn f)
0277         : f_(f)
0278     {}
0279 
0280     Return operator()(Class * const cl, Args...args) const {
0281         return (cl->*f_)(static_cast<Args>(args)...);
0282     }
0283 };
0284 
0285 }}}}
0286 #endif /* BOOST_DLL_DETAIL_IMPORT_MANGLED_HELPERS_HPP_ */