diff --git a/include/gsl/gsl b/include/gsl/gsl
new file mode 100644
index 0000000..55862eb
--- /dev/null
+++ b/include/gsl/gsl
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_GSL_H
+#define GSL_GSL_H
+
+#include <gsl/gsl_algorithm> // copy
+#include <gsl/gsl_assert>    // Ensures/Expects
+#include <gsl/gsl_byte>      // byte
+#include <gsl/gsl_util>      // finally()/narrow()/narrow_cast()...
+#include <gsl/multi_span>    // multi_span, strided_span...
+#include <gsl/pointers>      // owner, not_null
+#include <gsl/span>          // span
+#include <gsl/string_span>   // zstring, string_span, zstring_builder...
+
+#endif // GSL_GSL_H
diff --git a/include/gsl/gsl_algorithm b/include/gsl/gsl_algorithm
new file mode 100644
index 0000000..710792f
--- /dev/null
+++ b/include/gsl/gsl_algorithm
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_ALGORITHM_H
+#define GSL_ALGORITHM_H
+
+#include <gsl/gsl_assert> // for Expects
+#include <gsl/span>       // for dynamic_extent, span
+
+#include <algorithm>   // for copy_n
+#include <cstddef>     // for ptrdiff_t
+#include <type_traits> // for is_assignable
+
+#ifdef _MSC_VER
+#pragma warning(push)
+
+// turn off some warnings that are noisy about our Expects statements
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4996) // unsafe use of std::copy_n
+
+// blanket turn off warnings from CppCoreCheck for now
+// so people aren't annoyed by them when running the tool.
+// more targeted suppressions will be added in a future update to the GSL
+#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
+#endif // _MSC_VER
+
+namespace gsl
+{
+
+template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType,
+          std::ptrdiff_t DestExtent>
+void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
+{
+    static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
+                  "Elements of source span can not be assigned to elements of destination span");
+    static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent ||
+                      (SrcExtent <= DestExtent),
+                  "Source range is longer than target range");
+
+    Expects(dest.size() >= src.size());
+    std::copy_n(src.data(), src.size(), dest.data());
+}
+
+} // namespace gsl
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+#endif // GSL_ALGORITHM_H
diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert
new file mode 100644
index 0000000..131fa8b
--- /dev/null
+++ b/include/gsl/gsl_assert
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_CONTRACTS_H
+#define GSL_CONTRACTS_H
+
+#include <exception>
+#include <stdexcept> // for logic_error
+
+//
+// Temporary until MSVC STL supports no-exceptions mode.
+// Currently terminate is a no-op in this mode, so we add termination behavior back
+//
+#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
+#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
+#endif
+
+//
+// There are three configuration options for this GSL implementation's behavior
+// when pre/post conditions on the GSL types are violated:
+//
+// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
+// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
+// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
+//
+#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ||  \
+      defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
+#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
+#endif
+
+#define GSL_STRINGIFY_DETAIL(x) #x
+#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
+
+#if defined(__clang__) || defined(__GNUC__)
+#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
+#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+#define GSL_LIKELY(x) (!!(x))
+#define GSL_UNLIKELY(x) (!!(x))
+#endif
+
+//
+// GSL_ASSUME(cond)
+//
+// Tell the optimizer that the predicate cond must hold. It is unspecified
+// whether or not cond is actually evaluated.
+//
+#ifdef _MSC_VER
+#define GSL_ASSUME(cond) __assume(cond)
+#elif defined(__GNUC__)
+#define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable())
+#else
+#define GSL_ASSUME(cond) static_cast<void>((cond) ? 0 : 0)
+#endif
+
+//
+// GSL.assert: assertions
+//
+
+namespace gsl
+{
+struct fail_fast : public std::logic_error
+{
+    explicit fail_fast(char const* const message) : std::logic_error(message) {}
+};
+
+namespace details
+{
+#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
+
+    typedef void  (__cdecl *terminate_handler)();
+
+    inline gsl::details::terminate_handler& get_terminate_handler() noexcept
+    {
+        static terminate_handler handler = &abort;
+        return handler;
+    }
+
+#endif
+
+    [[noreturn]] inline void terminate() noexcept
+    {
+#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
+        (*gsl::details::get_terminate_handler())();
+#else
+        std::terminate();
+#endif
+    }
+
+#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
+
+    template <typename Exception>
+    [[noreturn]] void throw_exception(Exception&&)
+    {
+        gsl::details::terminate();
+    }
+
+#else
+
+    template <typename Exception>
+    [[noreturn]] void throw_exception(Exception&& exception)
+    {
+        throw std::forward<Exception>(exception);
+    }
+
+#endif
+
+} // namespace details
+} // namespace gsl
+
+#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
+
+#define GSL_CONTRACT_CHECK(type, cond)                                                             \
+    (GSL_LIKELY(cond) ? static_cast<void>(0)                                                       \
+                      : gsl::details::throw_exception(gsl::fail_fast(                              \
+                            "GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__))))
+
+#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
+
+#define GSL_CONTRACT_CHECK(type, cond)                                                             \
+    (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
+
+#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
+
+#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
+
+#endif
+
+#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
+#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
+
+#endif // GSL_CONTRACTS_H
diff --git a/include/gsl/gsl_byte b/include/gsl/gsl_byte
new file mode 100644
index 0000000..e861173
--- /dev/null
+++ b/include/gsl/gsl_byte
@@ -0,0 +1,181 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_BYTE_H
+#define GSL_BYTE_H
+
+#include <type_traits>
+
+#ifdef _MSC_VER
+
+#pragma warning(push)
+
+// don't warn about function style casts in byte related operators
+#pragma warning(disable : 26493)
+
+#ifndef GSL_USE_STD_BYTE
+// this tests if we are under MSVC and the standard lib has std::byte and it is enabled
+#if defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
+
+#define GSL_USE_STD_BYTE 1
+
+#else // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
+
+#define GSL_USE_STD_BYTE 0
+
+#endif // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
+#endif // GSL_USE_STD_BYTE
+
+#else // _MSC_VER
+
+#ifndef GSL_USE_STD_BYTE
+// this tests if we are under GCC or Clang with enough -std:c++1z power to get us std::byte
+#if defined(__cplusplus) && (__cplusplus >= 201703L)
+
+#define GSL_USE_STD_BYTE 1
+#include <cstddef>
+
+#else // defined(__cplusplus) && (__cplusplus >= 201703L)
+
+#define GSL_USE_STD_BYTE 0
+
+#endif //defined(__cplusplus) && (__cplusplus >= 201703L)
+#endif // GSL_USE_STD_BYTE
+
+#endif           // _MSC_VER
+
+// Use __may_alias__ attribute on gcc and clang
+#if defined __clang__ || (__GNUC__ > 5)
+#define byte_may_alias __attribute__((__may_alias__))
+#else // defined __clang__ || defined __GNUC__
+#define byte_may_alias
+#endif // defined __clang__ || defined __GNUC__
+
+namespace gsl
+{
+#if GSL_USE_STD_BYTE
+
+
+using std::byte;
+using std::to_integer;
+
+#else // GSL_USE_STD_BYTE
+
+// This is a simple definition for now that allows
+// use of byte within span<> to be standards-compliant
+enum class byte_may_alias byte : unsigned char
+{
+};
+
+template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
+constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
+{
+    return b = byte(static_cast<unsigned char>(b) << shift);
+}
+
+template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
+constexpr byte operator<<(byte b, IntegerType shift) noexcept
+{
+    return byte(static_cast<unsigned char>(b) << shift);
+}
+
+template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
+constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
+{
+    return b = byte(static_cast<unsigned char>(b) >> shift);
+}
+
+template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
+constexpr byte operator>>(byte b, IntegerType shift) noexcept
+{
+    return byte(static_cast<unsigned char>(b) >> shift);
+}
+
+constexpr byte& operator|=(byte& l, byte r) noexcept
+{
+    return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
+}
+
+constexpr byte operator|(byte l, byte r) noexcept
+{
+    return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
+}
+
+constexpr byte& operator&=(byte& l, byte r) noexcept
+{
+    return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
+}
+
+constexpr byte operator&(byte l, byte r) noexcept
+{
+    return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
+}
+
+constexpr byte& operator^=(byte& l, byte r) noexcept
+{
+    return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
+}
+
+constexpr byte operator^(byte l, byte r) noexcept
+{
+    return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
+}
+
+constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); }
+
+template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
+constexpr IntegerType to_integer(byte b) noexcept
+{
+    return static_cast<IntegerType>(b);
+}
+
+#endif // GSL_USE_STD_BYTE
+
+template <bool E, typename T>
+constexpr byte to_byte_impl(T t) noexcept
+{
+    static_assert(
+        E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
+           "If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version.");
+    return static_cast<byte>(t);
+}
+template <>
+constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
+{
+    return byte(t);
+}
+
+template <typename T>
+constexpr byte to_byte(T t) noexcept
+{
+    return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t);
+}
+
+template <int I>
+constexpr byte to_byte() noexcept
+{
+    static_assert(I >= 0 && I <= 255,
+                  "gsl::byte only has 8 bits of storage, values must be in range 0-255");
+    return static_cast<byte>(I);
+}
+
+} // namespace gsl
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+#endif // GSL_BYTE_H
diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util
new file mode 100644
index 0000000..25f8502
--- /dev/null
+++ b/include/gsl/gsl_util
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_UTIL_H
+#define GSL_UTIL_H
+
+#include <gsl/gsl_assert> // for Expects
+
+#include <array>
+#include <cstddef>          // for ptrdiff_t, size_t
+#include <exception>        // for exception
+#include <initializer_list> // for initializer_list
+#include <type_traits>      // for is_signed, integral_constant
+#include <utility>          // for forward
+
+#if defined(_MSC_VER)
+
+#pragma warning(push)
+#pragma warning(disable : 4127) // conditional expression is constant
+
+#if _MSC_VER < 1910
+#pragma push_macro("constexpr")
+#define constexpr /*constexpr*/
+#endif                          // _MSC_VER < 1910
+#endif                          // _MSC_VER
+
+namespace gsl
+{
+//
+// GSL.util: utilities
+//
+
+// index type for all container indexes/subscripts/sizes
+using index = std::ptrdiff_t;
+
+// final_action allows you to ensure something gets run at the end of a scope
+template <class F>
+class final_action
+{
+public:
+    explicit final_action(F f) noexcept : f_(std::move(f)) {}
+
+    final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
+    {
+        other.invoke_ = false;
+    }
+
+    final_action(const final_action&) = delete;
+    final_action& operator=(const final_action&) = delete;
+    final_action& operator=(final_action&&) = delete;
+
+    ~final_action() noexcept
+    {
+        if (invoke_) f_();
+    }
+
+private:
+    F f_;
+    bool invoke_ {true};
+};
+
+// finally() - convenience function to generate a final_action
+template <class F>
+
+final_action<F> finally(const F& f) noexcept
+{
+    return final_action<F>(f);
+}
+
+template <class F>
+final_action<F> finally(F&& f) noexcept
+{
+    return final_action<F>(std::forward<F>(f));
+}
+
+// narrow_cast(): a searchable way to do narrowing casts of values
+template <class T, class U>
+constexpr T narrow_cast(U&& u) noexcept
+{
+    return static_cast<T>(std::forward<U>(u));
+}
+
+struct narrowing_error : public std::exception
+{
+};
+
+namespace details
+{
+    template <class T, class U>
+    struct is_same_signedness
+        : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
+    {
+    };
+}
+
+// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
+template <class T, class U>
+T narrow(U u)
+{
+    T t = narrow_cast<T>(u);
+    if (static_cast<U>(t) != u) gsl::details::throw_exception(narrowing_error());
+    if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
+        gsl::details::throw_exception(narrowing_error());
+    return t;
+}
+
+//
+// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
+//
+template <class T, std::size_t N>
+constexpr T& at(T (&arr)[N], const index i)
+{
+    Expects(i >= 0 && i < narrow_cast<index>(N));
+    return arr[static_cast<std::size_t>(i)];
+}
+
+template <class Cont>
+constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
+{
+    Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
+    using size_type = decltype(cont.size());
+    return cont[static_cast<size_type>(i)];
+}
+
+template <class T>
+constexpr T at(const std::initializer_list<T> cont, const index i)
+{
+    Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
+    return *(cont.begin() + i);
+}
+
+} // namespace gsl
+
+#if defined(_MSC_VER)
+#if _MSC_VER < 1910
+#undef constexpr
+#pragma pop_macro("constexpr")
+
+#endif // _MSC_VER < 1910
+
+#pragma warning(pop)
+
+#endif // _MSC_VER
+
+#endif // GSL_UTIL_H
diff --git a/include/gsl/multi_span b/include/gsl/multi_span
new file mode 100644
index 0000000..9c0c27b
--- /dev/null
+++ b/include/gsl/multi_span
@@ -0,0 +1,2242 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_MULTI_SPAN_H
+#define GSL_MULTI_SPAN_H
+
+#include <gsl/gsl_assert> // for Expects
+#include <gsl/gsl_byte>   // for byte
+#include <gsl/gsl_util>   // for narrow_cast
+
+#include <algorithm> // for transform, lexicographical_compare
+#include <array>     // for array
+#include <cassert>
+#include <cstddef>          // for ptrdiff_t, size_t, nullptr_t
+#include <cstdint>          // for PTRDIFF_MAX
+#include <functional>       // for divides, multiplies, minus, negate, plus
+#include <initializer_list> // for initializer_list
+#include <iterator>         // for iterator, random_access_iterator_tag
+#include <limits>           // for numeric_limits
+#include <new>
+#include <numeric>
+#include <stdexcept>
+#include <string>      // for basic_string
+#include <type_traits> // for enable_if_t, remove_cv_t, is_same, is_co...
+#include <utility>
+
+#ifdef _MSC_VER
+
+// turn off some warnings that are noisy about our Expects statements
+#pragma warning(push)
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4702) // unreachable code
+
+#if _MSC_VER < 1910
+#pragma push_macro("constexpr")
+#define constexpr /*constexpr*/
+
+#endif                          // _MSC_VER < 1910
+#endif                          // _MSC_VER
+
+// GCC 7 does not like the signed unsigned missmatch (size_t ptrdiff_t)
+// While there is a conversion from signed to unsigned, it happens at 
+// compiletime, so the compiler wouldn't have to warn indiscriminently, but 
+// could check if the source value actually doesn't fit into the target type 
+// and only warn in those cases.
+#if __GNUC__ > 6
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#endif
+
+#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
+#define GSL_NOEXCEPT /*noexcept*/
+#else
+#define GSL_NOEXCEPT noexcept
+#endif // GSL_THROW_ON_CONTRACT_VIOLATION
+
+namespace gsl
+{
+
+/*
+** begin definitions of index and bounds
+*/
+namespace details
+{
+    template <typename SizeType>
+    struct SizeTypeTraits
+    {
+        static const SizeType max_value = std::numeric_limits<SizeType>::max();
+    };
+
+    template <typename... Ts>
+    class are_integral : public std::integral_constant<bool, true>
+    {
+    };
+
+    template <typename T, typename... Ts>
+    class are_integral<T, Ts...>
+        : public std::integral_constant<bool,
+                                        std::is_integral<T>::value && are_integral<Ts...>::value>
+    {
+    };
+}
+
+template <std::size_t Rank>
+class multi_span_index final
+{
+    static_assert(Rank > 0, "Rank must be greater than 0!");
+
+    template <std::size_t OtherRank>
+    friend class multi_span_index;
+
+public:
+    static const std::size_t rank = Rank;
+    using value_type = std::ptrdiff_t;
+    using size_type = value_type;
+    using reference = std::add_lvalue_reference_t<value_type>;
+    using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>;
+
+    constexpr multi_span_index() GSL_NOEXCEPT {}
+
+    constexpr multi_span_index(const value_type (&values)[Rank]) GSL_NOEXCEPT
+    {
+        std::copy(values, values + Rank, elems);
+    }
+
+    template <typename... Ts, typename = std::enable_if_t<(sizeof...(Ts) == Rank) &&
+                                                          details::are_integral<Ts...>::value>>
+    constexpr multi_span_index(Ts... ds) GSL_NOEXCEPT : elems{narrow_cast<value_type>(ds)...}
+    {
+    }
+
+    constexpr multi_span_index(const multi_span_index& other) GSL_NOEXCEPT = default;
+
+    constexpr multi_span_index& operator=(const multi_span_index& rhs) GSL_NOEXCEPT = default;
+
+    // Preconditions: component_idx < rank
+    constexpr reference operator[](std::size_t component_idx)
+    {
+        Expects(component_idx < Rank); // Component index must be less than rank
+        return elems[component_idx];
+    }
+
+    // Preconditions: component_idx < rank
+    constexpr const_reference operator[](std::size_t component_idx) const GSL_NOEXCEPT
+    {
+        Expects(component_idx < Rank); // Component index must be less than rank
+        return elems[component_idx];
+    }
+
+    constexpr bool operator==(const multi_span_index& rhs) const GSL_NOEXCEPT
+    {
+        return std::equal(elems, elems + rank, rhs.elems);
+    }
+
+    constexpr bool operator!=(const multi_span_index& rhs) const GSL_NOEXCEPT { return !(*this == rhs); }
+
+    constexpr multi_span_index operator+() const GSL_NOEXCEPT { return *this; }
+
+    constexpr multi_span_index operator-() const GSL_NOEXCEPT
+    {
+        multi_span_index ret = *this;
+        std::transform(ret, ret + rank, ret, std::negate<value_type>{});
+        return ret;
+    }
+
+    constexpr multi_span_index operator+(const multi_span_index& rhs) const GSL_NOEXCEPT
+    {
+        multi_span_index ret = *this;
+        ret += rhs;
+        return ret;
+    }
+
+    constexpr multi_span_index operator-(const multi_span_index& rhs) const GSL_NOEXCEPT
+    {
+        multi_span_index ret = *this;
+        ret -= rhs;
+        return ret;
+    }
+
+    constexpr multi_span_index& operator+=(const multi_span_index& rhs) GSL_NOEXCEPT
+    {
+        std::transform(elems, elems + rank, rhs.elems, elems, std::plus<value_type>{});
+        return *this;
+    }
+
+    constexpr multi_span_index& operator-=(const multi_span_index& rhs) GSL_NOEXCEPT
+    {
+        std::transform(elems, elems + rank, rhs.elems, elems, std::minus<value_type>{});
+        return *this;
+    }
+
+    constexpr multi_span_index operator*(value_type v) const GSL_NOEXCEPT
+    {
+        multi_span_index ret = *this;
+        ret *= v;
+        return ret;
+    }
+
+    constexpr multi_span_index operator/(value_type v) const GSL_NOEXCEPT
+    {
+        multi_span_index ret = *this;
+        ret /= v;
+        return ret;
+    }
+
+    friend constexpr multi_span_index operator*(value_type v, const multi_span_index& rhs) GSL_NOEXCEPT
+    {
+        return rhs * v;
+    }
+
+    constexpr multi_span_index& operator*=(value_type v) GSL_NOEXCEPT
+    {
+        std::transform(elems, elems + rank, elems,
+                       [v](value_type x) { return std::multiplies<value_type>{}(x, v); });
+        return *this;
+    }
+
+    constexpr multi_span_index& operator/=(value_type v) GSL_NOEXCEPT
+    {
+        std::transform(elems, elems + rank, elems,
+                       [v](value_type x) { return std::divides<value_type>{}(x, v); });
+        return *this;
+    }
+
+private:
+    value_type elems[Rank] = {};
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1910
+
+struct static_bounds_dynamic_range_t
+{
+    template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+    constexpr operator T() const GSL_NOEXCEPT
+    {
+        return narrow_cast<T>(-1);
+    }
+};
+
+constexpr bool operator==(static_bounds_dynamic_range_t, static_bounds_dynamic_range_t) GSL_NOEXCEPT
+{
+    return true;
+}
+
+constexpr bool operator!=(static_bounds_dynamic_range_t, static_bounds_dynamic_range_t) GSL_NOEXCEPT
+{
+    return false;
+}
+
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+constexpr bool operator==(static_bounds_dynamic_range_t, T other) GSL_NOEXCEPT
+{
+    return narrow_cast<T>(-1) == other;
+}
+
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+constexpr bool operator==(T left, static_bounds_dynamic_range_t right) GSL_NOEXCEPT
+{
+    return right == left;
+}
+
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+constexpr bool operator!=(static_bounds_dynamic_range_t, T other) GSL_NOEXCEPT
+{
+    return narrow_cast<T>(-1) != other;
+}
+
+template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+constexpr bool operator!=(T left, static_bounds_dynamic_range_t right) GSL_NOEXCEPT
+{
+    return right != left;
+}
+
+constexpr static_bounds_dynamic_range_t dynamic_range{};
+#else
+const std::ptrdiff_t dynamic_range = -1;
+#endif
+
+struct generalized_mapping_tag
+{
+};
+struct contiguous_mapping_tag : generalized_mapping_tag
+{
+};
+
+namespace details
+{
+
+    template <std::ptrdiff_t Left, std::ptrdiff_t Right>
+    struct LessThan
+    {
+        static const bool value = Left < Right;
+    };
+
+    template <std::ptrdiff_t... Ranges>
+    struct BoundsRanges
+    {
+        using size_type = std::ptrdiff_t;
+        static const size_type Depth = 0;
+        static const size_type DynamicNum = 0;
+        static const size_type CurrentRange = 1;
+        static const size_type TotalSize = 1;
+
+        // TODO : following signature is for work around VS bug
+        template <typename OtherRange>
+        BoundsRanges(const OtherRange&, bool /* firstLevel */)
+        {
+        }
+
+        BoundsRanges(const std::ptrdiff_t* const) {}
+        BoundsRanges() = default;
+
+        template <typename T, std::size_t Dim>
+        void serialize(T&) const
+        {
+        }
+
+        template <typename T, std::size_t Dim>
+        size_type linearize(const T&) const
+        {
+            return 0;
+        }
+
+        template <typename T, std::size_t Dim>
+        size_type contains(const T&) const
+        {
+            return -1;
+        }
+
+        size_type elementNum(std::size_t) const GSL_NOEXCEPT { return 0; }
+
+        size_type totalSize() const GSL_NOEXCEPT { return TotalSize; }
+
+        bool operator==(const BoundsRanges&) const GSL_NOEXCEPT { return true; }
+    };
+
+    template <std::ptrdiff_t... RestRanges>
+    struct BoundsRanges<dynamic_range, RestRanges...> : BoundsRanges<RestRanges...>
+    {
+        using Base = BoundsRanges<RestRanges...>;
+        using size_type = std::ptrdiff_t;
+        static const std::size_t Depth = Base::Depth + 1;
+        static const std::size_t DynamicNum = Base::DynamicNum + 1;
+        static const size_type CurrentRange = dynamic_range;
+        static const size_type TotalSize = dynamic_range;
+
+    private:
+        size_type m_bound;
+
+    public:
+        BoundsRanges(const std::ptrdiff_t* const arr)
+            : Base(arr + 1), m_bound(*arr * this->Base::totalSize())
+        {
+            Expects(0 <= *arr);
+        }
+
+        BoundsRanges() : m_bound(0) {}
+
+        template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
+        BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
+                     bool /* firstLevel */ = true)
+            : Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
+            , m_bound(other.totalSize())
+        {
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        void serialize(T& arr) const
+        {
+            arr[Dim] = elementNum();
+            this->Base::template serialize<T, Dim + 1>(arr);
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        size_type linearize(const T& arr) const
+        {
+            const size_type index = this->Base::totalSize() * arr[Dim];
+            Expects(index < m_bound);
+            return index + this->Base::template linearize<T, Dim + 1>(arr);
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        size_type contains(const T& arr) const
+        {
+            const ptrdiff_t last = this->Base::template contains<T, Dim + 1>(arr);
+            if (last == -1) return -1;
+            const ptrdiff_t cur = this->Base::totalSize() * arr[Dim];
+            return cur < m_bound ? cur + last : -1;
+        }
+
+        size_type totalSize() const GSL_NOEXCEPT { return m_bound; }
+
+        size_type elementNum() const GSL_NOEXCEPT { return totalSize() / this->Base::totalSize(); }
+
+        size_type elementNum(std::size_t dim) const GSL_NOEXCEPT
+        {
+            if (dim > 0)
+                return this->Base::elementNum(dim - 1);
+            else
+                return elementNum();
+        }
+
+        bool operator==(const BoundsRanges& rhs) const GSL_NOEXCEPT
+        {
+            return m_bound == rhs.m_bound &&
+                   static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
+        }
+    };
+
+    template <std::ptrdiff_t CurRange, std::ptrdiff_t... RestRanges>
+    struct BoundsRanges<CurRange, RestRanges...> : BoundsRanges<RestRanges...>
+    {
+        using Base = BoundsRanges<RestRanges...>;
+        using size_type = std::ptrdiff_t;
+        static const std::size_t Depth = Base::Depth + 1;
+        static const std::size_t DynamicNum = Base::DynamicNum;
+        static const size_type CurrentRange = CurRange;
+        static const size_type TotalSize =
+            Base::TotalSize == dynamic_range ? dynamic_range : CurrentRange * Base::TotalSize;
+
+        BoundsRanges(const std::ptrdiff_t* const arr) : Base(arr) {}
+        BoundsRanges() = default;
+
+        template <std::ptrdiff_t OtherRange, std::ptrdiff_t... RestOtherRanges>
+        BoundsRanges(const BoundsRanges<OtherRange, RestOtherRanges...>& other,
+                     bool firstLevel = true)
+            : Base(static_cast<const BoundsRanges<RestOtherRanges...>&>(other), false)
+        {
+            (void) firstLevel;
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        void serialize(T& arr) const
+        {
+            arr[Dim] = elementNum();
+            this->Base::template serialize<T, Dim + 1>(arr);
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        size_type linearize(const T& arr) const
+        {
+            Expects(arr[Dim] >= 0 && arr[Dim] < CurrentRange); // Index is out of range
+            return this->Base::totalSize() * arr[Dim] +
+                   this->Base::template linearize<T, Dim + 1>(arr);
+        }
+
+        template <typename T, std::size_t Dim = 0>
+        size_type contains(const T& arr) const
+        {
+            if (arr[Dim] >= CurrentRange) return -1;
+            const size_type last = this->Base::template contains<T, Dim + 1>(arr);
+            if (last == -1) return -1;
+            return this->Base::totalSize() * arr[Dim] + last;
+        }
+
+        size_type totalSize() const GSL_NOEXCEPT { return CurrentRange * this->Base::totalSize(); }
+
+        size_type elementNum() const GSL_NOEXCEPT { return CurrentRange; }
+
+        size_type elementNum(std::size_t dim) const GSL_NOEXCEPT
+        {
+            if (dim > 0)
+                return this->Base::elementNum(dim - 1);
+            else
+                return elementNum();
+        }
+
+        bool operator==(const BoundsRanges& rhs) const GSL_NOEXCEPT
+        {
+            return static_cast<const Base&>(*this) == static_cast<const Base&>(rhs);
+        }
+    };
+
+    template <typename SourceType, typename TargetType>
+    struct BoundsRangeConvertible
+        : public std::integral_constant<bool, (SourceType::TotalSize >= TargetType::TotalSize ||
+                                               TargetType::TotalSize == dynamic_range ||
+                                               SourceType::TotalSize == dynamic_range ||
+                                               TargetType::TotalSize == 0)>
+    {
+    };
+
+    template <typename TypeChain>
+    struct TypeListIndexer
+    {
+        const TypeChain& obj_;
+        TypeListIndexer(const TypeChain& obj) : obj_(obj) {}
+
+        template <std::size_t N>
+        const TypeChain& getObj(std::true_type)
+        {
+            return obj_;
+        }
+
+        template <std::size_t N, typename MyChain = TypeChain,
+                  typename MyBase = typename MyChain::Base>
+        auto getObj(std::false_type)
+            -> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
+        {
+            return TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>();
+        }
+
+        template <std::size_t N>
+        auto get() -> decltype(getObj<N - 1>(std::integral_constant<bool, N == 0>()))
+        {
+            return getObj<N - 1>(std::integral_constant<bool, N == 0>());
+        }
+    };
+
+    template <typename TypeChain>
+    TypeListIndexer<TypeChain> createTypeListIndexer(const TypeChain& obj)
+    {
+        return TypeListIndexer<TypeChain>(obj);
+    }
+
+    template <std::size_t Rank, bool Enabled = (Rank > 1),
+              typename Ret = std::enable_if_t<Enabled, multi_span_index<Rank - 1>>>
+    constexpr Ret shift_left(const multi_span_index<Rank>& other) GSL_NOEXCEPT
+    {
+        Ret ret{};
+        for (std::size_t i = 0; i < Rank - 1; ++i) {
+            ret[i] = other[i + 1];
+        }
+        return ret;
+    }
+}
+
+template <typename IndexType>
+class bounds_iterator;
+
+template <std::ptrdiff_t... Ranges>
+class static_bounds
+{
+public:
+    static_bounds(const details::BoundsRanges<Ranges...>&) {}
+};
+
+template <std::ptrdiff_t FirstRange, std::ptrdiff_t... RestRanges>
+class static_bounds<FirstRange, RestRanges...>
+{
+    using MyRanges = details::BoundsRanges<FirstRange, RestRanges...>;
+
+    MyRanges m_ranges;
+    constexpr static_bounds(const MyRanges& range) : m_ranges(range) {}
+
+    template <std::ptrdiff_t... OtherRanges>
+    friend class static_bounds;
+
+public:
+    static const std::size_t rank = MyRanges::Depth;
+    static const std::size_t dynamic_rank = MyRanges::DynamicNum;
+    static const std::ptrdiff_t static_size = MyRanges::TotalSize;
+
+    using size_type = std::ptrdiff_t;
+    using index_type = multi_span_index<rank>;
+    using const_index_type = std::add_const_t<index_type>;
+    using iterator = bounds_iterator<const_index_type>;
+    using const_iterator = bounds_iterator<const_index_type>;
+    using difference_type = std::ptrdiff_t;
+    using sliced_type = static_bounds<RestRanges...>;
+    using mapping_type = contiguous_mapping_tag;
+
+    constexpr static_bounds(const static_bounds&) = default;
+
+    template <typename SourceType, typename TargetType, std::size_t Rank>
+    struct BoundsRangeConvertible2;
+
+    template <std::size_t Rank, typename SourceType, typename TargetType,
+              typename Ret = BoundsRangeConvertible2<typename SourceType::Base,
+                                                     typename TargetType::Base, Rank>>
+    static auto helpBoundsRangeConvertible(SourceType, TargetType, std::true_type) -> Ret;
+
+    template <std::size_t Rank, typename SourceType, typename TargetType>
+    static auto helpBoundsRangeConvertible(SourceType, TargetType, ...) -> std::false_type;
+
+    template <typename SourceType, typename TargetType, std::size_t Rank>
+    struct BoundsRangeConvertible2
+        : decltype(helpBoundsRangeConvertible<Rank - 1>(
+              SourceType(), TargetType(),
+              std::integral_constant<bool,
+                                     SourceType::Depth == TargetType::Depth &&
+                                         (SourceType::CurrentRange == TargetType::CurrentRange ||
+                                          TargetType::CurrentRange == dynamic_range ||
+                                          SourceType::CurrentRange == dynamic_range)>()))
+    {
+    };
+
+    template <typename SourceType, typename TargetType>
+    struct BoundsRangeConvertible2<SourceType, TargetType, 0> : std::true_type
+    {
+    };
+
+    template <typename SourceType, typename TargetType, std::ptrdiff_t Rank = TargetType::Depth>
+    struct BoundsRangeConvertible
+        : decltype(helpBoundsRangeConvertible<Rank - 1>(
+              SourceType(), TargetType(),
+              std::integral_constant<bool,
+                                     SourceType::Depth == TargetType::Depth &&
+                                         (!details::LessThan<SourceType::CurrentRange,
+                                                             TargetType::CurrentRange>::value ||
+                                          TargetType::CurrentRange == dynamic_range ||
+                                          SourceType::CurrentRange == dynamic_range)>()))
+    {
+    };
+
+    template <typename SourceType, typename TargetType>
+    struct BoundsRangeConvertible<SourceType, TargetType, 0> : std::true_type
+    {
+    };
+
+    template <std::ptrdiff_t... Ranges,
+              typename = std::enable_if_t<details::BoundsRangeConvertible<
+                  details::BoundsRanges<Ranges...>,
+                  details::BoundsRanges<FirstRange, RestRanges...>>::value>>
+    constexpr static_bounds(const static_bounds<Ranges...>& other) : m_ranges(other.m_ranges)
+    {
+        Expects((MyRanges::DynamicNum == 0 && details::BoundsRanges<Ranges...>::DynamicNum == 0) ||
+                MyRanges::DynamicNum > 0 || other.m_ranges.totalSize() >= m_ranges.totalSize());
+    }
+
+    constexpr static_bounds(std::initializer_list<size_type> il)
+        : m_ranges(il.begin())
+    {
+        // Size of the initializer list must match the rank of the array
+        Expects((MyRanges::DynamicNum == 0 && il.size() == 1 && *il.begin() == static_size) ||
+                MyRanges::DynamicNum == il.size());
+        // Size of the range must be less than the max element of the size type
+        Expects(m_ranges.totalSize() <= PTRDIFF_MAX);
+    }
+
+    constexpr static_bounds() = default;
+
+    constexpr sliced_type slice() const GSL_NOEXCEPT
+    {
+        return sliced_type{static_cast<const details::BoundsRanges<RestRanges...>&>(m_ranges)};
+    }
+
+    constexpr size_type stride() const GSL_NOEXCEPT { return rank > 1 ? slice().size() : 1; }
+
+    constexpr size_type size() const GSL_NOEXCEPT { return m_ranges.totalSize(); }
+
+    constexpr size_type total_size() const GSL_NOEXCEPT { return m_ranges.totalSize(); }
+
+    constexpr size_type linearize(const index_type& idx) const { return m_ranges.linearize(idx); }
+
+    constexpr bool contains(const index_type& idx) const GSL_NOEXCEPT
+    {
+        return m_ranges.contains(idx) != -1;
+    }
+
+    constexpr size_type operator[](std::size_t idx) const GSL_NOEXCEPT
+    {
+        return m_ranges.elementNum(idx);
+    }
+
+    template <std::size_t Dim = 0>
+    constexpr size_type extent() const GSL_NOEXCEPT
+    {
+        static_assert(Dim < rank,
+                      "dimension should be less than rank (dimension count starts from 0)");
+        return details::createTypeListIndexer(m_ranges).template get<Dim>().elementNum();
+    }
+
+    template <typename IntType>
+    constexpr size_type extent(IntType dim) const GSL_NOEXCEPT
+    {
+        static_assert(std::is_integral<IntType>::value,
+                      "Dimension parameter must be supplied as an integral type.");
+        auto real_dim = narrow_cast<std::size_t>(dim);
+        Expects(real_dim < rank);
+
+        return m_ranges.elementNum(real_dim);
+    }
+
+    constexpr index_type index_bounds() const GSL_NOEXCEPT
+    {
+        size_type extents[rank] = {};
+        m_ranges.serialize(extents);
+        return {extents};
+    }
+
+    template <std::ptrdiff_t... Ranges>
+    constexpr bool operator==(const static_bounds<Ranges...>& rhs) const GSL_NOEXCEPT
+    {
+        return this->size() == rhs.size();
+    }
+
+    template <std::ptrdiff_t... Ranges>
+    constexpr bool operator!=(const static_bounds<Ranges...>& rhs) const GSL_NOEXCEPT
+    {
+        return !(*this == rhs);
+    }
+
+    constexpr const_iterator begin() const GSL_NOEXCEPT
+    {
+        return const_iterator(*this, index_type{});
+    }
+
+    constexpr const_iterator end() const GSL_NOEXCEPT
+    {
+        return const_iterator(*this, this->index_bounds());
+    }
+};
+
+template <std::size_t Rank>
+class strided_bounds
+{
+    template <std::size_t OtherRank>
+    friend class strided_bounds;
+
+public:
+    static const std::size_t rank = Rank;
+    using value_type = std::ptrdiff_t;
+    using reference = std::add_lvalue_reference_t<value_type>;
+    using const_reference = std::add_const_t<reference>;
+    using size_type = value_type;
+    using difference_type = value_type;
+    using index_type = multi_span_index<rank>;
+    using const_index_type = std::add_const_t<index_type>;
+    using iterator = bounds_iterator<const_index_type>;
+    using const_iterator = bounds_iterator<const_index_type>;
+    static const value_type dynamic_rank = rank;
+    static const value_type static_size = dynamic_range;
+    using sliced_type = std::conditional_t<rank != 0, strided_bounds<rank - 1>, void>;
+    using mapping_type = generalized_mapping_tag;
+
+    constexpr strided_bounds(const strided_bounds&) GSL_NOEXCEPT = default;
+
+    constexpr strided_bounds& operator=(const strided_bounds&) GSL_NOEXCEPT = default;
+
+    constexpr strided_bounds(const value_type (&values)[rank], index_type strides)
+        : m_extents(values), m_strides(std::move(strides))
+    {
+    }
+
+    constexpr strided_bounds(const index_type& extents, const index_type& strides) GSL_NOEXCEPT
+        : m_extents(extents),
+          m_strides(strides)
+    {
+    }
+
+    constexpr index_type strides() const GSL_NOEXCEPT { return m_strides; }
+
+    constexpr size_type total_size() const GSL_NOEXCEPT
+    {
+        size_type ret = 0;
+        for (std::size_t i = 0; i < rank; ++i) {
+            ret += (m_extents[i] - 1) * m_strides[i];
+        }
+        return ret + 1;
+    }
+
+    constexpr size_type size() const GSL_NOEXCEPT
+    {
+        size_type ret = 1;
+        for (std::size_t i = 0; i < rank; ++i) {
+            ret *= m_extents[i];
+        }
+        return ret;
+    }
+
+    constexpr bool contains(const index_type& idx) const GSL_NOEXCEPT
+    {
+        for (std::size_t i = 0; i < rank; ++i) {
+            if (idx[i] < 0 || idx[i] >= m_extents[i]) return false;
+        }
+        return true;
+    }
+
+    constexpr size_type linearize(const index_type& idx) const GSL_NOEXCEPT
+    {
+        size_type ret = 0;
+        for (std::size_t i = 0; i < rank; i++) {
+            Expects(idx[i] < m_extents[i]); // index is out of bounds of the array
+            ret += idx[i] * m_strides[i];
+        }
+        return ret;
+    }
+
+    constexpr size_type stride() const GSL_NOEXCEPT { return m_strides[0]; }
+
+    template <bool Enabled = (rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>>
+    constexpr sliced_type slice() const
+    {
+        return {details::shift_left(m_extents), details::shift_left(m_strides)};
+    }
+
+    template <std::size_t Dim = 0>
+    constexpr size_type extent() const GSL_NOEXCEPT
+    {
+        static_assert(Dim < Rank,
+                      "dimension should be less than rank (dimension count starts from 0)");
+        return m_extents[Dim];
+    }
+
+    constexpr index_type index_bounds() const GSL_NOEXCEPT { return m_extents; }
+    constexpr const_iterator begin() const GSL_NOEXCEPT
+    {
+        return const_iterator{*this, index_type{}};
+    }
+
+    constexpr const_iterator end() const GSL_NOEXCEPT
+    {
+        return const_iterator{*this, index_bounds()};
+    }
+
+private:
+    index_type m_extents;
+    index_type m_strides;
+};
+
+template <typename T>
+struct is_bounds : std::integral_constant<bool, false>
+{
+};
+template <std::ptrdiff_t... Ranges>
+struct is_bounds<static_bounds<Ranges...>> : std::integral_constant<bool, true>
+{
+};
+template <std::size_t Rank>
+struct is_bounds<strided_bounds<Rank>> : std::integral_constant<bool, true>
+{
+};
+
+template <typename IndexType>
+class bounds_iterator
+{
+public:
+    static const std::size_t rank = IndexType::rank;
+    using iterator_category = std::random_access_iterator_tag;
+    using value_type = IndexType;
+    using difference_type = std::ptrdiff_t;
+    using pointer = value_type*;
+    using reference = value_type&;
+    using index_type = value_type;
+    using index_size_type = typename IndexType::value_type;
+    template <typename Bounds>
+    explicit bounds_iterator(const Bounds& bnd, value_type curr) GSL_NOEXCEPT
+        : boundary_(bnd.index_bounds()),
+          curr_(std::move(curr))
+    {
+        static_assert(is_bounds<Bounds>::value, "Bounds type must be provided");
+    }
+
+    constexpr reference operator*() const GSL_NOEXCEPT { return curr_; }
+
+    constexpr pointer operator->() const GSL_NOEXCEPT { return &curr_; }
+
+    constexpr bounds_iterator& operator++() GSL_NOEXCEPT
+    {
+        for (std::size_t i = rank; i-- > 0;) {
+            if (curr_[i] < boundary_[i] - 1) {
+                curr_[i]++;
+                return *this;
+            }
+            curr_[i] = 0;
+        }
+        // If we're here we've wrapped over - set to past-the-end.
+        curr_ = boundary_;
+        return *this;
+    }
+
+    constexpr bounds_iterator operator++(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        ++(*this);
+        return ret;
+    }
+
+    constexpr bounds_iterator& operator--() GSL_NOEXCEPT
+    {
+        if (!less(curr_, boundary_)) {
+            // if at the past-the-end, set to last element
+            for (std::size_t i = 0; i < rank; ++i) {
+                curr_[i] = boundary_[i] - 1;
+            }
+            return *this;
+        }
+        for (std::size_t i = rank; i-- > 0;) {
+            if (curr_[i] >= 1) {
+                curr_[i]--;
+                return *this;
+            }
+            curr_[i] = boundary_[i] - 1;
+        }
+        // If we're here the preconditions were violated
+        // "pre: there exists s such that r == ++s"
+        Expects(false);
+        return *this;
+    }
+
+    constexpr bounds_iterator operator--(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        --(*this);
+        return ret;
+    }
+
+    constexpr bounds_iterator operator+(difference_type n) const GSL_NOEXCEPT
+    {
+        bounds_iterator ret{*this};
+        return ret += n;
+    }
+
+    constexpr bounds_iterator& operator+=(difference_type n) GSL_NOEXCEPT
+    {
+        auto linear_idx = linearize(curr_) + n;
+        std::remove_const_t<value_type> stride = 0;
+        stride[rank - 1] = 1;
+        for (std::size_t i = rank - 1; i-- > 0;) {
+            stride[i] = stride[i + 1] * boundary_[i + 1];
+        }
+        for (std::size_t i = 0; i < rank; ++i) {
+            curr_[i] = linear_idx / stride[i];
+            linear_idx = linear_idx % stride[i];
+        }
+        // index is out of bounds of the array
+        Expects(!less(curr_, index_type{}) && !less(boundary_, curr_));
+        return *this;
+    }
+
+    constexpr bounds_iterator operator-(difference_type n) const GSL_NOEXCEPT
+    {
+        bounds_iterator ret{*this};
+        return ret -= n;
+    }
+
+    constexpr bounds_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
+
+    constexpr difference_type operator-(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return linearize(curr_) - linearize(rhs.curr_);
+    }
+
+    constexpr value_type operator[](difference_type n) const GSL_NOEXCEPT { return *(*this + n); }
+
+    constexpr bool operator==(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return curr_ == rhs.curr_;
+    }
+
+    constexpr bool operator!=(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(*this == rhs);
+    }
+
+    constexpr bool operator<(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return less(curr_, rhs.curr_);
+    }
+
+    constexpr bool operator<=(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(rhs < *this);
+    }
+
+    constexpr bool operator>(const bounds_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
+
+    constexpr bool operator>=(const bounds_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(rhs > *this);
+    }
+
+    void swap(bounds_iterator& rhs) GSL_NOEXCEPT
+    {
+        std::swap(boundary_, rhs.boundary_);
+        std::swap(curr_, rhs.curr_);
+    }
+
+private:
+    constexpr bool less(index_type& one, index_type& other) const GSL_NOEXCEPT
+    {
+        for (std::size_t i = 0; i < rank; ++i) {
+            if (one[i] < other[i]) return true;
+        }
+        return false;
+    }
+
+    constexpr index_size_type linearize(const value_type& idx) const GSL_NOEXCEPT
+    {
+        // TODO: Smarter impl.
+        // Check if past-the-end
+        index_size_type multiplier = 1;
+        index_size_type res = 0;
+        if (!less(idx, boundary_)) {
+            res = 1;
+            for (std::size_t i = rank; i-- > 0;) {
+                res += (idx[i] - 1) * multiplier;
+                multiplier *= boundary_[i];
+            }
+        }
+        else
+        {
+            for (std::size_t i = rank; i-- > 0;) {
+                res += idx[i] * multiplier;
+                multiplier *= boundary_[i];
+            }
+        }
+        return res;
+    }
+
+    value_type boundary_;
+    std::remove_const_t<value_type> curr_;
+};
+
+template <typename IndexType>
+bounds_iterator<IndexType> operator+(typename bounds_iterator<IndexType>::difference_type n,
+                                     const bounds_iterator<IndexType>& rhs) GSL_NOEXCEPT
+{
+    return rhs + n;
+}
+
+namespace details
+{
+    template <typename Bounds>
+    constexpr std::enable_if_t<
+        std::is_same<typename Bounds::mapping_type, generalized_mapping_tag>::value,
+        typename Bounds::index_type>
+    make_stride(const Bounds& bnd) GSL_NOEXCEPT
+    {
+        return bnd.strides();
+    }
+
+    // Make a stride vector from bounds, assuming contiguous memory.
+    template <typename Bounds>
+    constexpr std::enable_if_t<
+        std::is_same<typename Bounds::mapping_type, contiguous_mapping_tag>::value,
+        typename Bounds::index_type>
+    make_stride(const Bounds& bnd) GSL_NOEXCEPT
+    {
+        auto extents = bnd.index_bounds();
+        typename Bounds::size_type stride[Bounds::rank] = {};
+
+        stride[Bounds::rank - 1] = 1;
+        for (std::size_t i = 1; i < Bounds::rank; ++i) {
+            stride[Bounds::rank - i - 1] = stride[Bounds::rank - i] * extents[Bounds::rank - i];
+        }
+        return {stride};
+    }
+
+    template <typename BoundsSrc, typename BoundsDest>
+    void verifyBoundsReshape(const BoundsSrc& src, const BoundsDest& dest)
+    {
+        static_assert(is_bounds<BoundsSrc>::value && is_bounds<BoundsDest>::value,
+                      "The src type and dest type must be bounds");
+        static_assert(std::is_same<typename BoundsSrc::mapping_type, contiguous_mapping_tag>::value,
+                      "The source type must be a contiguous bounds");
+        static_assert(BoundsDest::static_size == dynamic_range ||
+                          BoundsSrc::static_size == dynamic_range ||
+                          BoundsDest::static_size == BoundsSrc::static_size,
+                      "The source bounds must have same size as dest bounds");
+        Expects(src.size() == dest.size());
+    }
+
+} // namespace details
+
+template <typename Span>
+class contiguous_span_iterator;
+template <typename Span>
+class general_span_iterator;
+
+template <std::ptrdiff_t DimSize = dynamic_range>
+struct dim_t
+{
+    static const std::ptrdiff_t value = DimSize;
+};
+template <>
+struct dim_t<dynamic_range>
+{
+    static const std::ptrdiff_t value = dynamic_range;
+    const std::ptrdiff_t dvalue;
+    constexpr dim_t(std::ptrdiff_t size) GSL_NOEXCEPT : dvalue(size) {}
+};
+
+template <std::ptrdiff_t N, class = std::enable_if_t<(N >= 0)>>
+constexpr dim_t<N> dim() GSL_NOEXCEPT
+{
+    return dim_t<N>();
+}
+
+template <std::ptrdiff_t N = dynamic_range, class = std::enable_if_t<N == dynamic_range>>
+constexpr dim_t<N> dim(std::ptrdiff_t n) GSL_NOEXCEPT
+{
+    return dim_t<>(n);
+}
+
+template <typename ValueType, std::ptrdiff_t FirstDimension = dynamic_range,
+          std::ptrdiff_t... RestDimensions>
+class multi_span;
+template <typename ValueType, std::size_t Rank>
+class strided_span;
+
+namespace details
+{
+    template <typename T, typename = std::true_type>
+    struct SpanTypeTraits
+    {
+        using value_type = T;
+        using size_type = std::size_t;
+    };
+
+    template <typename Traits>
+    struct SpanTypeTraits<Traits, typename std::is_reference<typename Traits::span_traits&>::type>
+    {
+        using value_type = typename Traits::span_traits::value_type;
+        using size_type = typename Traits::span_traits::size_type;
+    };
+
+    template <typename T, std::ptrdiff_t... Ranks>
+    struct SpanArrayTraits
+    {
+        using type = multi_span<T, Ranks...>;
+        using value_type = T;
+        using bounds_type = static_bounds<Ranks...>;
+        using pointer = T*;
+        using reference = T&;
+    };
+    template <typename T, std::ptrdiff_t N, std::ptrdiff_t... Ranks>
+    struct SpanArrayTraits<T[N], Ranks...> : SpanArrayTraits<T, Ranks..., N>
+    {
+    };
+
+    template <typename BoundsType>
+    BoundsType newBoundsHelperImpl(std::ptrdiff_t totalSize, std::true_type) // dynamic size
+    {
+        Expects(totalSize >= 0 && totalSize <= PTRDIFF_MAX);
+        return BoundsType{totalSize};
+    }
+    template <typename BoundsType>
+    BoundsType newBoundsHelperImpl(std::ptrdiff_t totalSize, std::false_type) // static size
+    {
+        Expects(BoundsType::static_size <= totalSize);
+        return {};
+    }
+    template <typename BoundsType>
+    BoundsType newBoundsHelper(std::ptrdiff_t totalSize)
+    {
+        static_assert(BoundsType::dynamic_rank <= 1, "dynamic rank must less or equal to 1");
+        return newBoundsHelperImpl<BoundsType>(
+            totalSize, std::integral_constant<bool, BoundsType::dynamic_rank == 1>());
+    }
+
+    struct Sep
+    {
+    };
+
+    template <typename T, typename... Args>
+    T static_as_multi_span_helper(Sep, Args... args)
+    {
+        return T{narrow_cast<typename T::size_type>(args)...};
+    }
+    template <typename T, typename Arg, typename... Args>
+    std::enable_if_t<
+        !std::is_same<Arg, dim_t<dynamic_range>>::value && !std::is_same<Arg, Sep>::value, T>
+    static_as_multi_span_helper(Arg, Args... args)
+    {
+        return static_as_multi_span_helper<T>(args...);
+    }
+    template <typename T, typename... Args>
+    T static_as_multi_span_helper(dim_t<dynamic_range> val, Args... args)
+    {
+        return static_as_multi_span_helper<T>(args..., val.dvalue);
+    }
+
+    template <typename... Dimensions>
+    struct static_as_multi_span_static_bounds_helper
+    {
+        using type = static_bounds<(Dimensions::value)...>;
+    };
+
+    template <typename T>
+    struct is_multi_span_oracle : std::false_type
+    {
+    };
+
+    template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
+    struct is_multi_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>>
+        : std::true_type
+    {
+    };
+
+    template <typename ValueType, std::ptrdiff_t Rank>
+    struct is_multi_span_oracle<strided_span<ValueType, Rank>> : std::true_type
+    {
+    };
+
+    template <typename T>
+    struct is_multi_span : is_multi_span_oracle<std::remove_cv_t<T>>
+    {
+    };
+}
+
+template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
+class multi_span
+{
+    // TODO do we still need this?
+    template <typename ValueType2, std::ptrdiff_t FirstDimension2,
+              std::ptrdiff_t... RestDimensions2>
+    friend class multi_span;
+
+public:
+    using bounds_type = static_bounds<FirstDimension, RestDimensions...>;
+    static const std::size_t Rank = bounds_type::rank;
+    using size_type = typename bounds_type::size_type;
+    using index_type = typename bounds_type::index_type;
+    using value_type = ValueType;
+    using const_value_type = std::add_const_t<value_type>;
+    using pointer = std::add_pointer_t<value_type>;
+    using reference = std::add_lvalue_reference_t<value_type>;
+    using iterator = contiguous_span_iterator<multi_span>;
+    using const_span = multi_span<const_value_type, FirstDimension, RestDimensions...>;
+    using const_iterator = contiguous_span_iterator<const_span>;
+    using reverse_iterator = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+    using sliced_type =
+        std::conditional_t<Rank == 1, value_type, multi_span<value_type, RestDimensions...>>;
+
+private:
+    pointer data_;
+    bounds_type bounds_;
+
+    friend iterator;
+    friend const_iterator;
+
+public:
+    // default constructor - same as constructing from nullptr_t
+    constexpr multi_span() GSL_NOEXCEPT : multi_span(nullptr, bounds_type{})
+    {
+        static_assert(bounds_type::dynamic_rank != 0 ||
+                          (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
+                      "Default construction of multi_span<T> only possible "
+                      "for dynamic or fixed, zero-length spans.");
+    }
+
+    // construct from nullptr - get an empty multi_span
+    constexpr multi_span(std::nullptr_t) GSL_NOEXCEPT : multi_span(nullptr, bounds_type{})
+    {
+        static_assert(bounds_type::dynamic_rank != 0 ||
+                          (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
+                      "nullptr_t construction of multi_span<T> only possible "
+                      "for dynamic or fixed, zero-length spans.");
+    }
+
+    // construct from nullptr with size of 0 (helps with template function calls)
+    template <class IntType, typename = std::enable_if_t<std::is_integral<IntType>::value>>
+    constexpr multi_span(std::nullptr_t, IntType size) GSL_NOEXCEPT
+        : multi_span(nullptr, bounds_type{})
+    {
+        static_assert(bounds_type::dynamic_rank != 0 ||
+                          (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
+                      "nullptr_t construction of multi_span<T> only possible "
+                      "for dynamic or fixed, zero-length spans.");
+        Expects(size == 0);
+    }
+
+    // construct from a single element
+    constexpr multi_span(reference data) GSL_NOEXCEPT : multi_span(&data, bounds_type{1})
+    {
+        static_assert(bounds_type::dynamic_rank > 0 || bounds_type::static_size == 0 ||
+                          bounds_type::static_size == 1,
+                      "Construction from a single element only possible "
+                      "for dynamic or fixed spans of length 0 or 1.");
+    }
+
+    // prevent constructing from temporaries for single-elements
+    constexpr multi_span(value_type&&) = delete;
+
+    // construct from pointer + length
+    constexpr multi_span(pointer ptr, size_type size) GSL_NOEXCEPT
+        : multi_span(ptr, bounds_type{size})
+    {
+    }
+
+    // construct from pointer + length - multidimensional
+    constexpr multi_span(pointer data, bounds_type bounds) GSL_NOEXCEPT : data_(data),
+                                                                          bounds_(std::move(bounds))
+    {
+        Expects((bounds_.size() > 0 && data != nullptr) || bounds_.size() == 0);
+    }
+
+    // construct from begin,end pointer pair
+    template <typename Ptr,
+              typename = std::enable_if_t<std::is_convertible<Ptr, pointer>::value &&
+                                          details::LessThan<bounds_type::dynamic_rank, 2>::value>>
+    constexpr multi_span(pointer begin, Ptr end)
+        : multi_span(begin,
+                     details::newBoundsHelper<bounds_type>(static_cast<pointer>(end) - begin))
+    {
+        Expects(begin != nullptr && end != nullptr && begin <= static_cast<pointer>(end));
+    }
+
+    // construct from n-dimensions static array
+    template <typename T, std::size_t N, typename Helper = details::SpanArrayTraits<T, N>>
+    constexpr multi_span(T (&arr)[N])
+        : multi_span(reinterpret_cast<pointer>(arr), bounds_type{typename Helper::bounds_type{}})
+    {
+        static_assert(std::is_convertible<typename Helper::value_type(*)[], value_type(*)[]>::value,
+                      "Cannot convert from source type to target multi_span type.");
+        static_assert(std::is_convertible<typename Helper::bounds_type, bounds_type>::value,
+                      "Cannot construct a multi_span from an array with fewer elements.");
+    }
+
+    // construct from n-dimensions dynamic array (e.g. new int[m][4])
+    // (precedence will be lower than the 1-dimension pointer)
+    template <typename T, typename Helper = details::SpanArrayTraits<T, dynamic_range>>
+    constexpr multi_span(T* const& data, size_type size)
+        : multi_span(reinterpret_cast<pointer>(data), typename Helper::bounds_type{size})
+    {
+        static_assert(std::is_convertible<typename Helper::value_type(*)[], value_type(*)[]>::value,
+                      "Cannot convert from source type to target multi_span type.");
+    }
+
+    // construct from std::array
+    template <typename T, std::size_t N>
+    constexpr multi_span(std::array<T, N>& arr)
+        : multi_span(arr.data(), bounds_type{static_bounds<N>{}})
+    {
+        static_assert(
+            std::is_convertible<T(*)[], typename std::remove_const_t<value_type>(*)[]>::value,
+            "Cannot convert from source type to target multi_span type.");
+        static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value,
+                      "You cannot construct a multi_span from a std::array of smaller size.");
+    }
+
+    // construct from const std::array
+    template <typename T, std::size_t N>
+    constexpr multi_span(const std::array<T, N>& arr)
+        : multi_span(arr.data(), bounds_type{static_bounds<N>{}})
+    {
+        static_assert(std::is_convertible<T(*)[], typename std::remove_const_t<value_type>(*)[]>::value,
+                      "Cannot convert from source type to target multi_span type.");
+        static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value,
+                      "You cannot construct a multi_span from a std::array of smaller size.");
+    }
+
+    // prevent constructing from temporary std::array
+    template <typename T, std::size_t N>
+    constexpr multi_span(std::array<T, N>&& arr) = delete;
+
+    // construct from containers
+    // future: could use contiguous_iterator_traits to identify only contiguous containers
+    // type-requirements: container must have .size(), operator[] which are value_type compatible
+    template <typename Cont, typename DataType = typename Cont::value_type,
+              typename = std::enable_if_t<
+                  !details::is_multi_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>>
+    constexpr multi_span(Cont& cont)
+        : multi_span(static_cast<pointer>(cont.data()),
+                     details::newBoundsHelper<bounds_type>(narrow_cast<size_type>(cont.size())))
+    {
+    }
+
+    // prevent constructing from temporary containers
+    template <typename Cont, typename DataType = typename Cont::value_type,
+              typename = std::enable_if_t<
+                  !details::is_multi_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>>
+    explicit constexpr multi_span(Cont&& cont) = delete;
+
+    // construct from a convertible multi_span
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename OtherBounds = static_bounds<OtherDimensions...>,
+              typename = std::enable_if_t<std::is_convertible<OtherValueType, ValueType>::value &&
+                                          std::is_convertible<OtherBounds, bounds_type>::value>>
+    constexpr multi_span(multi_span<OtherValueType, OtherDimensions...> other) GSL_NOEXCEPT
+        : data_(other.data_),
+          bounds_(other.bounds_)
+    {
+    }
+
+    // trivial copy and move
+    constexpr multi_span(const multi_span&) = default;
+    constexpr multi_span(multi_span&&) = default;
+
+    // trivial assignment
+    constexpr multi_span& operator=(const multi_span&) = default;
+    constexpr multi_span& operator=(multi_span&&) = default;
+
+    // first() - extract the first Count elements into a new multi_span
+    template <std::ptrdiff_t Count>
+    constexpr multi_span<ValueType, Count> first() const GSL_NOEXCEPT
+    {
+        static_assert(Count >= 0, "Count must be >= 0.");
+        static_assert(bounds_type::static_size == dynamic_range ||
+                          Count <= bounds_type::static_size,
+                      "Count is out of bounds.");
+
+        Expects(bounds_type::static_size != dynamic_range || Count <= this->size());
+        return {this->data(), Count};
+    }
+
+    // first() - extract the first count elements into a new multi_span
+    constexpr multi_span<ValueType, dynamic_range> first(size_type count) const GSL_NOEXCEPT
+    {
+        Expects(count >= 0 && count <= this->size());
+        return {this->data(), count};
+    }
+
+    // last() - extract the last Count elements into a new multi_span
+    template <std::ptrdiff_t Count>
+    constexpr multi_span<ValueType, Count> last() const GSL_NOEXCEPT
+    {
+        static_assert(Count >= 0, "Count must be >= 0.");
+        static_assert(bounds_type::static_size == dynamic_range ||
+                          Count <= bounds_type::static_size,
+                      "Count is out of bounds.");
+
+        Expects(bounds_type::static_size != dynamic_range || Count <= this->size());
+        return {this->data() + this->size() - Count, Count};
+    }
+
+    // last() - extract the last count elements into a new multi_span
+    constexpr multi_span<ValueType, dynamic_range> last(size_type count) const GSL_NOEXCEPT
+    {
+        Expects(count >= 0 && count <= this->size());
+        return {this->data() + this->size() - count, count};
+    }
+
+    // subspan() - create a subview of Count elements starting at Offset
+    template <std::ptrdiff_t Offset, std::ptrdiff_t Count>
+    constexpr multi_span<ValueType, Count> subspan() const GSL_NOEXCEPT
+    {
+        static_assert(Count >= 0, "Count must be >= 0.");
+        static_assert(Offset >= 0, "Offset must be >= 0.");
+        static_assert(bounds_type::static_size == dynamic_range ||
+                          ((Offset <= bounds_type::static_size) &&
+                           Count <= bounds_type::static_size - Offset),
+                      "You must describe a sub-range within bounds of the multi_span.");
+
+        Expects(bounds_type::static_size != dynamic_range ||
+                (Offset <= this->size() && Count <= this->size() - Offset));
+        return {this->data() + Offset, Count};
+    }
+
+    // subspan() - create a subview of count elements starting at offset
+    // supplying dynamic_range for count will consume all available elements from offset
+    constexpr multi_span<ValueType, dynamic_range>
+    subspan(size_type offset, size_type count = dynamic_range) const GSL_NOEXCEPT
+    {
+        Expects((offset >= 0 && offset <= this->size()) &&
+                (count == dynamic_range || (count <= this->size() - offset)));
+        return {this->data() + offset, count == dynamic_range ? this->length() - offset : count};
+    }
+
+    // section - creates a non-contiguous, strided multi_span from a contiguous one
+    constexpr strided_span<ValueType, Rank> section(index_type origin,
+                                                    index_type extents) const GSL_NOEXCEPT
+    {
+        size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
+        return {&this->operator[](origin), size,
+                strided_bounds<Rank>{extents, details::make_stride(bounds())}};
+    }
+
+    // length of the multi_span in elements
+    constexpr size_type size() const GSL_NOEXCEPT { return bounds_.size(); }
+
+    // length of the multi_span in elements
+    constexpr size_type length() const GSL_NOEXCEPT { return this->size(); }
+
+    // length of the multi_span in bytes
+    constexpr size_type size_bytes() const GSL_NOEXCEPT
+    {
+        return narrow_cast<size_type>(sizeof(value_type)) * this->size();
+    }
+
+    // length of the multi_span in bytes
+    constexpr size_type length_bytes() const GSL_NOEXCEPT { return this->size_bytes(); }
+
+    constexpr bool empty() const GSL_NOEXCEPT { return this->size() == 0; }
+
+    static constexpr std::size_t rank() { return Rank; }
+
+    template <std::size_t Dim = 0>
+    constexpr size_type extent() const GSL_NOEXCEPT
+    {
+        static_assert(Dim < Rank,
+                      "Dimension should be less than rank (dimension count starts from 0).");
+        return bounds_.template extent<Dim>();
+    }
+
+    template <typename IntType>
+    constexpr size_type extent(IntType dim) const GSL_NOEXCEPT
+    {
+        return bounds_.extent(dim);
+    }
+
+    constexpr bounds_type bounds() const GSL_NOEXCEPT { return bounds_; }
+
+    constexpr pointer data() const GSL_NOEXCEPT { return data_; }
+
+    template <typename FirstIndex>
+    constexpr reference operator()(FirstIndex idx)
+    {
+        return this->operator[](narrow_cast<std::ptrdiff_t>(idx));
+    }
+
+    template <typename FirstIndex, typename... OtherIndices>
+    constexpr reference operator()(FirstIndex firstIndex, OtherIndices... indices)
+    {
+        index_type idx = {narrow_cast<std::ptrdiff_t>(firstIndex),
+                          narrow_cast<std::ptrdiff_t>(indices)...};
+        return this->operator[](idx);
+    }
+
+    constexpr reference operator[](const index_type& idx) const GSL_NOEXCEPT
+    {
+        return data_[bounds_.linearize(idx)];
+    }
+
+    template <bool Enabled = (Rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>>
+    constexpr Ret operator[](size_type idx) const GSL_NOEXCEPT
+    {
+        Expects(idx >= 0 && idx < bounds_.size()); // index is out of bounds of the array
+        const size_type ridx = idx * bounds_.stride();
+
+        // index is out of bounds of the underlying data
+        Expects(ridx < bounds_.total_size());
+        return Ret{data_ + ridx, bounds_.slice()};
+    }
+
+    constexpr iterator begin() const GSL_NOEXCEPT { return iterator{this, true}; }
+
+    constexpr iterator end() const GSL_NOEXCEPT { return iterator{this, false}; }
+
+    constexpr const_iterator cbegin() const GSL_NOEXCEPT
+    {
+        return const_iterator{reinterpret_cast<const const_span*>(this), true};
+    }
+
+    constexpr const_iterator cend() const GSL_NOEXCEPT
+    {
+        return const_iterator{reinterpret_cast<const const_span*>(this), false};
+    }
+
+    constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return reverse_iterator{end()}; }
+
+    constexpr reverse_iterator rend() const GSL_NOEXCEPT { return reverse_iterator{begin()}; }
+
+    constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT
+    {
+        return const_reverse_iterator{cend()};
+    }
+
+    constexpr const_reverse_iterator crend() const GSL_NOEXCEPT
+    {
+        return const_reverse_iterator{cbegin()};
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator==(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return bounds_.size() == other.bounds_.size() &&
+               (data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator!=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return !(*this == other);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator<(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator<=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return !(other < *this);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator>(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return (other < *this);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator>=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
+    {
+        return !(*this < other);
+    }
+};
+
+//
+// Free functions for manipulating spans
+//
+
+// reshape a multi_span into a different dimensionality
+// DimCount and Enabled here are workarounds for a bug in MSVC 2015
+template <typename SpanType, typename... Dimensions2, std::size_t DimCount = sizeof...(Dimensions2),
+          bool Enabled = (DimCount > 0), typename = std::enable_if_t<Enabled>>
+constexpr auto as_multi_span(SpanType s, Dimensions2... dims)
+    -> multi_span<typename SpanType::value_type, Dimensions2::value...>
+{
+    static_assert(details::is_multi_span<SpanType>::value,
+                  "Variadic as_multi_span() is for reshaping existing spans.");
+    using BoundsType =
+        typename multi_span<typename SpanType::value_type, (Dimensions2::value)...>::bounds_type;
+    auto tobounds = details::static_as_multi_span_helper<BoundsType>(dims..., details::Sep{});
+    details::verifyBoundsReshape(s.bounds(), tobounds);
+    return {s.data(), tobounds};
+}
+
+// convert a multi_span<T> to a multi_span<const byte>
+template <typename U, std::ptrdiff_t... Dimensions>
+multi_span<const byte, dynamic_range> as_bytes(multi_span<U, Dimensions...> s) GSL_NOEXCEPT
+{
+    static_assert(std::is_trivial<std::decay_t<U>>::value,
+                  "The value_type of multi_span must be a trivial type.");
+    return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
+}
+
+// convert a multi_span<T> to a multi_span<byte> (a writeable byte multi_span)
+// this is not currently a portable function that can be relied upon to work
+// on all implementations. It should be considered an experimental extension
+// to the standard GSL interface.
+template <typename U, std::ptrdiff_t... Dimensions>
+multi_span<byte> as_writeable_bytes(multi_span<U, Dimensions...> s) GSL_NOEXCEPT
+{
+    static_assert(std::is_trivial<std::decay_t<U>>::value,
+                  "The value_type of multi_span must be a trivial type.");
+    return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
+}
+
+// convert a multi_span<const byte> to a multi_span<const T>
+// this is not currently a portable function that can be relied upon to work
+// on all implementations. It should be considered an experimental extension
+// to the standard GSL interface.
+template <typename U, std::ptrdiff_t... Dimensions>
+constexpr auto
+as_multi_span(multi_span<const byte, Dimensions...> s) GSL_NOEXCEPT -> multi_span<
+    const U, static_cast<std::ptrdiff_t>(
+                 multi_span<const byte, Dimensions...>::bounds_type::static_size != dynamic_range
+                     ? (static_cast<std::size_t>(
+                            multi_span<const byte, Dimensions...>::bounds_type::static_size) /
+                        sizeof(U))
+                     : dynamic_range)>
+{
+    using ConstByteSpan = multi_span<const byte, Dimensions...>;
+    static_assert(
+        std::is_trivial<std::decay_t<U>>::value &&
+            (ConstByteSpan::bounds_type::static_size == dynamic_range ||
+             ConstByteSpan::bounds_type::static_size % narrow_cast<std::ptrdiff_t>(sizeof(U)) == 0),
+        "Target type must be a trivial type and its size must match the byte array size");
+
+    Expects((s.size_bytes() % narrow_cast<std::ptrdiff_t>(sizeof(U))) == 0 &&
+            (s.size_bytes() / narrow_cast<std::ptrdiff_t>(sizeof(U))) < PTRDIFF_MAX);
+    return {reinterpret_cast<const U*>(s.data()),
+            s.size_bytes() / narrow_cast<std::ptrdiff_t>(sizeof(U))};
+}
+
+// convert a multi_span<byte> to a multi_span<T>
+// this is not currently a portable function that can be relied upon to work
+// on all implementations. It should be considered an experimental extension
+// to the standard GSL interface.
+template <typename U, std::ptrdiff_t... Dimensions>
+constexpr auto as_multi_span(multi_span<byte, Dimensions...> s) GSL_NOEXCEPT
+    -> multi_span<U, narrow_cast<std::ptrdiff_t>(
+                         multi_span<byte, Dimensions...>::bounds_type::static_size != dynamic_range
+                             ? static_cast<std::size_t>(
+                                   multi_span<byte, Dimensions...>::bounds_type::static_size) /
+                                   sizeof(U)
+                             : dynamic_range)>
+{
+    using ByteSpan = multi_span<byte, Dimensions...>;
+    static_assert(
+        std::is_trivial<std::decay_t<U>>::value &&
+            (ByteSpan::bounds_type::static_size == dynamic_range ||
+             ByteSpan::bounds_type::static_size % sizeof(U) == 0),
+        "Target type must be a trivial type and its size must match the byte array size");
+
+    Expects((s.size_bytes() % sizeof(U)) == 0);
+    return {reinterpret_cast<U*>(s.data()),
+            s.size_bytes() / narrow_cast<std::ptrdiff_t>(sizeof(U))};
+}
+
+template <typename T, std::ptrdiff_t... Dimensions>
+constexpr auto as_multi_span(T* const& ptr, dim_t<Dimensions>... args)
+    -> multi_span<std::remove_all_extents_t<T>, Dimensions...>
+{
+    return {reinterpret_cast<std::remove_all_extents_t<T>*>(ptr),
+            details::static_as_multi_span_helper<static_bounds<Dimensions...>>(args...,
+                                                                               details::Sep{})};
+}
+
+template <typename T>
+constexpr auto as_multi_span(T* arr, std::ptrdiff_t len) ->
+    typename details::SpanArrayTraits<T, dynamic_range>::type
+{
+    return {reinterpret_cast<std::remove_all_extents_t<T>*>(arr), len};
+}
+
+template <typename T, std::size_t N>
+constexpr auto as_multi_span(T (&arr)[N]) -> typename details::SpanArrayTraits<T, N>::type
+{
+    return {arr};
+}
+
+template <typename T, std::size_t N>
+constexpr multi_span<const T, N> as_multi_span(const std::array<T, N>& arr)
+{
+    return {arr};
+}
+
+template <typename T, std::size_t N>
+constexpr multi_span<const T, N> as_multi_span(const std::array<T, N>&&) = delete;
+
+template <typename T, std::size_t N>
+constexpr multi_span<T, N> as_multi_span(std::array<T, N>& arr)
+{
+    return {arr};
+}
+
+template <typename T>
+constexpr multi_span<T, dynamic_range> as_multi_span(T* begin, T* end)
+{
+    return {begin, end};
+}
+
+template <typename Cont>
+constexpr auto as_multi_span(Cont& arr) -> std::enable_if_t<
+    !details::is_multi_span<std::decay_t<Cont>>::value,
+    multi_span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
+{
+    Expects(arr.size() < PTRDIFF_MAX);
+    return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())};
+}
+
+template <typename Cont>
+constexpr auto as_multi_span(Cont&& arr) -> std::enable_if_t<
+    !details::is_multi_span<std::decay_t<Cont>>::value,
+    multi_span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>> = delete;
+
+// from basic_string which doesn't have nonconst .data() member like other contiguous containers
+template <typename CharT, typename Traits, typename Allocator>
+constexpr auto as_multi_span(std::basic_string<CharT, Traits, Allocator>& str)
+    -> multi_span<CharT, dynamic_range>
+{
+    Expects(str.size() < PTRDIFF_MAX);
+    return {&str[0], narrow_cast<std::ptrdiff_t>(str.size())};
+}
+
+// strided_span is an extension that is not strictly part of the GSL at this time.
+// It is kept here while the multidimensional interface is still being defined.
+template <typename ValueType, std::size_t Rank>
+class strided_span
+{
+public:
+    using bounds_type = strided_bounds<Rank>;
+    using size_type = typename bounds_type::size_type;
+    using index_type = typename bounds_type::index_type;
+    using value_type = ValueType;
+    using const_value_type = std::add_const_t<value_type>;
+    using pointer = std::add_pointer_t<value_type>;
+    using reference = std::add_lvalue_reference_t<value_type>;
+    using iterator = general_span_iterator<strided_span>;
+    using const_strided_span = strided_span<const_value_type, Rank>;
+    using const_iterator = general_span_iterator<const_strided_span>;
+    using reverse_iterator = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+    using sliced_type =
+        std::conditional_t<Rank == 1, value_type, strided_span<value_type, Rank - 1>>;
+
+private:
+    pointer data_;
+    bounds_type bounds_;
+
+    friend iterator;
+    friend const_iterator;
+    template <typename OtherValueType, std::size_t OtherRank>
+    friend class strided_span;
+
+public:
+    // from raw data
+    constexpr strided_span(pointer ptr, size_type size, bounds_type bounds)
+        : data_(ptr), bounds_(std::move(bounds))
+    {
+        Expects((bounds_.size() > 0 && ptr != nullptr) || bounds_.size() == 0);
+        // Bounds cross data boundaries
+        Expects(this->bounds().total_size() <= size);
+        (void) size;
+    }
+
+    // from static array of size N
+    template <size_type N>
+    constexpr strided_span(value_type (&values)[N], bounds_type bounds)
+        : strided_span(values, N, std::move(bounds))
+    {
+    }
+
+    // from array view
+    template <typename OtherValueType, std::ptrdiff_t... Dimensions,
+              bool Enabled1 = (sizeof...(Dimensions) == Rank),
+              bool Enabled2 = std::is_convertible<OtherValueType*, ValueType*>::value,
+              typename = std::enable_if_t<Enabled1 && Enabled2>>
+    constexpr strided_span(multi_span<OtherValueType, Dimensions...> av, bounds_type bounds)
+        : strided_span(av.data(), av.bounds().total_size(), std::move(bounds))
+    {
+    }
+
+    // convertible
+    template <typename OtherValueType, typename = std::enable_if_t<std::is_convertible<
+                                           OtherValueType (*)[], value_type (*)[]>::value>>
+    constexpr strided_span(const strided_span<OtherValueType, Rank>& other)
+        : data_(other.data_), bounds_(other.bounds_)
+    {
+    }
+
+    // convert from bytes
+    template <typename OtherValueType>
+    constexpr strided_span<
+        typename std::enable_if<std::is_same<value_type, const byte>::value, OtherValueType>::type,
+        Rank>
+    as_strided_span() const
+    {
+        static_assert((sizeof(OtherValueType) >= sizeof(value_type)) &&
+                          (sizeof(OtherValueType) % sizeof(value_type) == 0),
+                      "OtherValueType should have a size to contain a multiple of ValueTypes");
+        auto d = narrow_cast<size_type>(sizeof(OtherValueType) / sizeof(value_type));
+
+        size_type size = this->bounds().total_size() / d;
+        return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())),
+                size,
+                bounds_type{resize_extent(this->bounds().index_bounds(), d),
+                            resize_stride(this->bounds().strides(), d)}};
+    }
+
+    constexpr strided_span section(index_type origin, index_type extents) const
+    {
+        size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
+        return {&this->operator[](origin), size,
+                bounds_type{extents, details::make_stride(bounds())}};
+    }
+
+    constexpr reference operator[](const index_type& idx) const
+    {
+        return data_[bounds_.linearize(idx)];
+    }
+
+    template <bool Enabled = (Rank > 1), typename Ret = std::enable_if_t<Enabled, sliced_type>>
+    constexpr Ret operator[](size_type idx) const
+    {
+        Expects(idx < bounds_.size()); // index is out of bounds of the array
+        const size_type ridx = idx * bounds_.stride();
+
+        // index is out of bounds of the underlying data
+        Expects(ridx < bounds_.total_size());
+        return {data_ + ridx, bounds_.slice().total_size(), bounds_.slice()};
+    }
+
+    constexpr bounds_type bounds() const GSL_NOEXCEPT { return bounds_; }
+
+    template <std::size_t Dim = 0>
+    constexpr size_type extent() const GSL_NOEXCEPT
+    {
+        static_assert(Dim < Rank,
+                      "dimension should be less than Rank (dimension count starts from 0)");
+        return bounds_.template extent<Dim>();
+    }
+
+    constexpr size_type size() const GSL_NOEXCEPT { return bounds_.size(); }
+
+    constexpr pointer data() const GSL_NOEXCEPT { return data_; }
+
+    constexpr explicit operator bool() const GSL_NOEXCEPT { return data_ != nullptr; }
+
+    constexpr iterator begin() const { return iterator{this, true}; }
+
+    constexpr iterator end() const { return iterator{this, false}; }
+
+    constexpr const_iterator cbegin() const
+    {
+        return const_iterator{reinterpret_cast<const const_strided_span*>(this), true};
+    }
+
+    constexpr const_iterator cend() const
+    {
+        return const_iterator{reinterpret_cast<const const_strided_span*>(this), false};
+    }
+
+    constexpr reverse_iterator rbegin() const { return reverse_iterator{end()}; }
+
+    constexpr reverse_iterator rend() const { return reverse_iterator{begin()}; }
+
+    constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator{cend()}; }
+
+    constexpr const_reverse_iterator crend() const { return const_reverse_iterator{cbegin()}; }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator==(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return bounds_.size() == other.bounds_.size() &&
+               (data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator!=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return !(*this == other);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator<(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator<=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return !(other < *this);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator>(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return (other < *this);
+    }
+
+    template <typename OtherValueType, std::ptrdiff_t OtherRank,
+              typename = std::enable_if_t<std::is_same<
+                  std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
+    constexpr bool
+    operator>=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
+    {
+        return !(*this < other);
+    }
+
+private:
+    static index_type resize_extent(const index_type& extent, std::ptrdiff_t d)
+    {
+        // The last dimension of the array needs to contain a multiple of new type elements
+        Expects(extent[Rank - 1] >= d && (extent[Rank - 1] % d == 0));
+
+        index_type ret = extent;
+        ret[Rank - 1] /= d;
+
+        return ret;
+    }
+
+    template <bool Enabled = (Rank == 1), typename = std::enable_if_t<Enabled>>
+    static index_type resize_stride(const index_type& strides, std::ptrdiff_t, void* = nullptr)
+    {
+        // Only strided arrays with regular strides can be resized
+        Expects(strides[Rank - 1] == 1);
+
+        return strides;
+    }
+
+    template <bool Enabled = (Rank > 1), typename = std::enable_if_t<Enabled>>
+    static index_type resize_stride(const index_type& strides, std::ptrdiff_t d)
+    {
+        // Only strided arrays with regular strides can be resized
+        Expects(strides[Rank - 1] == 1);
+        // The strides must have contiguous chunks of
+        // memory that can contain a multiple of new type elements
+        Expects(strides[Rank - 2] >= d && (strides[Rank - 2] % d == 0));
+
+        for (std::size_t i = Rank - 1; i > 0; --i) {
+            // Only strided arrays with regular strides can be resized
+            Expects((strides[i - 1] >= strides[i]) && (strides[i - 1] % strides[i] == 0));
+        }
+
+        index_type ret = strides / d;
+        ret[Rank - 1] = 1;
+
+        return ret;
+    }
+};
+
+template <class Span>
+class contiguous_span_iterator
+{
+public:
+    using iterator_category = std::random_access_iterator_tag;
+    using value_type = typename Span::value_type;
+    using difference_type = std::ptrdiff_t;
+    using pointer = value_type*;
+    using reference = value_type&;
+
+private:
+    template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
+    friend class multi_span;
+
+    pointer data_;
+    const Span* m_validator;
+    void validateThis() const
+    {
+        // iterator is out of range of the array
+        Expects(data_ >= m_validator->data_ && data_ < m_validator->data_ + m_validator->size());
+    }
+    contiguous_span_iterator(const Span* container, bool isbegin)
+        : data_(isbegin ? container->data_ : container->data_ + container->size())
+        , m_validator(container)
+    {
+    }
+
+public:
+    reference operator*() const GSL_NOEXCEPT
+    {
+        validateThis();
+        return *data_;
+    }
+    pointer operator->() const GSL_NOEXCEPT
+    {
+        validateThis();
+        return data_;
+    }
+    contiguous_span_iterator& operator++() GSL_NOEXCEPT
+    {
+        ++data_;
+        return *this;
+    }
+    contiguous_span_iterator operator++(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        ++(*this);
+        return ret;
+    }
+    contiguous_span_iterator& operator--() GSL_NOEXCEPT
+    {
+        --data_;
+        return *this;
+    }
+    contiguous_span_iterator operator--(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        --(*this);
+        return ret;
+    }
+    contiguous_span_iterator operator+(difference_type n) const GSL_NOEXCEPT
+    {
+        contiguous_span_iterator ret{*this};
+        return ret += n;
+    }
+    contiguous_span_iterator& operator+=(difference_type n) GSL_NOEXCEPT
+    {
+        data_ += n;
+        return *this;
+    }
+    contiguous_span_iterator operator-(difference_type n) const GSL_NOEXCEPT
+    {
+        contiguous_span_iterator ret{*this};
+        return ret -= n;
+    }
+    contiguous_span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
+    difference_type operator-(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_validator == rhs.m_validator);
+        return data_ - rhs.data_;
+    }
+    reference operator[](difference_type n) const GSL_NOEXCEPT { return *(*this + n); }
+    bool operator==(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_validator == rhs.m_validator);
+        return data_ == rhs.data_;
+    }
+    bool operator!=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(*this == rhs);
+    }
+    bool operator<(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_validator == rhs.m_validator);
+        return data_ < rhs.data_;
+    }
+    bool operator<=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(rhs < *this);
+    }
+    bool operator>(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
+    bool operator>=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        return !(rhs > *this);
+    }
+    void swap(contiguous_span_iterator& rhs) GSL_NOEXCEPT
+    {
+        std::swap(data_, rhs.data_);
+        std::swap(m_validator, rhs.m_validator);
+    }
+};
+
+template <typename Span>
+contiguous_span_iterator<Span> operator+(typename contiguous_span_iterator<Span>::difference_type n,
+                                         const contiguous_span_iterator<Span>& rhs) GSL_NOEXCEPT
+{
+    return rhs + n;
+}
+
+template <typename Span>
+class general_span_iterator
+{
+public:
+    using iterator_category = std::random_access_iterator_tag;
+    using value_type = typename Span::value_type;
+    using difference_type = std::ptrdiff_t;
+    using pointer = value_type*;
+    using reference = value_type&;
+
+private:
+    template <typename ValueType, std::size_t Rank>
+    friend class strided_span;
+
+    const Span* m_container;
+    typename Span::bounds_type::iterator m_itr;
+    general_span_iterator(const Span* container, bool isbegin)
+        : m_container(container)
+        , m_itr(isbegin ? m_container->bounds().begin() : m_container->bounds().end())
+    {
+    }
+
+public:
+    reference operator*() GSL_NOEXCEPT { return (*m_container)[*m_itr]; }
+    pointer operator->() GSL_NOEXCEPT { return &(*m_container)[*m_itr]; }
+    general_span_iterator& operator++() GSL_NOEXCEPT
+    {
+        ++m_itr;
+        return *this;
+    }
+    general_span_iterator operator++(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        ++(*this);
+        return ret;
+    }
+    general_span_iterator& operator--() GSL_NOEXCEPT
+    {
+        --m_itr;
+        return *this;
+    }
+    general_span_iterator operator--(int) GSL_NOEXCEPT
+    {
+        auto ret = *this;
+        --(*this);
+        return ret;
+    }
+    general_span_iterator operator+(difference_type n) const GSL_NOEXCEPT
+    {
+        general_span_iterator ret{*this};
+        return ret += n;
+    }
+    general_span_iterator& operator+=(difference_type n) GSL_NOEXCEPT
+    {
+        m_itr += n;
+        return *this;
+    }
+    general_span_iterator operator-(difference_type n) const GSL_NOEXCEPT
+    {
+        general_span_iterator ret{*this};
+        return ret -= n;
+    }
+    general_span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
+    difference_type operator-(const general_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_container == rhs.m_container);
+        return m_itr - rhs.m_itr;
+    }
+    value_type operator[](difference_type n) const GSL_NOEXCEPT { return (*m_container)[m_itr[n]]; }
+
+    bool operator==(const general_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_container == rhs.m_container);
+        return m_itr == rhs.m_itr;
+    }
+    bool operator!=(const general_span_iterator& rhs) const GSL_NOEXCEPT { return !(*this == rhs); }
+    bool operator<(const general_span_iterator& rhs) const GSL_NOEXCEPT
+    {
+        Expects(m_container == rhs.m_container);
+        return m_itr < rhs.m_itr;
+    }
+    bool operator<=(const general_span_iterator& rhs) const GSL_NOEXCEPT { return !(rhs < *this); }
+    bool operator>(const general_span_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
+    bool operator>=(const general_span_iterator& rhs) const GSL_NOEXCEPT { return !(rhs > *this); }
+    void swap(general_span_iterator& rhs) GSL_NOEXCEPT
+    {
+        std::swap(m_itr, rhs.m_itr);
+        std::swap(m_container, rhs.m_container);
+    }
+};
+
+template <typename Span>
+general_span_iterator<Span> operator+(typename general_span_iterator<Span>::difference_type n,
+                                      const general_span_iterator<Span>& rhs) GSL_NOEXCEPT
+{
+    return rhs + n;
+}
+
+} // namespace gsl
+
+#undef GSL_NOEXCEPT
+
+#ifdef _MSC_VER
+#if _MSC_VER < 1910
+
+#undef constexpr
+#pragma pop_macro("constexpr")
+#endif // _MSC_VER < 1910
+
+#pragma warning(pop)
+
+#endif // _MSC_VER
+
+#if __GNUC__ > 6 
+#pragma GCC diagnostic pop
+#endif // __GNUC__ > 6
+
+#endif // GSL_MULTI_SPAN_H
diff --git a/include/gsl/pointers b/include/gsl/pointers
new file mode 100644
index 0000000..69499d6
--- /dev/null
+++ b/include/gsl/pointers
@@ -0,0 +1,193 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_POINTERS_H
+#define GSL_POINTERS_H
+
+#include <gsl/gsl_assert>  // for Ensures, Expects
+
+#include <algorithm>    // for forward
+#include <iosfwd>       // for ptrdiff_t, nullptr_t, ostream, size_t
+#include <memory>       // for shared_ptr, unique_ptr
+#include <system_error> // for hash
+#include <type_traits>  // for enable_if_t, is_convertible, is_assignable
+
+#if defined(_MSC_VER) && _MSC_VER < 1910
+#pragma push_macro("constexpr")
+#define constexpr /*constexpr*/
+
+#endif                          // defined(_MSC_VER) && _MSC_VER < 1910
+
+namespace gsl
+{
+
+//
+// GSL.owner: ownership pointers
+//
+using std::unique_ptr;
+using std::shared_ptr;
+
+//
+// owner
+//
+// owner<T> is designed as a bridge for code that must deal directly with owning pointers for some reason
+//
+// T must be a pointer type
+// - disallow construction from any type other than pointer type
+//
+template <class T, class = std::enable_if_t<std::is_pointer<T>::value>>
+using owner = T;
+
+//
+// not_null
+//
+// Restricts a pointer or smart pointer to only hold non-null values.
+//
+// Has zero size overhead over T.
+//
+// If T is a pointer (i.e. T == U*) then
+// - allow construction from U*
+// - disallow construction from nullptr_t
+// - disallow default construction
+// - ensure construction from null U* fails
+// - allow implicit conversion to U*
+//
+template <class T>
+class not_null
+{
+public:
+    static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
+
+    template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
+    constexpr explicit not_null(U&& u) : ptr_(std::forward<U>(u))
+    {
+        Expects(ptr_ != nullptr);
+    }
+
+    template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
+    constexpr explicit not_null(T u) : ptr_(u)
+    {
+        Expects(ptr_ != nullptr);
+    }
+
+    template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
+    constexpr not_null(const not_null<U>& other) : not_null(other.get())
+    {
+    }
+
+    not_null(not_null&& other) = default;
+    not_null(const not_null& other) = default;
+    not_null& operator=(const not_null& other) = default;
+
+    constexpr T get() const
+    {
+        Ensures(ptr_ != nullptr);
+        return ptr_;
+    }
+
+    constexpr operator T() const { return get(); }
+    constexpr T operator->() const { return get(); }
+    constexpr decltype(auto) operator*() const { return *get(); } 
+
+    // prevents compilation when someone attempts to assign a null pointer constant
+    not_null(std::nullptr_t) = delete;
+    not_null& operator=(std::nullptr_t) = delete;
+
+    // unwanted operators...pointers only point to single objects!
+    not_null& operator++() = delete;
+    not_null& operator--() = delete;
+    not_null operator++(int) = delete;
+    not_null operator--(int) = delete;
+    not_null& operator+=(std::ptrdiff_t) = delete;
+    not_null& operator-=(std::ptrdiff_t) = delete;
+    void operator[](std::ptrdiff_t) const = delete;
+
+private:
+    T ptr_;
+};
+
+template <class T>
+std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
+{
+    os << val.get();
+    return os;
+}
+
+template <class T, class U>
+auto operator==(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() == rhs.get())
+{
+    return lhs.get() == rhs.get();
+}
+
+template <class T, class U>
+auto operator!=(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() != rhs.get())
+{
+    return lhs.get() != rhs.get();
+}
+
+template <class T, class U>
+auto operator<(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() < rhs.get())
+{
+    return lhs.get() < rhs.get();
+}
+
+template <class T, class U>
+auto operator<=(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() <= rhs.get())
+{
+    return lhs.get() <= rhs.get();
+}
+
+template <class T, class U>
+auto operator>(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() > rhs.get())
+{
+    return lhs.get() > rhs.get();
+}
+
+template <class T, class U>
+auto operator>=(const not_null<T>& lhs, const not_null<U>& rhs) -> decltype(lhs.get() >= rhs.get())
+{
+    return lhs.get() >= rhs.get();
+}
+
+// more unwanted operators
+template <class T, class U>
+std::ptrdiff_t operator-(const not_null<T>&, const not_null<U>&) = delete;
+template <class T>
+not_null<T> operator-(const not_null<T>&, std::ptrdiff_t) = delete;
+template <class T>
+not_null<T> operator+(const not_null<T>&, std::ptrdiff_t) = delete;
+template <class T>
+not_null<T> operator+(std::ptrdiff_t, const not_null<T>&) = delete;
+
+} // namespace gsl
+
+namespace std
+{
+template <class T>
+struct hash<gsl::not_null<T>>
+{
+    std::size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); }
+};
+
+} // namespace std
+
+#if defined(_MSC_VER) && _MSC_VER < 1910
+#undef constexpr
+#pragma pop_macro("constexpr")
+
+#endif // defined(_MSC_VER) && _MSC_VER < 1910
+
+#endif // GSL_POINTERS_H
diff --git a/include/gsl/span b/include/gsl/span
new file mode 100644
index 0000000..2fa9cc5
--- /dev/null
+++ b/include/gsl/span
@@ -0,0 +1,766 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_SPAN_H
+#define GSL_SPAN_H
+
+#include <gsl/gsl_assert> // for Expects
+#include <gsl/gsl_byte>   // for byte
+#include <gsl/gsl_util>   // for narrow_cast, narrow
+
+#include <algorithm> // for lexicographical_compare
+#include <array>     // for array
+#include <cstddef>   // for ptrdiff_t, size_t, nullptr_t
+#include <iterator>  // for reverse_iterator, distance, random_access_...
+#include <limits>
+#include <stdexcept>
+#include <type_traits> // for enable_if_t, declval, is_convertible, inte...
+#include <utility>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+
+// turn off some warnings that are noisy about our Expects statements
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4702) // unreachable code
+
+// blanket turn off warnings from CppCoreCheck for now
+// so people aren't annoyed by them when running the tool.
+// more targeted suppressions will be added in a future update to the GSL
+#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
+
+#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
+
+// GCC 7 does not like the signed unsigned missmatch (size_t ptrdiff_t)
+// While there is a conversion from signed to unsigned, it happens at 
+// compiletime, so the compiler wouldn't have to warn indiscriminently, but 
+// could check if the source value actually doesn't fit into the target type 
+// and only warn in those cases.
+#if __GNUC__ > 6
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#endif
+
+namespace gsl
+{
+
+// [views.constants], constants
+constexpr const std::ptrdiff_t dynamic_extent = -1;
+
+template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
+class span;
+
+// implementation details
+namespace details
+{
+    template <class T>
+    struct is_span_oracle : std::false_type
+    {
+    };
+
+    template <class ElementType, std::ptrdiff_t Extent>
+    struct is_span_oracle<gsl::span<ElementType, Extent>> : std::true_type
+    {
+    };
+
+    template <class T>
+    struct is_span : public is_span_oracle<std::remove_cv_t<T>>
+    {
+    };
+
+    template <class T>
+    struct is_std_array_oracle : std::false_type
+    {
+    };
+
+    template <class ElementType, std::size_t Extent>
+    struct is_std_array_oracle<std::array<ElementType, Extent>> : std::true_type
+    {
+    };
+
+    template <class T>
+    struct is_std_array : public is_std_array_oracle<std::remove_cv_t<T>>
+    {
+    };
+
+    template <std::ptrdiff_t From, std::ptrdiff_t To>
+    struct is_allowed_extent_conversion
+        : public std::integral_constant<bool, From == To || From == gsl::dynamic_extent ||
+                                                  To == gsl::dynamic_extent>
+    {
+    };
+
+    template <class From, class To>
+    struct is_allowed_element_type_conversion
+        : public std::integral_constant<bool, std::is_convertible<From (*)[], To (*)[]>::value>
+    {
+    };
+
+    template <class Span, bool IsConst>
+    class span_iterator
+    {
+        using element_type_ = typename Span::element_type;
+
+    public:
+
+#ifdef _MSC_VER
+        // Tell Microsoft standard library that span_iterators are checked.
+        using _Unchecked_type = typename Span::pointer;
+#endif
+
+        using iterator_category = std::random_access_iterator_tag;
+        using value_type = std::remove_cv_t<element_type_>;
+        using difference_type = typename Span::index_type;
+
+        using reference = std::conditional_t<IsConst, const element_type_, element_type_>&;
+        using pointer = std::add_pointer_t<reference>;
+
+        span_iterator() = default;
+
+        constexpr span_iterator(const Span* span, typename Span::index_type idx) noexcept
+            : span_(span), index_(idx)
+        {}
+
+        friend span_iterator<Span, true>;
+        template<bool B, std::enable_if_t<!B && IsConst>* = nullptr>
+        constexpr span_iterator(const span_iterator<Span, B>& other) noexcept
+            : span_iterator(other.span_, other.index_)
+        {
+        }
+
+        constexpr reference operator*() const
+        {
+            Expects(index_ != span_->size());
+            return *(span_->data() + index_);
+        }
+
+        constexpr pointer operator->() const
+        {
+            Expects(index_ != span_->size());
+            return span_->data() + index_;
+        }
+
+        constexpr span_iterator& operator++()
+        {
+            Expects(0 <= index_ && index_ != span_->size());
+            ++index_;
+            return *this;
+        }
+
+        constexpr span_iterator operator++(int)
+        {
+            auto ret = *this;
+            ++(*this);
+            return ret;
+        }
+
+        constexpr span_iterator& operator--()
+        {
+            Expects(index_ != 0 && index_ <= span_->size());
+            --index_;
+            return *this;
+        }
+
+        constexpr span_iterator operator--(int)
+        {
+            auto ret = *this;
+            --(*this);
+            return ret;
+        }
+
+        constexpr span_iterator operator+(difference_type n) const
+        {
+            auto ret = *this;
+            return ret += n;
+        }
+
+        friend constexpr span_iterator operator+(difference_type n, span_iterator const& rhs)
+        {
+            return rhs + n;
+        }
+
+        constexpr span_iterator& operator+=(difference_type n)
+        {
+            Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
+            index_ += n;
+            return *this;
+        }
+
+        constexpr span_iterator operator-(difference_type n) const
+        {
+            auto ret = *this;
+            return ret -= n;
+        }
+
+        constexpr span_iterator& operator-=(difference_type n) { return *this += -n; }
+
+        constexpr difference_type operator-(span_iterator rhs) const
+        {
+            Expects(span_ == rhs.span_);
+            return index_ - rhs.index_;
+        }
+
+        constexpr reference operator[](difference_type n) const
+        {
+            return *(*this + n);
+        }
+
+        constexpr friend bool operator==(span_iterator lhs,
+                                         span_iterator rhs) noexcept
+        {
+            return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
+        }
+
+        constexpr friend bool operator!=(span_iterator lhs,
+                                         span_iterator rhs) noexcept
+        {
+            return !(lhs == rhs);
+        }
+
+        constexpr friend bool operator<(span_iterator lhs,
+                                        span_iterator rhs) noexcept
+        {
+            return lhs.index_ < rhs.index_;
+        }
+
+        constexpr friend bool operator<=(span_iterator lhs,
+                                         span_iterator rhs) noexcept
+        {
+            return !(rhs < lhs);
+        }
+
+        constexpr friend bool operator>(span_iterator lhs,
+                                        span_iterator rhs) noexcept
+        {
+            return rhs < lhs;
+        }
+
+        constexpr friend bool operator>=(span_iterator lhs,
+                                         span_iterator rhs) noexcept
+        {
+            return !(rhs > lhs);
+        }
+
+#ifdef _MSC_VER
+        // MSVC++ iterator debugging support; allows STL algorithms in 15.8+
+        // to unwrap span_iterator to a pointer type after a range check in STL
+        // algorithm calls
+        friend constexpr void _Verify_range(span_iterator lhs,
+                                            span_iterator rhs) noexcept
+        {   // test that [lhs, rhs) forms a valid range inside an STL algorithm
+            Expects(lhs.span_ == rhs.span_ // range spans have to match
+                && lhs.index_ <= rhs.index_); // range must not be transposed
+        }
+
+        constexpr void _Verify_offset(const difference_type n) const noexcept
+        {   // test that the iterator *this + n is a valid range in an STL
+            // algorithm call
+            Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
+        }
+
+        constexpr pointer _Unwrapped() const noexcept
+        {   // after seeking *this to a high water mark, or using one of the
+            // _Verify_xxx functions above, unwrap this span_iterator to a raw
+            // pointer
+            return span_->data() + index_;
+        }
+
+        // Tell the STL that span_iterator should not be unwrapped if it can't
+        // validate in advance, even in release / optimized builds:
+#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
+        static constexpr const bool _Unwrap_when_unverified = false;
+#else
+        static constexpr bool _Unwrap_when_unverified = false;
+#endif
+        constexpr void _Seek_to(const pointer p) noexcept
+        {   // adjust the position of *this to previously verified location p
+            // after _Unwrapped
+            index_ = p - span_->data();
+        }
+#endif
+
+    protected:
+        const Span* span_ = nullptr;
+        std::ptrdiff_t index_ = 0;
+    };
+
+    template <std::ptrdiff_t Ext>
+    class extent_type
+    {
+    public:
+        using index_type = std::ptrdiff_t;
+
+        static_assert(Ext >= 0, "A fixed-size span must be >= 0 in size.");
+
+        constexpr extent_type() noexcept {}
+
+        template <index_type Other>
+        constexpr extent_type(extent_type<Other> ext)
+        {
+            static_assert(Other == Ext || Other == dynamic_extent,
+                          "Mismatch between fixed-size extent and size of initializing data.");
+            Expects(ext.size() == Ext);
+        }
+
+        constexpr extent_type(index_type size) { Expects(size == Ext); }
+
+        constexpr index_type size() const noexcept { return Ext; }
+    };
+
+    template <>
+    class extent_type<dynamic_extent>
+    {
+    public:
+        using index_type = std::ptrdiff_t;
+
+        template <index_type Other>
+        explicit constexpr extent_type(extent_type<Other> ext) : size_(ext.size())
+        {
+        }
+
+        explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); }
+
+        constexpr index_type size() const noexcept { return size_; }
+
+    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
+template <class ElementType, std::ptrdiff_t Extent>
+class span
+{
+public:
+    // constants and types
+    using element_type = ElementType;
+    using value_type = std::remove_cv_t<ElementType>;
+    using index_type = std::ptrdiff_t;
+    using pointer = element_type*;
+    using reference = element_type&;
+
+    using iterator = details::span_iterator<span<ElementType, Extent>, false>;
+    using const_iterator = details::span_iterator<span<ElementType, Extent>, true>;
+    using reverse_iterator = std::reverse_iterator<iterator>;
+    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+    using size_type = index_type;
+
+#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,
+              // "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE,
+              // since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0.
+              class = std::enable_if_t<(Dependent || Extent <= 0)>>
+    constexpr span() noexcept : storage_(nullptr, details::extent_type<0>())
+    {
+    }
+
+    constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
+
+    constexpr span(pointer firstElem, pointer lastElem)
+        : storage_(firstElem, std::distance(firstElem, lastElem))
+    {
+    }
+
+    template <std::size_t N>
+    constexpr span(element_type (&arr)[N]) noexcept
+        : storage_(KnownNotNull{&arr[0]}, details::extent_type<N>())
+    {
+    }
+
+    template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
+    constexpr span(std::array<ArrayElementType, N>& arr) noexcept
+        : storage_(&arr[0], details::extent_type<N>())
+    {
+    }
+
+    template <std::size_t N>
+    constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept
+        : storage_(&arr[0], details::extent_type<N>())
+    {
+    }
+
+    // NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
+    // on Container to be a contiguous sequence container.
+    template <class Container,
+              class = std::enable_if_t<
+                  !details::is_span<Container>::value && !details::is_std_array<Container>::value &&
+                  std::is_convertible<typename Container::pointer, pointer>::value &&
+                  std::is_convertible<typename Container::pointer,
+                                      decltype(std::declval<Container>().data())>::value>>
+    constexpr span(Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
+    {
+    }
+
+    template <class Container,
+              class = std::enable_if_t<
+                  std::is_const<element_type>::value && !details::is_span<Container>::value &&
+                  std::is_convertible<typename Container::pointer, pointer>::value &&
+                  std::is_convertible<typename Container::pointer,
+                                      decltype(std::declval<Container>().data())>::value>>
+    constexpr span(const Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
+    {
+    }
+
+    constexpr span(const span& other) noexcept = default;
+
+    template <
+        class OtherElementType, std::ptrdiff_t OtherExtent,
+        class = std::enable_if_t<
+            details::is_allowed_extent_conversion<OtherExtent, Extent>::value &&
+            details::is_allowed_element_type_conversion<OtherElementType, element_type>::value>>
+    constexpr span(const span<OtherElementType, OtherExtent>& other)
+        : storage_(other.data(), details::extent_type<OtherExtent>(other.size()))
+    {
+    }
+
+    ~span() noexcept = default;
+    constexpr span& operator=(const span& other) noexcept = default;
+
+    // [span.sub], span subviews
+    template <std::ptrdiff_t Count>
+    constexpr span<element_type, Count> first() const
+    {
+        Expects(Count >= 0 && Count <= size());
+        return {data(), Count};
+    }
+
+    template <std::ptrdiff_t Count>
+    constexpr span<element_type, Count> last() const
+    {
+        Expects(Count >= 0 && size() - Count >= 0);
+        return {data() + (size() - Count), Count};
+    }
+
+    template <std::ptrdiff_t Offset, std::ptrdiff_t Count = dynamic_extent>
+    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())));
+
+        return {data() + Offset, Count == dynamic_extent ? size() - Offset : Count};
+    }
+
+    constexpr span<element_type, dynamic_extent> first(index_type count) const
+    {
+        Expects(count >= 0 && count <= size());
+        return {data(), count};
+    }
+
+    constexpr span<element_type, dynamic_extent> last(index_type count) const
+    {
+        return make_subspan(size() - count, dynamic_extent, subspan_selector<Extent>{});
+    }
+
+    constexpr span<element_type, dynamic_extent> subspan(index_type offset,
+                                                         index_type count = dynamic_extent) const
+    {
+        return make_subspan(offset, count, subspan_selector<Extent>{});
+    }
+
+
+    // [span.obs], span observers
+    constexpr index_type size() const noexcept { return storage_.size(); }
+    constexpr index_type size_bytes() const noexcept
+    {
+        return size() * narrow_cast<index_type>(sizeof(element_type));
+    }
+    constexpr bool empty() const noexcept { return size() == 0; }
+
+    // [span.elem], span element access
+    constexpr reference operator[](index_type idx) const
+    {
+        Expects(idx >= 0 && idx < storage_.size());
+        return data()[idx];
+    }
+
+    constexpr reference at(index_type idx) const { return this->operator[](idx); }
+    constexpr reference operator()(index_type idx) const { return this->operator[](idx); }
+    constexpr pointer data() const noexcept { return storage_.data(); }
+
+    // [span.iter], span iterator support
+    constexpr iterator begin() const noexcept { return {this, 0}; }
+    constexpr iterator end() const noexcept { return {this, size()}; }
+
+    constexpr const_iterator cbegin() const noexcept { return {this, 0}; }
+    constexpr const_iterator cend() const noexcept { return {this, size()}; }
+
+    constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }
+    constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }
+
+    constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; }
+    constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; }
+
+#ifdef _MSC_VER
+    // Tell MSVC how to unwrap spans in range-based-for
+    constexpr pointer _Unchecked_begin() const noexcept { return data(); }
+    constexpr pointer _Unchecked_end() const noexcept { return data() + size(); }
+#endif // _MSC_VER
+
+private:
+
+    // Needed to remove unnecessary null check in subspans
+    struct KnownNotNull
+    {
+        pointer p;
+    };
+
+    // this implementation detail class lets us take advantage of the
+    // empty base class optimization to pay for only storage of a single
+    // pointer in the case of fixed-size spans
+    template <class ExtentType>
+    class storage_type : public ExtentType
+    {
+    public:
+        // KnownNotNull parameter is needed to remove unnecessary null check
+        // in subspans and constructors from arrays
+        template <class OtherExtentType>
+        constexpr storage_type(KnownNotNull data, OtherExtentType ext) : ExtentType(ext), data_(data.p)
+        {
+             Expects(ExtentType::size() >= 0);
+        }
+
+
+        template <class OtherExtentType>
+        constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data)
+        {
+             Expects(ExtentType::size() >= 0);
+             Expects(data || ExtentType::size() == 0);
+        }
+
+        constexpr pointer data() const noexcept { return data_; }
+
+    private:
+        pointer data_;
+    };
+
+    storage_type<details::extent_type<Extent>> storage_;
+
+    // The rest is needed to remove unnecessary null check
+    // in subspans and constructors from arrays
+    constexpr span(KnownNotNull ptr, index_type count) : storage_(ptr, count) {}
+
+    template <std::ptrdiff_t CallerExtent>
+    class subspan_selector {};
+
+    template <std::ptrdiff_t CallerExtent>
+    span<element_type, dynamic_extent> make_subspan(index_type offset,
+                                                    index_type count,
+                                                    subspan_selector<CallerExtent>) const
+    {
+        span<element_type, dynamic_extent> tmp(*this);
+        return tmp.subspan(offset, count);
+    }
+
+    span<element_type, dynamic_extent> make_subspan(index_type offset,
+                                                    index_type count,
+                                                    subspan_selector<dynamic_extent>) const
+    {
+        Expects(offset >= 0 && size() - offset >= 0);
+        if (count == dynamic_extent)
+        {
+            return { KnownNotNull{ data() + offset }, size() - offset };
+        }
+
+        Expects(count >= 0 && size() - offset >= count);
+        return { KnownNotNull{ data() + offset },  count };
+    }
+};
+
+#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>
+constexpr bool operator==(span<ElementType, FirstExtent> l,
+                          span<ElementType, SecondExtent> r)
+{
+    return std::equal(l.begin(), l.end(), r.begin(), r.end());
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr bool operator!=(span<ElementType, Extent> l,
+                          span<ElementType, Extent> r)
+{
+    return !(l == r);
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr bool operator<(span<ElementType, Extent> l,
+                         span<ElementType, Extent> r)
+{
+    return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr bool operator<=(span<ElementType, Extent> l,
+                          span<ElementType, Extent> r)
+{
+    return !(l > r);
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr bool operator>(span<ElementType, Extent> l,
+                         span<ElementType, Extent> r)
+{
+    return r < l;
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr bool operator>=(span<ElementType, Extent> l,
+                          span<ElementType, Extent> r)
+{
+    return !(l < r);
+}
+
+namespace details
+{
+    // if we only supported compilers with good constexpr support then
+    // this pair of classes could collapse down to a constexpr function
+
+    // we should use a narrow_cast<> to go to std::size_t, but older compilers may not see it as
+    // constexpr
+    // and so will fail compilation of the template
+    template <class ElementType, std::ptrdiff_t Extent>
+    struct calculate_byte_size
+        : std::integral_constant<std::ptrdiff_t,
+                                 static_cast<std::ptrdiff_t>(sizeof(ElementType) *
+                                                             static_cast<std::size_t>(Extent))>
+    {
+    };
+
+    template <class ElementType>
+    struct calculate_byte_size<ElementType, dynamic_extent>
+        : std::integral_constant<std::ptrdiff_t, dynamic_extent>
+    {
+    };
+}
+
+// [span.objectrep], views of object representation
+template <class ElementType, std::ptrdiff_t Extent>
+span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
+as_bytes(span<ElementType, Extent> s) noexcept
+{
+    return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
+}
+
+template <class ElementType, std::ptrdiff_t Extent,
+          class = std::enable_if_t<!std::is_const<ElementType>::value>>
+span<byte, details::calculate_byte_size<ElementType, Extent>::value>
+as_writeable_bytes(span<ElementType, Extent> s) noexcept
+{
+    return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
+}
+
+//
+// make_span() - Utility functions for creating spans
+//
+template <class ElementType>
+constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::index_type count)
+{
+    return span<ElementType>(ptr, count);
+}
+
+template <class ElementType>
+constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
+{
+    return span<ElementType>(firstElem, lastElem);
+}
+
+template <class ElementType, std::size_t N>
+constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
+{
+    return span<ElementType, N>(arr);
+}
+
+template <class Container>
+constexpr span<typename Container::value_type> make_span(Container& cont)
+{
+    return span<typename Container::value_type>(cont);
+}
+
+template <class Container>
+constexpr span<const typename Container::value_type> make_span(const Container& cont)
+{
+    return span<const typename Container::value_type>(cont);
+}
+
+template <class Ptr>
+constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::ptrdiff_t count)
+{
+    return span<typename Ptr::element_type>(cont, count);
+}
+
+template <class Ptr>
+constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
+{
+    return span<typename Ptr::element_type>(cont);
+}
+
+// Specialization of gsl::at for span
+template <class ElementType, std::ptrdiff_t Extent>
+constexpr ElementType& at(span<ElementType, Extent> s, index i)
+{
+    // No bounds checking here because it is done in span::operator[] called below
+    return s[i];
+}
+
+} // namespace gsl
+
+#ifdef _MSC_VER
+#if _MSC_VER < 1910
+#undef constexpr
+#pragma pop_macro("constexpr")
+
+#endif // _MSC_VER < 1910
+
+#pragma warning(pop)
+#endif // _MSC_VER
+
+#if __GNUC__ > 6 
+#pragma GCC diagnostic pop
+#endif // __GNUC__ > 6
+
+#endif // GSL_SPAN_H
diff --git a/include/gsl/string_span b/include/gsl/string_span
new file mode 100644
index 0000000..c08f246
--- /dev/null
+++ b/include/gsl/string_span
@@ -0,0 +1,730 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
+//
+// This code is licensed under the MIT License (MIT).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef GSL_STRING_SPAN_H
+#define GSL_STRING_SPAN_H
+
+#include <gsl/gsl_assert> // for Ensures, Expects
+#include <gsl/gsl_util>   // for narrow_cast
+#include <gsl/span>       // for operator!=, operator==, dynamic_extent
+
+#include <algorithm> // for equal, lexicographical_compare
+#include <array>     // for array
+#include <cstddef>   // for ptrdiff_t, size_t, nullptr_t
+#include <cstdint>   // for PTRDIFF_MAX
+#include <cstring>
+#include <string>      // for basic_string, allocator, char_traits
+#include <type_traits> // for declval, is_convertible, enable_if_t, add_...
+
+#ifdef _MSC_VER
+#pragma warning(push)
+
+// blanket turn off warnings from CppCoreCheck for now
+// so people aren't annoyed by them when running the tool.
+// more targeted suppressions will be added in a future update to the GSL
+#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
+
+#if _MSC_VER < 1910
+#pragma push_macro("constexpr")
+#define constexpr /*constexpr*/
+
+#endif // _MSC_VER < 1910
+#endif // _MSC_VER
+
+// In order to test the library, we need it to throw exceptions that we can catch
+#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
+#define GSL_NOEXCEPT /*noexcept*/
+#else
+#define GSL_NOEXCEPT noexcept
+#endif // GSL_THROW_ON_CONTRACT_VIOLATION
+
+namespace gsl
+{
+//
+// czstring and wzstring
+//
+// These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
+// that allow static analysis to help find bugs.
+//
+// There are no additional features/semantics that we can find a way to add inside the
+// type system for these types that will not either incur significant runtime costs or
+// (sometimes needlessly) break existing programs when introduced.
+//
+
+template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
+using basic_zstring = CharT*;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using czstring = basic_zstring<const char, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cwzstring = basic_zstring<const wchar_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cu16zstring = basic_zstring<const char16_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cu32zstring = basic_zstring<const char32_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using zstring = basic_zstring<char, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using wzstring = basic_zstring<wchar_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using u16zstring = basic_zstring<char16_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using u32zstring = basic_zstring<char32_t, Extent>;
+
+namespace details
+{
+    template <class CharT>
+    std::ptrdiff_t string_length(const CharT* str, std::ptrdiff_t n)
+    {
+        if (str == nullptr || n <= 0) return 0;
+
+        const span<const CharT> str_span{str, n};
+
+        std::ptrdiff_t len = 0;
+        while (len < n && str_span[len]) len++;
+
+        return len;
+    }
+}
+
+//
+// ensure_sentinel()
+//
+// Provides a way to obtain an span from a contiguous sequence
+// that ends with a (non-inclusive) sentinel value.
+//
+// Will fail-fast if sentinel cannot be found before max elements are examined.
+//
+template <typename T, const T Sentinel>
+span<T, dynamic_extent> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
+{
+    auto cur = seq;
+    while ((cur - seq) < max && *cur != Sentinel) ++cur;
+    Ensures(*cur == Sentinel);
+    return {seq, cur - seq};
+}
+
+//
+// ensure_z - creates a span for a zero terminated strings.
+// Will fail fast if a null-terminator cannot be found before
+// the limit of size_type.
+//
+template <typename CharT>
+span<CharT, dynamic_extent> ensure_z(CharT* const& sz, std::ptrdiff_t max = PTRDIFF_MAX)
+{
+    return ensure_sentinel<CharT, CharT(0)>(sz, max);
+}
+
+template <typename CharT, std::size_t N>
+span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N])
+{
+    return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N));
+}
+
+template <class Cont>
+span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent>
+ensure_z(Cont& cont)
+{
+    return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.size()));
+}
+
+template <typename CharT, std::ptrdiff_t>
+class basic_string_span;
+
+namespace details
+{
+    template <typename T>
+    struct is_basic_string_span_oracle : std::false_type
+    {
+    };
+
+    template <typename CharT, std::ptrdiff_t Extent>
+    struct is_basic_string_span_oracle<basic_string_span<CharT, Extent>> : std::true_type
+    {
+    };
+
+    template <typename T>
+    struct is_basic_string_span : is_basic_string_span_oracle<std::remove_cv_t<T>>
+    {
+    };
+}
+
+//
+// string_span and relatives
+//
+template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
+class basic_string_span
+{
+public:
+    using element_type = CharT;
+    using pointer = std::add_pointer_t<element_type>;
+    using reference = std::add_lvalue_reference_t<element_type>;
+    using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>;
+    using impl_type = span<element_type, Extent>;
+
+    using index_type = typename impl_type::index_type;
+    using iterator = typename impl_type::iterator;
+    using const_iterator = typename impl_type::const_iterator;
+    using reverse_iterator = typename impl_type::reverse_iterator;
+    using const_reverse_iterator = typename impl_type::const_reverse_iterator;
+
+    // default (empty)
+    constexpr basic_string_span() GSL_NOEXCEPT = default;
+
+    // copy
+    constexpr basic_string_span(const basic_string_span& other) GSL_NOEXCEPT = default;
+
+    // assign
+    constexpr basic_string_span& operator=(const basic_string_span& other) GSL_NOEXCEPT = default;
+
+    constexpr basic_string_span(pointer ptr, index_type length) : span_(ptr, length) {}
+    constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
+
+    // From static arrays - if 0-terminated, remove 0 from the view
+    // All other containers allow 0s within the length, so we do not remove them
+    template <std::size_t N>
+    constexpr basic_string_span(element_type (&arr)[N]) : span_(remove_z(arr))
+    {
+    }
+
+    template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
+    constexpr basic_string_span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT : span_(arr)
+    {
+    }
+
+    template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
+    constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
+        : span_(arr)
+    {
+    }
+
+    // Container signature should work for basic_string after C++17 version exists
+    template <class Traits, class Allocator>
+    constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator>& str)
+        : span_(&str[0], narrow_cast<std::ptrdiff_t>(str.length()))
+    {
+    }
+
+    template <class Traits, class Allocator>
+    constexpr basic_string_span(const std::basic_string<element_type, Traits, Allocator>& str)
+        : span_(&str[0], str.length())
+    {
+    }
+
+    // from containers. Containers must have a pointer type and data() function signatures
+    template <class Container,
+              class = std::enable_if_t<
+                  !details::is_basic_string_span<Container>::value &&
+                  std::is_convertible<typename Container::pointer, pointer>::value &&
+                  std::is_convertible<typename Container::pointer,
+                                      decltype(std::declval<Container>().data())>::value>>
+    constexpr basic_string_span(Container& cont) : span_(cont)
+    {
+    }
+
+    template <class Container,
+              class = std::enable_if_t<
+                  !details::is_basic_string_span<Container>::value &&
+                  std::is_convertible<typename Container::pointer, pointer>::value &&
+                  std::is_convertible<typename Container::pointer,
+                                      decltype(std::declval<Container>().data())>::value>>
+    constexpr basic_string_span(const Container& cont) : span_(cont)
+    {
+    }
+
+    // from string_span
+    template <
+        class OtherValueType, std::ptrdiff_t OtherExtent,
+        class = std::enable_if_t<std::is_convertible<
+            typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
+    constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
+        : span_(other.data(), other.length())
+    {
+    }
+
+    template <index_type Count>
+    constexpr basic_string_span<element_type, Count> first() const
+    {
+        return {span_.template first<Count>()};
+    }
+
+    constexpr basic_string_span<element_type, dynamic_extent> first(index_type count) const
+    {
+        return {span_.first(count)};
+    }
+
+    template <index_type Count>
+    constexpr basic_string_span<element_type, Count> last() const
+    {
+        return {span_.template last<Count>()};
+    }
+
+    constexpr basic_string_span<element_type, dynamic_extent> last(index_type count) const
+    {
+        return {span_.last(count)};
+    }
+
+    template <index_type Offset, index_type Count>
+    constexpr basic_string_span<element_type, Count> subspan() const
+    {
+        return {span_.template subspan<Offset, Count>()};
+    }
+
+    constexpr basic_string_span<element_type, dynamic_extent>
+    subspan(index_type offset, index_type count = dynamic_extent) const
+    {
+        return {span_.subspan(offset, count)};
+    }
+
+    constexpr reference operator[](index_type idx) const { return span_[idx]; }
+    constexpr reference operator()(index_type idx) const { return span_[idx]; }
+
+    constexpr pointer data() const { return span_.data(); }
+
+    constexpr index_type length() const GSL_NOEXCEPT { return span_.size(); }
+    constexpr index_type size() const GSL_NOEXCEPT { return span_.size(); }
+    constexpr index_type size_bytes() const GSL_NOEXCEPT { return span_.size_bytes(); }
+    constexpr index_type length_bytes() const GSL_NOEXCEPT { return span_.length_bytes(); }
+    constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
+
+    constexpr iterator begin() const GSL_NOEXCEPT { return span_.begin(); }
+    constexpr iterator end() const GSL_NOEXCEPT { return span_.end(); }
+
+    constexpr const_iterator cbegin() const GSL_NOEXCEPT { return span_.cbegin(); }
+    constexpr const_iterator cend() const GSL_NOEXCEPT { return span_.cend(); }
+
+    constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return span_.rbegin(); }
+    constexpr reverse_iterator rend() const GSL_NOEXCEPT { return span_.rend(); }
+
+    constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT { return span_.crbegin(); }
+    constexpr const_reverse_iterator crend() const GSL_NOEXCEPT { return span_.crend(); }
+
+private:
+    static impl_type remove_z(pointer const& sz, std::ptrdiff_t max)
+    {
+        return {sz, details::string_length(sz, max)};
+    }
+
+    template <std::size_t N>
+    static impl_type remove_z(element_type (&sz)[N])
+    {
+        return remove_z(&sz[0], narrow_cast<std::ptrdiff_t>(N));
+    }
+
+    impl_type span_;
+};
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using string_span = basic_string_span<char, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cstring_span = basic_string_span<const char, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using wstring_span = basic_string_span<wchar_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cwstring_span = basic_string_span<const wchar_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using u16string_span = basic_string_span<char16_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cu16string_span = basic_string_span<const char16_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using u32string_span = basic_string_span<char32_t, Extent>;
+
+template <std::ptrdiff_t Extent = dynamic_extent>
+using cu32string_span = basic_string_span<const char32_t, Extent>;
+
+//
+// to_string() allow (explicit) conversions from string_span to string
+//
+
+template <typename CharT, std::ptrdiff_t Extent>
+std::basic_string<typename std::remove_const<CharT>::type>
+to_string(basic_string_span<CharT, Extent> view)
+{
+    return {view.data(), static_cast<std::size_t>(view.length())};
+}
+
+template <typename CharT, typename Traits = typename std::char_traits<CharT>,
+          typename Allocator = std::allocator<CharT>, typename gCharT, std::ptrdiff_t Extent>
+std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view)
+{
+    return {view.data(), static_cast<std::size_t>(view.length())};
+}
+
+template <class ElementType, std::ptrdiff_t Extent>
+basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
+as_bytes(basic_string_span<ElementType, Extent> s) noexcept
+{
+	return { reinterpret_cast<const byte*>(s.data()), s.size_bytes() };
+}
+
+template <class ElementType, std::ptrdiff_t Extent,
+          class = std::enable_if_t<!std::is_const<ElementType>::value>>
+basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value>
+as_writeable_bytes(basic_string_span<ElementType, Extent> s) noexcept
+{
+    return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
+}
+
+// zero-terminated string span, used to convert
+// zero-terminated spans to legacy strings
+template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
+class basic_zstring_span
+{
+public:
+    using value_type = CharT;
+    using const_value_type = std::add_const_t<CharT>;
+
+    using pointer = std::add_pointer_t<value_type>;
+    using const_pointer = std::add_pointer_t<const_value_type>;
+
+    using zstring_type = basic_zstring<value_type, Extent>;
+    using const_zstring_type = basic_zstring<const_value_type, Extent>;
+
+    using impl_type = span<value_type, Extent>;
+    using string_span_type = basic_string_span<value_type, Extent>;
+
+    constexpr basic_zstring_span(impl_type s) GSL_NOEXCEPT : span_(s)
+    {
+        // expects a zero-terminated span
+        Expects(s[s.size() - 1] == '\0');
+    }
+
+    // copy
+    constexpr basic_zstring_span(const basic_zstring_span& other) = default;
+
+    // move
+    constexpr basic_zstring_span(basic_zstring_span&& other) = default;
+
+    // assign
+    constexpr basic_zstring_span& operator=(const basic_zstring_span& other) = default;
+
+    // move assign
+    constexpr basic_zstring_span& operator=(basic_zstring_span&& other) = default;
+
+    constexpr bool empty() const GSL_NOEXCEPT { return span_.size() == 0; }
+
+    constexpr string_span_type as_string_span() const GSL_NOEXCEPT
+    {
+        auto sz = span_.size();
+        return { span_.data(), sz > 1 ? sz - 1 : 0 };
+    }
+    constexpr string_span_type ensure_z() const GSL_NOEXCEPT { return gsl::ensure_z(span_); }
+
+    constexpr const_zstring_type assume_z() const GSL_NOEXCEPT { return span_.data(); }
+
+private:
+    impl_type span_;
+};
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using zstring_span = basic_zstring_span<char, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using wzstring_span = basic_zstring_span<wchar_t, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using u16zstring_span = basic_zstring_span<char16_t, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using u32zstring_span = basic_zstring_span<char32_t, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using czstring_span = basic_zstring_span<const char, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using cwzstring_span = basic_zstring_span<const wchar_t, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using cu16zstring_span = basic_zstring_span<const char16_t, Max>;
+
+template <std::ptrdiff_t Max = dynamic_extent>
+using cu32zstring_span = basic_zstring_span<const char32_t, Max>;
+
+// operator ==
+template <class CharT, std::ptrdiff_t Extent, class T,
+          class = std::enable_if_t<
+              details::is_basic_string_span<T>::value ||
+              std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
+bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) GSL_NOEXCEPT
+{
+    const gsl::basic_string_span<std::add_const_t<CharT>> tmp(other);
+    return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
+}
+
+template <class CharT, std::ptrdiff_t Extent, class T,
+          class = std::enable_if_t<
+              !details::is_basic_string_span<T>::value &&
+              std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
+bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) GSL_NOEXCEPT
+{
+    gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
+    return std::equal(tmp.begin(), tmp.end(), other.begin(), other.end());
+}
+
+// operator !=
+template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+          typename = std::enable_if_t<std::is_convertible<
+              T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
+bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return !(one == other);
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename = std::enable_if_t<
+        std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
+        !gsl::details::is_basic_string_span<T>::value>>
+bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return !(one == other);
+}
+
+// operator<
+template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+          typename = std::enable_if_t<std::is_convertible<
+              T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
+bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    const gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
+    return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename = std::enable_if_t<
+        std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
+        !gsl::details::is_basic_string_span<T>::value>>
+bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
+    return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
+}
+
+#ifndef _MSC_VER
+
+// VS treats temp and const containers as convertible to basic_string_span,
+// so the cases below are already covered by the previous operators
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
+    return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
+    return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
+}
+#endif
+
+// operator <=
+template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+          typename = std::enable_if_t<std::is_convertible<
+              T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
+bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return !(other < one);
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename = std::enable_if_t<
+        std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
+        !gsl::details::is_basic_string_span<T>::value>>
+bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return !(other < one);
+}
+
+#ifndef _MSC_VER
+
+// VS treats temp and const containers as convertible to basic_string_span,
+// so the cases below are already covered by the previous operators
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return !(other < one);
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return !(other < one);
+}
+#endif
+
+// operator>
+template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+          typename = std::enable_if_t<std::is_convertible<
+              T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
+bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return other < one;
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename = std::enable_if_t<
+        std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
+        !gsl::details::is_basic_string_span<T>::value>>
+bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return other < one;
+}
+
+#ifndef _MSC_VER
+
+// VS treats temp and const containers as convertible to basic_string_span,
+// so the cases below are already covered by the previous operators
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return other < one;
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return other < one;
+}
+#endif
+
+// operator >=
+template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+          typename = std::enable_if_t<std::is_convertible<
+              T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
+bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return !(one < other);
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename = std::enable_if_t<
+        std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
+        !gsl::details::is_basic_string_span<T>::value>>
+bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return !(one < other);
+}
+
+#ifndef _MSC_VER
+
+// VS treats temp and const containers as convertible to basic_string_span,
+// so the cases below are already covered by the previous operators
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
+{
+    return !(one < other);
+}
+
+template <
+    typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
+    typename DataType = typename T::value_type,
+    typename = std::enable_if_t<
+        !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
+        std::is_convertible<DataType*, CharT*>::value &&
+        std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
+                     DataType>::value>>
+bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
+{
+    return !(one < other);
+}
+#endif
+} // namespace gsl
+
+#undef GSL_NOEXCEPT
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+
+#if _MSC_VER < 1910
+#undef constexpr
+#pragma pop_macro("constexpr")
+
+#endif // _MSC_VER < 1910
+#endif // _MSC_VER
+
+#endif // GSL_STRING_SPAN_H
