Nugget
functional.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
5 #ifndef EASTL_FUNCTIONAL_H
6 #define EASTL_FUNCTIONAL_H
7 
8 
9 #include <EABase/eabase.h>
10 #include <EASTL/internal/config.h>
11 #include <EASTL/internal/move_help.h>
12 #include <EASTL/type_traits.h>
13 #include <EASTL/internal/functional_base.h>
14 #include <EASTL/internal/mem_fn.h>
15 
16 
17 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
18  #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
19 #endif
20 
21 
22 
23 namespace eastl
24 {
26  // Primary C++ functions
28 
29  template <typename T = void>
30  struct plus : public binary_function<T, T, T>
31  {
32  EA_CPP14_CONSTEXPR T operator()(const T& a, const T& b) const
33  { return a + b; }
34  };
35 
36  // http://en.cppreference.com/w/cpp/utility/functional/plus_void
37  template <>
38  struct plus<void>
39  {
40  typedef int is_transparent;
41  template<typename A, typename B>
42  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
43  -> decltype(eastl::forward<A>(a) + eastl::forward<B>(b))
44  { return eastl::forward<A>(a) + eastl::forward<B>(b); }
45  };
46 
47  template <typename T = void>
48  struct minus : public binary_function<T, T, T>
49  {
50  EA_CPP14_CONSTEXPR T operator()(const T& a, const T& b) const
51  { return a - b; }
52  };
53 
54  // http://en.cppreference.com/w/cpp/utility/functional/minus_void
55  template <>
56  struct minus<void>
57  {
58  typedef int is_transparent;
59  template<typename A, typename B>
60  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
61  -> decltype(eastl::forward<A>(a) - eastl::forward<B>(b))
62  { return eastl::forward<A>(a) - eastl::forward<B>(b); }
63  };
64 
65  template <typename T = void>
66  struct multiplies : public binary_function<T, T, T>
67  {
68  EA_CPP14_CONSTEXPR T operator()(const T& a, const T& b) const
69  { return a * b; }
70  };
71 
72  // http://en.cppreference.com/w/cpp/utility/functional/multiplies_void
73  template <>
74  struct multiplies<void>
75  {
76  typedef int is_transparent;
77  template<typename A, typename B>
78  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
79  -> decltype(eastl::forward<A>(a) * eastl::forward<B>(b))
80  { return eastl::forward<A>(a) * eastl::forward<B>(b); }
81  };
82 
83  template <typename T = void>
84  struct divides : public binary_function<T, T, T>
85  {
86  EA_CPP14_CONSTEXPR T operator()(const T& a, const T& b) const
87  { return a / b; }
88  };
89 
90  // http://en.cppreference.com/w/cpp/utility/functional/divides_void
91  template <>
92  struct divides<void>
93  {
94  typedef int is_transparent;
95  template<typename A, typename B>
96  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
97  -> decltype(eastl::forward<A>(a) / eastl::forward<B>(b))
98  { return eastl::forward<A>(a) / eastl::forward<B>(b); }
99  };
100 
101  template <typename T = void>
102  struct modulus : public binary_function<T, T, T>
103  {
104  EA_CPP14_CONSTEXPR T operator()(const T& a, const T& b) const
105  { return a % b; }
106  };
107 
108  // http://en.cppreference.com/w/cpp/utility/functional/modulus_void
109  template <>
110  struct modulus<void>
111  {
112  typedef int is_transparent;
113  template<typename A, typename B>
114  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
115  -> decltype(eastl::forward<A>(a) % eastl::forward<B>(b))
116  { return eastl::forward<A>(a) % eastl::forward<B>(b); }
117  };
118 
119  template <typename T = void>
120  struct negate : public unary_function<T, T>
121  {
122  EA_CPP14_CONSTEXPR T operator()(const T& a) const
123  { return -a; }
124  };
125 
126  // http://en.cppreference.com/w/cpp/utility/functional/negate_void
127  template <>
128  struct negate<void>
129  {
130  typedef int is_transparent;
131  template<typename T>
132  EA_CPP14_CONSTEXPR auto operator()(T&& t) const
133  -> decltype(-eastl::forward<T>(t))
134  { return -eastl::forward<T>(t); }
135  };
136 
137  template <typename T = void>
138  struct equal_to : public binary_function<T, T, bool>
139  {
140  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
141  { return a == b; }
142  };
143 
144  // http://en.cppreference.com/w/cpp/utility/functional/equal_to_void
145  template <>
146  struct equal_to<void>
147  {
148  typedef int is_transparent;
149  template<typename A, typename B>
150  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
151  -> decltype(eastl::forward<A>(a) == eastl::forward<B>(b))
152  { return eastl::forward<A>(a) == eastl::forward<B>(b); }
153  };
154 
155  template <typename T, typename Compare>
156  bool validate_equal_to(const T& a, const T& b, Compare compare)
157  {
158  return compare(a, b) == compare(b, a);
159  }
160 
161  template <typename T = void>
162  struct not_equal_to : public binary_function<T, T, bool>
163  {
164  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
165  { return a != b; }
166  };
167 
168  // http://en.cppreference.com/w/cpp/utility/functional/not_equal_to_void
169  template <>
170  struct not_equal_to<void>
171  {
172  typedef int is_transparent;
173  template<typename A, typename B>
174  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
175  -> decltype(eastl::forward<A>(a) != eastl::forward<B>(b))
176  { return eastl::forward<A>(a) != eastl::forward<B>(b); }
177  };
178 
179  template <typename T, typename Compare>
180  bool validate_not_equal_to(const T& a, const T& b, Compare compare)
181  {
182  return compare(a, b) == compare(b, a); // We want the not equal comparison results to be equal.
183  }
184 
203  template <typename T>
204  struct str_equal_to : public binary_function<T, T, bool>
205  {
206  EA_CPP14_CONSTEXPR bool operator()(T a, T b) const
207  {
208  while(*a && (*a == *b))
209  {
210  ++a;
211  ++b;
212  }
213  return (*a == *b);
214  }
215  };
216 
217  template <typename T = void>
218  struct greater : public binary_function<T, T, bool>
219  {
220  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
221  { return a > b; }
222  };
223 
224  // http://en.cppreference.com/w/cpp/utility/functional/greater_void
225  template <>
226  struct greater<void>
227  {
228  template<typename A, typename B>
229  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
230  -> decltype(eastl::forward<A>(a) > eastl::forward<B>(b))
231  { return eastl::forward<A>(a) > eastl::forward<B>(b); }
232  };
233 
234  template <typename T, typename Compare>
235  bool validate_greater(const T& a, const T& b, Compare compare)
236  {
237  return !compare(a, b) || !compare(b, a); // If (a > b), then !(b > a)
238  }
239 
240 
241  template <typename T, typename Compare>
242  bool validate_less(const T& a, const T& b, Compare compare)
243  {
244  return !compare(a, b) || !compare(b, a); // If (a < b), then !(b < a)
245  }
246 
262  template <typename T>
263  struct str_less : public binary_function<T, T, bool>
264  {
265  bool operator()(T a, T b) const
266  {
267  while(static_cast<typename make_unsigned<typename remove_pointer<T>::type>::type>(*a) ==
268  static_cast<typename make_unsigned<typename remove_pointer<T>::type>::type>(*b))
269  {
270  if(*a == 0)
271  return (*b != 0);
272  ++a;
273  ++b;
274  }
275 
276  char aValue = static_cast<typename remove_pointer<T>::type>(*a);
277  char bValue = static_cast<typename remove_pointer<T>::type>(*b);
278 
279  typename make_unsigned<char>::type aValueU = static_cast<typename make_unsigned<char>::type>(aValue);
280  typename make_unsigned<char>::type bValueU = static_cast<typename make_unsigned<char>::type>(bValue);
281 
282  return aValueU < bValueU;
283 
284  //return (static_cast<typename make_unsigned<typename remove_pointer<T>::type>::type>(*a) <
285  // static_cast<typename make_unsigned<typename remove_pointer<T>::type>::type>(*b));
286  }
287  };
288 
289  template <typename T = void>
290  struct greater_equal : public binary_function<T, T, bool>
291  {
292  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
293  { return a >= b; }
294  };
295 
296  // http://en.cppreference.com/w/cpp/utility/functional/greater_equal_void
297  template <>
298  struct greater_equal<void>
299  {
300  template<typename A, typename B>
301  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
302  -> decltype(eastl::forward<A>(a) >= eastl::forward<B>(b))
303  { return eastl::forward<A>(a) >= eastl::forward<B>(b); }
304  };
305 
306  template <typename T, typename Compare>
307  bool validate_greater_equal(const T& a, const T& b, Compare compare)
308  {
309  return !compare(a, b) || !compare(b, a); // If (a >= b), then !(b >= a)
310  }
311 
312  template <typename T = void>
313  struct less_equal : public binary_function<T, T, bool>
314  {
315  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
316  { return a <= b; }
317  };
318 
319  // http://en.cppreference.com/w/cpp/utility/functional/less_equal_void
320  template <>
321  struct less_equal<void>
322  {
323  template<typename A, typename B>
324  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
325  -> decltype(eastl::forward<A>(a) <= eastl::forward<B>(b))
326  { return eastl::forward<A>(a) <= eastl::forward<B>(b); }
327  };
328 
329  template <typename T, typename Compare>
330  bool validate_less_equal(const T& a, const T& b, Compare compare)
331  {
332  return !compare(a, b) || !compare(b, a); // If (a <= b), then !(b <= a)
333  }
334 
335  template <typename T = void>
336  struct logical_and : public binary_function<T, T, bool>
337  {
338  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
339  { return a && b; }
340  };
341 
342  // http://en.cppreference.com/w/cpp/utility/functional/logical_and_void
343  template <>
344  struct logical_and<void>
345  {
346  template<typename A, typename B>
347  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
348  -> decltype(eastl::forward<A>(a) && eastl::forward<B>(b))
349  { return eastl::forward<A>(a) && eastl::forward<B>(b); }
350  };
351 
352  template <typename T = void>
353  struct logical_or : public binary_function<T, T, bool>
354  {
355  EA_CPP14_CONSTEXPR bool operator()(const T& a, const T& b) const
356  { return a || b; }
357  };
358 
359  // http://en.cppreference.com/w/cpp/utility/functional/logical_or_void
360  template <>
361  struct logical_or<void>
362  {
363  template<typename A, typename B>
364  EA_CPP14_CONSTEXPR auto operator()(A&& a, B&& b) const
365  -> decltype(eastl::forward<A>(a) || eastl::forward<B>(b))
366  { return eastl::forward<A>(a) || eastl::forward<B>(b); }
367  };
368 
369  template <typename T = void>
370  struct logical_not : public unary_function<T, bool>
371  {
372  EA_CPP14_CONSTEXPR bool operator()(const T& a) const
373  { return !a; }
374  };
375 
376  // http://en.cppreference.com/w/cpp/utility/functional/logical_not_void
377  template <>
378  struct logical_not<void>
379  {
380  template<typename T>
381  EA_CPP14_CONSTEXPR auto operator()(T&& t) const
382  -> decltype(!eastl::forward<T>(t))
383  { return !eastl::forward<T>(t); }
384  };
385 
386 
387 
389  // Dual type functions
391 
392 
393  template <typename T, typename U>
394  struct equal_to_2 : public binary_function<T, U, bool>
395  {
396  EA_CPP14_CONSTEXPR bool operator()(const T& a, const U& b) const
397  { return a == b; }
398 
399  template <typename T_ = T, typename U_ = U, typename = eastl::enable_if_t<!eastl::is_same_v<eastl::remove_const_t<T_>, eastl::remove_const_t<U_>>>>
400  EA_CPP14_CONSTEXPR bool operator()(const U& b, const T& a) const
401  { return b == a; }
402  };
403 
404  template <typename T, typename U>
405  struct not_equal_to_2 : public binary_function<T, U, bool>
406  {
407  EA_CPP14_CONSTEXPR bool operator()(const T& a, const U& b) const
408  { return a != b; }
409 
410  template <typename T_ = T, typename U_ = U, typename = eastl::enable_if_t<!eastl::is_same_v<eastl::remove_const_t<T_>, eastl::remove_const_t<U_>>>>
411  EA_CPP14_CONSTEXPR bool operator()(const U& b, const T& a) const
412  { return b != a; }
413  };
414 
415 
416  template <typename T, typename U>
417  struct less_2 : public binary_function<T, U, bool>
418  {
419  EA_CPP14_CONSTEXPR bool operator()(const T& a, const U& b) const
420  { return a < b; }
421 
422  template <typename T_ = T, typename U_ = U, typename = eastl::enable_if_t<!eastl::is_same_v<eastl::remove_const_t<T_>, eastl::remove_const_t<U_>>>>
423  EA_CPP14_CONSTEXPR bool operator()(const U& b, const T& a) const
424  { return b < a; }
425  };
426 
427 
430  template <typename Predicate>
431  class unary_negate : public unary_function<typename Predicate::argument_type, bool>
432  {
433  protected:
434  Predicate mPredicate;
435  public:
436  explicit unary_negate(const Predicate& a)
437  : mPredicate(a) {}
438  EA_CPP14_CONSTEXPR bool operator()(const typename Predicate::argument_type& a) const
439  { return !mPredicate(a); }
440  };
441 
442  template <typename Predicate>
443  inline EA_CPP14_CONSTEXPR unary_negate<Predicate> not1(const Predicate& predicate)
444  { return unary_negate<Predicate>(predicate); }
445 
446 
447 
450  template <typename Predicate>
451  class binary_negate : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
452  {
453  protected:
454  Predicate mPredicate;
455  public:
456  explicit binary_negate(const Predicate& a)
457  : mPredicate(a) { }
458  EA_CPP14_CONSTEXPR bool operator()(const typename Predicate::first_argument_type& a, const typename Predicate::second_argument_type& b) const
459  { return !mPredicate(a, b); }
460  };
461 
462  template <typename Predicate>
463  inline EA_CPP14_CONSTEXPR binary_negate<Predicate> not2(const Predicate& predicate)
464  { return binary_negate<Predicate>(predicate); }
465 
466 
467 
470  template<typename Operation1, typename Operation2>
471  struct unary_compose : public unary_function<typename Operation2::argument_type, typename Operation1::result_type>
472  {
473  protected:
474  Operation1 op1;
475  Operation2 op2;
476 
477  public:
478  unary_compose(const Operation1& x, const Operation2& y)
479  : op1(x), op2(y) {}
480 
481  typename Operation1::result_type operator()(const typename Operation2::argument_type& x) const
482  { return op1(op2(x)); }
483 
484  typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
485  { return op1(op2(x)); }
486  };
487 
488  template<typename Operation1,typename Operation2>
490  compose1(const Operation1& op1, const Operation2& op2)
491  {
493  }
494 
495 
498  template <class Operation1, class Operation2, class Operation3>
499  class binary_compose : public unary_function<typename Operation2::argument_type, typename Operation1::result_type>
500  {
501  protected:
502  Operation1 op1;
503  Operation2 op2;
504  Operation3 op3;
505 
506  public:
507  // Support binary functors too.
508  typedef typename Operation2::argument_type first_argument_type;
509  typedef typename Operation3::argument_type second_argument_type;
510 
511  binary_compose(const Operation1& x, const Operation2& y, const Operation3& z)
512  : op1(x), op2(y), op3(z) { }
513 
514  typename Operation1::result_type operator()(const typename Operation2::argument_type& x) const
515  { return op1(op2(x),op3(x)); }
516 
517  typename Operation1::result_type operator()(typename Operation2::argument_type& x) const
518  { return op1(op2(x),op3(x)); }
519 
520  typename Operation1::result_type operator()(const typename Operation2::argument_type& x,const typename Operation3::argument_type& y) const
521  { return op1(op2(x),op3(y)); }
522 
523  typename Operation1::result_type operator()(typename Operation2::argument_type& x, typename Operation3::argument_type& y) const
524  { return op1(op2(x),op3(y)); }
525  };
526 
527 
528  template <class Operation1, class Operation2, class Operation3>
530  compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3)
531  {
533  }
534 
535 
536 
538  // pointer_to_unary_function
540 
552  template <typename Arg, typename Result>
553  class pointer_to_unary_function : public unary_function<Arg, Result>
554  {
555  protected:
556  Result (*mpFunction)(Arg);
557 
558  public:
560  { }
561 
562  explicit pointer_to_unary_function(Result (*pFunction)(Arg))
563  : mpFunction(pFunction) { }
564 
565  Result operator()(Arg x) const
566  { return mpFunction(x); }
567  };
568 
569 
578  template <typename Arg, typename Result>
580  ptr_fun(Result (*pFunction)(Arg))
581  { return pointer_to_unary_function<Arg, Result>(pFunction); }
582 
583 
584 
585 
586 
588  // pointer_to_binary_function
590 
597  template <typename Arg1, typename Arg2, typename Result>
598  class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
599  {
600  protected:
601  Result (*mpFunction)(Arg1, Arg2);
602 
603  public:
605  { }
606 
607  explicit pointer_to_binary_function(Result (*pFunction)(Arg1, Arg2))
608  : mpFunction(pFunction) {}
609 
610  Result operator()(Arg1 x, Arg2 y) const
611  { return mpFunction(x, y); }
612  };
613 
614 
621  template <typename Arg1, typename Arg2, typename Result>
623  ptr_fun(Result (*pFunction)(Arg1, Arg2))
625 
626 
627 
628 
629 
630 
632  // mem_fun
633  // mem_fun1
634  //
635  // Note that mem_fun calls member functions via *pointers* to classes
636  // and not instances of classes. mem_fun_ref is for calling functions
637  // via instances of classes or references to classes.
638  //
639  // NOTE:
640  // mem_fun was deprecated in C++11 and removed in C++17, in favor
641  // of the more general mem_fn and bind.
642  //
644 
649  template <typename Result, typename T>
650  class mem_fun_t : public unary_function<T*, Result>
651  {
652  public:
653  typedef Result (T::*MemberFunction)();
654 
655  inline explicit mem_fun_t(MemberFunction pMemberFunction)
656  : mpMemberFunction(pMemberFunction)
657  {
658  // Empty
659  }
660 
661  inline Result operator()(T* pT) const
662  {
663  return (pT->*mpMemberFunction)();
664  }
665 
666  protected:
667  MemberFunction mpMemberFunction;
668  };
669 
670 
675  template <typename Result, typename T, typename Argument>
676  class mem_fun1_t : public binary_function<T*, Argument, Result>
677  {
678  public:
679  typedef Result (T::*MemberFunction)(Argument);
680 
681  inline explicit mem_fun1_t(MemberFunction pMemberFunction)
682  : mpMemberFunction(pMemberFunction)
683  {
684  // Empty
685  }
686 
687  inline Result operator()(T* pT, Argument arg) const
688  {
689  return (pT->*mpMemberFunction)(arg);
690  }
691 
692  protected:
693  MemberFunction mpMemberFunction;
694  };
695 
696 
704  template <typename Result, typename T>
705  class const_mem_fun_t : public unary_function<const T*, Result>
706  {
707  public:
708  typedef Result (T::*MemberFunction)() const;
709 
710  inline explicit const_mem_fun_t(MemberFunction pMemberFunction)
711  : mpMemberFunction(pMemberFunction)
712  {
713  // Empty
714  }
715 
716  inline Result operator()(const T* pT) const
717  {
718  return (pT->*mpMemberFunction)();
719  }
720 
721  protected:
722  MemberFunction mpMemberFunction;
723  };
724 
725 
733  template <typename Result, typename T, typename Argument>
734  class const_mem_fun1_t : public binary_function<const T*, Argument, Result>
735  {
736  public:
737  typedef Result (T::*MemberFunction)(Argument) const;
738 
739  inline explicit const_mem_fun1_t(MemberFunction pMemberFunction)
740  : mpMemberFunction(pMemberFunction)
741  {
742  // Empty
743  }
744 
745  inline Result operator()(const T* pT, Argument arg) const
746  {
747  return (pT->*mpMemberFunction)(arg);
748  }
749 
750  protected:
751  MemberFunction mpMemberFunction;
752  };
753 
754 
766  template <typename Result, typename T>
767  inline mem_fun_t<Result, T>
768  mem_fun(Result (T::*MemberFunction)())
769  {
770  return eastl::mem_fun_t<Result, T>(MemberFunction);
771  }
772 
773  template <typename Result, typename T, typename Argument>
774  inline mem_fun1_t<Result, T, Argument>
775  mem_fun(Result (T::*MemberFunction)(Argument))
776  {
777  return eastl::mem_fun1_t<Result, T, Argument>(MemberFunction);
778  }
779 
780  template <typename Result, typename T>
781  inline const_mem_fun_t<Result, T>
782  mem_fun(Result (T::*MemberFunction)() const)
783  {
784  return eastl::const_mem_fun_t<Result, T>(MemberFunction);
785  }
786 
787  template <typename Result, typename T, typename Argument>
788  inline const_mem_fun1_t<Result, T, Argument>
789  mem_fun(Result (T::*MemberFunction)(Argument) const)
790  {
791  return eastl::const_mem_fun1_t<Result, T, Argument>(MemberFunction);
792  }
793 
794 
795 
796 
797 
799  // mem_fun_ref
800  // mem_fun1_ref
801  //
803 
806  template <typename Result, typename T>
807  class mem_fun_ref_t : public unary_function<T, Result>
808  {
809  public:
810  typedef Result (T::*MemberFunction)();
811 
812  inline explicit mem_fun_ref_t(MemberFunction pMemberFunction)
813  : mpMemberFunction(pMemberFunction)
814  {
815  // Empty
816  }
817 
818  inline Result operator()(T& t) const
819  {
820  return (t.*mpMemberFunction)();
821  }
822 
823  protected:
824  MemberFunction mpMemberFunction;
825  };
826 
827 
830  template <typename Result, typename T, typename Argument>
831  class mem_fun1_ref_t : public binary_function<T, Argument, Result>
832  {
833  public:
834  typedef Result (T::*MemberFunction)(Argument);
835 
836  inline explicit mem_fun1_ref_t(MemberFunction pMemberFunction)
837  : mpMemberFunction(pMemberFunction)
838  {
839  // Empty
840  }
841 
842  inline Result operator()(T& t, Argument arg) const
843  {
844  return (t.*mpMemberFunction)(arg);
845  }
846 
847  protected:
848  MemberFunction mpMemberFunction;
849  };
850 
851 
854  template <typename Result, typename T>
855  class const_mem_fun_ref_t : public unary_function<T, Result>
856  {
857  public:
858  typedef Result (T::*MemberFunction)() const;
859 
860  inline explicit const_mem_fun_ref_t(MemberFunction pMemberFunction)
861  : mpMemberFunction(pMemberFunction)
862  {
863  // Empty
864  }
865 
866  inline Result operator()(const T& t) const
867  {
868  return (t.*mpMemberFunction)();
869  }
870 
871  protected:
872  MemberFunction mpMemberFunction;
873  };
874 
875 
878  template <typename Result, typename T, typename Argument>
879  class const_mem_fun1_ref_t : public binary_function<T, Argument, Result>
880  {
881  public:
882  typedef Result (T::*MemberFunction)(Argument) const;
883 
884  inline explicit const_mem_fun1_ref_t(MemberFunction pMemberFunction)
885  : mpMemberFunction(pMemberFunction)
886  {
887  // Empty
888  }
889 
890  inline Result operator()(const T& t, Argument arg) const
891  {
892  return (t.*mpMemberFunction)(arg);
893  }
894 
895  protected:
896  MemberFunction mpMemberFunction;
897  };
898 
899 
908  template <typename Result, typename T>
910  mem_fun_ref(Result (T::*MemberFunction)())
911  {
912  return eastl::mem_fun_ref_t<Result, T>(MemberFunction);
913  }
914 
915  template <typename Result, typename T, typename Argument>
916  inline mem_fun1_ref_t<Result, T, Argument>
917  mem_fun_ref(Result (T::*MemberFunction)(Argument))
918  {
919  return eastl::mem_fun1_ref_t<Result, T, Argument>(MemberFunction);
920  }
921 
922  template <typename Result, typename T>
923  inline const_mem_fun_ref_t<Result, T>
924  mem_fun_ref(Result (T::*MemberFunction)() const)
925  {
926  return eastl::const_mem_fun_ref_t<Result, T>(MemberFunction);
927  }
928 
929  template <typename Result, typename T, typename Argument>
930  inline const_mem_fun1_ref_t<Result, T, Argument>
931  mem_fun_ref(Result (T::*MemberFunction)(Argument) const)
932  {
934  }
935 
936 
937  // not_fn_ret
938  // not_fn_ret is a implementation specified return type of eastl::not_fn.
939  // The type name is not specified but it does have mandated functions that conforming implementations must support.
940  //
941  // http://en.cppreference.com/w/cpp/utility/functional/not_fn
942  //
943  template <typename F>
944  struct not_fn_ret
945  {
946  explicit not_fn_ret(F&& f) : mDecayF(eastl::forward<F>(f)) {}
947  not_fn_ret(not_fn_ret&& f) = default;
948  not_fn_ret(const not_fn_ret& f) = default;
949 
950  // overloads for lvalues
951  template <class... Args>
952  auto operator()(Args&&... args) &
953  -> decltype(!eastl::declval<eastl::invoke_result_t<eastl::decay_t<F>&, Args...>>())
954  { return !eastl::invoke(mDecayF, eastl::forward<Args>(args)...); }
955 
956  template <class... Args>
957  auto operator()(Args&&... args) const &
958  -> decltype(!eastl::declval<eastl::invoke_result_t<eastl::decay_t<F> const&, Args...>>())
959  { return !eastl::invoke(mDecayF, eastl::forward<Args>(args)...); }
960 
961  // overloads for rvalues
962  template <class... Args>
963  auto operator()(Args&&... args) &&
964  -> decltype(!eastl::declval<eastl::invoke_result_t<eastl::decay_t<F>, Args...>>())
965  { return !eastl::invoke(eastl::move(mDecayF), eastl::forward<Args>(args)...); }
966 
967  template <class... Args>
968  auto operator()(Args&&... args) const &&
969  -> decltype(!eastl::declval<eastl::invoke_result_t<eastl::decay_t<F> const, Args...>>())
970  { return !eastl::invoke(eastl::move(mDecayF), eastl::forward<Args>(args)...); }
971 
972  eastl::decay_t<F> mDecayF;
973  };
974 
987  template <class F>
988  inline not_fn_ret<F> not_fn(F&& f)
989  {
990  return not_fn_ret<F>(eastl::forward<F>(f));
991  }
992 
993 
995  // hash
997  namespace Internal
998  {
999  // utility to disable the generic template specialization that is
1000  // used for enum types only.
1001  template <typename T, bool Enabled>
1002  struct EnableHashIf {};
1003 
1004  template <typename T>
1005  struct EnableHashIf<T, true>
1006  {
1007  size_t operator()(T p) const { return size_t(p); }
1008  };
1009  } // namespace Internal
1010 
1011 
1012  template <typename T> struct hash;
1013 
1014  template <typename T>
1015  struct hash : Internal::EnableHashIf<T, is_enum_v<T>> {};
1016 
1017  template <typename T> struct hash<T*> // Note that we use the pointer as-is and don't divide by sizeof(T*). This is because the table is of a prime size and this division doesn't benefit distribution.
1018  { size_t operator()(T* p) const { return size_t(uintptr_t(p)); } };
1019 
1020  template <> struct hash<bool>
1021  { size_t operator()(bool val) const { return static_cast<size_t>(val); } };
1022 
1023  template <> struct hash<char>
1024  { size_t operator()(char val) const { return static_cast<size_t>(val); } };
1025 
1026  template <> struct hash<signed char>
1027  { size_t operator()(signed char val) const { return static_cast<size_t>(val); } };
1028 
1029  template <> struct hash<unsigned char>
1030  { size_t operator()(unsigned char val) const { return static_cast<size_t>(val); } };
1031 
1032  #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE
1033  template <> struct hash<char8_t>
1034  { size_t operator()(char8_t val) const { return static_cast<size_t>(val); } };
1035  #endif
1036 
1037  #if defined(EA_CHAR16_NATIVE) && EA_CHAR16_NATIVE
1038  template <> struct hash<char16_t>
1039  { size_t operator()(char16_t val) const { return static_cast<size_t>(val); } };
1040  #endif
1041 
1042  #if defined(EA_CHAR32_NATIVE) && EA_CHAR32_NATIVE
1043  template <> struct hash<char32_t>
1044  { size_t operator()(char32_t val) const { return static_cast<size_t>(val); } };
1045  #endif
1046 
1047  // If wchar_t is a native type instead of simply a define to an existing type...
1048  #if !defined(EA_WCHAR_T_NON_NATIVE)
1049  template <> struct hash<wchar_t>
1050  { size_t operator()(wchar_t val) const { return static_cast<size_t>(val); } };
1051  #endif
1052 
1053  template <> struct hash<signed short>
1054  { size_t operator()(signed short val) const { return static_cast<size_t>(val); } };
1055 
1056  template <> struct hash<unsigned short>
1057  { size_t operator()(unsigned short val) const { return static_cast<size_t>(val); } };
1058 
1059  template <> struct hash<signed int>
1060  { size_t operator()(signed int val) const { return static_cast<size_t>(val); } };
1061 
1062  template <> struct hash<unsigned int>
1063  { size_t operator()(unsigned int val) const { return static_cast<size_t>(val); } };
1064 
1065  template <> struct hash<signed long>
1066  { size_t operator()(signed long val) const { return static_cast<size_t>(val); } };
1067 
1068  template <> struct hash<unsigned long>
1069  { size_t operator()(unsigned long val) const { return static_cast<size_t>(val); } };
1070 
1071  template <> struct hash<signed long long>
1072  { size_t operator()(signed long long val) const { return static_cast<size_t>(val); } };
1073 
1074  template <> struct hash<unsigned long long>
1075  { size_t operator()(unsigned long long val) const { return static_cast<size_t>(val); } };
1076 
1077  template <> struct hash<float>
1078  { size_t operator()(float val) const { return static_cast<size_t>(val); } };
1079 
1080  template <> struct hash<double>
1081  { size_t operator()(double val) const { return static_cast<size_t>(val); } };
1082 
1083  template <> struct hash<long double>
1084  { size_t operator()(long double val) const { return static_cast<size_t>(val); } };
1085 
1086  #if defined(EA_HAVE_INT128) && EA_HAVE_INT128
1087  template <> struct hash<uint128_t>
1088  { size_t operator()(uint128_t val) const { return static_cast<size_t>(val); } };
1089  #endif
1090 
1091 
1093  // string hashes
1094  //
1095  // Note that our string hashes here intentionally are slow for long strings.
1096  // The reasoning for this is so:
1097  // - The large majority of hashed strings are only a few bytes long.
1098  // - The hash function is significantly more efficient if it can make this assumption.
1099  // - The user is welcome to make a custom hash for those uncommon cases where
1100  // long strings need to be hashed. Indeed, the user can probably make a
1101  // special hash customized for such strings that's better than what we provide.
1103 
1104  template <> struct hash<char*>
1105  {
1106  size_t operator()(const char* p) const
1107  {
1108  uint32_t c, result = 2166136261U; // FNV1 hash. Perhaps the best string hash. Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1109  while((c = (uint8_t)*p++) != 0) // Using '!=' disables compiler warnings.
1110  result = (result * 16777619) ^ c;
1111  return (size_t)result;
1112  }
1113  };
1114 
1115  template <> struct hash<const char*>
1116  {
1117  size_t operator()(const char* p) const
1118  {
1119  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1120  while((c = (uint8_t)*p++) != 0) // cast to unsigned 8 bit.
1121  result = (result * 16777619) ^ c;
1122  return (size_t)result;
1123  }
1124  };
1125 
1126 #if EA_CHAR8_UNIQUE
1127  template <> struct hash<char8_t*>
1128  {
1129  size_t operator()(const char8_t* p) const
1130  {
1131  uint32_t c, result = 2166136261U; // FNV1 hash. Perhaps the best string hash. Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1132  while((c = (uint8_t)*p++) != 0) // Using '!=' disables compiler warnings.
1133  result = (result * 16777619) ^ c;
1134  return (size_t)result;
1135  }
1136  };
1137 
1138  template <> struct hash<const char8_t*>
1139  {
1140  size_t operator()(const char8_t* p) const
1141  {
1142  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1143  while((c = (uint8_t)*p++) != 0) // cast to unsigned 8 bit.
1144  result = (result * 16777619) ^ c;
1145  return (size_t)result;
1146  }
1147  };
1148 #endif
1149 
1150 
1151  template <> struct hash<char16_t*>
1152  {
1153  size_t operator()(const char16_t* p) const
1154  {
1155  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1156  while((c = (uint16_t)*p++) != 0) // cast to unsigned 16 bit.
1157  result = (result * 16777619) ^ c;
1158  return (size_t)result;
1159  }
1160  };
1161 
1162  template <> struct hash<const char16_t*>
1163  {
1164  size_t operator()(const char16_t* p) const
1165  {
1166  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1167  while((c = (uint16_t)*p++) != 0) // cast to unsigned 16 bit.
1168  result = (result * 16777619) ^ c;
1169  return (size_t)result;
1170  }
1171  };
1172 
1173  template <> struct hash<char32_t*>
1174  {
1175  size_t operator()(const char32_t* p) const
1176  {
1177  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1178  while((c = (uint32_t)*p++) != 0) // cast to unsigned 32 bit.
1179  result = (result * 16777619) ^ c;
1180  return (size_t)result;
1181  }
1182  };
1183 
1184  template <> struct hash<const char32_t*>
1185  {
1186  size_t operator()(const char32_t* p) const
1187  {
1188  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1189  while((c = (uint32_t)*p++) != 0) // cast to unsigned 32 bit.
1190  result = (result * 16777619) ^ c;
1191  return (size_t)result;
1192  }
1193  };
1194 
1195 #if defined(EA_WCHAR_UNIQUE) && EA_WCHAR_UNIQUE
1196  template<> struct hash<wchar_t*>
1197  {
1198  size_t operator()(const wchar_t* p) const
1199  {
1200  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1201  while ((c = (uint32_t)*p++) != 0) // cast to unsigned 32 bit.
1202  result = (result * 16777619) ^ c;
1203  return (size_t)result;
1204  }
1205  };
1206 
1207  template<> struct hash<const wchar_t*>
1208  {
1209  size_t operator()(const wchar_t* p) const
1210  {
1211  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1212  while ((c = (uint32_t)*p++) != 0) // cast to unsigned 32 bit.
1213  result = (result * 16777619) ^ c;
1214  return (size_t)result;
1215  }
1216  };
1217 #endif
1218 
1226  template <typename String>
1228  {
1229  typedef String string_type;
1230  typedef typename String::value_type value_type;
1231  typedef typename eastl::add_unsigned<value_type>::type unsigned_value_type;
1232 
1233  size_t operator()(const string_type& s) const
1234  {
1235  const unsigned_value_type* p = (const unsigned_value_type*)s.c_str();
1236  uint32_t c, result = 2166136261U; // Intentionally uint32_t instead of size_t, so the behavior is the same regardless of size.
1237  while((c = *p++) != 0)
1238  result = (result * 16777619) ^ c;
1239  return (size_t)result;
1240  }
1241  };
1242 
1243 
1244 } // namespace eastl
1245 
1246 #include <EASTL/internal/function.h>
1247 
1248 #endif // Header include guard
1249 
1250 
1251 
1252 
1253 
1254 
1255 
Definition: functional.h:500
Definition: functional.h:452
Definition: functional.h:880
Definition: functional.h:735
Definition: functional.h:856
Definition: functional.h:706
Definition: functional.h:832
Definition: functional.h:677
Definition: functional.h:808
Definition: functional.h:651
Definition: functional.h:599
Definition: functional.h:554
Definition: functional.h:432
EA Standard Template Library.
Definition: algorithm.h:288
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170
mem_fun_t< Result, T > mem_fun(Result(T::*MemberFunction)())
Definition: functional.h:768
not_fn_ret< F > not_fn(F &&f)
Definition: functional.h:988
pointer_to_unary_function< Arg, Result > ptr_fun(Result(*pFunction)(Arg))
Definition: functional.h:580
mem_fun_ref_t< Result, T > mem_fun_ref(Result(T::*MemberFunction)())
Definition: functional.h:910
Definition: functional.h:1002
Definition: functional_base.h:192
Definition: functional.h:85
Definition: functional.h:395
Definition: functional.h:139
Definition: functional.h:291
Definition: functional.h:219
Definition: functional.h:1015
Definition: functional.h:418
Definition: functional.h:314
Definition: functional.h:337
Definition: functional.h:371
Definition: functional.h:354
Definition: type_transformations.h:378
Definition: functional.h:49
Definition: functional.h:103
Definition: functional.h:67
Definition: functional.h:121
Definition: functional.h:406
Definition: functional.h:163
Definition: functional.h:945
Definition: functional.h:31
Definition: functional.h:205
Definition: functional.h:264
Definition: functional.h:1228
Definition: functional.h:472
Definition: functional_base.h:184
Definition: int128.h:203