File: test_core.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (302 lines) | stat: -rw-r--r-- 8,769 bytes parent folder | download | duplicates (2)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
// Copyright (c) 2018-2025 Jean-Louis Leroy
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <type_traits>

#define BOOST_TEST_MODULE core
#include <boost/test/unit_test.hpp>

#include <boost/openmethod/preamble.hpp>

using namespace boost::openmethod;
using namespace boost::openmethod::detail;
namespace mp11 = boost::mp11;

#include <boost/openmethod.hpp>
#include <boost/openmethod/inplace_vptr.hpp>
#include <boost/openmethod/interop/std_shared_ptr.hpp>

#include "test_util.hpp"

namespace test_virtual {

struct base {
    virtual ~base() {
    }
};

struct a : base {};
struct b : base {};
struct c : base {};
struct d : base {};
struct e : base {};
struct f : base {};

static_assert(std::is_same_v<
              virtual_traits<base&, default_registry>::virtual_type, base>);

static_assert(
    std::is_same_v<
        virtual_traits<const base&, default_registry>::virtual_type, base>);

static_assert(std::is_same_v<
              virtual_traits<base&&, default_registry>::virtual_type, base>);

static_assert(std::is_same_v<
              mp11::mp_filter<
                  is_virtual, mp11::mp_list<virtual_<a&>, b, virtual_<c&>>>,
              mp11::mp_list<virtual_<a&>, virtual_<c&>>>);

static_assert(std::is_same_v<remove_virtual_<virtual_<a&>>, a&>);

static_assert(std::is_same_v<virtual_type<a&, default_registry>, a>);

static_assert(
    std::is_same_v<
        virtual_types<mp11::mp_list<
            virtual_<std::shared_ptr<a>>, b, virtual_<std::shared_ptr<c>>>>,
        mp11::mp_list<std::shared_ptr<a>, std::shared_ptr<c>>>);

static_assert(std::is_same_v<
              overrider_virtual_types<
                  mp11::mp_list<virtual_<a&>, b, virtual_<c&>>,
                  mp11::mp_list<d&, e, f&>, default_registry>,
              mp11::mp_list<d, f>>);

static_assert(
    std::is_same_v<virtual_type<std::shared_ptr<a>, default_registry>, a>);

static_assert(
    std::is_same_v<
        virtual_traits<virtual_ptr<a>, default_registry>::virtual_type, a>);

static_assert(std::is_same_v<
              select_overrider_virtual_type_aux<
                  virtual_ptr<base>, virtual_ptr<a>, default_registry>::type,
              a>);

static_assert(
    std::is_same_v<
        overrider_virtual_types<
            mp11::mp_list<virtual_ptr<a>, b, virtual_ptr<c>>,
            mp11::mp_list<virtual_ptr<d>, e, virtual_ptr<f>>, default_registry>,
        mp11::mp_list<d, f>>);

static_assert(
    std::is_same_v<
        overrider_virtual_types<
            mp11::mp_list<
                const virtual_ptr<base>&, b, const virtual_ptr<base>&>,
            mp11::mp_list<const virtual_ptr<d>&, e, const virtual_ptr<f>&>,
            default_registry>,
        mp11::mp_list<d, f>>);

static_assert(
    std::is_same_v<
        overrider_virtual_types<
            mp11::mp_list<
                virtual_<std::shared_ptr<a>>, b, virtual_<std::shared_ptr<c>>>,
            mp11::mp_list<std::shared_ptr<d>, e, std::shared_ptr<f>>,
            default_registry>,
        mp11::mp_list<d, f>>);

static_assert(std::is_same_v<
              mp11::mp_transform<
                  remove_virtual_, mp11::mp_list<virtual_<a&>, virtual_<c&>>>,
              mp11::mp_list<a&, c&>>);

static_assert(
    std::is_same_v<
        mp11::mp_transform_q<
            mp11::mp_bind_back<virtual_type, default_registry>,
            mp11::mp_transform<
                remove_virtual_, mp11::mp_list<virtual_<a&>, virtual_<c&>>>>,
        mp11::mp_list<a, c>>);

static_assert(
    std::is_same_v<
        mp11::mp_transform_q<
            mp11::mp_bind_back<virtual_type, default_registry>,
            mp11::mp_transform<
                remove_virtual_,
                mp11::mp_filter<
                    is_virtual, mp11::mp_list<virtual_<a&>, b, virtual_<c&>>>>>,
        mp11::mp_list<a, c>>);

struct registry1 : default_registry::with<unique<registry1>> {};
struct registry2 : default_registry::with<unique<registry2>> {};

struct non_polymorphic_inplace_vptr {};

auto boost_openmethod_vptr(const non_polymorphic_inplace_vptr&, void*)
    -> vptr_type;

// clang-format on

static_assert(std::is_same_v<
              virtual_types<mp11::mp_list<virtual_<a&>, b, virtual_<c&>>>,
              mp11::mp_list<a&, c&>>);

static_assert(detail::is_registry<default_registry>);

struct not_a_policy {};
static_assert(!detail::is_registry<not_a_policy>);

BOOST_AUTO_TEST_CASE(test_init_type_ids) {
    type_id ids[2];
    auto last = init_type_ids<default_registry, mp11::mp_list<a&, b&>>::fn(ids);
    BOOST_TEST_REQUIRE(last - ids == 2);
    BOOST_TEST_REQUIRE(ids[0] == type_id(&typeid(a)));
    BOOST_TEST_REQUIRE(ids[1] == type_id(&typeid(b)));
}

} // namespace test_virtual

namespace test_macros {

// Check that macros can handle commas in parameter and return types.

struct Animal {
    virtual ~Animal() = default;
};

BOOST_OPENMETHOD(poke, (virtual_<Animal&>), std::tuple<int, int>);

} // namespace test_macros

namespace casts {

struct Animal {
    virtual ~Animal() {
    }
    int a{1};
};

struct Mammal : virtual Animal {
    int m{2};
};

struct Carnivore : virtual Animal {
    int c{3};
};

struct Dog : Mammal, Carnivore {
    int d{4};
};

auto mammal_this(const Mammal& obj) -> const void* {
    return &obj;
}

auto carnivore_this(const Carnivore& obj) -> const void* {
    return &obj;
}

auto dog_this(const Dog& obj) -> const void* {
    return &obj;
}

BOOST_AUTO_TEST_CASE(casts) {
    Dog dog;
    const Animal& animal = dog;
    const Mammal& mammal = dog;
    const Carnivore& carnivore = dog;

    BOOST_TEST(
        (&virtual_traits<const Animal&, default_registry>::cast<const Mammal&>(
              animal)
              .m) == &dog.m);
    BOOST_TEST(
        (&virtual_traits<const Animal&, default_registry>::cast<
              const Carnivore&>(animal)
              .c) == &dog.c);
    BOOST_TEST(
        (&virtual_traits<const Animal&, default_registry>::cast<const Mammal&>(
              animal)
              .m) == &dog.m);
    BOOST_TEST(
        (&virtual_traits<const Animal&, default_registry>::cast<const Dog&>(
              animal)
              .d) == &dog.d);
    BOOST_TEST(
        (&virtual_traits<const Mammal&, default_registry>::cast<const Dog&>(
              mammal)
              .d) == &dog.d);
    BOOST_TEST(
        (&virtual_traits<const Carnivore&, default_registry>::cast<const Dog&>(
              carnivore)
              .c) == &dog.c);

    using virtual_animal_t = virtual_type<const Animal&, default_registry>;
    static_assert(std::is_same_v<virtual_animal_t, Animal>, "animal");
    using virtual_mammal_t = virtual_type<const Mammal&, default_registry>;
    static_assert(std::is_same_v<virtual_mammal_t, Mammal>, "mammal");
}

} // namespace casts

namespace test_use_classes {

struct Animal {};
struct Dog : public Animal {};
struct Bulldog : public Dog {};
struct Cat : public Animal {};
struct Dolphin : public Animal {};

static_assert(
    std::is_same_v<
        inheritance_map<Animal, Dog, Bulldog, Cat, Dolphin>,
        mp11::mp_list<
            mp11::mp_list<Animal, Animal>, mp11::mp_list<Dog, Animal, Dog>,
            mp11::mp_list<Bulldog, Animal, Dog, Bulldog>,
            mp11::mp_list<Cat, Animal, Cat>,
            mp11::mp_list<Dolphin, Animal, Dolphin>>>);

static_assert(
    std::is_same_v<
        detail::use_classes_tuple_type<Animal, Dog, Bulldog, Cat, Dolphin>,
        std::tuple<
            use_class_aux<default_registry, mp11::mp_list<Animal, Animal>>,
            use_class_aux<default_registry, mp11::mp_list<Dog, Animal, Dog>>,
            use_class_aux<
                default_registry, mp11::mp_list<Bulldog, Animal, Dog, Bulldog>>,
            use_class_aux<default_registry, mp11::mp_list<Cat, Animal, Cat>>,
            use_class_aux<
                default_registry, mp11::mp_list<Dolphin, Animal, Dolphin>>>>);

} // namespace test_use_classes

namespace TEST_NS {

struct Animal {
    friend auto boost_openmethod_vptr(const Animal&, void*) -> vptr_type;
};

static_assert(detail::has_vptr_fn<Animal, default_registry>);

} // namespace TEST_NS

namespace TEST_NS {

using test_registry = test_registry_<__COUNTER__>;

const detail::word value;

struct Animal {
    friend auto boost_openmethod_vptr(const Animal&, test_registry*) {
        return &value;
    }
};

static_assert(detail::has_vptr_fn<Animal, test_registry>);
static_assert(!detail::has_vptr_fn<Animal, default_registry>);

BOOST_AUTO_TEST_CASE(vptr_from_function) {
    initialize<test_registry>();
    BOOST_TEST(detail::acquire_vptr<test_registry>(Animal{}) == &value);
}

} // namespace TEST_NS