Loading...
Searching...
No Matches
make_from.h
Go to the documentation of this file.
1#ifndef _BBM_MAKE_FROM_H_
2#define _BBM_MAKE_FROM_H_
3
4#include "core/error.h"
5
6#include "util/type_traits.h"
7#include "util/literal.h"
8
9
10
11/************************************************************************/
12/*! \file make_from.h
13
14 \brief Tools for making an object:
15
16 1) from a series of literals
17 2) from an array literal
18 3) from a parameter pack
19*************************************************************************/
20
21namespace bbm {
22
23 /**********************************************************************/
24 /*! \brief Make an object T from a series of non-array template literals
25
26 \tparam T = object-type to create
27 \tparam V = template literals to pass as constructor arguments.
28 \returns T(V...)
29
30 Will be at compile time if the constructor of T is constexpr.
31 ***********************************************************************/
32 template<typename T, literal... V> requires std::constructible_from<T, decltype(V.value)...> && (!(is_array_v<decltype(V.value)> && ...))
33 inline constexpr T make_from() { return T(V.value...); }
34
35
36 /**********************************************************************/
37 /*! \brief Make an object T from the values passed in a array literal
38
39 \tparam T = object-type to create
40 \tparam A = std::array<arg_type, N>, i.e., N arguments to be passed to T.
41 \returns T(A[0], A[1], ...., A[N])
42 ***********************************************************************/
43 template<typename T, literal A> requires bbm::is_array_v<decltype(A.value)>
44 inline constexpr T make_from()
45 {
46 auto helper = []<size_t... IDX>(std::index_sequence<IDX...>) { return T{A.value[IDX]...}; };
47 return helper(std::make_index_sequence<std::tuple_size_v<decltype(A.value)>>{});
48 }
49
50 /**********************************************************************/
51 /*! \brief Make an object T from a pack of arguments.
52
53 \tparam T = object type to construct
54 \param args = argument pack
55 \returns T(args...)
56
57 This function is essentially identical to directly calling T(args...)
58 except for one key difference: this method will compile even if T is not
59 constructible from 'args'. At run-time an exeption is thrown in the
60 latter case.
61 ***********************************************************************/
62 template<typename T, typename... Args>
63 inline constexpr T make_from(Args&&... args)
64 {
65 if constexpr (std::constructible_from<T, Args...>)
66 {
67 if constexpr (sizeof...(Args) == 0) return T{};
68 else return T(std::forward<Args>(args)...);
69 }
70 else throw bbm_unevaluable;
71 }
72
73
74} // end bbm namespace
75
76#endif /* _BBM_MAKE_FROM_H_ */
Predefined exceptions for common errors.
#define bbm_unevaluable
Definition: error.h:46
Work around for using floating point literals for compilers that do not support it (e....
Definition: aggregatebsdf.h:29
constexpr T make_from()
Make an object T from a series of non-array template literals.
Definition: make_from.h:33
constexpr bool is_array_v
Definition: type_traits.h:166
Forward declaration.
Definition: args.h:248