-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate<typename main>.cpp
More file actions
101 lines (78 loc) · 2.38 KB
/
template<typename main>.cpp
File metadata and controls
101 lines (78 loc) · 2.38 KB
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
// Copyright (c) December 2025 Félix-Olivier Dumas. All rights reserved.
// Licensed under the terms described in the LICENSE file
#include <iostream>
#include <string>
template<typename Variation>
class IPrinter {
public:
template<typename... Args>
auto print(Args&&... args) noexcept ->
std::enable_if_t<std::is_void_v
<decltype(std::declval<Variation>().print(std::declval<Args>()...))>,
void> { static_cast<Variation*>(this)->print(std::forward<Args>(args)...); }
};
class ConsolePrinter : public IPrinter<ConsolePrinter> {
public:
template<typename T>
void print(const T& printable) const noexcept {
std::cout << printable << std::endl;
}
};
struct GenericStoragePolicy {
template<typename T>
struct Storage {
[[nodiscard]] std::string to_string() const noexcept {
return std::to_string(data_);
}
private:
T data_{};
};
};
struct ConsolePrintingPolicy {
struct Printer {
template<typename... Ts>
void print(Ts&&... args) const noexcept {
(..., (std::cout << args << std::endl));
}
};
};
template<typename StoragePolicy, typename PrintingPolicy>
class DynamicStorage {
public:
void print_storage() const noexcept {
printer_.print(storage_.to_string());
}
private:
typename StoragePolicy::template Storage<int> storage_;
typename PrintingPolicy::Printer printer_;
};
class DynamicBase {
public:
template<typename Derived, typename... Args>
auto print(Args&&... args) noexcept ->
std::enable_if_t<std::is_base_of_v<DynamicBase, Derived>
&& std::is_void_v<decltype(
std::declval<Derived>().print(std::declval<Args>()...)
)>, void> { static_cast<Derived*>(this)->print(std::forward<Args>(args)...); }
};
class StringPrinter : public DynamicBase {
public:
void print(const std::string& printable) const noexcept {
std::cout << printable << std::endl;
}
private:
};
class IntegerPrinter : public DynamicBase {
public:
void print(const int printable) const noexcept {
std::cout << printable << std::endl;
}
};
int main() {
DynamicStorage<GenericStoragePolicy, ConsolePrintingPolicy> s;
DynamicBase base;
base.print<StringPrinter>("test");
base.print<IntegerPrinter>(5);
IPrinter<ConsolePrinter> consolePrinter;
consolePrinter.print(5);
}