aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNeil MacIntosh <neilmac@fb.com>2018-03-03 19:12:45 -0800
committerGitHub <noreply@github.com>2018-03-03 19:12:45 -0800
commit6a33b97a84f9c0a60ede78b5db98647e9a48d6c9 (patch)
tree843904bdf2e4a60554a30960df4557a8ef815746 /include
parentcbd64c9ff6c45cdbf0312a1829d1f76f713403dd (diff)
downloadplatform_external_Microsoft-GSL-6a33b97a84f9c0a60ede78b5db98647e9a48d6c9.tar.gz
platform_external_Microsoft-GSL-6a33b97a84f9c0a60ede78b5db98647e9a48d6c9.tar.bz2
platform_external_Microsoft-GSL-6a33b97a84f9c0a60ede78b5db98647e9a48d6c9.zip
Fix return type of templated span.subspan() (#625)
* Added support for returning fixed-spize spans from subspan(). * Addressed issues from code review. * Took simpler approach to static data member. * Subtle fix to support MSVC 15. * Helps to not introduce extraneous >
Diffstat (limited to 'include')
-rw-r--r--include/gsl/span28
1 files changed, 26 insertions, 2 deletions
diff --git a/include/gsl/span b/include/gsl/span
index e8ccb35..22e8459 100644
--- a/include/gsl/span
+++ b/include/gsl/span
@@ -45,8 +45,17 @@
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
+#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
#endif // _MSC_VER < 1910
+#else // _MSC_VER
+
+// See if we have enough C++17 power to use a static constexpr data member
+// without needing an out-of-line definition
+#if !(defined(__cplusplus) && (__cplusplus >= 201703L))
+#define GSL_USE_STATIC_CONSTEXPR_WORKAROUND
+#endif // !(defined(__cplusplus) && (__cplusplus >= 201703L))
+
#endif // _MSC_VER
#define GSL_NOEXCEPT noexcept
@@ -302,6 +311,12 @@ namespace details
private:
index_type size_;
};
+
+ template <class ElementType, std::ptrdiff_t Extent, std::ptrdiff_t Offset, std::ptrdiff_t Count>
+ struct calculate_subspan_type
+ {
+ using type = span<ElementType, Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : Extent)>;
+ };
} // namespace details
// [span], class template span
@@ -323,7 +338,11 @@ public:
using size_type = index_type;
- constexpr static const index_type extent = Extent;
+#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
+ static constexpr const index_type extent { Extent };
+#else
+ static constexpr index_type extent { Extent };
+#endif
// [span.cons], span constructors, copy, assignment, and destructor
template <bool Dependent = false,
@@ -412,7 +431,7 @@ public:
}
template <std::ptrdiff_t Offset, std::ptrdiff_t Count = dynamic_extent>
- constexpr span<element_type, Count> subspan() const
+ constexpr auto subspan() const -> typename details::calculate_subspan_type<ElementType, Extent, Offset, Count>::type
{
Expects((Offset >= 0 && size() - Offset >= 0) &&
(Count == dynamic_extent || (Count >= 0 && Offset + Count <= size())));
@@ -525,6 +544,11 @@ private:
}
};
+#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr const typename span<ElementType, Extent>::index_type span<ElementType, Extent>::extent;
+#endif
+
// [span.comparison], span comparison operators
template <class ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent>