// Copyright 2024 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 V8_OBJECTS_UNION_H_ #define V8_OBJECTS_UNION_H_ #include "src/base/template-utils.h" #include "src/common/globals.h" namespace v8::internal { // Union<Ts...> represents a union of multiple V8 types. // // Unions are required to be non-nested (i.e. no unions of unions), and to // have each type only once. The UnionOf<Ts...> helper can be used to flatten // nested unions and remove duplicates. // // Inheritance from Unions is forbidden because it messes with `is_subtype` // checking. template <typename... Ts> class Union; // is_union<T> is a type trait that returns true if T is a union. template <typename... Ts> struct is_union : public std::false_type { … }; is_union<Union<Ts...>>; is_union_v; template <typename... Ts> class Union final : public AllStatic { … }; namespace detail { template <typename Accumulator, typename... InputTypes> struct FlattenUnionHelper; // Base case: No input types, return the accumulated types. FlattenUnionHelper<Union<OutputTs...>>; // Recursive case: Non-union input, accumulate and continue. FlattenUnionHelper<Union<OutputTs...>, Head, Ts...>; // Recursive case: Smi input, normalize to always be the first element. // // This is a small optimization to try reduce the number of template // specializations -- ideally we would fully sort the types but this probably // costs more templates than it saves. FlattenUnionHelper<Union<OutputTs...>, Smi, Ts...>; // Recursive case: Union input, flatten and continue. FlattenUnionHelper<Union<OutputTs...>, Union<HeadTs...>, Ts...>; } // namespace detail // UnionOf<Ts...> is a helper that returns a union of multiple V8 types, // flattening any nested unions and removing duplicate types. UnionOf; // Unions of unions are flattened. static_assert …; // Unions with duplicates are deduplicated. static_assert …; // Unions with Smis are normalized to have the Smi be the first element. static_assert …; } // namespace v8::internal #endif // V8_OBJECTS_UNION_H_