YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
functional.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 YB_INC_ystdex_functional_hpp_
29 #define YB_INC_ystdex_functional_hpp_ 1
30 
31 #include "type_op.hpp" // for ../ydef.h, ystdex::remove_reference_t;
32 #include "tuple.hpp"
33 #include <functional>
34 #include <string> // for std::char_traits;
35 
36 namespace ystdex
37 {
38 
40 
41 template<typename _tFrom, typename _tTo, typename... _tFromParams,
42  typename... _tToParams>
43 struct is_covariant<_tFrom(_tFromParams...), _tTo(_tToParams...)>
44  : is_covariant<_tFrom, _tTo>
45 {};
46 
47 
48 template<typename _tResFrom, typename _tResTo, typename... _tFromParams,
49  typename... _tToParams>
50 struct is_contravariant<_tResFrom(_tFromParams...), _tResTo(_tToParams...)>
51  : is_contravariant<std::tuple<_tFromParams...>, std::tuple<_tToParams...>>
52 {};
54 
55 
60 template<typename... _tParams>
61 yconstfn size_t
62 sizeof_params(_tParams&&...)
63 {
64  return sizeof...(_tParams);
65 }
66 
67 
69 
70 
72 template<size_t _vN>
74 {
75  template<typename _type, typename... _tParams>
76  yconstfn static auto
77  get(_type&&, _tParams&&... args)
79  {
80  static_assert(sizeof...(args) == _vN,
81  "Wrong variadic arguments number found.");
82 
84  }
85 };
86 
87 template<>
88 struct variadic_param<0U>
89 {
90  template<typename _type>
91  yconstfn static auto
92  get(_type&& arg) -> decltype(yforward(arg))
93  {
94  return yforward(arg);
95  }
96 };
98 
99 
104 template<size_t _vN, typename... _tParams>
105 yconstexpr auto
106 varg(_tParams&&... args)
107  -> decltype(variadic_param<_vN>::get(yforward(args)...))
108 {
109  static_assert(_vN < sizeof...(args),
110  "Out-of-range index of variadic argument found.");
111 
113 }
115 
116 
123 template<typename _fCallable>
124 inline void
125 seq_apply(_fCallable&&)
126 {}
127 template<typename _fCallable, typename _type, typename... _tParams>
128 inline void
129 seq_apply(_fCallable&& f, _type&& arg, _tParams&&... args)
130 {
131  yforward(f)(yforward(arg));
133 }
135 
136 
142 template<typename _fCallable, typename... _tParams>
143 inline void
144 unseq_apply(_fCallable&& f, _tParams&&... args)
145 {
146  yunseq((void(yforward(f)(yforward(args))), 0)...);
147 }
148 
149 
156 template<typename>
158 
160 template<typename _fCallable>
162 
163 template<typename _tRet, typename... _tParams>
164 struct make_parameter_tuple<_tRet(_tParams...)>
165 {
166  using type = std::tuple<_tParams...>;
167 };
168 
169 template<typename _tRet, typename... _tParams>
170 struct make_parameter_tuple<_tRet(*)(_tParams...)>
171 {
172  using type = std::tuple<_tParams...>;
173 };
174 
175 template<typename _tRet, typename... _tParams>
176 struct make_parameter_tuple<_tRet(&)(_tParams...)>
177 {
178  using type = std::tuple<_tParams...>;
179 };
180 
181 template<typename _tRet, class _tClass, typename... _tParams>
182 struct make_parameter_tuple<_tRet(_tClass::*)(_tParams...)>
183 {
184  using type = std::tuple<_tParams...>;
185 };
186 
188 
189 template<typename _tRet, class _tClass, typename... _tParams>
190 struct make_parameter_tuple<_tRet(_tClass::*)(_tParams...) const>
191 {
192  using type = std::tuple<_tParams...>;
193 };
194 
195 template<typename _tRet, class _tClass, typename... _tParams>
196 struct make_parameter_tuple<_tRet(_tClass::*)(_tParams...) volatile>
197 {
198  using type = std::tuple<_tParams...>;
199 };
200 
201 template<typename _tRet, class _tClass, typename... _tParams>
202 struct make_parameter_tuple<_tRet(_tClass::*)(_tParams...) const volatile>
203 {
204  using type = std::tuple<_tParams...>;
205 };
207 
209 template<typename _tRet, typename... _tParams>
210 struct make_parameter_tuple<std::function<_tRet(_tParams...)>>
211 {
212  using type = std::tuple<_tParams...>;
213 };
215 
216 
223 template<typename>
224 struct return_of;
225 
227 template<typename _fCallable>
229 
230 template<typename _tRet, typename... _tParams>
231 struct return_of<_tRet(_tParams...)>
232 {
233  using type = _tRet;
234 };
235 
236 template<typename _tRet, typename... _tParams>
237 struct return_of<_tRet(*)(_tParams...)>
238 {
239  using type = _tRet;
240 };
241 
242 template<typename _tRet, typename... _tParams>
243 struct return_of<_tRet(&)(_tParams...)>
244 {
245  using type = _tRet;
246 };
247 
248 template<typename _tRet, class _tClass, typename... _tParams>
249 struct return_of<_tRet(_tClass::*)(_tParams...)>
250 {
251  using type = _tRet;
252 };
253 
255 
256 template<typename _tRet, class _tClass, typename... _tParams>
257 struct return_of<_tRet(_tClass::*)(_tParams...) const>
258 {
259  using type = _tRet;
260 };
261 
262 template<typename _tRet, class _tClass, typename... _tParams>
263 struct return_of<_tRet(_tClass::*)(_tParams...) volatile>
264 {
265  using type = _tRet;
266 };
267 
268 template<typename _tRet, class _tClass, typename... _tParams>
269 struct return_of<_tRet(_tClass::*)(_tParams...) const volatile>
270 {
271  using type = _tRet;
272 };
274 
276 template<typename _tRet, typename... _tParams>
277 struct return_of<std::function<_tRet(_tParams...)>>
278 {
279  using type = _tRet;
280 };
282 
283 
290 template<size_t _vIdx, typename _fCallable>
292 {
293  using type = tuple_element_t<_vIdx,
295 };
296 
298 template<size_t _vIdx, typename _fCallable>
301 
302 
308 template<typename _fCallable>
309 struct paramlist_size : integral_constant<size_t, std::tuple_size<typename
310  make_parameter_tuple<_fCallable>::type>::value>
311 {};
312 
313 
319 template<typename, class>
321 
322 template<typename _tRet, typename... _tParams, size_t... _vSeq>
323 struct call_projection<_tRet(_tParams...), variadic_sequence<_vSeq...>>
324 {
326  template<typename _fCallable>
327  static _tRet
328  call(_fCallable&& f, std::tuple<_tParams...>&& args, remove_reference_t<
329  decltype(yforward(f)(yforward(std::get<_vSeq>(std::move(args)))...))>*
330  = {})
331  {
332  yforward(f)(yforward(std::get<_vSeq>(std::move(args)))...);
333  }
334 };
335 
337 template<typename _tRet, typename... _tParams, size_t... _vSeq>
338 struct call_projection<std::function<_tRet(_tParams...)>,
339  variadic_sequence<_vSeq...>> : private
340  call_projection<_tRet(_tParams...), variadic_sequence<_vSeq...>>
341 {
342  using
343  call_projection<_tRet(_tParams...), variadic_sequence<_vSeq...>>::call;
344 };
346 
347 
349 namespace details
350 {
351 
353 template<typename _fCallable, size_t _vLen = paramlist_size<_fCallable>::value>
354 struct expand_proxy : private call_projection<_fCallable,
355  make_natural_sequence_t<_vLen>>, private expand_proxy<_fCallable, _vLen - 1>
356 {
358  using expand_proxy<_fCallable, _vLen - 1>::call;
359 };
360 
362 template<typename _fCallable>
363 struct expand_proxy<_fCallable, 0>
364  : private call_projection<_fCallable, variadic_sequence<>>
365 {
367 };
368 
369 } // namespace details;
370 
371 
377 template<typename _fHandler, typename _fCallable>
379 {
381  static_assert(is_object<_fCallable>::value,
382  "Callable object type is needed.");
383 
384  _fCallable Caller;
385 
387  template<typename _fCaller,
389  expanded_caller(_fCaller&& f)
390  : Caller(yforward(f))
391  {}
392 
393  template<typename... _tParams>
394  auto
395  operator()(_tParams&&... args)
397  std::forward_as_tuple(yforward(args)...)))
398  {
400  std::forward_as_tuple(yforward(args)...));
401  }
402 };
403 
404 
410 template<typename _fHandler, typename _fCallable>
411 yconstfn expanded_caller<_fHandler, decay_t<_fCallable>>
412 make_expanded(_fCallable&& f)
413 {
415 }
416 
417 
424 template<typename _type>
425 struct wrapped_traits : false_type
426 {
427  using type = _type;
428 };
429 
430 template<typename _tWrapped>
431 struct wrapped_traits<std::reference_wrapper<_tWrapped>> : true_type
432 {
433  using type = _tWrapped;
434 };
436 
437 
445 template<typename _type>
446 _type&
447 unref(_type&& x) ynothrow
448 {
449  return x;
450 }
451 template<typename _type>
452 _type&
453 unref(const std::reference_wrapper<_type>& x) ynothrow
454 {
455  return x.get();
456 }
458 
459 
472 template<typename _type>
473 inline void
474 hash_combine(size_t& seed, const _type& val)
475 {
476  seed ^= std::hash<_type>()(val) + 0x9E3779B9 + (seed << 6) + (seed >> 2);
477 }
478 
485 template<typename _type>
486 yconstfn size_t
487 hash_combine_seq(size_t seed, const _type& val)
488 {
489  return ystdex::hash_combine(seed, val), seed;
490 }
491 template<typename _type, typename... _tParams>
492 yconstfn size_t
493 hash_combine_seq(size_t seed, const _type& x, const _tParams&... args)
494 {
495  return ystdex::hash_combine_seq(ystdex::hash_combine_seq(seed, x), args...);
496 }
498 
504 template<typename _tIn>
505 inline size_t
506 hash_range(_tIn first, _tIn last)
507 {
508  size_t seed(0);
509 
510  for(; first != last; ++first)
511  hash_combine(seed, *first);
512  return seed;
513 }
514 template<typename _tIn>
515 inline size_t
516 hash_range(size_t& seed, _tIn first, _tIn last)
517 {
518  for(; first != last; ++first)
519  hash_combine(seed, *first);
520  return seed;
521 }
523 
524 
530 template<typename...>
532 
533 template<typename _type>
534 struct combined_hash<_type> : std::hash<_type>
535 {};
536 
537 namespace details
538 {
539 
540 template<bool, class, class>
542 
543 template<bool _bNoExcept, typename _type, size_t... _vSeq>
544 struct combined_hash_tuple<_bNoExcept, _type, variadic_sequence<_vSeq...>>
545 {
546  static yconstfn size_t
547  call(const _type& tp) ynoexcept(_bNoExcept)
548  {
549  return ystdex::hash_combine_seq(0, std::get<_vSeq>(tp)...);
550  }
551 };
552 
553 } // namespace details;
554 
555 template<typename... _types>
556 struct combined_hash<std::tuple<_types...>>
557 {
558 public:
559  using type = std::tuple<_types...>;
560 
561 #if YB_HAS_NOEXCEPT
562 private:
564  static yconstexpr bool is_noexcept_v = noexcept(
565  ystdex::hash_combine_seq(0, std::declval<const _types&>()...));
566 #endif
567 
568 public:
569  yconstfn size_t
570  operator()(const type& tp) const ynoexcept(is_noexcept_v)
571  {
572  return details::combined_hash_tuple<is_noexcept_v, type,
573  make_natural_sequence_t<sizeof...(_types)>>::call(tp);
574  }
575 };
576 
577 template<typename _type1, typename _type2>
578 struct combined_hash<std::pair<_type1, _type2>>
579  : combined_hash<std::tuple<_type1, _type2>>
580 {};
582 
583 
584 
597 struct is_equal
598 {
599  template<typename _type1, typename _type2>
600  yconstfn bool
601  operator()(const _type1& x, const _type2& y) const
602  {
603  return x == y;
604  }
605 };
606 
611 template<typename _type>
612 struct ref_eq
613 {
614  yconstfn bool
615  operator()(const _type& _x, const _type& _y) const
616  {
617  return &_x == &_y;
618  }
619 };
620 
626 template<bool, typename _tScalar>
627 struct xcrease_t
628 {
629  inline _tScalar&
630  operator()(_tScalar& _x)
631  {
632  return ++_x;
633  }
634 };
635 template<typename _tScalar>
636 struct xcrease_t<false, _tScalar>
637 {
638  inline _tScalar&
639  operator()(_tScalar& _x)
640  {
641  return --_x;
642  }
643 };
645 
652 template<bool, typename _tScalar1, typename _tScalar2>
654 {
655  yconstfn _tScalar1&
656  operator()(_tScalar1& x, _tScalar2 y) const
657  {
658  return x += y;
659  }
660 };
661 template<typename _tScalar1, typename _tScalar2>
662 struct delta_assignment<false, _tScalar1, _tScalar2>
663 {
664  yconstfn _tScalar1&
665  operator()(_tScalar1& x, _tScalar2 y) const
666  {
667  return x -= y;
668  }
669 };
671 
676 template<bool _bIsPositive, typename _tScalar>
677 yconstfn _tScalar&
678 xcrease(_tScalar& _x)
679 {
681 }
682 
688 template<bool _bIsPositive, typename _tScalar1, typename _tScalar2>
689 yconstfn _tScalar1&
690 delta_assign(_tScalar1& _x, _tScalar2& _y)
691 {
693 }
694 
695 
700 template<typename _type>
701 struct deref_op
702 {
706  yconstfn _type*
707  operator()(_type& _x) const
708  {
709  return &_x;
710  }
711 };
712 
713 
718 template<typename _type>
720 {
724  inline const _type*
725  operator()(const _type& _x) const
726  {
727  return &_x;
728  }
729 };
730 
731 
738 template<typename _type, typename _tPointer = _type*,
739  class _fCompare = std::less<_type>>
741 {
742  /*
743  \brief 比较指针指向的对象。
744  \return 若参数有空指针则 false ,否则判断是否满足 _fCompare()(*_x, *_y) 。
745  */
746  bool
747  operator()(const _tPointer& _x, const _tPointer& _y) const
748  {
749  return bool(_x) && bool(_y) && _fCompare()(*_x, *_y);
750  }
751 };
752 
753 
760 template<typename _tChar, class _fCompare = std::less<_tChar>>
762 {
767  bool
768  operator()(const _tChar* x, const _tChar* y) const
769  {
770  using traits_type = std::char_traits<_tChar>;
771 
772  return x && y && std::lexicographical_compare(x, x + traits_type
773  ::length(x), y, y + traits_type::length(y), _fCompare());
774  }
775 };
776 
777 } // namespace ystdex;
778 
779 #endif
780 
变长参数操作模板。
Definition: functional.hpp:73
_tScalar1 & delta_assign(_tScalar1 &_x, _tScalar2 &_y)
编译期选择加法/减法复合赋值运算。
Definition: functional.hpp:690
expanded_caller(_fCaller &&f)
Definition: functional.hpp:389
typename std::tuple_element< _vIdx, _type >::type tuple_element_t
Definition: tuple.hpp:44
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
间接访问字符串比较仿函数。
Definition: functional.hpp:761
typename remove_reference< _type >::type remove_reference_t
Definition: type_op.hpp:234
yconstfn const string _tParams && args
Definition: Loader.h:111
const _type * operator()(const _type &_x) const
对指定 const 对象使用 operator& 并返回结果。
Definition: functional.hpp:725
bool operator()(const _tChar *x, const _tChar *y) const
比较指定字符串首字符的指针。
Definition: functional.hpp:768
typename parameter_of< _vIdx, _fCallable >::type parameter_of_t
Definition: functional.hpp:299
typename return_of< _fCallable >::type return_of_t
Definition: functional.hpp:228
auto operator()(_tParams &&...args) -> decltype(details::expand_proxy< _fHandler >::call(Caller, std::forward_as_tuple(std::forward< decltype(args)>(args)...)))
Definition: functional.hpp:395
void unseq_apply(_fCallable &&f, _tParams &&...args)
无序调用。
Definition: functional.hpp:144
相等关系仿函数。
Definition: functional.hpp:597
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
void seq_apply(_fCallable &&)
顺序递归调用。
Definition: functional.hpp:125
_tScalar & operator()(_tScalar &_x)
Definition: functional.hpp:639
#define yimpl(...)
实现标签。
Definition: ydef.h:177
tuple_element_t< _vIdx, typename make_parameter_tuple< _fCallable >::type > type
Definition: functional.hpp:294
接受冗余参数的可调用对象。
Definition: functional.hpp:378
expanded_caller< _fHandler, decay_t< _fCallable > > make_expanded(_fCallable &&f)
构造接受冗余参数的可调用对象。
Definition: functional.hpp:412
变长参数标记的整数序列。
Definition: variadic.hpp:42
_tScalar & operator()(_tScalar &_x)
Definition: functional.hpp:630
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functional.hpp:656
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
判断指定类型之间是否协变。
Definition: type_op.hpp:379
引用仿函数。
Definition: functional.hpp:701
_tScalar & xcrease(_tScalar &_x)
编译期选择自增/自减运算。
Definition: functional.hpp:678
const 引用仿函数。
Definition: functional.hpp:719
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
使用 std::hash 和 ystdex::hash_combine_seq 实现的对特定类型的散列。
Definition: functional.hpp:531
引用相等关系仿函数。
Definition: functional.hpp:612
_type * operator()(_type &_x) const
对指定对象使用 operator& 并返回结果。
Definition: functional.hpp:707
编译期选择自增/自减运算仿函数。
Definition: functional.hpp:627
取 std::reference_wrapper 实例特征。
Definition: functional.hpp:425
static auto get(_type &&, _tParams &&...args) -> decltype(variadic_param< _vN-1 >::get(std::forward< decltype(args)>(args)...))
Definition: functional.hpp:77
元组类型和操作。
取参数列表元组。
Definition: functional.hpp:157
_type & unref(_type &&x)
解除引用包装。
Definition: functional.hpp:447
void hash_combine(size_t &seed, const _type &val)
重复计算散列。
Definition: functional.hpp:474
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
_tWidget _fCallable && f
Definition: ywgtevt.h:597
size_t sizeof_params(_tParams &&...)
统计函数参数列表中的参数个数。
Definition: functional.hpp:62
enable_if_t<!is_same< _tClass &, remove_rcv_t< _tParam > & >::value, _type > exclude_self_ctor_t
移除选择类类型的特定重载避免构造模板和复制/转移构造函数冲突。
Definition: type_op.hpp:766
间接访问比较仿函数。
Definition: functional.hpp:740
取参数列表大小。
Definition: functional.hpp:309
判断指定类型之间是否逆变。
Definition: type_op.hpp:389
编译期选择加法/减法复合赋值运算仿函数。
Definition: functional.hpp:653
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
bool operator()(const _tPointer &_x, const _tPointer &_y) const
Definition: functional.hpp:747
const auto varg(_tParams &&...args) -> decltype(variadic_param< _vN >::get(std::forward< decltype(args)>(args)...))
取指定位置的变长参数。
Definition: functional.hpp:106
C++ 类型操作。
bool operator()(const _type1 &x, const _type2 &y) const
Definition: functional.hpp:601
取返回类型。
Definition: functional.hpp:224
#define ynoexcept(...)
YSLib 无异常抛出保证:指定特定的异常规范。
Definition: ydef.h:526
size_t hash_range(_tIn first, _tIn last)
重复对范围计算散列。
Definition: functional.hpp:506
size_t operator()(const type &tp) const
Definition: functional.hpp:570
取指定索引的参数类型。
Definition: functional.hpp:291
static _tRet call(_fCallable &&f, std::tuple< _tParams...> &&args, remove_reference_t< decltype(std::forward< decltype(f)>(f)(std::forward< decltype(std::get< _vSeq >(std::move(args)))>(std::get< _vSeq >(std::move(args)))...))> *={})
Definition: functional.hpp:328
typename make_parameter_tuple< _fCallable >::type make_parameter_tuple_t
Definition: functional.hpp:161
_tScalar1 & operator()(_tScalar1 &x, _tScalar2 y) const
Definition: functional.hpp:665
size_t hash_combine_seq(size_t seed, const _type &val)
重复计算序列散列。
Definition: functional.hpp:487
bool operator()(const _type &_x, const _type &_y) const
Definition: functional.hpp:615
typename make_natural_sequence< _vN >::type make_natural_sequence_t
Definition: variadic.hpp:240
调用投影:向原调用传递序列指定的位置的参数。
Definition: functional.hpp:320