chromium/v8/include/v8-memory-span.h

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef INCLUDE_V8_MEMORY_SPAN_H_
#define INCLUDE_V8_MEMORY_SPAN_H_

#include <stddef.h>

#include <array>
#include <iterator>
#include <type_traits>

#include "v8config.h"  // NOLINT(build/include_directory)

// TODO(pkasting): Use <compare>/spaceship unconditionally after dropping
// support for old libstdc++ versions.
#if __has_include(<version>)
#include <version>
#endif
#if defined(__cpp_lib_three_way_comparison) && \
    __cpp_lib_three_way_comparison >= 201711L
#define V8_HAVE_SPACESHIP_OPERATOR
#else
#define V8_HAVE_SPACESHIP_OPERATOR
#endif

// TODO(pkasting): Make this block unconditional after dropping support for old
// libstdc++ versions.
#if __has_include(<ranges>)
#include <ranges>

namespace v8 {

template <typename T>
class V8_EXPORT MemorySpan;

}  // namespace v8

// Mark `MemorySpan` as satisfying the `view` and `borrowed_range` concepts.
// This should be done before the definition of `MemorySpan`, so that any
// inlined calls to range functionality use the correct specializations.
enable_view;
enable_borrowed_range;
#endif

namespace v8 {

/**
 * Points to an unowned contiguous buffer holding a known number of elements.
 *
 * This is similar to std::span (under consideration for C++20), but does not
 * require advanced C++ support. In the (far) future, this may be replaced with
 * or aliased to std::span.
 *
 * To facilitate future migration, this class exposes a subset of the interface
 * implemented by std::span.
 */
template <typename T>
class V8_EXPORT MemorySpan {};

/**
 * Helper function template to create an array of fixed length, initialized by
 * the provided initializer list, without explicitly specifying the array size,
 * e.g.
 *
 *   auto arr = v8::to_array<Local<String>>({v8_str("one"), v8_str("two")});
 *
 * In the future, this may be replaced with or aliased to std::to_array (under
 * consideration for C++20).
 */

namespace detail {
template <class T, std::size_t N, std::size_t... I>
[[nodiscard]] constexpr std::array<std::remove_cv_t<T>, N> to_array_lvalue_impl(
    T (&a)[N], std::index_sequence<I...>) {}

template <class T, std::size_t N, std::size_t... I>
[[nodiscard]] constexpr std::array<std::remove_cv_t<T>, N> to_array_rvalue_impl(
    T (&&a)[N], std::index_sequence<I...>) {}
}  // namespace detail

template <class T, std::size_t N>
[[nodiscard]] constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N]) {}

template <class T, std::size_t N>
[[nodiscard]] constexpr std::array<std::remove_cv_t<T>, N> to_array(
    T (&&a)[N]) {}

}  // namespace v8
#endif  // INCLUDE_V8_MEMORY_SPAN_H_