-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy path_cpp_template_test.cc
138 lines (115 loc) · 3.72 KB
/
_cpp_template_test.cc
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
#include <iostream>
#include <string>
#include <pybind11/pybind11.h>
#include "cpp/name_trait.h"
#include "python/bindings/pymodule/tpl/cpp_template.h"
namespace cpp_template_test {
struct SimpleType {};
template <typename T>
void template_type() {
std::cout << "template_type: " << nice_type_name<T>() << std::endl;
}
template <typename... Ts>
void template_list() {
std::cout << "template_list: " << std::endl;
for (std::string name : {nice_type_name<Ts>()...}) {
std::cout << "- " << name << std::endl;
}
}
template <typename... Ts>
class SimpleTemplate {
public:
int size() const {
return type_pack<Ts...>::size;
}
template <typename U>
void check() const {
using Check = check_different_from<U>;
std::cout << "check: ";
for (bool value : {Check::template check<Ts>::value...}) {
std::cout << value << " ";
}
std::cout << std::endl;
}
};
template <bool Value>
void template_bool() {
std::cout << "template_bool: " << Value << std::endl;
}
template <int Value>
void template_int() {
std::cout << "template_int: " << Value << std::endl;
}
template <typename T, T ... Values>
using type_pack_literals =
type_pack<type_pack<std::integral_constant<T, Values>>...>;
template <typename T, T ... Values>
using type_pack_literals_raw =
type_pack<std::integral_constant<T, Values>...>;
} // namespace cpp_template_test
PYBIND11_MODULE(_cpp_template_test, m) {
using namespace cpp_template_test;
m.doc() = "C++ Template Test";
// Custom type used in templates.
py::class_<SimpleType>(m, "SimpleType");
// Types - Manual.
AddTemplateFunction<int>(
m, "template_type", &template_type<int>);
AddTemplateFunction<double>(
m, "template_type", &template_type<double>);
AddTemplateFunction<SimpleType>(
m, "template_type", &template_type<SimpleType>);
// - Lists
AddTemplateFunction<int>(
m, "template_list", &template_list<int>);
AddTemplateFunction<int, double>(
m, "template_list", &template_list<int, double>);
AddTemplateFunction<int, double, SimpleType>(
m, "template_list", &template_list<int, double, SimpleType>);
// - Class w/ looping.
{
auto inst = [&m](auto param) {
using Param = decltype(param);
using SimpleTemplateT = typename Param::template bind<SimpleTemplate>;
// N.B. This name will be overwritten by `AddTemplateClass`.
py::class_<SimpleTemplateT> py_class(
m, TemplateClassName<SimpleTemplateT>().c_str());
py_class
.def(py::init<>())
.def("size", &SimpleTemplateT::size);
AddTemplateMethod<double>(
py_class, "check", &SimpleTemplateT::template check<double>);
AddTemplateClass(
m, "SimpleTemplateTpl", py_class, "SimpleTemplate", param);
};
using ParamList = type_pack<
type_pack<int>,
type_pack<int, double, SimpleType>>;
type_visit(inst, ParamList{});
}
// Literals.
{
// Manual - must wrap with `integral_constant`, since that is what is
// registered.
AddTemplateFunction<std::integral_constant<int, 0>>(
m, "template_int", &template_int<0>);
// Looping, raw.
auto inst = [&m](auto tag) {
using Tag = decltype(tag);
constexpr int Value = Tag::value;
AddTemplateFunction<Tag>(
m, "template_int", &template_int<Value>);
};
type_visit(inst, type_pack_literals_raw<int, 1, 2, 5>{});
}
{
// Looping, Type packs.
auto inst = [&m](auto param) {
constexpr bool Value = decltype(param)::template type_at<0>::value;
// N.B. Use of `param` argument, no template specification.
AddTemplateFunction(
m, "template_bool", &template_bool<Value>, param);
};
type_visit(inst, type_pack_literals<bool, false, true>{});
}
}