// Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved. // // 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. // The file has been adapted from pytorch project // Licensed under BSD-style license - // https://github.com/pytorch/pytorch/blob/main/LICENSE #pragma once #include #include #include #include namespace c10 { template class OptionalArrayRef final { public: // Constructors constexpr OptionalArrayRef() noexcept = default; constexpr OptionalArrayRef(std::nullopt_t) noexcept {} OptionalArrayRef(const OptionalArrayRef& other) = default; OptionalArrayRef(OptionalArrayRef&& other) noexcept = default; constexpr OptionalArrayRef(const std::optional>& other) noexcept : wrapped_opt_array_ref(other) {} constexpr OptionalArrayRef(std::optional>&& other) noexcept : wrapped_opt_array_ref(std::move(other)) {} constexpr OptionalArrayRef(const T& value) noexcept : wrapped_opt_array_ref(value) {} template < typename U = ArrayRef, std::enable_if_t, OptionalArrayRef> && !std::is_same_v, std::in_place_t> && std::is_constructible_v, U&&> && std::is_convertible_v> && !std::is_convertible_v, bool> = false> constexpr OptionalArrayRef(U&& value) noexcept( std::is_nothrow_constructible_v, U&&>) : wrapped_opt_array_ref(std::forward(value)) {} template < typename U = ArrayRef, std::enable_if_t, OptionalArrayRef> && !std::is_same_v, std::in_place_t> && std::is_constructible_v, U&&> && !std::is_convertible_v>, bool> = false> constexpr explicit OptionalArrayRef(U&& value) noexcept( std::is_nothrow_constructible_v, U&&>) : wrapped_opt_array_ref(std::forward(value)) {} template constexpr explicit OptionalArrayRef(std::in_place_t ip, Args&&... args) noexcept : wrapped_opt_array_ref(ip, std::forward(args)...) {} template constexpr explicit OptionalArrayRef(std::in_place_t ip, std::initializer_list il, Args&&... args) : wrapped_opt_array_ref(ip, il, std::forward(args)...) {} constexpr OptionalArrayRef(const std::initializer_list& Vec) : wrapped_opt_array_ref(ArrayRef(Vec)) {} // Destructor ~OptionalArrayRef() = default; // Assignment constexpr OptionalArrayRef& operator=(std::nullopt_t) noexcept { wrapped_opt_array_ref = std::nullopt; return *this; } OptionalArrayRef& operator=(const OptionalArrayRef& other) = default; OptionalArrayRef& operator=(OptionalArrayRef&& other) noexcept = default; constexpr OptionalArrayRef& operator=( const std::optional>& other) noexcept { wrapped_opt_array_ref = other; return *this; } constexpr OptionalArrayRef& operator=( std::optional>&& other) noexcept { wrapped_opt_array_ref = std::move(other); return *this; } template , typename = std::enable_if_t< !std::is_same_v, OptionalArrayRef> && std::is_constructible_v, U&&> && std::is_assignable_v&, U&&>>> constexpr OptionalArrayRef& operator=(U&& value) noexcept( std::is_nothrow_constructible_v, U&&>&& std::is_nothrow_assignable_v&, U&&>) { wrapped_opt_array_ref = std::forward(value); return *this; } // Observers constexpr ArrayRef* operator->() noexcept { return &wrapped_opt_array_ref.value(); } constexpr const ArrayRef* operator->() const noexcept { return &wrapped_opt_array_ref.value(); } constexpr ArrayRef& operator*() & noexcept { return wrapped_opt_array_ref.value(); } constexpr const ArrayRef& operator*() const& noexcept { return wrapped_opt_array_ref.value(); } constexpr ArrayRef&& operator*() && noexcept { return std::move(wrapped_opt_array_ref.value()); } constexpr const ArrayRef&& operator*() const&& noexcept { return std::move(wrapped_opt_array_ref.value()); } constexpr explicit operator bool() const noexcept { return wrapped_opt_array_ref.has_value(); } constexpr bool has_value() const noexcept { return wrapped_opt_array_ref.has_value(); } constexpr ArrayRef& value() & { return wrapped_opt_array_ref.value(); } constexpr const ArrayRef& value() const& { return wrapped_opt_array_ref.value(); } constexpr ArrayRef&& value() && { return std::move(wrapped_opt_array_ref.value()); } constexpr const ArrayRef&& value() const&& { return std::move(wrapped_opt_array_ref.value()); } template constexpr std::enable_if_t>, ArrayRef> value_or(U&& default_value) const& { return wrapped_opt_array_ref.value_or(std::forward(default_value)); } template constexpr std::enable_if_t>, ArrayRef> value_or(U&& default_value) && { return wrapped_opt_array_ref.value_or(std::forward(default_value)); } // Modifiers constexpr void swap(OptionalArrayRef& other) noexcept { std::swap(wrapped_opt_array_ref, other.wrapped_opt_array_ref); } constexpr void reset() noexcept { wrapped_opt_array_ref.reset(); } template constexpr std::enable_if_t, Args&&...>, ArrayRef&> emplace(Args&&... args) noexcept( std::is_nothrow_constructible_v, Args&&...>) { return wrapped_opt_array_ref.emplace(std::forward(args)...); } template constexpr ArrayRef& emplace(std::initializer_list il, Args&&... args) noexcept { return wrapped_opt_array_ref.emplace(il, std::forward(args)...); } private: std::optional> wrapped_opt_array_ref; }; using OptionalIntArrayRef = OptionalArrayRef; inline bool operator==(const OptionalIntArrayRef& a1, const IntArrayRef& other) { if (!a1.has_value()) { return false; } return a1.value() == other; } inline bool operator==(const c10::IntArrayRef& a1, const c10::OptionalIntArrayRef& a2) { return a2 == a1; } } // namespace c10 namespace at { using c10::OptionalIntArrayRef; } // namespace at namespace torch { using c10::OptionalIntArrayRef; } // namespace torch