summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/utility/utility.inplace/inplace.pass.cpp
blob: 0cf8e38f5ab0b051d37d4a045873ffcd0f7849d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//===----------------------------------------------------------------------===//
//
//                     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, c++14

// <utility>

// struct in_place_tag { in_place_tag() = delete; };
//
// using in_place_t = in_place_tag(&)(unspecified);
// template <class T>
//     using in_place_type_t = in_place_tag(&)(unspecified<T>);
// template <size_t N>
//     using in_place_index_t = in_place_tag(&)(unspecified<N>);
//
// in_place_tag in_place(unspecified);
//
// template <class T>;
// in_place_tag in_place(unspecified<T>);
//
// template <size_t N>
// in_place_tag in_place(unspecified<N>);

#include <utility>
#include <cassert>
#include <memory>

#include "test_macros.h"
#include "type_id.h"

template <class Tp>
struct CheckRet : std::false_type {};
template <class Arg>
struct CheckRet<std::in_place_tag(Arg)> : std::true_type {};

TypeID const* test_fn(std::in_place_t) { return &makeTypeID<std::in_place_t>(); }
template <class T>
TypeID const* test_fn(std::in_place_type_t<T>)
{ return &makeTypeID<std::in_place_type_t<T>>(); }

template <size_t I>
TypeID const* test_fn(std::in_place_index_t<I>)
{ return &makeTypeID<std::in_place_index_t<I>>(); }

// Concrete test overloads that don't have to be deduced.
template <class Tag>
TypeID const* concrete_test_fn(Tag) {  return &makeTypeID<Tag>(); }

template <class Tp>
bool check_tag_basic() {
  using RawTp = typename std::remove_reference<Tp>::type;
  static_assert(std::is_lvalue_reference<Tp>::value, "");
  static_assert(std::is_function<RawTp>::value, "");
  static_assert(CheckRet<RawTp>::value, "");
  auto concrete_fn = concrete_test_fn<Tp>;
  return test_fn((Tp)std::in_place) == &makeTypeID<Tp>()
      && concrete_fn(std::in_place) == &makeTypeID<Tp>();
}

int main() {
    // test in_place_tag
    {
        static_assert(!std::is_default_constructible<std::in_place_tag>::value, "");
    }
    // test in_place_t
    {
        using T = std::in_place_t;
        assert(check_tag_basic<std::in_place_t>());
        assert(test_fn((T)std::in_place) == &makeTypeID<T>());
    }
    // test in_place_type_t
    {
        using T1 = std::in_place_type_t<void>;
        using T2 = std::in_place_type_t<int>;
        using T3 = std::in_place_type_t<const int>;
        assert(check_tag_basic<T1>());
        assert(check_tag_basic<T2>());
        assert(check_tag_basic<T3>());
        static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
        static_assert(!std::is_same<T2, T3>::value, "");
    }
    // test in_place_index_t
    {
        using T1 = std::in_place_index_t<0>;
        using T2 = std::in_place_index_t<1>;
        using T3 = std::in_place_index_t<static_cast<size_t>(-1)>;
        assert(check_tag_basic<T1>());
        assert(check_tag_basic<T2>());
        assert(check_tag_basic<T3>());
        static_assert(!std::is_same<T1, T2>::value && !std::is_same<T1, T3>::value, "");
        static_assert(!std::is_same<T2, T3>::value, "");
    }
}
OpenPOWER on IntegriCloud