Mercurial > minori
comparison dep/toml11/toml/utility.hpp @ 318:3b355fa948c7
config: use TOML instead of INI
unfortunately, INI is not enough, and causes some paths including
semicolons to break with our current storage of the library folders.
so, I decided to switch to TOML which does support real arrays...
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 12 Jun 2024 05:25:41 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
317:b1f4d1867ab1 | 318:3b355fa948c7 |
---|---|
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 |