root/core/private_/dsel_core_work_creation.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 #ifndef libjmmcg_core_private_dsel_core_work_creation_hpp
   2 #define libjmmcg_core_private_dsel_core_work_creation_hpp
   3 
   4 /******************************************************************************
   5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/private_/dsel_core_work_creation.hpp 2287 2018-06-24 17:53:41Z jmmcg $
   6 **
   7 ** Copyright (c) 2012 by J.M.McGuiness, coder@hussar.me.uk
   8 **
   9 ** This library is free software; you can redistribute it and/or
  10 ** modify it under the terms of the GNU Lesser General Public
  11 ** License as published by the Free Software Foundation; either
  12 ** version 2.1 of the License, or (at your option) any later version.
  13 **
  14 ** This library is distributed in the hope that it will be useful,
  15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17 ** Lesser General Public License for more details.
  18 **
  19 ** You should have received a copy of the GNU Lesser General Public
  20 ** License along with this library; if not, write to the Free Software
  21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23 
  24 #include <boost/type_traits/function_traits.hpp>
  25 
  26 namespace jmmcg { namespace ppd { namespace private_ {
  27 
  28 /**
  29         If the is an error in thread_pool_base::create_direct in the instantiation of BOOST_TYPEOF_TPL because this class is selected as the best match, it is possible that he incorrect operator<<() overload is being selected in "thread_desl_types.hpp".
  30 */
  31 template<class T, class CFG>
  32 struct crack_process_fn_traits {
  33         static constexpr bool no_except=false;
  34         typedef T class_type;
  35         typedef typename T::result_type argument_type;
  36         static constexpr bool is_const=false;
  37 };
  38 template<class T, class CFG, bool NoExcept>
  39 struct crack_process_fn_traits<void (__fastcall T::*)() const noexcept(NoExcept), CFG> {
  40         static constexpr bool no_except=NoExcept;
  41         typedef boost::function_traits<void () const noexcept(no_except)> process_fn_type;
  42         typedef T class_type;
  43         typedef void argument_type;
  44         static constexpr bool is_const=true;
  45         template<void (__fastcall T::*Fn)() const noexcept(no_except)>
  46         struct queue_item {
  47                 typedef closure::closure_void_static_const<T, no_except, Fn, CFG> result;
  48         };
  49 };
  50 template<class T, class CFG, bool NoExcept>
  51 struct crack_process_fn_traits<void (__fastcall T::*)() noexcept(NoExcept), CFG> {
  52         static constexpr bool no_except=NoExcept;
  53         typedef boost::function_traits<void () noexcept(no_except)> process_fn_type;
  54         typedef T class_type;
  55         typedef void argument_type;
  56         static constexpr bool is_const=false;
  57         template<void (__fastcall T::*Fn)() noexcept(no_except)>
  58         struct queue_item {
  59                 typedef closure::closure_void_static<T, no_except, Fn, CFG> result;
  60         };
  61 };
  62 template<class T, class A, class CFG, bool NoExcept>
  63 struct crack_process_fn_traits<void (__fastcall T::*)(A &) const noexcept(NoExcept), CFG> {
  64         static constexpr bool no_except=NoExcept;
  65         typedef boost::function_traits<void (A &) noexcept(no_except)> process_fn_type;
  66         typedef T class_type;
  67         typedef A argument_type;
  68         static constexpr bool is_const=true;
  69         template<void (__fastcall T::*Fn)(A &) const noexcept(no_except)>
  70         struct queue_item {
  71                 typedef closure::closure_static_const<T, A, no_except, Fn, CFG> result;
  72         };
  73 };
  74 template<class T, class A, class CFG, bool NoExcept>
  75 struct crack_process_fn_traits<void (__fastcall T::*)(A &) noexcept(NoExcept), CFG> {
  76         static constexpr bool no_except=NoExcept;
  77         typedef boost::function_traits<void (A &) noexcept(no_except)> process_fn_type;
  78         typedef T class_type;
  79         typedef A argument_type;
  80         static constexpr bool is_const=false;
  81         template<void (__fastcall T::*Fn)(A &) noexcept(no_except)>
  82         struct queue_item {
  83                 typedef closure::closure_static<T, A, no_except, Fn, CFG> result;
  84         };
  85 };
  86 template<class T, class A1, class A2, class CFG, bool NoExcept>
  87 struct crack_process_fn_traits<void (__fastcall T::*)(A1 &, A2 const &) const noexcept(NoExcept), CFG> {
  88         static constexpr bool no_except=NoExcept;
  89         typedef boost::function_traits<void (A1 &, A2 const &) noexcept(no_except)> process_fn_type;
  90         typedef T class_type;
  91         typedef A1 argument_type;
  92         typedef A2 second_argument_type;
  93         static constexpr bool is_const=true;
  94         template<void (__fastcall T::*Fn)(A1 &, A2 const &) const noexcept(no_except)>
  95         struct queue_item {
  96                 typedef closure::closure_static_cfg_const<T, A1, A2, no_except, Fn, CFG> result;
  97         };
  98 };
  99 template<class T, class A1, class A2, class CFG, bool NoExcept>
 100 struct crack_process_fn_traits<void (__fastcall T::*)(A1 &, A2 const &) noexcept(NoExcept), CFG> {
 101         static constexpr bool no_except=NoExcept;
 102         typedef boost::function_traits<void (A1 &, A2 const &) noexcept(no_except)> process_fn_type;
 103         typedef T class_type;
 104         typedef A1 argument_type;
 105         typedef A2 second_argument_type;
 106         static constexpr bool is_const=false;
 107         template<void (__fastcall T::*Fn)(A1 &, A2 const &) noexcept(no_except)>
 108         struct queue_item {
 109                 typedef closure::closure_static_cfg<T, A1, A2, no_except, Fn, CFG> result;
 110         };
 111 };
 112 template<class T, class PFP, class Wk, class CFG>
 113 struct choose_process_fn {
 114         typedef crack_process_fn_traits<PFP, CFG> type;
 115         typedef typename type::class_type class_type;
 116         typedef typename type::argument_type result_type;
 117         BOOST_MPL_ASSERT((std::is_same<class_type, typename std::remove_const<typename std::remove_reference<Wk>::type>::type>));
 118         typedef PFP process_fn_ptr;
 119         static constexpr bool is_const=type::is_const;
 120         static constexpr bool no_except=type::no_except;
 121 };
 122 template<class PFP, class Wk, class CFG>
 123 struct choose_process_fn<std::false_type, PFP, Wk, CFG> {
 124         typedef Wk class_type;
 125         typedef typename Wk::result_type result_type;
 126         static constexpr bool is_const=false;
 127         static constexpr bool no_except=false;
 128 };
 129 template<class Wk, class Fn, class CFG>
 130 class get_process_fn_traits {
 131 private:
 132         typedef Fn process_fn_ptr;
 133         typedef typename std::is_member_function_pointer<process_fn_ptr>::type has_process_fn;
 134         typedef choose_process_fn<has_process_fn, process_fn_ptr, Wk, CFG> got_result_type;
 135 
 136 public:
 137         typedef got_result_type type;
 138 };
 139 
 140 template<class V>
 141 struct noop {
 142         typedef V argument_type;
 143         typedef argument_type result_type;
 144 
 145         constexpr result_type operator()(argument_type const &a) const noexcept(true) FORCE_INLINE {
 146                 return a;
 147         }
 148 };
 149 
 150 /// This library-internal class just creates a thread_wk_t for the user's closure_base-derived closure.
 151 /**
 152         Note: one cannot give "exception-specifications" to non-joinable work, as you can't call get_results() on it, because the non-joinable transfer doesn't return an execution_context. (A constructor isn't used because you can't return a value from the constructor, and a member-template isn't used because of MSVC++ v12.00.8168 compiler limitations.)
 153 
 154         \param  InpWk   The closure_base-derived closure should contain a non-overloaded function called process() or process(result_type &), possibly const-qualified.
 155 
 156         \see thread_wk_t
 157 */
 158 template<class P, class InpWk, class FnType, FnType FnPtr>
 159 struct create_direct {
 160         typedef P pool_traits_type;
 161         typedef typename pool_traits_type::os_traits os_traits;
 162         typedef typename pool_traits_type::cfg_type cfg_type;
 163         /**
 164                 \todo It would be good to make use of the is_const member to determine if the mutation is pure. If so then all sorts of nice things could be done like memoization of the result of the mutation, i.e. place this object type into a hash_map at compile-time, and place the result into there too, and for later mutations of the same object instance to short-cut needing to do all the using a thread to generate the result malarky, as long as we save the object instance state sufficiently.
 165         */
 166         typedef typename get_process_fn_traits<InpWk, FnType, cfg_type>::type process_fn_traits;
 167         typedef typename process_fn_traits::result_type result_type;
 168         typedef typename process_fn_traits::process_fn_ptr process_fn_ptr;
 169         typedef typename process_fn_traits::type::template queue_item<FnPtr>::result closure_t;
 170 };
 171 
 172 } } }
 173 
 174 #endif

/* [<][>][^][v][top][bottom][index][help] */