Skip to content

Commit

Permalink
lambda removed; readme upd
Browse files Browse the repository at this point in the history
  • Loading branch information
Morglod committed Aug 10, 2022
1 parent d317f64 commit b0b6569
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/example/tmp
/example/tmp
/example/picobench
46 changes: 27 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ Which saves pointer to T and picks specific trait's implementation for type T.
"Trait" structure will hold pointer to initial object & pointer to implementation
static cost will be: 1 pointer per method per type

### Performance

https://quick-bench.com/q/4xOCNLsrgt_TDeF9k-hxv_mUdLw

Method call:
* GCC 11.2 -O3 virtual call is 20% faster
* Clang 13 -O3 equal to virtual call
* MSVC 2022 +- same as virtual call

### Build example

Run `example/build.cmd / sh` or use `example/CMakeLists.txt`
Expand All @@ -52,32 +61,29 @@ Trait structure under macro:
```cpp
template <typename T>
struct Addable_impl_T {
void (*add)(void *self, int) = [](void *self, int _1) {
return ((T *)self)->add(_1);
};
using Self = Addable_impl_T<T>;
void (*add)(void *self, int) = &Self::static_add;
static void static_add(void *self, int _1) { return ((T *)self)->add(_1); };
};

struct Addable_impl {
void (*add)(void *self, int);
void (*add)(void *self, int);
};

struct Addable {
void *self = nullptr;

Addable() = delete;
void *self = nullptr;
Addable() = delete;
inline void add(int _1) { return _impl->add(_get_self(), _1); }

inline void add(int _1) {
return _impl->add(self, _1);
}

template <typename T>
Addable(T &t) : self(&t) {
static Addable_impl_T<T> impl;
_impl = (Addable_impl *)(void *)&impl;
}
template <typename T>
Addable(T &t) : self(&t) {
static Addable_impl_T<T> impl;
_impl = (Addable_impl *)(void *)&impl;
}

private:
Addable_impl *_impl;
inline void *_get_self() { return self; }
Addable_impl *_impl;
};
```
Expand Down Expand Up @@ -165,8 +171,10 @@ void do_stuff() {
---
## Requirements
* `__VA_OPT__` (tested currently on C++20 only)
* `__VA_OPT__` (currently for C++20 only)
## todo
* Benchmarks
* Remove `__VA_OPT__`, than C++11 may be supported
* More benchmarks & tests
14 changes: 8 additions & 6 deletions traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@
#define __TRAIT_METHOD_PICK_ARGS(_ret, _name, ...) __VA_ARGS__
#define _TRAIT_METHOD_PICK_ARGS(_trait_tuple_) __TRAIT_METHOD_PICK_ARGS _trait_tuple_

#define _TRAIT_STRUCT_METHOD_POINTER(_method_tuple_) \
_TRAIT_METHOD_PICK_RET(_method_tuple_) (* _TRAIT_METHOD_PICK_NAME(_method_tuple_)) (void* self _TRAIT_COMMA_IF_( _TRAIT_METHOD_PICK_ARGS(_method_tuple_) ) ) = \
[](void* self _TRAIT_COMMA_IF_( _TRAIT_NAMED_ARGS1_(_TRAIT_METHOD_PICK_ARGS(_method_tuple_)) ) ) { \
#define _TRAIT_STRUCT_METHOD_POINTER_MEMBER(_method_tuple_) \
_TRAIT_METHOD_PICK_RET(_method_tuple_) (* _TRAIT_METHOD_PICK_NAME(_method_tuple_)) (void* self _TRAIT_COMMA_IF_( _TRAIT_METHOD_PICK_ARGS(_method_tuple_) ) ) = &Self::_TRAIT_STRUCT_CONCAT(static_, _TRAIT_METHOD_PICK_NAME(_method_tuple_));

#define _TRAIT_STRUCT_METHOD_POINTER_STATIC(_method_tuple_) \
static _TRAIT_METHOD_PICK_RET(_method_tuple_) _TRAIT_STRUCT_CONCAT(static_, _TRAIT_METHOD_PICK_NAME(_method_tuple_)) (void* self _TRAIT_COMMA_IF_( _TRAIT_NAMED_ARGS1_(_TRAIT_METHOD_PICK_ARGS(_method_tuple_)) ) ) { \
return ((T*)self)->_TRAIT_METHOD_PICK_NAME(_method_tuple_) ( _TRAIT_NAMED_ARGS2_(_TRAIT_METHOD_PICK_ARGS(_method_tuple_)) ); \
};

Expand All @@ -67,13 +69,14 @@
#define _TRAIT_STRUCT_BASE(_NAME, ...) \
template<typename T> \
struct _NAME##_impl_T { \
MACRO_MAP(_TRAIT_STRUCT_METHOD_POINTER, __VA_ARGS__) \
using Self = _NAME##_impl_T<T>; \
MACRO_MAP(_TRAIT_STRUCT_METHOD_POINTER_MEMBER, __VA_ARGS__) \
MACRO_MAP(_TRAIT_STRUCT_METHOD_POINTER_STATIC, __VA_ARGS__) \
}; \
struct _NAME##_impl { \
MACRO_MAP(_TRAIT_STRUCT_METHOD_POINTER_NO_INIT, __VA_ARGS__) \
}; \
struct _NAME { \
using SelfPtr = void*; \
void* self = nullptr; \
_NAME() = delete; \
MACRO_MAP(_TRAIT_STRUCT_PROXY_METHOD, __VA_ARGS__) \
Expand All @@ -89,7 +92,6 @@

#define _TRAIT_STRUCT_PTR(_NAME, ...) \
struct _NAME##_ptr { \
using SelfPtr = std::shared_ptr<void>; \
std::shared_ptr<void> self = nullptr; \
MACRO_MAP(_TRAIT_STRUCT_PROXY_METHOD, __VA_ARGS__) \
_NAME##_ptr() = default; \
Expand Down

0 comments on commit b0b6569

Please sign in to comment.