]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #include <memory> | |
16 | #include <type_traits> | |
17 | ||
18 | #ifndef CEPH_COMMON_BACKPORT14_H | |
19 | #define CEPH_COMMON_BACKPORT14_H | |
20 | ||
21 | // Library code from C++14 that can be implemented in C++11. | |
22 | ||
23 | namespace ceph { | |
24 | template<typename T> | |
25 | using remove_extent_t = typename std::remove_extent<T>::type; | |
26 | template<typename T> | |
27 | using remove_reference_t = typename std::remove_reference<T>::type; | |
28 | template<typename T> | |
29 | using result_of_t = typename std::result_of<T>::type; | |
d2e6a577 FG |
30 | template<typename T> |
31 | using decay_t = typename std::decay<T>::type; | |
31f18b77 FG |
32 | |
33 | namespace _backport14 { | |
34 | template<typename T> | |
35 | struct uniquity { | |
36 | using datum = std::unique_ptr<T>; | |
37 | }; | |
38 | ||
39 | template<typename T> | |
40 | struct uniquity<T[]> { | |
41 | using array = std::unique_ptr<T[]>; | |
42 | }; | |
43 | ||
44 | template<typename T, std::size_t N> | |
45 | struct uniquity<T[N]> { | |
46 | using verboten = void; | |
47 | }; | |
48 | ||
49 | template<typename T, typename... Args> | |
50 | inline typename uniquity<T>::datum make_unique(Args&&... args) { | |
51 | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |
52 | } | |
53 | ||
54 | template<typename T> | |
55 | inline typename uniquity<T>::array make_unique(std::size_t n) { | |
56 | return std::unique_ptr<T>(new remove_extent_t<T>[n]()); | |
57 | } | |
58 | ||
59 | template<typename T, class... Args> | |
60 | typename uniquity<T>::verboten | |
61 | make_unique(Args&&...) = delete; | |
62 | ||
63 | // The constexpr variant of std::max(). | |
64 | template<class T> | |
65 | constexpr const T& max(const T& a, const T& b) { | |
66 | return a < b ? b : a; | |
67 | } | |
68 | } // namespace _backport14 | |
69 | ||
70 | namespace _backport17 { | |
71 | template <class C> | |
72 | constexpr auto size(const C& c) -> decltype(c.size()) { | |
73 | return c.size(); | |
74 | } | |
75 | ||
76 | template <typename T, std::size_t N> | |
77 | constexpr std::size_t size(const T (&array)[N]) noexcept { | |
78 | return N; | |
79 | } | |
d2e6a577 FG |
80 | |
81 | /// http://en.cppreference.com/w/cpp/utility/functional/not_fn | |
82 | // this implementation uses c++14's result_of_t (above) instead of the c++17 | |
83 | // invoke_result_t, and so may not behave correctly when SFINAE is required | |
84 | template <typename F> | |
85 | class not_fn_result { | |
86 | using DecayF = decay_t<F>; | |
87 | DecayF fn; | |
88 | public: | |
89 | explicit not_fn_result(F&& f) : fn(std::forward<F>(f)) {} | |
90 | not_fn_result(not_fn_result&& f) = default; | |
91 | not_fn_result(const not_fn_result& f) = default; | |
92 | ||
93 | template<class... Args> | |
94 | auto operator()(Args&&... args) & | |
95 | -> decltype(!std::declval<result_of_t<DecayF&(Args...)>>()) { | |
96 | return !fn(std::forward<Args>(args)...); | |
97 | } | |
98 | template<class... Args> | |
99 | auto operator()(Args&&... args) const& | |
100 | -> decltype(!std::declval<result_of_t<DecayF const&(Args...)>>()) { | |
101 | return !fn(std::forward<Args>(args)...); | |
102 | } | |
103 | ||
104 | template<class... Args> | |
105 | auto operator()(Args&&... args) && | |
106 | -> decltype(!std::declval<result_of_t<DecayF(Args...)>>()) { | |
107 | return !std::move(fn)(std::forward<Args>(args)...); | |
108 | } | |
109 | template<class... Args> | |
110 | auto operator()(Args&&... args) const&& | |
111 | -> decltype(!std::declval<result_of_t<DecayF const(Args...)>>()) { | |
112 | return !std::move(fn)(std::forward<Args>(args)...); | |
113 | } | |
114 | }; | |
115 | ||
116 | template <typename F> | |
117 | not_fn_result<F> not_fn(F&& fn) { | |
118 | return not_fn_result<F>(std::forward<F>(fn)); | |
119 | } | |
120 | ||
31f18b77 FG |
121 | } // namespace _backport17 |
122 | using _backport14::make_unique; | |
123 | using _backport17::size; | |
124 | using _backport14::max; | |
d2e6a577 | 125 | using _backport17::not_fn; |
31f18b77 FG |
126 | } // namespace ceph |
127 | ||
128 | #endif // CEPH_COMMON_BACKPORT14_H |