Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)

// Test with different ref/ptr/cv qualified argument types.

#include <experimental/tuple>
#include <array>
#include <utility>
#include <cassert>

namespace ex = std::experimental;

int call_with_value(int x, int y) { return (x + y); }
int call_with_ref(int & x, int & y) { return (x + y); }
int call_with_const_ref(int const & x, int const & y) { return (x + y); }
int call_with_rvalue_ref(int && x, int && y) { return (x + y); }
int call_with_pointer(int * x, int * y) { return (*x + *y); }
int call_with_const_pointer(int const* x, int const * y) { return (*x + *y); }


template <class Tuple>
void test_values()
{
{
Tuple t{1, 2};
assert(3 == ex::apply(call_with_value, t));
}
{
Tuple t{2, 2};
assert(4 == ex::apply(call_with_ref, t));
}
{
Tuple t{2, 3};
assert(5 == ex::apply(call_with_const_ref, t));
}
{
Tuple t{3, 3};
assert(6 == ex::apply(call_with_rvalue_ref, static_cast<Tuple &&>(t)));
}
{
Tuple const t{4, 4};
assert(8 == ex::apply(call_with_value, t));
}
{
Tuple const t{4, 5};
assert(9 == ex::apply(call_with_const_ref, t));
}
}

template <class Tuple>
void test_refs()
{
int x = 0;
int y = 0;
{
x = 1; y = 2;
Tuple t{x, y};
assert(3 == ex::apply(call_with_value, t));
}
{
x = 2; y = 2;
Tuple t{x, y};
assert(4 == ex::apply(call_with_ref, t));
}
{
x = 2; y = 3;
Tuple t{x, y};
assert(5 == ex::apply(call_with_const_ref, t));
}
{
x = 3; y = 3;
Tuple const t{x, y};
assert(6 == ex::apply(call_with_value, t));
}
{
x = 3; y = 4;
Tuple const t{x, y};
assert(7 == ex::apply(call_with_const_ref, t));
}
}

template <class Tuple>
void test_const_refs()
{
int x = 0;
int y = 0;
{
x = 1; y = 2;
Tuple t{x, y};
assert(3 == ex::apply(call_with_value, t));
}
{
x = 2; y = 3;
Tuple t{x, y};
assert(5 == ex::apply(call_with_const_ref, t));
}
{
x = 3; y = 3;
Tuple const t{x, y};
assert(6 == ex::apply(call_with_value, t));
}
{
x = 3; y = 4;
Tuple const t{x, y};
assert(7 == ex::apply(call_with_const_ref, t));
}
}


template <class Tuple>
void test_pointer()
{
int x = 0;
int y = 0;
{
x = 2; y = 2;
Tuple t{&x, &y};
assert(4 == ex::apply(call_with_pointer, t));
}
{
x = 2; y = 3;
Tuple t{&x, &y};
assert(5 == ex::apply(call_with_const_pointer, t));
}
{
x = 3; y = 4;
Tuple const t{&x, &y};
assert(7 == ex::apply(call_with_const_pointer, t));
}
}


template <class Tuple>
void test_const_pointer()
{
int x = 0;
int y = 0;
{
x = 2; y = 3;
Tuple t{&x, &y};
assert(5 == ex::apply(call_with_const_pointer, t));
}
{
x = 3; y = 4;
Tuple const t{&x, &y};
assert(7 == ex::apply(call_with_const_pointer, t));
}
}


int main()
{
test_values<std::tuple<int, int>>();
test_values<std::pair<int, int>>();
test_values<std::array<int, 2>>();

test_refs<std::tuple<int &, int &>>();
test_refs<std::pair<int &, int &>>();

test_const_refs<std::tuple<int const &, int const &>>();
test_const_refs<std::pair<int const &, int const &>>();

test_pointer<std::tuple<int *, int *>>();
test_pointer<std::pair<int *, int *>>();
test_pointer<std::array<int *, 2>>();

test_const_pointer<std::tuple<int const *, int const *>>();
test_const_pointer<std::pair<int const *, int const *>>();
test_const_pointer<std::array<int const *, 2>>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)

// Testing constexpr evaluation

#include <experimental/tuple>
#include <utility>
#include <cassert>

constexpr int f_int_0() { return 1; }
constexpr int f_int_1(int x) { return x; }
constexpr int f_int_2(int x, int y) { return (x + y); }

struct A_int_0
{
constexpr A_int_0() {}
constexpr int operator()() const { return 1; }
};

struct A_int_1
{
constexpr A_int_1() {}
constexpr int operator()(int x) const { return x; }
};

struct A_int_2
{
constexpr A_int_2() {}
constexpr int operator()(int x, int y) const { return (x + y); }
};

namespace ex = std::experimental;

template <class Tuple>
void test_0()
{
// function
{
constexpr Tuple t{};
static_assert(1 == ex::apply(f_int_0, t), "");
}
// function pointer
{
constexpr Tuple t{};
constexpr auto fp = &f_int_0;
static_assert(1 == ex::apply(fp, t), "");
}
// functor
{
constexpr Tuple t{};
constexpr A_int_0 a;
static_assert(1 == ex::apply(a, t), "");
}
}

template <class Tuple>
void test_1()
{
// function
{
constexpr Tuple t{1};
static_assert(1 == ex::apply(f_int_1, t), "");
}
// function pointer
{
constexpr Tuple t{2};
constexpr int (*fp)(int) = f_int_1;
static_assert(2 == ex::apply(fp, t), "");
}
// functor
{
constexpr Tuple t{3};
constexpr A_int_1 fn;
static_assert(3 == ex::apply(fn, t), "");
}
}

template <class Tuple>
void test_2()
{
// function
{
constexpr Tuple t{1, 2};
static_assert(3 == ex::apply(f_int_2, t), "");
}
// function pointer
{
constexpr Tuple t{2, 3};
constexpr auto fp = &f_int_2;
static_assert(5 == ex::apply(fp, t), "");
}
// functor
{
constexpr Tuple t{3, 4};
constexpr A_int_2 a;
static_assert(7 == ex::apply(a, t), "");
}
}

int main()
{
test_0<std::tuple<>>();
test_1<std::tuple<int>>();
test_2<std::tuple<int, int>>();
test_2<std::pair<int, int>>();
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)

// Stress testing large arities with tuple and array.

#include <experimental/tuple>
#include <array>
#include <utility>
#include <cassert>

////////////////////////////////////////////////////////////////////////////////
template <class T, std::size_t Dummy = 0>
struct always_imp
{
typedef T type;
};

template <class T, std::size_t Dummy = 0>
using always_t = typename always_imp<T, Dummy>::type;

////////////////////////////////////////////////////////////////////////////////
template <class Tuple, class Idx>
struct make_function;

template <class Tp, std::size_t ...Idx>
struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>>
{
using type = bool (*)(always_t<Tp, Idx>...);
};

template <class Tp, std::size_t Size>
using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type;

////////////////////////////////////////////////////////////////////////////////
template <class Tp, class Idx>
struct make_tuple_imp;

////////////////////////////////////////////////////////////////////////////////
template <class Tp, std::size_t ...Idx>
struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>>
{
using type = std::tuple<always_t<Tp, Idx>...>;
};

template <class Tp, std::size_t Size>
using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type;

template <class ...Types>
bool test_apply_fn(Types...) { return true; }

namespace ex = std::experimental;

template <std::size_t Size>
void test_all()
{

using A = std::array<int, Size>;
using ConstA = std::array<int const, Size>;

using Tuple = make_tuple_t<int, Size>;
using CTuple = make_tuple_t<const int, Size>;

using ValFn = make_function_t<int, Size>;
ValFn val_fn = &test_apply_fn;

using RefFn = make_function_t<int &, Size>;
RefFn ref_fn = &test_apply_fn;

using CRefFn = make_function_t<int const &, Size>;
CRefFn cref_fn = &test_apply_fn;

using RRefFn = make_function_t<int &&, Size>;
RRefFn rref_fn = &test_apply_fn;

{
A a{};
assert(ex::apply(val_fn, a));
assert(ex::apply(ref_fn, a));
assert(ex::apply(cref_fn, a));
assert(ex::apply(rref_fn, std::move(a)));
}
{
ConstA a{};
assert(ex::apply(val_fn, a));
assert(ex::apply(cref_fn, a));
}
{
Tuple a{};
assert(ex::apply(val_fn, a));
assert(ex::apply(ref_fn, a));
assert(ex::apply(cref_fn, a));
assert(ex::apply(rref_fn, std::move(a)));
}
{
CTuple a{};
assert(ex::apply(val_fn, a));
assert(ex::apply(cref_fn, a));
}

}


template <std::size_t Size>
void test_one()
{
using A = std::array<int, Size>;
using Tuple = make_tuple_t<int, Size>;

using ValFn = make_function_t<int, Size>;
ValFn val_fn = &test_apply_fn;

{
A a{};
assert(ex::apply(val_fn, a));
}
{
Tuple a{};
assert(ex::apply(val_fn, a));
}
}

int main()
{
// Instantiate with 1-5 arguments.
test_all<1>();
test_all<2>();
test_all<3>();
test_all<4>();
test_all<5>();

// Stress test with 128.
test_one<128>();
//test_one<256>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)

// Testing ref qualified functions

#include <experimental/tuple>
#include <cassert>

struct func_obj
{
constexpr func_obj() {}

constexpr int operator()() const & { return 1; }
constexpr int operator()() const && { return 2; }
constexpr int operator()() & { return 3; }
constexpr int operator()() && { return 4; }
};

namespace ex = std::experimental;

int main()
{
{
constexpr func_obj f;
constexpr std::tuple<> tp;

static_assert(1 == ex::apply(static_cast<func_obj const &>(f), tp), "");
static_assert(2 == ex::apply(static_cast<func_obj const &&>(f), tp), "");
}
{
func_obj f;
std::tuple<> tp;
assert(1 == ex::apply(static_cast<func_obj const &>(f), tp));
assert(2 == ex::apply(static_cast<func_obj const &&>(f), tp));
assert(3 == ex::apply(static_cast<func_obj &>(f), tp));
assert(4 == ex::apply(static_cast<func_obj &&>(f), tp));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)

// Test the return type deduction.

#include <experimental/tuple>
#include <cassert>

static int my_int = 42;

template <int N> struct index {};

void f(index<0>) {}

int f(index<1>) { return 0; }
int const f(index<2>) { return 0; }
int volatile f(index<3>) { return 0; }
int const volatile f(index<4>) { return 0; }

int & f(index<5>) { return static_cast<int &>(my_int); }
int const & f(index<6>) { return static_cast<int const &>(my_int); }
int volatile & f(index<7>) { return static_cast<int volatile &>(my_int); }
int const volatile & f(index<8>) { return static_cast<int const volatile &>(my_int); }

int && f(index<9>) { return static_cast<int &&>(my_int); }
int const && f(index<10>) { return static_cast<int const &&>(my_int); }
int volatile && f(index<11>) { return static_cast<int volatile &&>(my_int); }
int const volatile && f(index<12>) { return static_cast<int const volatile &&>(my_int); }

int * f(index<13>) { return static_cast<int *>(&my_int); }
int const * f(index<14>) { return static_cast<int const *>(&my_int); }
int volatile * f(index<15>) { return static_cast<int volatile *>(&my_int); }
int const volatile * f(index<16>) { return static_cast<int const volatile *>(&my_int); }


template <int Func, class Expect>
void test()
{
using F = decltype((f(index<Func>{})));
static_assert(std::is_same<F, Expect>::value, "");
}

namespace ex = std::experimental;

int main()
{
test<0, void>();
test<1, int>();
//test<2, int const>();
//test<3, int volatile>();
//test<4, int const volatile>();
test<5, int &>();
test<6, int const &>();
test<7, int volatile &>();
test<8, int const volatile &>();
test<9, int &&>();
test<10, int const &&>();
test<11, int volatile &&>();
test<12, int const volatile &&>();
test<13, int *>();
test<14, int const *>();
test<15, int volatile *>();
test<16, int const volatile *>();
}

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions libcxx/test/std/experimental/utilities/tuple/tuple_size_v.fail.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;

// Test with reference

#include <experimental/tuple>

namespace ex = std::experimental;

int main()
{
auto x = ex::tuple_size_v<std::tuple<> &>;
}
45 changes: 45 additions & 0 deletions libcxx/test/std/experimental/utilities/tuple/tuple_size_v.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;

#include <experimental/tuple>
#include <utility>
#include <array>

namespace ex = std::experimental;

template <class Tuple, int Expect>
void test()
{
static_assert(ex::tuple_size_v<Tuple> == Expect, "");
static_assert(ex::tuple_size_v<Tuple> == std::tuple_size<Tuple>::value, "");
static_assert(ex::tuple_size_v<Tuple const> == std::tuple_size<Tuple>::value, "");
static_assert(ex::tuple_size_v<Tuple volatile> == std::tuple_size<Tuple>::value, "");
static_assert(ex::tuple_size_v<Tuple const volatile> == std::tuple_size<Tuple>::value, "");
}

int main()
{
test<std::tuple<>, 0>();

test<std::tuple<int>, 1>();
test<std::array<int, 1>, 1>();

test<std::tuple<int, int>, 2>();
test<std::pair<int, int>, 2>();
test<std::array<int, 2>, 2>();

test<std::tuple<int, int, int>, 3>();
test<std::array<int, 3>, 3>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;

// Test with non tuple type

#include <experimental/tuple>

namespace ex = std::experimental;

int main()
{
auto x = ex::tuple_size_v<int>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03, c++11

// <experimental/tuple>

// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;

// Test with pointer

#include <experimental/tuple>

namespace ex = std::experimental;

int main()
{
auto x = ex::tuple_size_v<std::tuple<>*>;
}
2 changes: 1 addition & 1 deletion libcxx/www/ts1z_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ <h3>Features in Library Fundamentals 1</h3>
<tr><td>Additions to std::packaged_task</td><td>Not started</td></tr>
<tr><td></td><td></td></tr>
<tr><td>Class erased_type</td><td>Complete</td></tr>
<tr><td>Calling a function with a tuple of arguments</td><td>Implementation in progress</td></tr>
<tr><td>Calling a function with a tuple of arguments</td><td>Complete</td></tr>
<tr><td>Other type transformations</td><td>Not started</td></tr>
<tr><td>Compile-time Rational Arithmetic</td><td>Implementation in progress</td></tr>
<tr><td>Time Utilities</td><td>Complete</td></tr>
Expand Down