diff --git a/optional.hpp b/optional.hpp index 0c1982c..ec1ad04 100644 --- a/optional.hpp +++ b/optional.hpp @@ -17,12 +17,18 @@ #include #include -#if __cplusplus == 201103L +#if __cplusplus == 201103L || _MSC_VER == 1900 #define TL_OPTIONAL_11_CONSTEXPR #else #define TL_OPTIONAL_11_CONSTEXPR constexpr #endif +#if _MSC_VER == 1900 +#define TL_OPTIONAL_MSVC_2015_CONSTEXPR +#else +#define TL_OPTIONAL_MSVC_2015_CONSTEXPR constexpr +#endif + namespace tl { template class optional; class monostate {}; @@ -79,16 +85,19 @@ template struct is_optional_impl> : std::true_type {}; template using is_optional = is_optional_impl>; // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround -template >{}, int> = 0> +template < + typename Fn, typename... Args, + typename = enable_if_t>{}>, + int = 0> constexpr auto invoke(Fn &&f, Args &&... args) noexcept( noexcept(std::mem_fn(f)(std::forward(args)...))) -> decltype(std::mem_fn(f)(std::forward(args)...)) { return std::mem_fn(f)(std::forward(args)...); } -template >{}, int> = 0> +template < + typename Fn, typename... Args, + typename = enable_if_t>{}>> constexpr auto invoke(Fn &&f, Args &&... args) noexcept( noexcept(std::forward(f)(std::forward(args)...))) -> decltype(std::forward(f)(std::forward(args)...)) { @@ -143,7 +152,7 @@ using enable_if_ret_void = enable_if_t::value>; template using disable_if_ret_void = enable_if_t::value>; -} +} // namespace detail struct in_place_t { explicit in_place_t() = default; @@ -196,6 +205,12 @@ using enable_assign_from_other = detail::enable_if_t< !std::is_assignable &>::value && !std::is_assignable &&>::value>; +#ifdef _MSC_VER +// TODO make a version which works with MSVC +template struct is_swappable : std::true_type {}; + +template struct is_nothrow_swappable : std::true_type {}; +#else // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept namespace swap_adl_tests { // if swap ADL finds this then it would call std::swap otherwise (same @@ -230,16 +245,8 @@ struct is_std_swap_noexcept : is_std_swap_noexcept {}; template struct is_adl_swap_noexcept : std::integral_constant(0))> {}; -} +} // namespace swap_adl_tests -#ifdef _MSC_VER - // TODO make a version which works with MSVC - template - struct is_swappable : std::true_type{}; - - template - struct is_nothrow_swappable : std::true_type{}; -#else template struct is_swappable : std::integral_constant< @@ -271,7 +278,7 @@ struct is_nothrow_swappable }; #endif -} +} // namespace detail // [optional.nullopt], no-value state indicator struct nullopt_t { @@ -444,7 +451,7 @@ inline constexpr optional make_optional(std::initializer_list il, Args &&... args) { return optional(in_place, il, std::forward(args)...); } -} +} // namespace tl // [optional.hash], hash support namespace std { @@ -457,7 +464,7 @@ template struct hash> { return hash>()(*o); } }; -} +} // namespace std namespace tl { namespace detail { @@ -502,7 +509,7 @@ template struct optional_storage_base { bool m_has_value = false; }; -} +} // namespace detail template class optional : private detail::optional_storage_base { using base = detail::optional_storage_base; @@ -967,7 +974,7 @@ public: } template * = nullptr> - optional constexpr or_else(F &&f) & { + optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) & { if (has_value()) return *this; @@ -976,7 +983,7 @@ public: } template * = nullptr> - optional constexpr or_else(F &&f) & { + optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) & { return has_value() ? *this : std::forward(f)(); } @@ -990,7 +997,7 @@ public: } template * = nullptr> - optional constexpr or_else(F &&f) && { + optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) && { return has_value() ? std::move(*this) : std::forward(f)(); } @@ -1004,7 +1011,7 @@ public: } template * = nullptr> - optional constexpr or_else(F &&f) const & { + optional TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) const & { return has_value() ? *this : std::forward(f)(); } @@ -1064,4 +1071,4 @@ public: }; // template optional(T)->optional; -} +} // namespace tl