diff --git a/include/span.h b/include/span.h index 72d55d6..f8b9015 100644 --- a/include/span.h +++ b/include/span.h @@ -45,6 +45,12 @@ #pragma push_macro("constexpr") #define constexpr +// On Windows, if NOMINMAX is not defined, then windows.h defines the macro max +#ifdef _WIN32 +#pragma push_macro("max") +#define max max +#endif + // VS 2013 workarounds #if _MSC_VER <= 1800 @@ -2196,6 +2202,11 @@ general_span_iterator operator+(typename general_span_iterator::diff #undef constexpr #pragma pop_macro("constexpr") +#ifdef _WIN32 +#undef max +#pragma pop_macro("max") +#endif + #if _MSC_VER <= 1800 #pragma warning(pop) diff --git a/include/string_span.h b/include/string_span.h index feb5ac6..b406d2a 100644 --- a/include/string_span.h +++ b/include/string_span.h @@ -34,6 +34,7 @@ #if _MSC_VER <= 1800 #define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG +#define GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER // noexcept is not understood #ifndef GSL_THROW_ON_CONTRACT_VIOLATION @@ -235,13 +236,28 @@ public: constexpr basic_string_span(const basic_string_span& other) = default; // move +#ifdef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT + constexpr basic_string_span(basic_string_span&& other) + : span_(std::move(other.span_)) + { + } +#else constexpr basic_string_span(basic_string_span&& other) = default; +#endif // assign constexpr basic_string_span& operator=(const basic_string_span& other) = default; // move assign +#ifdef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT + constexpr basic_string_span& operator=(basic_string_span&& other) + { + span_ = std::move(other.span_); + return *this; + } +#else constexpr basic_string_span& operator=(basic_string_span&& other) = default; +#endif // from nullptr constexpr basic_string_span(std::nullptr_t ptr) noexcept @@ -273,6 +289,74 @@ public: : span_(const_cast(s.data()), narrow_cast(s.length())) {} +#ifdef GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER + template< + typename Cont, + typename DataType = typename Cont::value_type + > + constexpr basic_string_span( + Cont& cont, + std::enable_if_t< + !details::is_span::value + && !details::is_basic_string_span::value + && !(!std::is_const::value && std::is_const::value) + && std::is_convertible::value + && std::is_same().size(), *std::declval().data())>, DataType>::value + >* = nullptr + ) + : span_(cont.data(), cont.size()) + {} + + // disallow creation from temporary containers and strings + template< + typename Cont, + typename DataType = typename Cont::value_type + > + explicit basic_string_span( + Cont&& cont + , + std::enable_if_t< + !details::is_span::value + && !details::is_basic_string_span::value + && std::is_convertible::value + && std::is_same().size(), *std::declval().data())>, DataType>::value + >* = nullptr + ) = delete; + + // from span + template< + typename OtherValueType, + std::ptrdiff_t... OtherDimensions, + typename OtherBounds = static_bounds + > + constexpr basic_string_span( + span other, + typename std::enable_if< + std::is_convertible::value && + std::is_convertible::value + >::type* = nullptr + ) noexcept + : span_(other) + {} + + // from string_span + template< + typename OtherValueType, + std::ptrdiff_t OtherExtent, + typename OtherBounds = static_bounds + > + constexpr basic_string_span( + basic_string_span other, + std::enable_if_t< + std::is_convertible::value + && std::is_convertible::value + >* = nullptr + ) noexcept + : span_(other.data(), other.length()) + {} + +#else // GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER + // from containers. Containers must have .size() and .data() function signatures template ::value @@ -311,6 +395,7 @@ public: constexpr basic_string_span(basic_string_span other) noexcept : span_(other.data(), other.length()) {} +#endif // GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER constexpr bool empty() const noexcept { @@ -856,13 +941,12 @@ bool operator>=(const T& one, gsl::basic_string_span other) noexc #if _MSC_VER <= 1800 -#pragma warning(pop) - #ifndef GSL_THROW_ON_CONTRACT_VIOLATION #undef noexcept #pragma pop_macro("noexcept") #endif // GSL_THROW_ON_CONTRACT_VIOLATION +#undef GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER #undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG #endif // _MSC_VER <= 1800