.. _program_listing_file_include_opentelemetry_nostd_span.h: Program Listing for File span.h =============================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/opentelemetry/nostd/span.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2020, OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #ifdef HAVE_CPP_STDLIB # include "opentelemetry/std/span.h" #else # include # include # include # include # include # include # include "opentelemetry/nostd/utility.h" # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { constexpr size_t dynamic_extent = static_cast(-1); template class span; namespace detail { template struct is_specialized_span_convertible : std::false_type {}; template struct is_specialized_span_convertible> : std::true_type {}; template struct is_specialized_span_convertible : std::true_type {}; template struct is_specialized_span_convertible> : std::true_type {}; } // namespace detail template class span { public: static constexpr size_t extent = Extent; // This arcane code is how we make default-construction result in an SFINAE error // with C++11 when Extent != 0 as specified by the std::span API. // // See https://stackoverflow.com/a/10309720/4447365 template ::type * = nullptr> span() noexcept : data_{nullptr} {} span(T *data, size_t count) noexcept : data_{data} { if (count != Extent) { std::terminate(); } } span(T *first, T *last) noexcept : data_{first} { if (std::distance(first, last) != Extent) { std::terminate(); } } template ::type * = nullptr> span(T (&array)[N]) noexcept : data_{array} {} template ::type * = nullptr> span(std::array &array) noexcept : data_{array.data()} {} template ::type * = nullptr> span(const std::array &array) noexcept : data_{array.data()} {} template < class C, typename std::enable_if::value && std::is_convertible()))>::type (*)[], T (*)[]>::value && std::is_convertible())), size_t>::value>::type * = nullptr> span(C &c) noexcept(noexcept(nostd::data(c), nostd::size(c))) : data_{nostd::data(c)} { if (nostd::size(c) != Extent) { std::terminate(); } } template < class C, typename std::enable_if::value && std::is_convertible()))>::type (*)[], T (*)[]>::value && std::is_convertible())), size_t>::value>::type * = nullptr> span(const C &c) noexcept(noexcept(nostd::data(c), nostd::size(c))) : data_{nostd::data(c)} { if (nostd::size(c) != Extent) { std::terminate(); } } template ::value>::type * = nullptr> span(const span &other) noexcept : data_{other.data()} {} span(const span &) noexcept = default; bool empty() const noexcept { return Extent == 0; } T *data() const noexcept { return data_; } size_t size() const noexcept { return Extent; } T &operator[](size_t index) const noexcept { assert(index < Extent); return data_[index]; } T *begin() const noexcept { return data_; } T *end() const noexcept { return data_ + Extent; } private: T *data_; }; template class span { public: static constexpr size_t extent = dynamic_extent; span() noexcept : extent_{0}, data_{nullptr} {} span(T *data, size_t count) noexcept : extent_{count}, data_{data} {} span(T *first, T *last) noexcept : extent_{static_cast(std::distance(first, last))}, data_{first} { assert(first <= last); } template span(T (&array)[N]) noexcept : extent_{N}, data_{array} {} template span(std::array &array) noexcept : extent_{N}, data_{array.data()} {} template span(const std::array &array) noexcept : extent_{N}, data_{array.data()} {} template < class C, typename std::enable_if::value && std::is_convertible()))>::type (*)[], T (*)[]>::value && std::is_convertible())), size_t>::value>::type * = nullptr> span(C &c) noexcept(noexcept(nostd::data(c), nostd::size(c))) : extent_{nostd::size(c)}, data_{nostd::data(c)} {} template < class C, typename std::enable_if::value && std::is_convertible()))>::type (*)[], T (*)[]>::value && std::is_convertible())), size_t>::value>::type * = nullptr> span(const C &c) noexcept(noexcept(nostd::data(c), nostd::size(c))) : extent_{nostd::size(c)}, data_{nostd::data(c)} {} template ::value>::type * = nullptr> span(const span &other) noexcept : extent_{other.size()}, data_{other.data()} {} span(const span &) noexcept = default; bool empty() const noexcept { return extent_ == 0; } T *data() const noexcept { return data_; } size_t size() const noexcept { return extent_; } T &operator[](size_t index) const noexcept { assert(index < extent_); return data_[index]; } T *begin() const noexcept { return data_; } T *end() const noexcept { return data_ + extent_; } private: // Note: matches libstdc++'s layout for std::span // See // https://github.com/gcc-mirror/gcc/blob/a60701e05b3878000ff9fdde1aecbc472b9dec5a/libstdc%2B%2B-v3/include/std/span#L402-L403 size_t extent_; T *data_; }; } // namespace nostd OPENTELEMETRY_END_NAMESPACE #endif