Back to home page

EIC code displayed by LXR

 
 

    


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

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