Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/GSL.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/string_span.h142
-rw-r--r--tests/string_span_tests.cpp40
2 files changed, 76 insertions, 106 deletions
diff --git a/include/string_span.h b/include/string_span.h
index 44a3f56..c9a4dc9 100644
--- a/include/string_span.h
+++ b/include/string_span.h
@@ -34,8 +34,9 @@
#if _MSC_VER <= 1800
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
-#define GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER
-#define GSL_MSVC2013_EQUAL_ALGORITHM_IS_NOT_CPP14
+#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
+#define GSL_MSVC_NO_CPP14_STD_EQUAL
+#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
// noexcept is not understood
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
@@ -237,27 +238,26 @@ 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
+#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr basic_string_span(basic_string_span&& other) = default;
+#else
+ constexpr basic_string_span(basic_string_span&& other)
+ : span_(std::move(other.span_))
+ {}
#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
+#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr basic_string_span& operator=(basic_string_span&& other) = default;
+#else
+ constexpr basic_string_span& operator=(basic_string_span&& other)
+ {
+ span_ = std::move(other.span_);
+ return *this;
+ }
#endif
// from nullptr
@@ -290,74 +290,6 @@ public:
: span_(const_cast<pointer>(s.data()), narrow_cast<std::ptrdiff_t>(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<Cont>::value
- && !details::is_basic_string_span<Cont>::value
- && !(!std::is_const<value_type>::value && std::is_const<Cont>::value)
- && std::is_convertible<DataType*, value_type*>::value
- && std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().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<Cont>::value
- && !details::is_basic_string_span<Cont>::value
- && std::is_convertible<DataType*, value_type*>::value
- && std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().data())>, DataType>::value
- >* = nullptr
- ) = delete;
-
- // from span
- template<
- typename OtherValueType,
- std::ptrdiff_t... OtherDimensions,
- typename OtherBounds = static_bounds<OtherDimensions...>
- >
- constexpr basic_string_span(
- span<OtherValueType, OtherDimensions...> other,
- typename std::enable_if<
- std::is_convertible<OtherValueType, value_type>::value &&
- std::is_convertible<OtherBounds, bounds_type>::value
- >::type* = nullptr
- ) noexcept
- : span_(other)
- {}
-
- // from string_span
- template<
- typename OtherValueType,
- std::ptrdiff_t OtherExtent,
- typename OtherBounds = static_bounds<OtherExtent>
- >
- constexpr basic_string_span(
- basic_string_span<OtherValueType, OtherExtent> other,
- std::enable_if_t<
- std::is_convertible<OtherValueType*, value_type*>::value
- && std::is_convertible<OtherBounds, bounds_type>::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 <typename Cont, typename DataType = typename Cont::value_type,
typename Dummy = std::enable_if_t<!details::is_span<Cont>::value
@@ -379,14 +311,27 @@ public:
>
basic_string_span(Cont&& cont) = delete;
+#ifndef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
// from span
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
- typename OtherBounds = static_bounds<OtherExtent>,
- typename Dummy = std::enable_if_t<std::is_convertible<OtherValueType*, value_type*>::value && std::is_convertible<OtherBounds, bounds_type>::value>
+ typename Dummy = std::enable_if_t<
+ std::is_convertible<OtherValueType*, value_type*>::value
+ && std::is_convertible<static_bounds<OtherExtent>, bounds_type>::value>
>
constexpr basic_string_span(span<OtherValueType, OtherExtent> other) noexcept
: span_(other)
{}
+#else
+ // from span
+ constexpr basic_string_span(span<value_type, Extent> other) noexcept
+ : span_(other)
+ {}
+
+ template <typename Dummy = std::enable_if_t<!std::is_same<std::remove_const_t<value_type>, value_type>::value>>
+ constexpr basic_string_span(span<std::remove_const_t<value_type>, Extent> other) noexcept
+ : span_(other)
+ {}
+#endif
// from string_span
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
@@ -396,7 +341,6 @@ public:
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) noexcept
: span_(other.data(), other.length())
{}
-#endif // GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER
constexpr bool empty() const noexcept
{
@@ -556,22 +500,22 @@ std::basic_string<typename std::remove_const<CharT>::type> to_string(basic_strin
inline std::string to_string(cstring_span<> view)
{
- return{ view.data(), view.length() };
+ return{ view.data(), static_cast<size_t>(view.length()) };
}
inline std::string to_string(string_span<> view)
{
- return{ view.data(), view.length() };
+ return{ view.data(), static_cast<size_t>(view.length()) };
}
inline std::wstring to_string(cwstring_span<> view)
{
- return{ view.data(), view.length() };
+ return{ view.data(), static_cast<size_t>(view.length()) };
}
inline std::wstring to_string(wstring_span<> view)
{
- return{ view.data(), view.length() };
+ return{ view.data(), static_cast<size_t>(view.length()) };
}
#endif
@@ -622,10 +566,8 @@ template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T
bool operator==(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept
{
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
-#ifdef GSL_MSVC2013_EQUAL_ALGORITHM_IS_NOT_CPP14
- if (std::distance(one.begin(), one.end()) != std::distance(tmp.begin(), tmp.end()))
- return false;
- return std::equal(one.begin(), one.end(), tmp.begin());
+#ifdef GSL_MSVC_NO_CPP14_STD_EQUAL
+ return (one.size() == tmp.size()) && std::equal(one.begin(), one.end(), tmp.begin());
#else
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
#endif
@@ -639,10 +581,8 @@ template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T
bool operator==(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept
{
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
-#ifdef GSL_MSVC2013_EQUAL_ALGORITHM_IS_NOT_CPP14
- if (std::distance(tmp.begin(), tmp.end()) != std::distance(other.begin(), other.end()))
- return false;
- return std::equal(tmp.begin(), tmp.end(), other.begin());
+#ifdef GSL_MSVC_NO_CPP14_STD_EQUAL
+ return (tmp.size() == other.size()) && std::equal(tmp.begin(), tmp.end(), other.begin());
#else
return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end());
#endif
@@ -959,9 +899,10 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
#pragma pop_macro("noexcept")
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
-#undef GSL_MSVC2013_EQUAL_ALGORITHM_IS_NOT_CPP14
-#undef GSL_MSVC2013_ICE_WHEN_USING_DUMMY_TEMPLATE_PARAMETER
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
+#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
+#define GSL_MSVC_NO_CPP14_STD_EQUAL
+#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#endif // _MSC_VER <= 1800
#endif // _MSC_VER
@@ -975,5 +916,4 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
#endif
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
-
#endif // GSL_STRING_SPAN_H
diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp
index 18fda26..88d125a 100644
--- a/tests/string_span_tests.cpp
+++ b/tests/string_span_tests.cpp
@@ -29,7 +29,6 @@ SUITE(string_span_tests)
TEST(TestLiteralConstruction)
{
cwstring_span<> v = ensure_z(L"Hello");
-
CHECK(5 == v.length());
#ifdef CONFIRM_COMPILATION_ERRORS
@@ -118,6 +117,24 @@ SUITE(string_span_tests)
{
{
cstring_span<> span = "Hello";
+ cstring_span<> span1;
+
+ // comparison to empty span
+ CHECK(span1 != span);
+ CHECK(span != span1);
+ }
+
+ {
+ cstring_span<> span = "Hello";
+ cstring_span<> span1 = "Hello1";
+
+ // comparison to different span
+ CHECK(span1 != span);
+ CHECK(span != span1);
+ }
+
+ {
+ cstring_span<> span = "Hello";
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
const char ar1[] = "Hello";
@@ -153,9 +170,6 @@ SUITE(string_span_tests)
// comparison to string_span
CHECK(span == span);
-
- // comparison of the original data to string
- CHECK(span.data() == std::string("Hello"));
}
{
@@ -431,6 +445,22 @@ SUITE(string_span_tests)
{
// creating cstring_span
+ // from span of a final extent
+ {
+ span<const char, 6> sp = "Hello";
+ cstring_span<> span = sp;
+ CHECK(span.length() == 6);
+ }
+
+ // from const span of a final extent to non-const string_span
+#ifdef CONFIRM_COMPILATION_ERRORS
+ {
+ span<const char, 6> sp = "Hello";
+ string_span<> span = sp;
+ CHECK(span.length() == 6);
+ }
+#endif
+
// from string temporary
#ifdef CONFIRM_COMPILATION_ERRORS
{
@@ -794,7 +824,7 @@ SUITE(string_span_tests)
TEST(Conversion)
{
-#ifdef CONFIRM_COMPPILATION_ERRORS
+#ifdef CONFIRM_COMPILATION_ERRORS
cstring_span<> span = "Hello";
cwstring_span<> wspan{ span };
CHECK(wspan.length() == 5);