summaryrefslogtreecommitdiff
path: root/src/mongo/base/concept/constructible.h
blob: b6e5211e6f1f8fc8d69630e160a623cc6b88335e (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
#pragma once

#include <type_traits>

#include "mongo/stdx/type_traits.h"

namespace mongo {
namespace concept {

/**
 * The Constructable trait indicates whether `T` is constructible from `Constructible`.
 *
 * RETURNS: true if `T{ std::declval< Constructible >() }` is a valid expression and false
 * otherwise.
 */
template <typename T, typename Constructible, typename = void>
struct is_constructible : std::false_type {};

template <typename T, typename Constructible>
struct is_constructible<T,
                        Constructible,
                        stdx::void_t<decltype(T{std::declval<Constructible<T>>()})>>
    : std::true_type {};

/**
 * The Constructable concept models a type which can be passed to a single-argument constructor of
 * `T`.
 * This is not possible to describe in the type `Constructible`.
 *
 * The expression: `T{ std::declval< Constructible< T > >() }` should be valid.
 *
 * This concept is more broadly applicable than `ConvertibleTo`.  `ConvertibleTo` uses implicit
 * conversion, whereas `Constructible` uses direct construction.
 */
template <typename T>
struct Constructible {};
}  // namespace concept
}  // namespace mongo