From 37cdb6bc50848e031ebe6a2291d953c178da7954 Mon Sep 17 00:00:00 2001 From: Pascal Menuet Date: Fri, 11 Dec 2015 20:47:07 +0100 Subject: [PATCH 1/2] Disable macro max in Windows. Implement move ctors in string_span for VS2013. Remove redundant pragma warning pop for VS2013. --- include/span.h | 11 +++++++++++ include/string_span.h | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/span.h b/include/span.h index 8151737..7bb9c18 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 cc87068..6a71ce9 100644 --- a/include/string_span.h +++ b/include/string_span.h @@ -235,13 +235,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 and length constexpr basic_string_span(std::nullptr_t ptr, size_type length) noexcept @@ -561,8 +576,6 @@ bool operator>=(const gsl::basic_string_span& one, const gsl::bas #if _MSC_VER <= 1800 -#pragma warning(pop) - #ifndef GSL_THROW_ON_CONTRACT_VIOLATION #undef noexcept #pragma pop_macro("noexcept") From 5e7e68c8b042d5b87b3b2a47999aa3665e1fb7f9 Mon Sep 17 00:00:00 2001 From: Pascal Menuet Date: Sat, 12 Dec 2015 22:51:49 +0100 Subject: [PATCH 2/2] For VS2013, fix an ICE by replacing dummy template type parameter by a dummy function parameter --- include/string_span.h | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/include/string_span.h b/include/string_span.h index 6a71ce9..01c56dc 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 @@ -283,6 +284,74 @@ public: : span_(&(s.at(0)), 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 @@ -321,6 +390,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 { @@ -581,6 +651,7 @@ bool operator>=(const gsl::basic_string_span& one, const gsl::bas #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