Cogs.Core
Method.h
1#pragma once
2
3#include <cassert>
4
5#include "Name.h"
6
7#ifdef _WIN32
8// Turn off VS optimization of member pointers.
9#pragma pointers_to_members(full_generality, single_inheritance)
10#endif
11
12namespace Cogs
13{
14 namespace Reflection
15 {
18 struct ReflectedTarget
19 {
20 // No members needed.
21 };
23
25 constexpr size_t kMaxMethodArguments = 4;
26
71 class COGSFOUNDATION_API Method
72 {
73 public:
76 typedef void (ReflectedTarget::*MemberFunction)();
77
82 template<typename Class, typename Ret, typename... Args>
83 Method(const Name& name, Ret (Class::*method)(Args...)) :
84 name(name),
85 function(reinterpret_cast<MemberFunction>(method)),
86 numArguments(sizeof...(Args)),
87 returnTypeSize(getReturnSize<Ret>())
88 {
89#ifdef _DEBUG
90 setSizes<Args...>();
91#endif
92 }
93
95 Method(const Method & other) = default;
96
98 Method(Method && other) noexcept = default;
99
101 Method & operator=(const Method & other) = default;
102
104 Method & operator=(Method && other) noexcept = default;
105
107 template<typename Ret>
108 size_t getReturnSize() const
109 {
110 return sizeof(Ret);
111 }
112
114 template<typename... Args>
115 void setSizes()
116 {
117 size_t sizes[] = { (sizeof(Args))... };
118 static_assert(kMaxMethodArguments >= sizeof...(Args));
119
120 for (size_t i = 0; i < numArguments; ++i) {
121 argumentSizes[i] = sizes[i];
122 }
123 }
124
126 template<typename... Args>
127 void compareSizes() const
128 {
129 size_t sizes [] = { (sizeof(Args))... };
130 static_assert(kMaxMethodArguments >= sizeof...(Args));
131
132 for (size_t i = 0; i < numArguments; ++i) {
133 assert(argumentSizes[i] == sizes[i] && "Argument passed to method not of correct type or size");
134 }
135 }
136
143 template<typename Class, typename... Arg>
144 void call(Class * object, Arg... arg) const
145 {
146 assert(numArguments == sizeof...(Arg) && "Method does not support being called with the given number of arguments.");
147
148#ifdef _DEBUG
149 compareSizes<Arg...>();
150#endif
151
152 typedef void (Class::*TypedMessage)(Arg...);
153
154 auto method = reinterpret_cast<TypedMessage>(function);
155
156 (object->*method)(arg...);
157 }
158
167 template<typename Class, typename Ret, typename... Arg>
168 Ret callWithReturn(Class * object, Ret, Arg... arg) const
169 {
170 assert(returnTypeSize == getReturnSize<Ret>() && "Method does not have correct return type or size.");
171 assert(numArguments == sizeof...(Arg) && "Method does not support being called with the given number of arguments.");
172
173#ifdef _DEBUG
174 compareSizes<Arg...>();
175#endif
176
177 typedef Ret (Class::*TypedMessage)(Arg...);
178
179 auto method = reinterpret_cast<TypedMessage>(function);
180
181 return (object->*method)(arg...);
182 }
183
185 const Name & getName() const { return name; }
186
187 private:
190
192 MemberFunction function;
193
196
199
201 size_t argumentSizes[kMaxMethodArguments] = {};
202 };
203
205 template<>
206 inline size_t Method::getReturnSize<void>() const
207 {
208 return 0;
209 }
210
212 template<>
213 inline void Method::setSizes<>()
214 {
215
216 }
217
219 template<>
220 inline void Method::compareSizes<>() const
221 {
222
223 }
224 }
225}
Simple method definition.
Definition: Method.h:72
Method(Method &&other) noexcept=default
Default move constructor.
size_t returnTypeSize
Return type size.
Definition: Method.h:198
Ret callWithReturn(Class *object, Ret, Arg... arg) const
Call the method named name on the given object, with the given arguments, returning a value of type R...
Definition: Method.h:168
void compareSizes() const
Compare the sizes of a set of given arguments to the stored argument sizes.
Definition: Method.h:127
const Name & getName() const
Get the name of this method.
Definition: Method.h:185
Method & operator=(const Method &other)=default
Default copy assignment operator.
MemberFunction function
Pointer to member function for our method.
Definition: Method.h:192
Method(const Name &name, Ret(Class::*method)(Args...))
Creates a new method definition using the given name and the given pointer to member function.
Definition: Method.h:83
Name name
Name to use when looking up this method.
Definition: Method.h:189
size_t numArguments
Number of arguments given.
Definition: Method.h:195
Method & operator=(Method &&other) noexcept=default
Default move assignment operator.
Method(const Method &other)=default
Default copy constructor.
void call(Class *object, Arg... arg) const
Call the method named name on the given object, with the given arguments.
Definition: Method.h:144
void setSizes()
Register argument sizes.
Definition: Method.h:115
size_t getReturnSize() const
Register the size of the return type.
Definition: Method.h:108
constexpr size_t kMaxMethodArguments
Max number of method arguments supported.
Definition: Method.h:25
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Represents an unique name.
Definition: Name.h:70