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:
authordmitrykobets-msft <89153909+dmitrykobets-msft@users.noreply.github.com>2022-03-22 23:20:54 +0300
committerGitHub <noreply@github.com>2022-03-22 23:20:54 +0300
commit383723676cd548d615159701ac3d050f8dd1e128 (patch)
treeab9ed33ee235acf25b15d24a5978f8b8dc55a34a
parentf22f524aa2d5e5ad334bcf88c69ffdb5636deed9 (diff)
Make gsl::span's iterators use the contiguous_iterator concept (#1035)
Resolves #1016 Co-authored-by: Casey Carter <Casey@Carter.net>
-rw-r--r--include/gsl/span24
-rw-r--r--tests/span_tests.cpp20
2 files changed, 44 insertions, 0 deletions
diff --git a/include/gsl/span b/include/gsl/span
index 5488f52..4413a4d 100644
--- a/include/gsl/span
+++ b/include/gsl/span
@@ -25,8 +25,13 @@
#include <array> // for array
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t
#include <iterator> // for reverse_iterator, distance, random_access_...
+#include <memory> // for pointer_traits
#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
+#if defined(__has_include) && __has_include(<version>)
+#include <version>
+#endif
+
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
@@ -110,6 +115,9 @@ namespace details
class span_iterator
{
public:
+#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
+ using iterator_concept = std::contiguous_iterator_tag;
+#endif // __cpp_lib_ranges
using iterator_category = std::random_access_iterator_tag;
using value_type = std::remove_cv_t<Type>;
using difference_type = std::ptrdiff_t;
@@ -329,8 +337,24 @@ namespace details
pointer begin_ = nullptr;
pointer end_ = nullptr;
pointer current_ = nullptr;
+
+ template <typename Ptr>
+ friend struct std::pointer_traits;
};
+}} // namespace gsl::details
+
+template <class Type>
+struct std::pointer_traits<::gsl::details::span_iterator<Type>> {
+ using pointer = ::gsl::details::span_iterator<Type>;
+ using element_type = Type;
+ using difference_type = ptrdiff_t;
+
+ static constexpr element_type* to_address(const pointer i) noexcept {
+ return i.current_;
+ }
+};
+namespace gsl { namespace details {
template <std::size_t Ext>
class extent_type
{
diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp
index 33ccf56..41ac3ae 100644
--- a/tests/span_tests.cpp
+++ b/tests/span_tests.cpp
@@ -40,6 +40,9 @@
#endif // __has_include(<string_view>)
#endif // __has_include
#endif // (defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L))
+#if defined(__cplusplus) && __cplusplus >= 202002L
+#include <span>
+#endif // __cplusplus >= 202002L
#include "deathTestCommon.h"
@@ -1297,3 +1300,20 @@ TEST(span_test, front_back)
EXPECT_DEATH(s2.front(), expected);
EXPECT_DEATH(s2.back(), expected);
}
+
+#if defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
+TEST(span_test, std_span)
+{
+ // make sure std::span can be constructed from gsl::span
+ int arr[5] = {1, 2, 3, 4, 5};
+ gsl::span<int> gsl_span{arr};
+#if defined(__cpp_lib_ranges) || (defined(_MSVC_STL_VERSION) && defined(__cpp_lib_concepts))
+ EXPECT_TRUE(std::to_address(gsl_span.begin()) == gsl_span.data());
+ EXPECT_TRUE(std::to_address(gsl_span.end()) == gsl_span.data() + gsl_span.size());
+#endif // __cpp_lib_ranges
+
+ std::span<int> std_span = gsl_span;
+ EXPECT_TRUE(std_span.data() == gsl_span.data());
+ EXPECT_TRUE(std_span.size() == gsl_span.size());
+}
+#endif // defined(FORCE_STD_SPAN_TESTS) || defined(__cpp_lib_span) && __cpp_lib_span >= 202002L