From f106c5ae24059ede2e7a19b41a877912ee572d8b Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 24 Apr 2015 18:16:35 +0100 Subject: [PATCH] get rid of namespace internal --- README.md | 2 +- octa/algorithm.h | 136 +++++++------- octa/functional.h | 453 +++++++++++++++++++++++----------------------- octa/range.h | 46 +++-- 4 files changed, 326 insertions(+), 311 deletions(-) diff --git a/README.md b/README.md index ae38061..90d6150 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ go beyond C++11 level when it comes to core language features. Compiler | Version -------- | ------- gcc/g++ | 4.8+ -clang | 3.4+ +clang | 3.3+ MSVC++ | 2015+ Other C++11 compliant compilers might work as well. OctaSTD does not utilize diff --git a/octa/algorithm.h b/octa/algorithm.h index 2361626..c279fd0 100644 --- a/octa/algorithm.h +++ b/octa/algorithm.h @@ -14,6 +14,8 @@ #include "octa/initializer_list.h" namespace octa { + /* partitioning */ + template R partition(R range, U pred) { R ret = range; @@ -34,6 +36,8 @@ namespace octa { return true; } + /* insertion sort */ + template void insertion_sort(R range, C compare) { size_t rlen = range.length(); @@ -52,76 +56,76 @@ namespace octa { insertion_sort(range, Less::value>()); } - namespace internal { - template - struct UnaryCompare { - const T &val; - U comp; - bool operator()(const T &v) const { return comp(v, val); } - }; + /* sort (introsort) */ - template - void hs_sift_down(R range, size_t s, size_t e, C compare) { - size_t r = s; - while ((r * 2 + 1) <= e) { - size_t ch = r * 2 + 1; - size_t sw = r; - if (compare(range[sw], range[ch])) - sw = ch; - if (((ch + 1) <= e) && compare(range[sw], range[ch + 1])) - sw = ch + 1; - if (sw != r) { - swap(range[r], range[sw]); - r = sw; - } else return; - } - } + template + struct __OctaUnaryCompare { + const T &val; + U comp; + bool operator()(const T &v) const { return comp(v, val); } + }; - template - void heapsort(R range, C compare) { - size_t len = range.length(); - size_t st = (len - 2) / 2; - for (;;) { - hs_sift_down(range, st, len - 1, compare); - if (st-- == 0) break; - } - size_t e = len - 1; - while (e > 0) { - swap(range[e], range[0]); - --e; - hs_sift_down(range, 0, e, compare); - } - } - - template - void introloop(R range, C compare, size_t depth) { - if (range.length() <= 10) { - insertion_sort(range, compare); - return; - } - if (depth == 0) { - heapsort(range, compare); - return; - } - typename RangeTraits::reference p = range[range.length() / 2]; - swap(p, range.last()); - R r = partition(range, UnaryCompare{ p, compare }); - R l = range.slice(0, range.length() - r.length()); - swap(r.first(), r.last()); - introloop(l, compare, depth - 1); - introloop(r, compare, depth - 1); - } - - template - void introsort(R range, C compare) { - introloop(range, compare, size_t(2 - * (log(range.length()) / log(2)))); + template + void __octa_hs_sift_down(R range, size_t s, size_t e, C compare) { + size_t r = s; + while ((r * 2 + 1) <= e) { + size_t ch = r * 2 + 1; + size_t sw = r; + if (compare(range[sw], range[ch])) + sw = ch; + if (((ch + 1) <= e) && compare(range[sw], range[ch + 1])) + sw = ch + 1; + if (sw != r) { + swap(range[r], range[sw]); + r = sw; + } else return; } } + template + void __octa_heapsort(R range, C compare) { + size_t len = range.length(); + size_t st = (len - 2) / 2; + for (;;) { + __octa_hs_sift_down(range, st, len - 1, compare); + if (st-- == 0) break; + } + size_t e = len - 1; + while (e > 0) { + swap(range[e], range[0]); + --e; + __octa_hs_sift_down(range, 0, e, compare); + } + } + + template + void __octa_introloop(R range, C compare, size_t depth) { + if (range.length() <= 10) { + insertion_sort(range, compare); + return; + } + if (depth == 0) { + __octa_heapsort(range, compare); + return; + } + typename RangeTraits::reference p = range[range.length() / 2]; + swap(p, range.last()); + R r = partition(range, __OctaUnaryCompare{ p, compare }); + R l = range.slice(0, range.length() - r.length()); + swap(r.first(), r.last()); + __octa_introloop(l, compare, depth - 1); + __octa_introloop(r, compare, depth - 1); + } + + template + void __octa_introsort(R range, C compare) { + __octa_introloop(range, compare, size_t(2 + * (log(range.length()) / log(2)))); + } + template void sort(R range, C compare) { - internal::introsort(range, compare); + __octa_introsort(range, compare); } template @@ -129,6 +133,8 @@ namespace octa { sort(range, Less::value>()); } + /* min/max(_element) */ + template inline const T &min(const T &a, const T &b) { return (a < b) ? a : b; @@ -200,6 +206,8 @@ namespace octa { return max_element(il.range(), compare).first(); } + /* algos that don't change the range */ + template F for_each(R range, F func) { for (; !range.empty(); range.pop_first()) @@ -289,6 +297,8 @@ namespace octa { return range2.empty(); } + /* algos that modify ranges or work with output ranges */ + template R2 copy(R1 irange, R2 orange) { for (; !irange.empty(); irange.pop_first()) diff --git a/octa/functional.h b/octa/functional.h index ba0626f..71cbc0c 100644 --- a/octa/functional.h +++ b/octa/functional.h @@ -12,7 +12,9 @@ #include "octa/traits.h" namespace octa { -#define OCTA_DEFINE_BINARY_OP(name, op, rettype) \ + /* basic function objects */ + +#define __OCTA_DEFINE_BINARY_OP(name, op, rettype) \ template struct name { \ bool operator()(const T &x, const T &y) const { return x op y; } \ struct type { \ @@ -22,24 +24,24 @@ namespace octa { }; \ }; - 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) + __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) -#undef OCTA_DEFINE_BINARY_OP +#undef __OCTA_DEFINE_BINARY_OP template struct LogicalNot { bool operator()(const T &x) const { return !x; } @@ -93,6 +95,8 @@ namespace octa { return BinaryNegate(fn); } + /* reference wrapper */ + template struct ReferenceWrapper { typedef T type; @@ -126,64 +130,64 @@ namespace octa { } template void cref(const T &&) = delete; - namespace internal { - template struct MemTypes; - template - struct MemTypes { - typedef R result; - typedef T argument; - }; - template - struct MemTypes { - typedef R result; - typedef T first; - typedef A second; - }; - template - struct MemTypes { - typedef R result; - typedef const T argument; - }; - template - struct MemTypes { - typedef R result; - typedef const T first; - typedef A second; - }; + /* mem_fn */ - template - class MemFn { - R T::*p_ptr; - public: - struct type: MemTypes {}; - - MemFn(R T::*ptr): p_ptr(ptr) {} - template - auto operator()(T &obj, A &&...args) -> - decltype(((obj).*(p_ptr))(forward(args)...)) { - return ((obj).*(p_ptr))(forward(args)...); - } - template - auto operator()(const T &obj, A &&...args) -> - decltype(((obj).*(p_ptr))(forward(args)...)) const { - return ((obj).*(p_ptr))(forward(args)...); - } - template - auto operator()(T *obj, A &&...args) -> - decltype(((obj)->*(p_ptr))(forward(args)...)) { - return ((obj)->*(p_ptr))(forward(args)...); - } - template - auto operator()(const T *obj, A &&...args) -> - decltype(((obj)->*(p_ptr))(forward(args)...)) const { - return ((obj)->*(p_ptr))(forward(args)...); - } - }; - } + template struct __OctaMemTypes; + template + struct __OctaMemTypes { + typedef R result; + typedef T argument; + }; + template + struct __OctaMemTypes { + typedef R result; + typedef T first; + typedef A second; + }; + template + struct __OctaMemTypes { + typedef R result; + typedef const T argument; + }; + template + struct __OctaMemTypes { + typedef R result; + typedef const T first; + typedef A second; + }; template - internal::MemFn mem_fn(R T:: *ptr) { - return internal::MemFn(ptr); + class __OctaMemFn { + R T::*p_ptr; + public: + struct type: __OctaMemTypes {}; + + __OctaMemFn(R T::*ptr): p_ptr(ptr) {} + template + auto operator()(T &obj, A &&...args) -> + decltype(((obj).*(p_ptr))(forward(args)...)) { + return ((obj).*(p_ptr))(forward(args)...); + } + template + auto operator()(const T &obj, A &&...args) -> + decltype(((obj).*(p_ptr))(forward(args)...)) const { + return ((obj).*(p_ptr))(forward(args)...); + } + template + auto operator()(T *obj, A &&...args) -> + decltype(((obj)->*(p_ptr))(forward(args)...)) { + return ((obj)->*(p_ptr))(forward(args)...); + } + template + auto operator()(const T *obj, A &&...args) -> + decltype(((obj)->*(p_ptr))(forward(args)...)) const { + return ((obj)->*(p_ptr))(forward(args)...); + } + }; + + template + __OctaMemFn mem_fn(R T:: *ptr) { + return __OctaMemFn(ptr); } /* function impl @@ -192,158 +196,161 @@ namespace octa { template struct Function; - namespace internal { - struct FunctorData { - void *p1, *p2; - }; + struct __OctaFunctorData { + void *p1, *p2; + }; - template - struct FunctorInPlace { - static constexpr bool value = sizeof(T) <= sizeof(FunctorData) - && (alignof(FunctorData) % alignof(T)) == 0 - && octa::IsNothrowMoveConstructible::value; - }; + template + struct __OctaFunctorInPlace { + static constexpr bool value = sizeof(T) <= sizeof(__OctaFunctorData) + && (alignof(__OctaFunctorData) % alignof(T)) == 0 + && octa::IsNothrowMoveConstructible::value; + }; - template - struct FunctorDataManager { - template - static R call(const FunctorData &s, A ...args) { - return ((T &)s)(forward(args)...); - } - - static void store_f(FunctorData &s, T v) { - new (&get_ref(s)) T(forward(v)); - } - - static void move_f(FunctorData &lhs, FunctorData &&rhs) { - new (&get_ref(lhs)) T(move(get_ref(rhs))); - } - - static void destroy_f(FunctorData &s) { - get_ref(s).~T(); - } - - static T &get_ref(const FunctorData &s) { - return (T &)s; - } - }; - - template - struct FunctorDataManager - ::value>::type> { - template - static R call(const FunctorData &s, A ...args) { - return (*(T *&)s)(forward(args)...); - } - - static void store_f(FunctorData &s, T v) { - new (&get_ptr_ref(s)) T *(new T(forward(v))); - } - - 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(FunctorData &s) { - T *&ptr = get_ptr_ref(s); - if (!ptr) return; - delete ptr; - ptr = nullptr; - } - - static T &get_ref(const FunctorData &s) { - return *get_ptr_ref(s); - } - - static T *&get_ptr_ref(FunctorData &s) { - return (T *&)s; - } - - static T *&get_ptr_ref(const FunctorData &s) { - return (T *&)s; - } - }; - - struct FunctionManager; - - struct ManagerStorage { - FunctorData data; - const FunctionManager *manager; - }; - - template - static const FunctionManager &get_default_manager(); - - struct FunctionManager { - template - inline static const FunctionManager create_default_manager() { - return FunctionManager { - &t_call_move_and_destroy, - &t_call_copy, - &t_call_destroy - }; - } - - void (* const call_move_and_destroy)(ManagerStorage &lhs, ManagerStorage &&rhs); - void (* const call_copy)(ManagerStorage &lhs, const ManagerStorage &rhs); - void (* const call_destroy)(ManagerStorage &s); - - template - static void t_call_move_and_destroy(ManagerStorage &lhs, ManagerStorage &&rhs) { - typedef FunctorDataManager spec; - spec::move_f(lhs.data, move(rhs.data)); - spec::destroy_f(rhs.data); - lhs.manager = &get_default_manager(); - } - - template - static void t_call_copy(ManagerStorage &lhs, const ManagerStorage &rhs) { - typedef FunctorDataManager spec; - lhs.manager = &get_default_manager(); - spec::store_f(lhs.data, spec::get_ref(rhs.data)); - } - - template - static void t_call_destroy(ManagerStorage &s) { - typedef FunctorDataManager spec; - spec::destroy_f(s.data); - } - }; - - template - inline static const FunctionManager &get_default_manager() { - static const FunctionManager def_manager = FunctionManager::create_default_manager(); - return def_manager; + template + struct __OctaFunctorDataManager { + template + static R call(const __OctaFunctorData &s, A ...args) { + return ((T &)s)(forward(args)...); } - template - struct FunctionBase { - struct type { - typedef R result; - }; - }; + static void store_f(__OctaFunctorData &s, T v) { + new (&get_ref(s)) T(forward(v)); + } - template - struct FunctionBase { - struct type { - typedef R result; - typedef T argument; - }; - }; + static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) { + new (&get_ref(lhs)) T(move(get_ref(rhs))); + } - template - struct FunctionBase { - struct type { - typedef R result; - typedef T first; - typedef U second; + static void destroy_f(__OctaFunctorData &s) { + get_ref(s).~T(); + } + + static T &get_ref(const __OctaFunctorData &s) { + return (T &)s; + } + }; + + template + struct __OctaFunctorDataManager + ::value>::type> { + template + static R call(const __OctaFunctorData &s, A ...args) { + return (*(T *&)s)(forward(args)...); + } + + static void store_f(__OctaFunctorData &s, T v) { + new (&get_ptr_ref(s)) T *(new T(forward(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 destroy_f(__OctaFunctorData &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_ptr_ref(__OctaFunctorData &s) { + return (T *&)s; + } + + static T *&get_ptr_ref(const __OctaFunctorData &s) { + return (T *&)s; + } + }; + + struct __OctaFunctionManager; + + struct __OctaFMStorage { + __OctaFunctorData data; + const __OctaFunctionManager *manager; + }; + + template + static const __OctaFunctionManager &__octa_get_default_fm(); + + struct __OctaFunctionManager { + template + inline static const __OctaFunctionManager create_default_manager() { + return __OctaFunctionManager { + &t_call_move_and_destroy, + &t_call_copy, + &t_call_destroy }; - }; + } + + void (* const call_move_and_destroy)(__OctaFMStorage &lhs, + __OctaFMStorage &&rhs); + void (* const call_copy)(__OctaFMStorage &lhs, + const __OctaFMStorage &rhs); + void (* const call_destroy)(__OctaFMStorage &s); + + template + static void t_call_move_and_destroy(__OctaFMStorage &lhs, + __OctaFMStorage &&rhs) { + typedef __OctaFunctorDataManager spec; + spec::move_f(lhs.data, move(rhs.data)); + spec::destroy_f(rhs.data); + lhs.manager = &__octa_get_default_fm(); + } + + template + static void t_call_copy(__OctaFMStorage &lhs, + const __OctaFMStorage &rhs) { + typedef __OctaFunctorDataManager spec; + lhs.manager = &__octa_get_default_fm(); + spec::store_f(lhs.data, spec::get_ref(rhs.data)); + } + + template + static void t_call_destroy(__OctaFMStorage &s) { + typedef __OctaFunctorDataManager spec; + spec::destroy_f(s.data); + } + }; + + template + inline static const __OctaFunctionManager &__octa_get_default_fm() { + static const __OctaFunctionManager def_manager + = __OctaFunctionManager::create_default_manager(); + return def_manager; } + template + struct __OctaFunction { + struct type { + typedef R result; + }; + }; + + template + struct __OctaFunction { + struct type { + typedef R result; + typedef T argument; + }; + }; + + template + struct __OctaFunction { + struct type { + typedef R result; + typedef T first; + typedef U second; + }; + }; + template - struct Function: internal::FunctionBase { + struct Function: __OctaFunction { Function( ) { initialize_empty(); } Function(nullptr_t) { initialize_empty(); } @@ -391,7 +398,7 @@ namespace octa { } void swap(Function &f) { - internal::ManagerStorage tmp; + __OctaFMStorage tmp; f.p_stor.manager->call_move_and_destroy(tmp, move(f.p_stor)); p_stor.manager->call_move_and_destroy(f.p_stor, move(p_stor)); tmp.manager->call_move_and_destroy(p_stor, move(tmp)); @@ -401,21 +408,21 @@ namespace octa { operator bool() const { return p_call != nullptr; } private: - internal::ManagerStorage p_stor; - R (*p_call)(const internal::FunctorData &, A...); + __OctaFMStorage p_stor; + R (*p_call)(const __OctaFunctorData &, A...); template void initialize(T f) { - p_call = &internal::FunctorDataManager::template call; - p_stor.manager = &internal::get_default_manager(); - internal::FunctorDataManager::store_f(p_stor.data, forward(f)); + p_call = &__OctaFunctorDataManager::template call; + p_stor.manager = &__octa_get_default_fm(); + __OctaFunctorDataManager::store_f(p_stor.data, forward(f)); } void initialize_empty() { typedef R(*emptyf)(A...); p_call = nullptr; - p_stor.manager = &internal::get_default_manager(); - internal::FunctorDataManager::store_f(p_stor.data, nullptr); + p_stor.manager = &__octa_get_default_fm(); + __OctaFunctorDataManager::store_f(p_stor.data, nullptr); } template diff --git a/octa/range.h b/octa/range.h index d206392..26eb3e2 100644 --- a/octa/range.h +++ b/octa/range.h @@ -25,26 +25,24 @@ namespace octa { typedef typename T::type::reference reference; }; - namespace internal { - template - struct RangeIterator { - RangeIterator(): p_range() {} - explicit RangeIterator(const T &range): p_range(range) {} - RangeIterator &operator++() { - p_range.pop_first(); - return *this; - } - typename RangeTraits::reference operator*() { - return p_range.first(); - } - typename RangeTraits::reference operator*() const { - return p_range.first(); - } - bool operator!=(RangeIterator) const { return !p_range.empty(); } - private: - T p_range; - }; - } + template + struct __OctaRangeIterator { + __OctaRangeIterator(): p_range() {} + explicit __OctaRangeIterator(const T &range): p_range(range) {} + __OctaRangeIterator &operator++() { + p_range.pop_first(); + return *this; + } + typename RangeTraits::reference operator*() { + return p_range.first(); + } + typename RangeTraits::reference operator*() const { + return p_range.first(); + } + bool operator!=(__OctaRangeIterator) const { return !p_range.empty(); } + private: + T p_range; + }; template struct InputRangeBase { @@ -54,11 +52,11 @@ namespace octa { typedef R reference; }; - internal::RangeIterator begin() { - return internal::RangeIterator((const B &)*this); + __OctaRangeIterator begin() { + return __OctaRangeIterator((const B &)*this); } - internal::RangeIterator end() { - return internal::RangeIterator(); + __OctaRangeIterator end() { + return __OctaRangeIterator(); } };