/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include "cpp/Marshallable.h" namespace hs_std_variant::detail { template void std_variant_poke(void* var, void* val, uint32_t idx) { constexpr auto variant_size = std::variant_size_v; DCHECK_NE(idx, 0); DCHECK_LT(idx, variant_size); boost::mp11::mp_with_index(idx, [&](auto tag) { using type = std::variant_alternative_t; auto& val_ = *reinterpret_cast(val); new (var) V{std::in_place_index, std::move(val_)}; }); } } // namespace hs_std_variant::detail // **************************************************************************** #define hsc_derive_hs_std_variant_unsafe(cxx_name...) \ hsc_printf( \ "deriveHsStdVariantUnsafe \"%s\" %lu ", \ #cxx_name, \ (unsigned long)sizeof(hs_std_variant::cxx_name)); \ hsc_alignment(hs_std_variant::cxx_name); #define HS_STD_VARIANT_H(Name, ...) \ namespace hs_std_variant { \ using Name = std::variant; \ } #define HS_STD_VARIANT_CPP(Name) \ HS_PEEKABLE(hs_std_variant::Name); \ HS_DEFINE_MARSHALLABLE(Name, hs_std_variant::Name) \ \ extern "C" void* std_variant_peek##Name(void* var, int32_t* idx) noexcept { \ constexpr auto variant_size = std::variant_size_v; \ auto& var_ = *reinterpret_cast(var); \ *idx = var_.index(); \ DCHECK_GT(*idx, 0); \ DCHECK_LT(*idx, variant_size); \ return boost::mp11::mp_with_index(*idx, [&](auto tag) { \ return reinterpret_cast(&std::get(var_)); \ }); \ } \ \ extern "C" void std_variant_poke##Name( \ void* variant, void* val, int32_t tag) noexcept { \ hs_std_variant::detail::std_variant_poke( \ variant, val, tag); \ }