cplusplus_14.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #ifndef REST_RPC_CPLUSPLUS_14_H_
  2. #define REST_RPC_CPLUSPLUS_14_H_
  3. #include <type_traits>
  4. #include <memory>
  5. #include <tuple>
  6. #if __cplusplus == 201103L
  7. namespace std {
  8. template<class T>
  9. struct unique_if {
  10. typedef unique_ptr<T> single_object;
  11. };
  12. template<class T>
  13. struct unique_if<T[]> {
  14. typedef unique_ptr<T[]> unknown_bound;
  15. };
  16. template<class T, size_t N>
  17. struct unique_if<T[N]> {
  18. typedef void known_bound;
  19. };
  20. template<class T, class... Args>
  21. typename unique_if<T>::single_object make_unique(Args&&... args) {
  22. return unique_ptr<T>(new T(forward<Args>(args)...));
  23. }
  24. template<class T>
  25. typename unique_if<T>::unknown_bound make_unique(size_t n) {
  26. typedef typename remove_extent<T>::type U;
  27. return unique_ptr<T>(new U[n]());
  28. }
  29. template<class T, class... Args>
  30. typename unique_if<T>::known_bound make_unique(Args&&...) = delete;
  31. template<size_t... Ints>
  32. struct index_sequence {
  33. using type = index_sequence;
  34. using value_type = size_t;
  35. static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
  36. };
  37. // --------------------------------------------------------------
  38. template<class Sequence1, class Sequence2>
  39. struct _merge_and_renumber;
  40. template<size_t... I1, size_t... I2>
  41. struct _merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
  42. : index_sequence<I1..., (sizeof...(I1) + I2)...> {};
  43. // --------------------------------------------------------------
  44. template<size_t N>
  45. struct make_index_sequence : _merge_and_renumber<typename make_index_sequence<N / 2>::type,
  46. typename make_index_sequence<N - N / 2>::type> {};
  47. template<>
  48. struct make_index_sequence<0> : index_sequence<> {};
  49. template<>
  50. struct make_index_sequence<1> : index_sequence<0> {};
  51. template<typename... T>
  52. using index_sequence_for = make_index_sequence<sizeof...(T)>;
  53. template<bool B, class T = void>
  54. using enable_if_t = typename enable_if<B, T>::type;
  55. template<typename T>
  56. using remove_const_t = typename remove_const<T>::type;
  57. template<typename T>
  58. using remove_reference_t = typename remove_reference<T>::type;
  59. template<int I, typename T>
  60. using tuple_element_t = typename tuple_element<I, T>::type;
  61. template<typename T>
  62. using decay_t = typename decay<T>::type;
  63. template<typename F, typename Tuple, size_t... Idx>
  64. auto apply_helper(F&& f, Tuple&& tp, std::index_sequence<Idx...>)
  65. -> decltype(std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(tp))...)) {
  66. return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(tp))...);
  67. }
  68. template<typename F, typename Tuple>
  69. auto apply(F&& f, Tuple&& tp)
  70. -> decltype(apply_helper(std::forward<F>(f), std::forward<Tuple>(tp),
  71. std::make_index_sequence<std::tuple_size<decay_t<Tuple>>::value>{})) {
  72. return apply_helper(std::forward<F>(f), std::forward<Tuple>(tp),
  73. std::make_index_sequence<std::tuple_size<decay_t<Tuple>>::value>{});
  74. }
  75. template<typename F, typename... Args>
  76. auto invoke(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {
  77. return std::forward<F>(f)(std::forward<Args>(args)...);
  78. }
  79. } // namespace std
  80. #endif
  81. #endif // REST_RPC_CPLUSPLUS_14_H_