libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
dsel_core_work_creation.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_PRIVATE_DSEL_CORE_WORK_CREATION_HPP
2 #define LIBJMMCG_CORE_PRIVATE_DSEL_CORE_WORK_CREATION_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2012 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "../config.h"
23 
24 #include <boost/type_traits/function_traits.hpp>
25 
26 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace private_ {
27 
28 /**
29  If the is an error in thread_pool_base::create_direct in the instantiation of decltype 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 Cls, class CFG>
33  static constexpr bool no_except=false;
34  typedef Cls class_type;
35  typedef typename Cls::result_type argument_type;
36  static constexpr bool is_const=false;
37 };
38 template<class Cls, class CFG, bool NoExcept>
39 struct crack_process_fn_traits<void (__fastcall Cls::*)() 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 Cls class_type;
43  typedef void argument_type;
44  static constexpr bool is_const=true;
45  template<void (__fastcall Cls::*Fn)() const noexcept(no_except)>
46  struct queue_item {
48  };
49 };
50 template<class Cls, class CFG, bool NoExcept>
51 struct crack_process_fn_traits<void (__fastcall Cls::*)() noexcept(NoExcept), CFG> {
52  static constexpr bool no_except=NoExcept;
53  typedef boost::function_traits<void () noexcept(no_except)> process_fn_type;
54  typedef Cls class_type;
55  typedef void argument_type;
56  static constexpr bool is_const=false;
57  template<void (__fastcall Cls::*Fn)() noexcept(no_except)>
58  struct queue_item {
60  };
61 };
62 template<class Cls, class ResT, class CFG, bool NoExcept>
63 struct crack_process_fn_traits<void (__fastcall Cls::*)(ResT &) const noexcept(NoExcept), CFG> {
64  static constexpr bool no_except=NoExcept;
65  typedef boost::function_traits<void (ResT &) noexcept(no_except)> process_fn_type;
66  typedef Cls class_type;
67  typedef ResT argument_type;
68  static constexpr bool is_const=true;
69  template<void (__fastcall Cls::*Fn)(ResT &) const noexcept(no_except)>
70  struct queue_item {
72  };
73 };
74 template<class Cls, class ResT, class CFG, bool NoExcept>
75 struct crack_process_fn_traits<void (__fastcall Cls::*)(ResT &) noexcept(NoExcept), CFG> {
76  static constexpr bool no_except=NoExcept;
77  typedef boost::function_traits<void (ResT &) noexcept(no_except)> process_fn_type;
78  typedef Cls class_type;
79  typedef ResT argument_type;
80  static constexpr bool is_const=false;
81  template<void (__fastcall Cls::*Fn)(ResT &) noexcept(no_except)>
82  struct queue_item {
84  };
85 };
86 template<class Cls, class ResT, class A2, class CFG, bool NoExcept>
87 struct crack_process_fn_traits<void (__fastcall Cls::*)(ResT &, A2 const &) const noexcept(NoExcept), CFG> {
88  static constexpr bool no_except=NoExcept;
89  typedef boost::function_traits<void (ResT &, A2 const &) noexcept(no_except)> process_fn_type;
90  typedef Cls class_type;
91  typedef ResT argument_type;
93  static constexpr bool is_const=true;
94  template<void (__fastcall Cls::*Fn)(ResT &, A2 const &) const noexcept(no_except)>
95  struct queue_item {
97  };
98 };
99 template<class Cls, class ResT, class A2, class CFG, bool NoExcept>
100 struct crack_process_fn_traits<void (__fastcall Cls::*)(ResT &, A2 const &) noexcept(NoExcept), CFG> {
101  static constexpr bool no_except=NoExcept;
102  typedef boost::function_traits<void (ResT &, A2 const &) noexcept(no_except)> process_fn_type;
103  typedef Cls class_type;
104  typedef ResT argument_type;
106  static constexpr bool is_const=false;
107  template<void (__fastcall Cls::*Fn)(ResT &, A2 const &) noexcept(no_except)>
108  struct queue_item {
110  };
111 };
112 template<class IsMemFn, class PFP, class Wk, class CFG>
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 FnType, class CFG>
131 private:
132  using process_fn_ptr=FnType;
133  using has_process_fn=typename std::is_member_function_pointer<process_fn_ptr>::type;
134  using got_result_type=choose_process_fn<has_process_fn, process_fn_ptr, Wk, CFG>;
135 
136 public:
137  using type=got_result_type;
138 };
139 
140 template<class V>
141 struct noop {
142  typedef V argument_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>
160  typedef P pool_traits_type;
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;
169  typedef typename process_fn_traits::type::template queue_item<FnPtr>::result closure_t;
170 };
171 
172 } } } }
173 
174 #endif