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