blob: 9f56f2ad838722ab7c8ab4927d58bedb83babac1 [file] [log] [blame] [edit]
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "cc_bindings_from_rs/test/tuples/tuples.h"
#include <tuple>
#include <type_traits>
#include <utility>
#include "gtest/gtest.h"
namespace crubit {
namespace {
TEST(TuplesTest, ReturnUnitIsNotTuple) {
static_assert(
std::is_same_v<decltype(tuples::return_unit_is_not_tuple()), void>);
tuples::return_unit_is_not_tuple();
}
TEST(TuplesTest, ReturnCAbiCompatibleFiveInTuple) {
std::tuple<uint32_t> v = tuples::return_c_abi_compatible_five_in_tuple();
EXPECT_EQ(std::get<0>(v), 5);
}
TEST(TuplesTest, ParamCAbiCompatibleFiveInTuple) {
tuples::param_c_abi_compatible_five_in_tuple(std::make_tuple(5));
}
TEST(TuplesTest, AdtInTuple) {
std::tuple<tuples::AdtHoldingFiveAndSix> v = tuples::return_adt_in_tuple();
tuples::param_adt_in_tuple(std::move(v));
}
TEST(TuplesTest, NontrivialDropInTuple) {
// NOTE: `assert_nontrivial_drop_count` accesses a global variable
// mutated by the `NontrivialDrop` destructor.
//
// Copying this test will result in assertion failures.
tuples::assert_nontrivial_drop_count(0);
{
std::tuple<tuples::NontrivialDrop> v =
tuples::return_new_nontrivial_drop_in_tuple();
tuples::assert_nontrivial_drop_count(0);
}
tuples::assert_nontrivial_drop_count(1);
tuples::param_nontrivial_drop_in_tuple(
tuples::return_new_nontrivial_drop_in_tuple());
tuples::assert_nontrivial_drop_count(2);
}
// TODO(jeanpierreda): enable non-movable types inside compound data types like
// tuples?
//
// TEST(TuplesTest, NonCppMovableInTuple) {
// std::tuple<tuples::NonCppMovable> v =
// tuples::return_new_non_cpp_movable_in_tuple();
// EXPECT_EQ(std::get<0>(v).value, 42);
// std::tuple<std::tuple<tuples::NonCppMovable>> nested_v =
// tuples::return_new_non_cpp_movable_in_nested_tuple();
// EXPECT_EQ(std::get<0>(std::get<0>(nested_v)).value, 42);
// }
TEST(TuplesTest, NestedTupleParameters) {
tuples::param_nested_tuples(std::make_tuple(std::make_tuple(1, 2), 3));
}
TEST(TuplesTest, NestedTupleReturns) {
std::tuple<std::tuple<int32_t, int32_t>, int32_t> v =
tuples::return_nested_tuples();
EXPECT_EQ(std::get<0>(std::get<0>(v)), 1);
EXPECT_EQ(std::get<1>(std::get<0>(v)), 2);
EXPECT_EQ(std::get<1>(v), 3);
}
TEST(TuplesTest, TriplyNestedTupleParameters) {
tuples::param_triply_nested_tuple(
std::make_tuple(std::make_tuple(std::make_tuple(57))));
}
TEST(TuplesTest, TriplyNestedTupleReturns) {
std::tuple<std::tuple<std::tuple<int32_t>>> v =
tuples::return_triply_nested_tuple();
EXPECT_EQ(std::get<0>(std::get<0>(std::get<0>(v))), 57);
}
TEST(TuplesTest, FfiAliasInTuple) {
std::tuple<char> v = tuples::return_ffi_alias_in_tuple();
EXPECT_EQ(std::get<0>(v), 5);
tuples::param_ffi_alias_in_tuple(std::make_tuple<char>(5));
}
template <typename T>
concept HasBadTupleMethod = requires(T t) { t.tuple_not_by_value(); };
TEST(TuplesTest, TupleStruct) {
// Can't directly test the tuple fields, because binary blob fields are
// private, and ZST fields don't exist at all.
EXPECT_FALSE(HasBadTupleMethod<tuples::TupleStruct>)
<< "Tuples cannot be bridged to std::tuple except when used by value";
}
} // namespace
} // namespace crubit