From 153812e91e95df7f210daf3b26141d468605e282 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 3 Jun 2015 23:27:09 +0100 Subject: [PATCH] deuglify functional.h --- octa/functional.h | 830 +++++++++++++++++++++++----------------------- 1 file changed, 422 insertions(+), 408 deletions(-) diff --git a/octa/functional.h b/octa/functional.h index fb01f12..4926bae 100644 --- a/octa/functional.h +++ b/octa/functional.h @@ -12,631 +12,645 @@ #include "octa/type_traits.h" namespace octa { - /* basic function objects */ -#define __OCTA_DEFINE_BINARY_OP(_name, _op, _rettype) \ - template struct _name { \ - _rettype operator()(const _T &__x, const _T &__y) const { \ - return __x _op __y; \ - } \ - typedef _T FirstArgument; \ - typedef _T SecondArgument; \ - typedef _rettype Result; \ - }; +/* basic function objects */ - __OCTA_DEFINE_BINARY_OP(Less, <, bool) - __OCTA_DEFINE_BINARY_OP(LessEqual, <=, bool) - __OCTA_DEFINE_BINARY_OP(Greater, >, bool) - __OCTA_DEFINE_BINARY_OP(GreaterEqual, >=, bool) - __OCTA_DEFINE_BINARY_OP(Equal, ==, bool) - __OCTA_DEFINE_BINARY_OP(NotEqual, !=, bool) - __OCTA_DEFINE_BINARY_OP(LogicalAnd, &&, bool) - __OCTA_DEFINE_BINARY_OP(LogicalOr, ||, bool) - __OCTA_DEFINE_BINARY_OP(Modulus, %, _T) - __OCTA_DEFINE_BINARY_OP(Multiplies, *, _T) - __OCTA_DEFINE_BINARY_OP(Divides, /, _T) - __OCTA_DEFINE_BINARY_OP(Plus, +, _T) - __OCTA_DEFINE_BINARY_OP(Minus, -, _T) - __OCTA_DEFINE_BINARY_OP(BitAnd, &, _T) - __OCTA_DEFINE_BINARY_OP(BitOr, |, _T) - __OCTA_DEFINE_BINARY_OP(BitXor, ^, _T) +#define OCTA_DEFINE_BINARY_OP(_name, _op, _rettype) \ +template struct _name { \ + _rettype operator()(const _T &x, const _T &y) const { \ + return x _op y; \ + } \ + typedef _T FirstArgument; \ + typedef _T SecondArgument; \ + typedef _rettype Result; \ +}; -#undef __OCTA_DEFINE_BINARY_OP +OCTA_DEFINE_BINARY_OP(Less, <, bool) +OCTA_DEFINE_BINARY_OP(LessEqual, <=, bool) +OCTA_DEFINE_BINARY_OP(Greater, >, bool) +OCTA_DEFINE_BINARY_OP(GreaterEqual, >=, bool) +OCTA_DEFINE_BINARY_OP(Equal, ==, bool) +OCTA_DEFINE_BINARY_OP(NotEqual, !=, bool) +OCTA_DEFINE_BINARY_OP(LogicalAnd, &&, bool) +OCTA_DEFINE_BINARY_OP(LogicalOr, ||, bool) +OCTA_DEFINE_BINARY_OP(Modulus, %, _T) +OCTA_DEFINE_BINARY_OP(Multiplies, *, _T) +OCTA_DEFINE_BINARY_OP(Divides, /, _T) +OCTA_DEFINE_BINARY_OP(Plus, +, _T) +OCTA_DEFINE_BINARY_OP(Minus, -, _T) +OCTA_DEFINE_BINARY_OP(BitAnd, &, _T) +OCTA_DEFINE_BINARY_OP(BitOr, |, _T) +OCTA_DEFINE_BINARY_OP(BitXor, ^, _T) - template struct LogicalNot { - bool operator()(const _T &__x) const { return !__x; } - typedef _T Argument; - typedef bool Result; - }; +#undef OCTA_DEFINE_BINARY_OP - template struct Negate { - bool operator()(const _T &__x) const { return -__x; } - typedef _T Argument; - typedef _T Result; - }; +template struct LogicalNot { + bool operator()(const _T &x) const { return !x; } + typedef _T Argument; + typedef bool Result; +}; - template struct BinaryNegate { - typedef typename _T::FirstArgument FirstArgument; - typedef typename _T::SecondArgument SecondArgument; - typedef bool Result; +template struct Negate { + bool operator()(const _T &x) const { return -x; } + typedef _T Argument; + typedef _T Result; +}; - explicit BinaryNegate(const _T &__f): __fn(__f) {} +template struct BinaryNegate { + typedef typename _T::FirstArgument FirstArgument; + typedef typename _T::SecondArgument SecondArgument; + typedef bool Result; - bool operator()(const FirstArgument &__x, - const SecondArgument &__y) { - return !__fn(__x, __y); - } - private: - _T __fn; - }; + explicit BinaryNegate(const _T &f): p_fn(f) {} - template struct UnaryNegate { - typedef typename _T::Argument Argument; - typedef bool Result; - - explicit UnaryNegate(const _T &__f): __fn(__f) {} - bool operator()(const Argument &__x) { - return !__fn(__x); - } - private: - _T __fn; - }; - - template UnaryNegate<_T> not1(const _T &__fn) { - return UnaryNegate<_T>(__fn); + bool operator()(const FirstArgument &x, + const SecondArgument &y) { + return !p_fn(x, y); } +private: + _T p_fn; +}; - template BinaryNegate<_T> not2(const _T &__fn) { - return BinaryNegate<_T>(__fn); +template struct UnaryNegate { + typedef typename _T::Argument Argument; + typedef bool Result; + + explicit UnaryNegate(const _T &f): p_fn(f) {} + bool operator()(const Argument &x) { + return !p_fn(x); } +private: + _T p_fn; +}; - /* hash */ +template UnaryNegate<_T> not1(const _T &fn) { + return UnaryNegate<_T>(fn); +} - template struct Hash; +template BinaryNegate<_T> not2(const _T &fn) { + return BinaryNegate<_T>(fn); +} - template struct __OctaHashBase { +/* hash */ + +template struct Hash; + +namespace detail { + template struct HashBase { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - return size_t(__v); + size_t operator()(_T v) const { + return size_t(v); } }; +} -#define __OCTA_HASH_BASIC(_T) template<> struct Hash<_T>: __OctaHashBase<_T> {}; +#define OCTA_HASH_BASIC(_T) template<> struct Hash<_T>: octa::detail::HashBase<_T> {}; - __OCTA_HASH_BASIC(bool) - __OCTA_HASH_BASIC(char) - __OCTA_HASH_BASIC(schar) - __OCTA_HASH_BASIC(uchar) - __OCTA_HASH_BASIC(char16_t) - __OCTA_HASH_BASIC(char32_t) - __OCTA_HASH_BASIC(wchar_t) - __OCTA_HASH_BASIC(short) - __OCTA_HASH_BASIC(ushort) - __OCTA_HASH_BASIC(int) - __OCTA_HASH_BASIC(uint) - __OCTA_HASH_BASIC(long) - __OCTA_HASH_BASIC(ulong) +OCTA_HASH_BASIC(bool) +OCTA_HASH_BASIC(char) +OCTA_HASH_BASIC(schar) +OCTA_HASH_BASIC(uchar) +OCTA_HASH_BASIC(char16_t) +OCTA_HASH_BASIC(char32_t) +OCTA_HASH_BASIC(wchar_t) +OCTA_HASH_BASIC(short) +OCTA_HASH_BASIC(ushort) +OCTA_HASH_BASIC(int) +OCTA_HASH_BASIC(uint) +OCTA_HASH_BASIC(long) +OCTA_HASH_BASIC(ulong) -#undef __OCTA_HASH_BASIC +#undef OCTA_HASH_BASIC - static inline size_t __octa_mem_hash(const void *__p, size_t __l) { - const uchar *__d = (const uchar *)__p; - size_t __h = 5381; - for (size_t __i = 0; __i < __l; ++__i) __h = ((__h << 5) + __h) ^ __d[__i]; - return __h; +namespace detail { + static inline size_t mem_hash(const void *p, size_t l) { + const uchar *d = (const uchar *)p; + size_t h = 5381; + for (size_t i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i]; + return h; } template - struct __OctaScalarHash; + struct ScalarHash; - template struct __OctaScalarHash<_T, 0> { + template struct ScalarHash<_T, 0> { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - union { _T __v; size_t __h; } __u; - __u.__h = 0; - __u.__v = __v; - return __u.__h; + size_t operator()(_T v) const { + union { _T v; size_t h; } u; + u.h = 0; + u.v = v; + return u.h; } }; - template struct __OctaScalarHash<_T, 1> { + template struct ScalarHash<_T, 1> { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - union { _T __v; size_t __h; } __u; - __u.__v = __v; - return __u.__h; + size_t operator()(_T v) const { + union { _T v; size_t h; } u; + u.v = v; + return u.h; } }; - template struct __OctaScalarHash<_T, 2> { + template struct ScalarHash<_T, 2> { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - union { _T __v; struct { size_t __h1, __h2; }; } __u; - __u.__v = __v; - return __octa_mem_hash((const void *)&__u, sizeof(__u)); + size_t operator()(_T v) const { + union { _T v; struct { size_t h1, h2; }; } u; + u.v = v; + return mem_hash((const void *)&u, sizeof(u)); } }; - template struct __OctaScalarHash<_T, 3> { + template struct ScalarHash<_T, 3> { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - union { _T __v; struct { size_t __h1, __h2, __h3; }; } __u; - __u.__v = __v; - return __octa_mem_hash((const void *)&__u, sizeof(__u)); + size_t operator()(_T v) const { + union { _T v; struct { size_t h1, h2, h3; }; } u; + u.v = v; + return mem_hash((const void *)&u, sizeof(u)); } }; - template struct __OctaScalarHash<_T, 4> { + template struct ScalarHash<_T, 4> { typedef _T Argument; typedef size_t Result; - size_t operator()(_T __v) const { - union { _T __v; struct { size_t __h1, __h2, __h3, __h4; }; } __u; - __u.__v = __v; - return __octa_mem_hash((const void *)&__u, sizeof(__u)); + size_t operator()(_T v) const { + union { _T v; struct { size_t h1, h2, h3, h4; }; } u; + u.v = v; + return mem_hash((const void *)&u, sizeof(u)); } }; +} /* namespace detail */ - template<> struct Hash: __OctaScalarHash {}; - template<> struct Hash: __OctaScalarHash {}; +template<> struct Hash: octa::detail::ScalarHash {}; +template<> struct Hash: octa::detail::ScalarHash {}; - template<> struct Hash: __OctaScalarHash { - size_t operator()(float __v) const { - if (__v == 0) return 0; - return __OctaScalarHash::operator()(__v); - } - }; +template<> struct Hash: octa::detail::ScalarHash { + size_t operator()(float v) const { + if (v == 0) return 0; + return octa::detail::ScalarHash::operator()(v); + } +}; - template<> struct Hash: __OctaScalarHash { - size_t operator()(double __v) const { - if (__v == 0) return 0; - return __OctaScalarHash::operator()(__v); - } - }; +template<> struct Hash: octa::detail::ScalarHash { + size_t operator()(double v) const { + if (v == 0) return 0; + return octa::detail::ScalarHash::operator()(v); + } +}; - template<> struct Hash: __OctaScalarHash { - size_t operator()(ldouble __v) const { - if (__v == 0) return 0; +template<> struct Hash: octa::detail::ScalarHash { + size_t operator()(ldouble v) const { + if (v == 0) return 0; #ifdef __i386__ - union { ldouble __v; struct { size_t __h1, __h2, __h3, __h4; }; } __u; - __u.__h1 = __u.__h2 = __u.__h3 = __u.__h4 = 0; - __u.__v = __v; - return (__u.__h1 ^ __u.__h2 ^ __u.__h3 ^ __u.__h4); + union { ldouble v; struct { size_t h1, h2, h3, h4; }; } u; + u.h1 = u.h2 = u.h3 = u.h4 = 0; + u.v = v; + return (u.h1 ^ u.h2 ^ u.h3 ^ u.h4); #else #ifdef __x86_64__ - union { ldouble __v; struct { size_t __h1, __h2; }; } __u; - __u.__h1 = __u.__h2 = 0; - __u.__v = __v; - return (__u.__h1 ^ __u.__h2); + union { ldouble v; struct { size_t h1, h2; }; } u; + u.h1 = u.h2 = 0; + u.v = v; + return (u.h1 ^ u.h2); #else - return __OctaScalarHash::operator()(__v); + return octa::detail::ScalarHash::operator()(v); #endif #endif - } - }; - - template struct Hash<_T *> { - typedef _T *Argument; - typedef size_t Result; - - size_t operator()(_T *__v) const { - union { _T *__v; size_t __h; } __u; - __u.__v = __v; - return __octa_mem_hash((const void *)&__u, sizeof(__u)); - } - }; - - /* reference wrapper */ - - template - struct ReferenceWrapper { - typedef _T type; - - ReferenceWrapper(_T &__v): __ptr(address_of(__v)) {} - ReferenceWrapper(const ReferenceWrapper &) = default; - ReferenceWrapper(_T &&) = delete; - - ReferenceWrapper &operator=(const ReferenceWrapper &) = default; - - operator _T &() const { return *__ptr; } - _T &get() const { return *__ptr; } - - private: - _T *__ptr; - }; - - template - ReferenceWrapper<_T> ref(_T &__v) { - return ReferenceWrapper<_T>(__v); } - template - ReferenceWrapper<_T> ref(ReferenceWrapper<_T> __v) { - return ReferenceWrapper<_T>(__v); - } - template void ref(const _T &&) = delete; +}; - template - ReferenceWrapper cref(const _T &__v) { - return ReferenceWrapper<_T>(__v); - } - template - ReferenceWrapper cref(ReferenceWrapper<_T> __v) { - return ReferenceWrapper<_T>(__v); - } - template void cref(const _T &&) = delete; +template struct Hash<_T *> { + typedef _T *Argument; + typedef size_t Result; - /* mem_fn */ + size_t operator()(_T *v) const { + union { _T *v; size_t h; } u; + u.v = v; + return octa::detail::mem_hash((const void *)&u, sizeof(u)); + } +}; - template struct __OctaMemTypes; +/* reference wrapper */ + +template +struct ReferenceWrapper { + typedef _T type; + + ReferenceWrapper(_T &v): p_ptr(address_of(v)) {} + ReferenceWrapper(const ReferenceWrapper &) = default; + ReferenceWrapper(_T &&) = delete; + + ReferenceWrapper &operator=(const ReferenceWrapper &) = default; + + operator _T &() const { return *p_ptr; } + _T &get() const { return *p_ptr; } + +private: + _T *p_ptr; +}; + +template +ReferenceWrapper<_T> ref(_T &v) { + return ReferenceWrapper<_T>(v); +} +template +ReferenceWrapper<_T> ref(ReferenceWrapper<_T> v) { + return ReferenceWrapper<_T>(v); +} +template void ref(const _T &&) = delete; + +template +ReferenceWrapper cref(const _T &v) { + return ReferenceWrapper<_T>(v); +} +template +ReferenceWrapper cref(ReferenceWrapper<_T> v) { + return ReferenceWrapper<_T>(v); +} +template void cref(const _T &&) = delete; + +/* mem_fn */ + +namespace detail { + template struct MemTypes; template - struct __OctaMemTypes<_T, _R(_A...)> { + struct MemTypes<_T, _R(_A...)> { typedef _R Result; typedef _T Argument; }; template - struct __OctaMemTypes<_T, _R(_A)> { + struct MemTypes<_T, _R(_A)> { typedef _R Result; typedef _T FirstArgument; typedef _A SecondArgument; }; template - struct __OctaMemTypes<_T, _R(_A...) const> { + struct MemTypes<_T, _R(_A...) const> { typedef _R Result; typedef const _T Argument; }; template - struct __OctaMemTypes<_T, _R(_A) const> { + struct MemTypes<_T, _R(_A) const> { typedef _R Result; typedef const _T FirstArgument; typedef _A SecondArgument; }; template - class __OctaMemFn: __OctaMemTypes<_T, _R> { - _R _T::*__ptr; + class MemFn: MemTypes<_T, _R> { + _R _T::*p_ptr; public: - __OctaMemFn(_R _T::*__ptr): __ptr(__ptr) {} + MemFn(_R _T::*ptr): p_ptr(ptr) {} template - auto operator()(_T &__obj, _A &&...__args) -> - decltype(((__obj).*(__ptr))(forward<_A>(__args)...)) { - return ((__obj).*(__ptr))(forward<_A>(__args)...); + auto operator()(_T &obj, _A &&...args) -> + decltype(((obj).*(p_ptr))(forward<_A>(args)...)) { + return ((obj).*(p_ptr))(forward<_A>(args)...); } template - auto operator()(const _T &__obj, _A &&...__args) -> - decltype(((__obj).*(__ptr))(forward<_A>(__args)...)) const { - return ((__obj).*(__ptr))(forward<_A>(__args)...); + auto operator()(const _T &obj, _A &&...args) -> + decltype(((obj).*(p_ptr))(forward<_A>(args)...)) const { + return ((obj).*(p_ptr))(forward<_A>(args)...); } template - auto operator()(_T *__obj, _A &&...__args) -> - decltype(((__obj)->*(__ptr))(forward<_A>(__args)...)) { - return ((__obj)->*(__ptr))(forward<_A>(__args)...); + auto operator()(_T *obj, _A &&...args) -> + decltype(((obj)->*(p_ptr))(forward<_A>(args)...)) { + return ((obj)->*(p_ptr))(forward<_A>(args)...); } template - auto operator()(const _T *__obj, _A &&...__args) -> - decltype(((__obj)->*(__ptr))(forward<_A>(__args)...)) const { - return ((__obj)->*(__ptr))(forward<_A>(__args)...); + auto operator()(const _T *obj, _A &&...args) -> + decltype(((obj)->*(p_ptr))(forward<_A>(args)...)) const { + return ((obj)->*(p_ptr))(forward<_A>(args)...); } }; +} /* namespace detail */ - template - __OctaMemFn<_R, _T> mem_fn(_R _T:: *__ptr) { - return __OctaMemFn<_R, _T>(__ptr); - } +template +octa::detail::MemFn<_R, _T> mem_fn(_R _T:: *ptr) { + return octa::detail::MemFn<_R, _T>(ptr); +} - /* function impl - * reference: http://probablydance.com/2013/01/13/a-faster-implementation-of-stdfunction - */ +/* function impl + * reference: http://probablydance.com/2013/01/13/a-faster-implementation-of-stdfunction + */ - template struct Function; +template struct Function; - struct __OctaFunctorData { - void *__p1, *__p2; +namespace detail { + struct FunctorData { + void *p1, *p2; }; template - struct __OctaFunctorInPlace { - static constexpr bool value = sizeof(_T) <= sizeof(__OctaFunctorData) - && (alignof(__OctaFunctorData) % alignof(_T)) == 0 + struct FunctorInPlace { + static constexpr bool value = sizeof(_T) <= sizeof(FunctorData) + && (alignof(FunctorData) % alignof(_T)) == 0 && octa::IsMoveConstructible<_T>::value; }; template - struct __OctaFunctorDataManager { + struct FunctorDataManager { template - static _R __call(const __OctaFunctorData &__s, _A ...__args) { - return ((_T &)__s)(octa::forward<_A>(__args)...); + static _R call(const FunctorData &s, _A ...args) { + return ((_T &)s)(octa::forward<_A>(args)...); } - static void __store_f(__OctaFunctorData &__s, _T __v) { - new (&__get_ref(__s)) _T(octa::forward<_T>(__v)); + static void store_f(FunctorData &s, _T v) { + new (&get_ref(s)) _T(octa::forward<_T>(v)); } - static void __move_f(__OctaFunctorData &__lhs, __OctaFunctorData &&__rhs) { - new (&__get_ref(__lhs)) _T(octa::move(__get_ref(__rhs))); + static void move_f(FunctorData &lhs, FunctorData &&rhs) { + new (&get_ref(lhs)) _T(octa::move(get_ref(rhs))); } - static void __destroy_f(__OctaFunctorData &__s) { - __get_ref(__s).~_T(); + static void destroy_f(FunctorData &s) { + get_ref(s).~_T(); } - static _T &__get_ref(const __OctaFunctorData &__s) { - return (_T &)__s; + static _T &get_ref(const FunctorData &s) { + return (_T &)s; } }; template - struct __OctaFunctorDataManager<_T, EnableIf::value>> { + struct FunctorDataManager<_T, + EnableIf::value> + > { template - static _R __call(const __OctaFunctorData &__s, _A ...__args) { - return (*(_T *&)__s)(octa::forward<_A>(__args)...); + static _R call(const FunctorData &s, _A ...args) { + return (*(_T *&)s)(octa::forward<_A>(args)...); } - static void __store_f(__OctaFunctorData &__s, _T __v) { - new (&__get_ptr_ref(__s)) _T *(new _T(octa::forward<_T>(__v))); + static void store_f(FunctorData &s, _T v) { + new (&get_ptr_ref(s)) _T *(new _T(octa::forward<_T>(v))); } - static void __move_f(__OctaFunctorData &__lhs, __OctaFunctorData &&__rhs) { - new (&__get_ptr_ref(__lhs)) _T *(__get_ptr_ref(__rhs)); - __get_ptr_ref(__rhs) = nullptr; + static void move_f(FunctorData &lhs, FunctorData &&rhs) { + new (&get_ptr_ref(lhs)) _T *(get_ptr_ref(rhs)); + get_ptr_ref(rhs) = nullptr; } - static void __destroy_f(__OctaFunctorData &__s) { - _T *&__ptr = __get_ptr_ref(__s); - if (!__ptr) return; - delete __ptr; - __ptr = nullptr; + static void destroy_f(FunctorData &s) { + _T *&ptr = get_ptr_ref(s); + if (!ptr) return; + delete ptr; + ptr = nullptr; } - static _T &__get_ref(const __OctaFunctorData &__s) { - return *__get_ptr_ref(__s); + static _T &get_ref(const FunctorData &s) { + return *get_ptr_ref(s); } - static _T *&__get_ptr_ref(__OctaFunctorData &__s) { - return (_T *&)__s; + static _T *&get_ptr_ref(FunctorData &s) { + return (_T *&)s; } - static _T *&__get_ptr_ref(const __OctaFunctorData &__s) { - return (_T *&)__s; + static _T *&get_ptr_ref(const FunctorData &s) { + return (_T *&)s; } }; - struct __OctaFunctionManager; + struct FunctionManager; - struct __OctaFmStorage { - __OctaFunctorData __data; - const __OctaFunctionManager *__manager; + struct FmStorage { + FunctorData data; + const FunctionManager *manager; }; template - static const __OctaFunctionManager &__octa_get_default_fm(); + static const FunctionManager &get_default_fm(); - struct __OctaFunctionManager { + struct FunctionManager { template - inline static const __OctaFunctionManager __create_default_manager() { - return __OctaFunctionManager { - &__call_move_and_destroy<_T>, - &__call_copy<_T>, - &__call_destroy<_T> + inline static const FunctionManager create_default_manager() { + return FunctionManager { + &call_move_and_destroy<_T>, + &call_copy<_T>, + &call_destroy<_T> }; } - void (* const __call_move_and_destroyf)(__OctaFmStorage &__lhs, - __OctaFmStorage &&__rhs); - void (* const __call_copyf)(__OctaFmStorage &__lhs, - const __OctaFmStorage &__rhs); - void (* const __call_destroyf)(__OctaFmStorage &__s); + void (* const call_move_and_destroyf)(FmStorage &lhs, + FmStorage &&rhs); + void (* const call_copyf)(FmStorage &lhs, + const FmStorage &rhs); + void (* const call_destroyf)(FmStorage &s); template - static void __call_move_and_destroy(__OctaFmStorage &__lhs, - __OctaFmStorage &&__rhs) { - typedef __OctaFunctorDataManager<_T> _spec; - _spec::__move_f(__lhs.__data, octa::move(__rhs.__data)); - _spec::__destroy_f(__rhs.__data); - __lhs.__manager = &__octa_get_default_fm<_T>(); + static void call_move_and_destroy(FmStorage &lhs, + FmStorage &&rhs) { + typedef FunctorDataManager<_T> _spec; + _spec::move_f(lhs.data, octa::move(rhs.data)); + _spec::destroy_f(rhs.data); + lhs.manager = &get_default_fm<_T>(); } template - static void __call_copy(__OctaFmStorage &__lhs, - const __OctaFmStorage &__rhs) { - typedef __OctaFunctorDataManager<_T> _spec; - __lhs.__manager = &__octa_get_default_fm<_T>(); - _spec::__store_f(__lhs.__data, _spec::__get_ref(__rhs.__data)); + static void call_copy(FmStorage &lhs, + const FmStorage &rhs) { + typedef FunctorDataManager<_T> _spec; + lhs.manager = &get_default_fm<_T>(); + _spec::store_f(lhs.data, _spec::get_ref(rhs.data)); } template - static void __call_destroy(__OctaFmStorage &__s) { - typedef __OctaFunctorDataManager<_T> _spec; - _spec::__destroy_f(__s.__data); + static void call_destroy(FmStorage &s) { + typedef FunctorDataManager<_T> _spec; + _spec::destroy_f(s.data); } }; template - inline static const __OctaFunctionManager &__octa_get_default_fm() { - static const __OctaFunctionManager __def_manager - = __OctaFunctionManager::__create_default_manager<_T>(); - return __def_manager; + inline static const FunctionManager &get_default_fm() { + static const FunctionManager def_manager + = FunctionManager::create_default_manager<_T>(); + return def_manager; } template - struct __OctaFunction { + struct FunctionBase { typedef _R Result; }; template - struct __OctaFunction<_R, _T> { + struct FunctionBase<_R, _T> { typedef _R Result; typedef _T Argument; }; template - struct __OctaFunction<_R, _T, _U> { + struct FunctionBase<_R, _T, _U> { typedef _R Result; typedef _T FirstArgument; typedef _U SecondArgument; }; template - struct __OctaIsValidFunctor { + struct IsValidFunctor { static constexpr bool value = false; }; template - struct __OctaIsValidFunctor, _R(_A...)> { + struct IsValidFunctor, _R(_A...)> { static constexpr bool value = false; }; - struct __OctaEmpty { + struct Empty { }; template - _T __octa_func_to_functor(_T &&__f) { - return octa::forward<_T>(__f); + _T func_to_functor(_T &&f) { + return octa::forward<_T>(f); } template - auto __octa_func_to_functor(_RR (_T::*__f)(_AA...)) - -> decltype(mem_fn(__f)) { - return mem_fn(__f); + auto func_to_functor(_RR (_T::*f)(_AA...)) + -> decltype(mem_fn(f)) { + return mem_fn(f); } template - auto __octa_func_to_functor(_RR (_T::*__f)(_AA...) const) - -> decltype(mem_fn(__f)) { - return mem_fn(__f); + auto func_to_functor(_RR (_T::*f)(_AA...) const) + -> decltype(mem_fn(f)) { + return mem_fn(f); } template - struct __OctaIsValidFunctor<_T, _R(_A...)> { + struct IsValidFunctor<_T, _R(_A...)> { template - static decltype(__octa_func_to_functor(octa::declval<_U>()) - (octa::declval<_A>()...)) __test(_U *); + static decltype(func_to_functor(octa::declval<_U>()) + (octa::declval<_A>()...)) test(_U *); template - static __OctaEmpty __test(...); + static Empty test(...); static constexpr bool value = octa::IsConvertible< - decltype(__test<_T>(nullptr)), _R + decltype(test<_T>(nullptr)), _R >::value; }; +} /* namespace detail */ - template - struct Function<_R(_A...)>: __OctaFunction<_R, _A...> { - Function( ) { __init_empty(); } - Function(nullptr_t) { __init_empty(); } +template +struct Function<_R(_A...)>: octa::detail::FunctionBase<_R, _A...> { + Function( ) { init_empty(); } + Function(nullptr_t) { init_empty(); } - Function(Function &&__f) { - __init_empty(); - swap(__f); + Function(Function &&f) { + init_empty(); + swap(f); + } + + Function(const Function &f): p_call(f.p_call) { + f.p_stor.manager->call_copyf(p_stor, f.p_stor); + } + + template + Function(_T f, EnableIf< + octa::detail::IsValidFunctor<_T, _R(_A...)>::value, + octa::detail::Empty + > = octa::detail::Empty()) { + if (func_is_null(f)) { + init_empty(); + return; } + initialize(octa::detail::func_to_functor(octa::forward<_T>(f))); + } - Function(const Function &__f): __call(__f.__call) { - __f.__stor.__manager->__call_copyf(__stor, __f.__stor); - } + ~Function() { + p_stor.manager->call_destroyf(p_stor); + } - template - Function(_T __f, EnableIf<__OctaIsValidFunctor<_T, _R(_A...)>::value, __OctaEmpty> - = __OctaEmpty()) { - if (__func_is_null(__f)) { - __init_empty(); - return; - } - __initialize(__octa_func_to_functor(octa::forward<_T>(__f))); - } + Function &operator=(Function &&f) { + p_stor.manager->call_destroyf(p_stor); + swap(f); + return *this; + } - ~Function() { - __stor.__manager->__call_destroyf(__stor); - } - - Function &operator=(Function &&__f) { - __stor.__manager->__call_destroyf(__stor); - swap(__f); - return *this; - } - - Function &operator=(const Function &__f) { - __stor.__manager->__call_destroyf(__stor); - __f.__stor.__manager->__call_copyf(__stor, __f.__stor); - return *this; - }; - - _R operator()(_A ...__args) const { - return __call(__stor.__data, octa::forward<_A>(__args)...); - } - - template void assign(_F &&__f) { - Function(octa::forward<_F>(__f)).swap(*this); - } - - void swap(Function &__f) { - __OctaFmStorage __tmp; - __f.__stor.__manager->__call_move_and_destroyf(__tmp, - octa::move(__f.__stor)); - __stor.__manager->__call_move_and_destroyf(__f.__stor, - octa::move(__stor)); - __tmp.__manager->__call_move_and_destroyf(__stor, - octa::move(__tmp)); - octa::swap(__call, __f.__call); - } - - operator bool() const { return __call != nullptr; } - - private: - __OctaFmStorage __stor; - _R (*__call)(const __OctaFunctorData &, _A...); - - template - void __initialize(_T __f) { - __call = &__OctaFunctorDataManager<_T>::template __call<_R, _A...>; - __stor.__manager = &__octa_get_default_fm<_T>(); - __OctaFunctorDataManager<_T>::__store_f(__stor.__data, - octa::forward<_T>(__f)); - } - - void __init_empty() { - typedef _R(*__emptyf)(_A...); - __call = nullptr; - __stor.__manager = &__octa_get_default_fm<__emptyf>(); - __OctaFunctorDataManager<__emptyf>::__store_f(__stor.__data, nullptr); - } - - template - static bool __func_is_null(const _T &) { return false; } - - static bool __func_is_null(_R (* const &__fptr)(_A...)) { - return __fptr == nullptr; - } - - template - static bool __func_is_null(_RR (_T::* const &__fptr)(_AA...)) { - return __fptr == nullptr; - } - - template - static bool __func_is_null(_RR (_T::* const &__fptr)(_AA...) const) { - return __fptr == nullptr; - } + Function &operator=(const Function &f) { + p_stor.manager->call_destroyf(p_stor); + f.p_stor.manager->call_copyf(p_stor, f.p_stor); + return *this; }; - template - bool operator==(nullptr_t, const Function<_T> &__rhs) { return !__rhs; } + _R operator()(_A ...args) const { + return p_call(p_stor.data, octa::forward<_A>(args)...); + } + + template void assign(_F &&f) { + Function(octa::forward<_F>(f)).swap(*this); + } + + void swap(Function &f) { + octa::detail::FmStorage tmp; + f.p_stor.manager->call_move_and_destroyf(tmp, + octa::move(f.p_stor)); + p_stor.manager->call_move_and_destroyf(f.p_stor, + octa::move(p_stor)); + tmp.manager->call_move_and_destroyf(p_stor, + octa::move(tmp)); + octa::swap(p_call, f.p_call); + } + + operator bool() const { return p_call != nullptr; } + +private: + octa::detail::FmStorage p_stor; + _R (*p_call)(const octa::detail::FunctorData &, _A...); template - bool operator==(const Function<_T> &__lhs, nullptr_t) { return !__lhs; } + void initialize(_T f) { + p_call = &octa::detail::FunctorDataManager<_T>::template call<_R, _A...>; + p_stor.manager = &octa::detail::get_default_fm<_T>(); + octa::detail::FunctorDataManager<_T>::store_f(p_stor.data, + octa::forward<_T>(f)); + } + + void init_empty() { + typedef _R(*emptyf)(_A...); + p_call = nullptr; + p_stor.manager = &octa::detail::get_default_fm(); + octa::detail::FunctorDataManager::store_f(p_stor.data, nullptr); + } template - bool operator!=(nullptr_t, const Function<_T> &__rhs) { return __rhs; } + static bool func_is_null(const _T &) { return false; } - template - bool operator!=(const Function<_T> &__lhs, nullptr_t) { return __lhs; } -} + static bool func_is_null(_R (* const &fptr)(_A...)) { + return fptr == nullptr; + } + + template + static bool func_is_null(_RR (_T::* const &fptr)(_AA...)) { + return fptr == nullptr; + } + + template + static bool func_is_null(_RR (_T::* const &fptr)(_AA...) const) { + return fptr == nullptr; + } +}; + +template +bool operator==(nullptr_t, const Function<_T> &rhs) { return !rhs; } + +template +bool operator==(const Function<_T> &lhs, nullptr_t) { return !lhs; } + +template +bool operator!=(nullptr_t, const Function<_T> &rhs) { return rhs; } + +template +bool operator!=(const Function<_T> &lhs, nullptr_t) { return lhs; } + +} /* namespace octa */ #endif \ No newline at end of file