318
|
1 // Copyright Toru Niina 2017.
|
|
2 // Distributed under the MIT License.
|
|
3 #ifndef TOML11_UTILITY_HPP
|
|
4 #define TOML11_UTILITY_HPP
|
|
5 #include <memory>
|
|
6 #include <sstream>
|
|
7 #include <utility>
|
|
8
|
|
9 #include "traits.hpp"
|
|
10 #include "version.hpp"
|
|
11
|
|
12 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L
|
|
13 # define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]]
|
|
14 #elif defined(__GNUC__)
|
|
15 # define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
|
16 #elif defined(_MSC_VER)
|
|
17 # define TOML11_MARK_AS_DEPRECATED(msg) __declspec(deprecated(msg))
|
|
18 #else
|
|
19 # define TOML11_MARK_AS_DEPRECATED
|
|
20 #endif
|
|
21
|
|
22 namespace toml
|
|
23 {
|
|
24
|
|
25 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L
|
|
26
|
|
27 using std::make_unique;
|
|
28
|
|
29 #else
|
|
30
|
|
31 template<typename T, typename ... Ts>
|
|
32 inline std::unique_ptr<T> make_unique(Ts&& ... args)
|
|
33 {
|
|
34 return std::unique_ptr<T>(new T(std::forward<Ts>(args)...));
|
|
35 }
|
|
36
|
|
37 #endif // TOML11_CPLUSPLUS_STANDARD_VERSION >= 2014
|
|
38
|
|
39 namespace detail
|
|
40 {
|
|
41 template<typename Container>
|
|
42 void try_reserve_impl(Container& container, std::size_t N, std::true_type)
|
|
43 {
|
|
44 container.reserve(N);
|
|
45 return;
|
|
46 }
|
|
47 template<typename Container>
|
|
48 void try_reserve_impl(Container&, std::size_t, std::false_type) noexcept
|
|
49 {
|
|
50 return;
|
|
51 }
|
|
52 } // detail
|
|
53
|
|
54 template<typename Container>
|
|
55 void try_reserve(Container& container, std::size_t N)
|
|
56 {
|
|
57 if(N <= container.size()) {return;}
|
|
58 detail::try_reserve_impl(container, N, detail::has_reserve_method<Container>{});
|
|
59 return;
|
|
60 }
|
|
61
|
|
62 namespace detail
|
|
63 {
|
|
64 inline std::string concat_to_string_impl(std::ostringstream& oss)
|
|
65 {
|
|
66 return oss.str();
|
|
67 }
|
|
68 template<typename T, typename ... Ts>
|
|
69 std::string concat_to_string_impl(std::ostringstream& oss, T&& head, Ts&& ... tail)
|
|
70 {
|
|
71 oss << std::forward<T>(head);
|
|
72 return concat_to_string_impl(oss, std::forward<Ts>(tail) ... );
|
|
73 }
|
|
74 } // detail
|
|
75
|
|
76 template<typename ... Ts>
|
|
77 std::string concat_to_string(Ts&& ... args)
|
|
78 {
|
|
79 std::ostringstream oss;
|
|
80 oss << std::boolalpha << std::fixed;
|
|
81 return detail::concat_to_string_impl(oss, std::forward<Ts>(args) ...);
|
|
82 }
|
|
83
|
|
84 template<typename T>
|
|
85 T from_string(const std::string& str, T opt)
|
|
86 {
|
|
87 T v(opt);
|
|
88 std::istringstream iss(str);
|
|
89 iss >> v;
|
|
90 return v;
|
|
91 }
|
|
92
|
|
93 namespace detail
|
|
94 {
|
|
95 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201402L
|
|
96 template<typename T>
|
|
97 decltype(auto) last_one(T&& tail) noexcept
|
|
98 {
|
|
99 return std::forward<T>(tail);
|
|
100 }
|
|
101
|
|
102 template<typename T, typename ... Ts>
|
|
103 decltype(auto) last_one(T&& /*head*/, Ts&& ... tail) noexcept
|
|
104 {
|
|
105 return last_one(std::forward<Ts>(tail)...);
|
|
106 }
|
|
107 #else // C++11
|
|
108 // The following code
|
|
109 // ```cpp
|
|
110 // 1 | template<typename T, typename ... Ts>
|
|
111 // 2 | auto last_one(T&& /*head*/, Ts&& ... tail)
|
|
112 // 3 | -> decltype(last_one(std::forward<Ts>(tail)...))
|
|
113 // 4 | {
|
|
114 // 5 | return last_one(std::forward<Ts>(tail)...);
|
|
115 // 6 | }
|
|
116 // ```
|
|
117 // does not work because the function `last_one(...)` is not yet defined at
|
|
118 // line #3, so `decltype()` cannot deduce the type returned from `last_one`.
|
|
119 // So we need to determine return type in a different way, like a meta func.
|
|
120
|
|
121 template<typename T, typename ... Ts>
|
|
122 struct last_one_in_pack
|
|
123 {
|
|
124 using type = typename last_one_in_pack<Ts...>::type;
|
|
125 };
|
|
126 template<typename T>
|
|
127 struct last_one_in_pack<T>
|
|
128 {
|
|
129 using type = T;
|
|
130 };
|
|
131 template<typename ... Ts>
|
|
132 using last_one_in_pack_t = typename last_one_in_pack<Ts...>::type;
|
|
133
|
|
134 template<typename T>
|
|
135 T&& last_one(T&& tail) noexcept
|
|
136 {
|
|
137 return std::forward<T>(tail);
|
|
138 }
|
|
139 template<typename T, typename ... Ts>
|
|
140 enable_if_t<(sizeof...(Ts) > 0), last_one_in_pack_t<Ts&& ...>>
|
|
141 last_one(T&& /*head*/, Ts&& ... tail)
|
|
142 {
|
|
143 return last_one(std::forward<Ts>(tail)...);
|
|
144 }
|
|
145
|
|
146 #endif
|
|
147 } // detail
|
|
148
|
|
149 }// toml
|
|
150 #endif // TOML11_UTILITY
|