YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
yfunc.hpp
浏览该文件的文档.
1 /*
2  © 2010-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #ifndef YSL_INC_Core_yfunc_hpp_
29 #define YSL_INC_Core_yfunc_hpp_ 1
30 
31 #include "YModules.h"
32 #include YFM_YSLib_Core_YShellDefinition
33 #include <functional>
34 #include <typeinfo>
35 #include YFM_YSLib_Adaptor_YContainer
36 
37 namespace YSLib
38 {
39 
40 #if 0
41 /*
42 \brief 调用时动态类型检查仿函数模板。
43 */
44 template<typename _type, typename _tArg, typename _tRet>
45 class GHDynamicFunction
46 {
47 private:
48  const union Pointer
49  {
50  public:
51  _tRet (*_f_ptr)(_type&, _tArg);
52  _tRet (_type::*_mf_ptr)(_tArg) const;
53 
57  explicit
58  Pointer(_tRet (&_f_)(_type&, _tArg))
59  : _f_ptr(&_f_)
60  {}
64  explicit
65  Pointer(_tRet(_type::*_mf_ptr_)(_tArg) const)
66  : _mf_ptr(_mf_ptr_)
67  {}
68  } _m_ptr;
69  const enum
70  {
71  _func = 1,
72  _mem_func = 2
73  } _state;
74 
75 public:
79  explicit
80  GHDynamicFunction(_tRet(&_f)(_type&, _tArg))
81  : _m_ptr(_f), _state(_func)
82  {}
86  explicit
87  GHDynamicFunction(_tRet(_type::*_pf)(_tArg) const)
88  : _m_ptr(_pf), _state(_mem_func)
89  {}
90 
95  _tRet
96  operator()(_type& _r, _tArg _x) const
97  {
98  if(_state == _func)
99  return _m_ptr._f_ptr(_r, _x);
100  // if(_state == _mem_func && _m_ptr._mf_ptr)
101  else if(_m_ptr._mf_ptr)
102  return (_r.*_m_ptr._mf_ptr)(_x);
103  }
108  template<class _tNew>
109  _tRet
110  operator()(const _tNew& _r, _tArg _x) const
111  {
112  if(_state == _mem_func && _m_ptr._mf_ptr)
113  {
114  try
115  {
116  return dynamic_cast<_type&>(_r).*_m_ptr._mf_ptr(_x);
117  }
118  catch(std::bad_cast&)
119  {}
120  }
121  }
122 };
123 
124 
128 template<typename _type, typename _tArg, typename _tRet>
129 inline GHDynamicFunction<_type, _tArg, _tRet>
130 ConstructDynamicFunctionWith(_tRet (&_f)(_type&, _tArg))
131 {
132  return GHDynamicFunction<_type, _tArg, _tRet>(_f);
133 }
138 template<typename _tRet, typename _type, typename _tArg>
139 inline GHDynamicFunction<_tRet, _type, _tArg>
140 ConstructDynamicFunctionWith(_tRet (_type::*_f)(_tArg) const)
141 {
142  return GHDynamicFunction<_tRet, _type, _tArg>(_f);
143 }
144 #endif
145 
146 
151 template<class _type, typename _tRet, typename _tPara, class _tNew = _type>
153 {
154 private:
155  _tRet(_type::*_pm)(_tPara);
156 
157 public:
161  yconstfn
162  ExpandMemberFirst(_tRet(_type::*p)(_tPara))
163  : _pm(p)
164  {}
165 
170  yconstfn bool
172  {
173  return _pm == rhs._pm;
174  }
175 
180  _tRet
181  operator()(_type& o, _tPara arg)
182  {
183  if(YB_LIKELY(_pm))
184  return o.*_pm(arg);
185  }
191  _tRet
192  operator()(_tNew& o, _tPara&& arg)
193  {
194  if(YB_LIKELY(_pm))
195  try
196  {
197  return (dynamic_cast<_type&>(o).*_pm)(yforward(arg));
198  }
199  catch(std::bad_cast&)
200  {}
201  }
202 };
203 
204 
209 template<class _type, typename _tRet, typename _tPara, class _tNew = _type>
211 {
212 private:
213  _type* _po;
214  _tRet(_type::*_pm)(_tPara);
215 
216 public:
221  yconstfn
222  ExpandMemberFirstBinder(_tNew& obj, _tRet(_type::*p)(_tPara))
223  : _po(dynamic_cast<_type*>(&obj)), _pm(p)
224  {}
225 
230  yconstfn bool
232  {
233  return _po == rhs._po && _pm == rhs._pm;
234  }
235 
241  _tRet
242  operator()(_tPara&& arg)
243  {
244  if(YB_LIKELY(_po && _pm))
245  return (_po->*_pm)(yforward(arg));
246  }
252  template<class _tN>
253  _tRet
254  operator()(_tN&, _tPara&& arg)
255  {
256  if(YB_LIKELY(_po && _pm))
257  return (_po->*_pm)(yforward(arg));
258  }
259 };
260 
261 
262 #if 0
263 template<class _fCallable, typename _tParm>
265 struct InversedCurrying
266 {
267  using Result = typename _fCallable::Result;
268  using Parm1 = typename _fCallable::Parm1;
269 
270  _fCallable f;
271 
275  InversedCurrying(_fCallable f_)
276  : f(f_)
277  {}
278 
279  PDefHOp(bool, ==, const InversedCurrying& r) const
280  ImplRet(f == r.f)
281 
282 
285  Result
286  operator()(_tParm, Parm1 arg1) const
287  {
288  return f(arg1);
289  }
290 };
291 
292 
294 struct PolymorphicFunctorBase
295 {
296  DefDeDtor(PolymorphicFunctorBase)
297 };
298 
299 
300 /*
301 \brief 多态仿函数模板。
302 \note 继承其它仿函数。
303 */
304 template<class _tFunctor>
305 class GFunctor : public PolymorphicFunctorBase, public _tFunctor
306 {
307 public:
308  GFunctor(_tFunctor&& _f)
309  : PolymorphicFunctorBase(), _tFunctor(yforward(_f))
310  {}
311 
312  template<typename... _tArgs>
313  GFunctor(_tArgs&&... _args)
314  : PolymorphicFunctorBase(),
315  _tFunctor(yforward(_args)...)
316  {}
317 };
318 #endif
319 
320 
327 template<class _tDerived, typename _tKey, typename _fHandler>
329 {
330 private:
331  unordered_map<_tKey, _fHandler> registered_map{};
332 
333 public:
335  PDefH(bool, Contains, const _tKey& key) const
336  ImplRet(registered_map.count(key) != 0)
337 
338  DeclSEntry(template<_type, _fHandler> _fHandler GetRegister() const)
339 
340  template<typename... _tParams>
341  auto
342  Call(const _tKey& key, _tParams&&... args)
343  -> ystdex::result_of_t<_fHandler&(_tParams&&...)>
344  {
345  if(const auto f = registered_map[key])
346  {
347  // TODO: Do right trace.
348  // YTraceDe(Notice, "Found registered handler: %s.",
349  // to_string(key).c_str());
350 
351  return f(yforward(args)...);
352  }
353  return ystdex::result_of_t<_fHandler&(_tParams&&...)>();
354  }
355 
356  template<class _type>
357  void
358  Register(const _tKey& key)
359  {
360  registered_map.emplace(key, static_cast<_tDerived*>(this)
361  ->template GetRegister<_type, _fHandler>(key));
362  }
363  template<typename _tIn, class _type, class _tTuple>
364  void
365  Register(_tIn first, _tIn last)
366  {
367  YAssert(first != last && std::distance(first, last)
368  == std::tuple_size<_tTuple>::value + 1, "Wrong range found.");
369  Register<_type>(*first);
370  ++first;
371  YAssert((first == last) == (std::tuple_size<_tTuple>::value == 0),
372  "Wrong number of parameters found.");
373  // static_if(std::tuple_size<_tTuple>::value != 0)
374  // RegisterTail<_tIn, std::tuple_element<0, _tTuple>,
375  // typename tuple_split<_tTuple>::tail>(first, last);
376  RegisterTail<_tIn>(static_cast<_tTuple*>(nullptr), first, last);
377  }
378  template<class _type, class... _types>
379  void
380  Register(std::initializer_list<string> il)
381  {
382  YAssert(il.size() == sizeof...(_types) + 1,
383  "Wrong size of initializer list found.");
384  Register<std::initializer_list<string>::const_iterator, _type,
385  tuple<_types...>>(il.begin(), il.end());
386  }
387 
388 private:
389  template<typename _tIn>
390  void
391  RegisterTail(tuple<>*, _tIn first, _tIn last)
392  {
393  YAssert(first == last, "Wrong size of initializer list found.");
394  yunused(first),
395  yunused(last);
396  }
397  template<typename _tIn, class _type, class... _types>
398  void
399  RegisterTail(tuple<_type, _types...>*, _tIn first, _tIn last)
400  {
401  Register<_tIn, _type, tuple<_types...>>(first, last);
402  }
403 };
404 
405 } // namespace YSLib;
406 
407 #endif
408 
PDefH(bool, Contains, const _tKey &key) const ImplRet(registered_map.count(key)!=0) DeclSEntry(template< _type
void Register(std::initializer_list< string > il)
Definition: yfunc.hpp:380
#define DefDeDtor(_t)
定义默认析构函数。
Definition: YBaseMacro.h:146
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
#define ImplRet(...)
Definition: YBaseMacro.h:97
yconstfn ExpandMemberFirst(_tRet(_type::*p)(_tPara))
构造:使用函数指针。
Definition: yfunc.hpp:162
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:697
typename result_of< _type >::type result_of_t
Definition: type_op.hpp:286
yconstfn const string _tParams && args
Definition: Loader.h:111
void RegisterTail(tuple< _type, _types...> *, _tIn first, _tIn last)
Definition: yfunc.hpp:399
仿函数:替换非静态成员二元函数的第一个参数。
Definition: yfunc.hpp:152
_fHandler _fHandler GetRegister() const ) template< typename..._tParams > auto Call(const _tKey &key
_tRet(_type::* _pm)(_tPara)
Definition: yfunc.hpp:155
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
yconstfn ExpandMemberFirstBinder(_tNew &obj, _tRet(_type::*p)(_tPara))
构造:使用非 _type 类型对象引用和成员函数指针。
Definition: yfunc.hpp:222
yconstfn bool operator==(const ExpandMemberFirst &rhs) const ynothrow
比较:相等关系。
Definition: yfunc.hpp:171
_tRet operator()(_type &o, _tPara arg)
调用:使用对象引用和参数。
Definition: yfunc.hpp:181
void RegisterTail(tuple<> *, _tIn first, _tIn last)
Definition: yfunc.hpp:391
void Register(const _tKey &key)
Definition: yfunc.hpp:358
_tRet operator()(_tPara &&arg)
调用:使用替换对象引用和参数。
Definition: yfunc.hpp:242
yconstfn bool operator==(const ExpandMemberFirstBinder &rhs) const ynothrow
比较:相等关系。
Definition: yfunc.hpp:231
_tRet(_type::* _pm)(_tPara)
Definition: yfunc.hpp:214
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
_tRet operator()(_tN &, _tPara &&arg)
调用:使用替换对象引用和参数。
Definition: yfunc.hpp:254
#define DeclSEntry(...)
静态接口。
Definition: YBaseMacro.h:323
注册处理器抽象模板:供派生类加载一个或多个键和指定类型关联的例程。
Definition: yfunc.hpp:328
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
_tWidget _fCallable && f
Definition: ywgtevt.h:597
Selected const shared_ptr< ListType > const pair< Color, Color > viewer Contains
Definition: textlist.h:124
void Register(_tIn first, _tIn last)
Definition: yfunc.hpp:365
bounds & r
Definition: ydraw.h:220
仿函数:替换非静态成员二元函数的第一个参数并绑定到指定对象。
Definition: yfunc.hpp:210
#define YB_LIKELY(expr)
Definition: ydef.h:297
_tRet operator()(_tNew &o, _tPara &&arg)
调用:使用非 _type 类型对象引用和参数。
Definition: yfunc.hpp:192
#define YAssert(_expr, _msg)
Definition: cassert.h:73
unordered_map< _tKey, _fHandler > registered_map
Definition: yfunc.hpp:331