// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. #pragma once #include #include #include #include namespace wpi { struct empty_array_t {}; constexpr empty_array_t empty_array; /** * This class is a wrapper around std::array that does compile time size * checking. * * std::array's implicit constructor can result in uninitialized elements if the * number of arguments doesn't match the std::array size. */ template class array : public std::array { public: constexpr explicit array(empty_array_t) {} template constexpr array(T arg, Ts&&... args) // NOLINT : std::array{std::forward(arg), std::forward(args)...} { static_assert(1 + sizeof...(args) == N, "Dimension mismatch"); } constexpr array(const array&) = default; constexpr array& operator=(const array&) = default; constexpr array(array&&) = default; constexpr array& operator=(array&&) = default; constexpr array(const std::array& rhs) { // NOLINT *static_cast*>(this) = rhs; } constexpr array& operator=(const std::array& rhs) { *static_cast*>(this) = rhs; return *this; } constexpr array(std::array&& rhs) { // NOLINT *static_cast*>(this) = rhs; } constexpr array& operator=(std::array&& rhs) { *static_cast*>(this) = rhs; return *this; } }; template array(T, Ts...) -> array && ...), T>, 1 + sizeof...(Ts)>; } // namespace wpi template constexpr T& get(wpi::array& arr) noexcept { static_assert(I < N, "array index is within bounds"); return std::get(static_cast>(arr)); } template constexpr T&& get(wpi::array&& arr) noexcept { static_assert(I < N, "array index is within bounds"); return std::move(std::get(arr)); } template constexpr const T& get(const wpi::array& arr) noexcept { static_assert(I < N, "array index is within bounds"); return std::get(static_cast>(arr)); } template constexpr const T&& get(const wpi::array&& arr) noexcept { static_assert(I < N, "array index is within bounds"); return std::move(std::get(arr)); } // Enables structured bindings namespace std { // NOLINT // Partial specialization for wpi::array template struct tuple_size> : public integral_constant {}; // Partial specialization for wpi::array template struct tuple_element> { static_assert(I < N, "index is out of bounds"); using type = T; }; } // namespace std