// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once #include #include "core/common/gsl.h" namespace onnxruntime { // AsSpan inspired by Fekir's Blog https://fekir.info/post/span-the-missing-constructor/ // Used under MIT license // Use AsSpan for less typing on any container including initializer list to create a span // (unnamed, untyped initializer list does not automatically convert to gsl::span). // {1, 2, 3} as such does not have a type // (see https://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html) // // Example: AsSpan({1, 2, 3}) results in gsl::span // // The above would deduce to std::initializer_list and the result is gsl::span // // AsSpan({1, 2, 3}) produces gsl::span // // We can also do std::array{1, 2, 3} that can be automatically converted to span // without memory allocation. // // If type conversion is not required, then for C++17 std::array template parameters are // auto-deduced. Example: std::array{1, 2, 3}. // We are aiming at not allocating memory dynamically. namespace details { template constexpr auto AsSpanImpl(P* p, size_t s) { return gsl::span

(p, s); } } // namespace details template constexpr auto AsSpan(C& c) { return details::AsSpanImpl(c.data(), c.size()); } template constexpr auto AsSpan(const C& c) { return details::AsSpanImpl(c.data(), c.size()); } template constexpr auto AsSpan(C&& c) { return details::AsSpanImpl(c.data(), c.size()); } template constexpr auto AsSpan(std::initializer_list c) { return details::AsSpanImpl(c.begin(), c.size()); } template constexpr auto AsSpan(T (&arr)[N]) { return details::AsSpanImpl(arr, N); } template constexpr auto AsSpan(const T (&arr)[N]) { return details::AsSpanImpl(arr, N); } template inline gsl::span EmptySpan() { return gsl::span(); } template [[nodiscard]] inline gsl::span ReinterpretAsSpan(gsl::span src) { // adapted from gsl-lite span::as_span(): // https://github.com/gsl-lite/gsl-lite/blob/4720a2980a30da085b4ddb4a0ea2a71af7351a48/include/gsl/gsl-lite.hpp#L4102-L4108 Expects(src.size_bytes() % sizeof(U) == 0); return gsl::span(reinterpret_cast(src.data()), src.size_bytes() / sizeof(U)); } template [[nodiscard]] inline bool SpanEq(gsl::span a, gsl::span b) { static_assert(std::is_same_v, std::remove_const_t>, "T1 and T2 should be the same type except for const qualification"); return std::equal(a.begin(), a.end(), b.begin(), b.end()); } } // namespace onnxruntime