Commit 5f3e20a906d0aa45ec3acec3b061c559e3908c9a
1 parent
3952addd
C++14 like syntax for enable_if_t
Showing
1 changed file
with
21 additions
and
15 deletions
include/CLI.hpp
| @@ -13,13 +13,18 @@ | @@ -13,13 +13,18 @@ | ||
| 13 | #include <iomanip> | 13 | #include <iomanip> |
| 14 | #include <numeric> | 14 | #include <numeric> |
| 15 | 15 | ||
| 16 | -// This is unreachable outside this file; you should not use Combiner directly | ||
| 17 | -namespace { | 16 | +//#define CLI_LOG 1 |
| 18 | 17 | ||
| 18 | +namespace CLI { | ||
| 19 | + | ||
| 20 | +/// Log a message, can be enabled with CLI_LOG | ||
| 19 | void logit(std::string) { | 21 | void logit(std::string) { |
| 20 | - //std::cout << "\033[1;31m" << output << "\033[0m" << std::endl; | 22 | +#ifdef CLI_LOG |
| 23 | + std::cout << "\033[1;31m" << output << "\033[0m" << std::endl; | ||
| 24 | +#endif | ||
| 21 | } | 25 | } |
| 22 | 26 | ||
| 27 | +/// Simple fucntion to join a string | ||
| 23 | template <typename T> | 28 | template <typename T> |
| 24 | std::string join(const T& v, std::string delim = ",") { | 29 | std::string join(const T& v, std::string delim = ",") { |
| 25 | std::ostringstream s; | 30 | std::ostringstream s; |
| @@ -32,22 +37,23 @@ std::string join(const T& v, std::string delim = ",") { | @@ -32,22 +37,23 @@ std::string join(const T& v, std::string delim = ",") { | ||
| 32 | return s.str(); | 37 | return s.str(); |
| 33 | } | 38 | } |
| 34 | 39 | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | -namespace CLI { | ||
| 38 | - | ||
| 39 | // Based generally on https://rmf.io/cxx11/almost-static-if | 40 | // Based generally on https://rmf.io/cxx11/almost-static-if |
| 40 | namespace detail { | 41 | namespace detail { |
| 42 | + /// Simple empty scoped class | ||
| 41 | enum class enabler {}; | 43 | enum class enabler {}; |
| 42 | } | 44 | } |
| 45 | + | ||
| 46 | +/// An instance to use in EnableIf | ||
| 43 | constexpr detail::enabler dummy = {}; | 47 | constexpr detail::enabler dummy = {}; |
| 44 | 48 | ||
| 45 | // Copied from C++14 | 49 | // Copied from C++14 |
| 50 | +#if __cplusplus < 201402L | ||
| 46 | template< bool B, class T = void > | 51 | template< bool B, class T = void > |
| 47 | using enable_if_t = typename std::enable_if<B,T>::type; | 52 | using enable_if_t = typename std::enable_if<B,T>::type; |
| 48 | - | ||
| 49 | -template <bool Condition> | ||
| 50 | -using EnableIf = enable_if_t<Condition, detail::enabler>; | 53 | +#else |
| 54 | +using std::enable_if_t; | ||
| 55 | +#endif | ||
| 56 | +// If your compiler supports C++14, you can use that definition instead | ||
| 51 | 57 | ||
| 52 | struct Combiner { | 58 | struct Combiner { |
| 53 | int num; | 59 | int num; |
| @@ -265,7 +271,7 @@ public: | @@ -265,7 +271,7 @@ public: | ||
| 265 | }; | 271 | }; |
| 266 | 272 | ||
| 267 | 273 | ||
| 268 | -template<typename T, EnableIf<std::is_integral<T>::value> = dummy> | 274 | +template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = dummy> |
| 269 | bool lexical_cast(std::string input, T& output) { | 275 | bool lexical_cast(std::string input, T& output) { |
| 270 | logit("Int lexical cast " + input); | 276 | logit("Int lexical cast " + input); |
| 271 | try{ | 277 | try{ |
| @@ -278,7 +284,7 @@ bool lexical_cast(std::string input, T& output) { | @@ -278,7 +284,7 @@ bool lexical_cast(std::string input, T& output) { | ||
| 278 | } | 284 | } |
| 279 | } | 285 | } |
| 280 | 286 | ||
| 281 | -template<typename T, EnableIf<std::is_floating_point<T>::value> = dummy> | 287 | +template<typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = dummy> |
| 282 | bool lexical_cast(std::string input, T& output) { | 288 | bool lexical_cast(std::string input, T& output) { |
| 283 | logit("Floating lexical cast " + input); | 289 | logit("Floating lexical cast " + input); |
| 284 | try{ | 290 | try{ |
| @@ -293,7 +299,7 @@ bool lexical_cast(std::string input, T& output) { | @@ -293,7 +299,7 @@ bool lexical_cast(std::string input, T& output) { | ||
| 293 | 299 | ||
| 294 | // String and similar | 300 | // String and similar |
| 295 | template<typename T, | 301 | template<typename T, |
| 296 | -EnableIf<!std::is_floating_point<T>::value && !std::is_integral<T>::value> = dummy> | 302 | +enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value, detail::enabler> = dummy> |
| 297 | bool lexical_cast(std::string input, T& output) { | 303 | bool lexical_cast(std::string input, T& output) { |
| 298 | logit("Direct lexical cast: " + input); | 304 | logit("Direct lexical cast: " + input); |
| 299 | output = input; | 305 | output = input; |
| @@ -384,7 +390,7 @@ public: | @@ -384,7 +390,7 @@ public: | ||
| 384 | } | 390 | } |
| 385 | 391 | ||
| 386 | /// Add option for string | 392 | /// Add option for string |
| 387 | - template<typename T, EnableIf<!std::is_array<T>::value> = dummy> | 393 | + template<typename T, enable_if_t<!std::is_array<T>::value, detail::enabler> = dummy> |
| 388 | void add_option( | 394 | void add_option( |
| 389 | std::string name, ///< The name, long,short | 395 | std::string name, ///< The name, long,short |
| 390 | T &variable, ///< The variable to set | 396 | T &variable, ///< The variable to set |
| @@ -448,7 +454,7 @@ public: | @@ -448,7 +454,7 @@ public: | ||
| 448 | } | 454 | } |
| 449 | 455 | ||
| 450 | /// Add option for flag | 456 | /// Add option for flag |
| 451 | - template<typename T, EnableIf<std::is_integral<T>::value> = dummy> | 457 | + template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = dummy> |
| 452 | void add_flag( | 458 | void add_flag( |
| 453 | std::string name, ///< The name, short,long | 459 | std::string name, ///< The name, short,long |
| 454 | T &count, ///< A varaible holding the count | 460 | T &count, ///< A varaible holding the count |