get rid of namespace internal

master
Daniel Kolesa 2015-04-24 18:16:35 +01:00
parent cca0a62d34
commit f106c5ae24
4 changed files with 326 additions and 311 deletions

View File

@ -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

View File

@ -14,6 +14,8 @@
#include "octa/initializer_list.h"
namespace octa {
/* partitioning */
template<typename R, typename U>
R partition(R range, U pred) {
R ret = range;
@ -34,6 +36,8 @@ namespace octa {
return true;
}
/* insertion sort */
template<typename R, typename C>
void insertion_sort(R range, C compare) {
size_t rlen = range.length();
@ -52,76 +56,76 @@ namespace octa {
insertion_sort(range, Less<typename RangeTraits<R>::value>());
}
namespace internal {
template<typename T, typename U>
struct UnaryCompare {
const T &val;
U comp;
bool operator()(const T &v) const { return comp(v, val); }
};
/* sort (introsort) */
template<typename R, typename C>
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<typename T, typename U>
struct __OctaUnaryCompare {
const T &val;
U comp;
bool operator()(const T &v) const { return comp(v, val); }
};
template<typename R, typename C>
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<typename R, typename C>
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<R>::reference p = range[range.length() / 2];
swap(p, range.last());
R r = partition(range, UnaryCompare<decltype(p), C>{ 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<typename R, typename C>
void introsort(R range, C compare) {
introloop(range, compare, size_t(2
* (log(range.length()) / log(2))));
template<typename R, typename C>
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<typename R, typename C>
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<typename R, typename C>
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<R>::reference p = range[range.length() / 2];
swap(p, range.last());
R r = partition(range, __OctaUnaryCompare<decltype(p), C>{ 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<typename R, typename C>
void __octa_introsort(R range, C compare) {
__octa_introloop(range, compare, size_t(2
* (log(range.length()) / log(2))));
}
template<typename R, typename C>
void sort(R range, C compare) {
internal::introsort(range, compare);
__octa_introsort(range, compare);
}
template<typename R>
@ -129,6 +133,8 @@ namespace octa {
sort(range, Less<typename RangeTraits<R>::value>());
}
/* min/max(_element) */
template<typename T>
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<typename R, typename F>
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<typename R1, typename R2>
R2 copy(R1 irange, R2 orange) {
for (; !irange.empty(); irange.pop_first())

View File

@ -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<typename T> 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<typename T> struct LogicalNot {
bool operator()(const T &x) const { return !x; }
@ -93,6 +95,8 @@ namespace octa {
return BinaryNegate<T>(fn);
}
/* reference wrapper */
template<typename T>
struct ReferenceWrapper {
typedef T type;
@ -126,64 +130,64 @@ namespace octa {
}
template<typename T> void cref(const T &&) = delete;
namespace internal {
template<typename, typename> struct MemTypes;
template<typename T, typename R, typename ...A>
struct MemTypes<T, R(A...)> {
typedef R result;
typedef T argument;
};
template<typename T, typename R, typename A>
struct MemTypes<T, R(A)> {
typedef R result;
typedef T first;
typedef A second;
};
template<typename T, typename R, typename ...A>
struct MemTypes<T, R(A...) const> {
typedef R result;
typedef const T argument;
};
template<typename T, typename R, typename A>
struct MemTypes<T, R(A) const> {
typedef R result;
typedef const T first;
typedef A second;
};
/* mem_fn */
template<typename R, typename T>
class MemFn {
R T::*p_ptr;
public:
struct type: MemTypes<T, R> {};
MemFn(R T::*ptr): p_ptr(ptr) {}
template<typename... A>
auto operator()(T &obj, A &&...args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) {
return ((obj).*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(const T &obj, A &&...args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) const {
return ((obj).*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(T *obj, A &&...args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) {
return ((obj)->*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(const T *obj, A &&...args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) const {
return ((obj)->*(p_ptr))(forward<A>(args)...);
}
};
}
template<typename, typename> struct __OctaMemTypes;
template<typename T, typename R, typename ...A>
struct __OctaMemTypes<T, R(A...)> {
typedef R result;
typedef T argument;
};
template<typename T, typename R, typename A>
struct __OctaMemTypes<T, R(A)> {
typedef R result;
typedef T first;
typedef A second;
};
template<typename T, typename R, typename ...A>
struct __OctaMemTypes<T, R(A...) const> {
typedef R result;
typedef const T argument;
};
template<typename T, typename R, typename A>
struct __OctaMemTypes<T, R(A) const> {
typedef R result;
typedef const T first;
typedef A second;
};
template<typename R, typename T>
internal::MemFn<R, T> mem_fn(R T:: *ptr) {
return internal::MemFn<R, T>(ptr);
class __OctaMemFn {
R T::*p_ptr;
public:
struct type: __OctaMemTypes<T, R> {};
__OctaMemFn(R T::*ptr): p_ptr(ptr) {}
template<typename... A>
auto operator()(T &obj, A &&...args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) {
return ((obj).*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(const T &obj, A &&...args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) const {
return ((obj).*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(T *obj, A &&...args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) {
return ((obj)->*(p_ptr))(forward<A>(args)...);
}
template<typename... A>
auto operator()(const T *obj, A &&...args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) const {
return ((obj)->*(p_ptr))(forward<A>(args)...);
}
};
template<typename R, typename T>
__OctaMemFn<R, T> mem_fn(R T:: *ptr) {
return __OctaMemFn<R, T>(ptr);
}
/* function impl
@ -192,158 +196,161 @@ namespace octa {
template<typename> struct Function;
namespace internal {
struct FunctorData {
void *p1, *p2;
};
struct __OctaFunctorData {
void *p1, *p2;
};
template<typename T>
struct FunctorInPlace {
static constexpr bool value = sizeof(T) <= sizeof(FunctorData)
&& (alignof(FunctorData) % alignof(T)) == 0
&& octa::IsNothrowMoveConstructible<T>::value;
};
template<typename T>
struct __OctaFunctorInPlace {
static constexpr bool value = sizeof(T) <= sizeof(__OctaFunctorData)
&& (alignof(__OctaFunctorData) % alignof(T)) == 0
&& octa::IsNothrowMoveConstructible<T>::value;
};
template<typename T, typename E = void>
struct FunctorDataManager {
template<typename R, typename ...A>
static R call(const FunctorData &s, A ...args) {
return ((T &)s)(forward<A>(args)...);
}
static void store_f(FunctorData &s, T v) {
new (&get_ref(s)) T(forward<T>(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<typename T>
struct FunctorDataManager<T, typename EnableIf<!FunctorInPlace<T>
::value>::type> {
template<typename R, typename ...A>
static R call(const FunctorData &s, A ...args) {
return (*(T *&)s)(forward<A>(args)...);
}
static void store_f(FunctorData &s, T v) {
new (&get_ptr_ref(s)) T *(new T(forward<T>(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<typename T>
static const FunctionManager &get_default_manager();
struct FunctionManager {
template<typename T>
inline static const FunctionManager create_default_manager() {
return FunctionManager {
&t_call_move_and_destroy<T>,
&t_call_copy<T>,
&t_call_destroy<T>
};
}
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<typename T>
static void t_call_move_and_destroy(ManagerStorage &lhs, ManagerStorage &&rhs) {
typedef FunctorDataManager<T> spec;
spec::move_f(lhs.data, move(rhs.data));
spec::destroy_f(rhs.data);
lhs.manager = &get_default_manager<T>();
}
template<typename T>
static void t_call_copy(ManagerStorage &lhs, const ManagerStorage &rhs) {
typedef FunctorDataManager<T> spec;
lhs.manager = &get_default_manager<T>();
spec::store_f(lhs.data, spec::get_ref(rhs.data));
}
template<typename T>
static void t_call_destroy(ManagerStorage &s) {
typedef FunctorDataManager<T> spec;
spec::destroy_f(s.data);
}
};
template<typename T>
inline static const FunctionManager &get_default_manager() {
static const FunctionManager def_manager = FunctionManager::create_default_manager<T>();
return def_manager;
template<typename T, typename E = void>
struct __OctaFunctorDataManager {
template<typename R, typename ...A>
static R call(const __OctaFunctorData &s, A ...args) {
return ((T &)s)(forward<A>(args)...);
}
template<typename R, typename...>
struct FunctionBase {
struct type {
typedef R result;
};
};
static void store_f(__OctaFunctorData &s, T v) {
new (&get_ref(s)) T(forward<T>(v));
}
template<typename R, typename T>
struct FunctionBase<R, T> {
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<typename R, typename T, typename U>
struct FunctionBase<R, T, U> {
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<typename T>
struct __OctaFunctorDataManager<T, typename EnableIf<!__OctaFunctorInPlace<T>
::value>::type> {
template<typename R, typename ...A>
static R call(const __OctaFunctorData &s, A ...args) {
return (*(T *&)s)(forward<A>(args)...);
}
static void store_f(__OctaFunctorData &s, T v) {
new (&get_ptr_ref(s)) T *(new T(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 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<typename T>
static const __OctaFunctionManager &__octa_get_default_fm();
struct __OctaFunctionManager {
template<typename T>
inline static const __OctaFunctionManager create_default_manager() {
return __OctaFunctionManager {
&t_call_move_and_destroy<T>,
&t_call_copy<T>,
&t_call_destroy<T>
};
};
}
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<typename T>
static void t_call_move_and_destroy(__OctaFMStorage &lhs,
__OctaFMStorage &&rhs) {
typedef __OctaFunctorDataManager<T> spec;
spec::move_f(lhs.data, move(rhs.data));
spec::destroy_f(rhs.data);
lhs.manager = &__octa_get_default_fm<T>();
}
template<typename T>
static void t_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));
}
template<typename T>
static void t_call_destroy(__OctaFMStorage &s) {
typedef __OctaFunctorDataManager<T> spec;
spec::destroy_f(s.data);
}
};
template<typename T>
inline static const __OctaFunctionManager &__octa_get_default_fm() {
static const __OctaFunctionManager def_manager
= __OctaFunctionManager::create_default_manager<T>();
return def_manager;
}
template<typename R, typename...>
struct __OctaFunction {
struct type {
typedef R result;
};
};
template<typename R, typename T>
struct __OctaFunction<R, T> {
struct type {
typedef R result;
typedef T argument;
};
};
template<typename R, typename T, typename U>
struct __OctaFunction<R, T, U> {
struct type {
typedef R result;
typedef T first;
typedef U second;
};
};
template<typename R, typename ...A>
struct Function<R(A...)>: internal::FunctionBase<R, A...> {
struct Function<R(A...)>: __OctaFunction<R, A...> {
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<typename T>
void initialize(T f) {
p_call = &internal::FunctorDataManager<T>::template call<R, A...>;
p_stor.manager = &internal::get_default_manager<T>();
internal::FunctorDataManager<T>::store_f(p_stor.data, forward<T>(f));
p_call = &__OctaFunctorDataManager<T>::template call<R, A...>;
p_stor.manager = &__octa_get_default_fm<T>();
__OctaFunctorDataManager<T>::store_f(p_stor.data, forward<T>(f));
}
void initialize_empty() {
typedef R(*emptyf)(A...);
p_call = nullptr;
p_stor.manager = &internal::get_default_manager<emptyf>();
internal::FunctorDataManager<emptyf>::store_f(p_stor.data, nullptr);
p_stor.manager = &__octa_get_default_fm<emptyf>();
__OctaFunctorDataManager<emptyf>::store_f(p_stor.data, nullptr);
}
template<typename T>

View File

@ -25,26 +25,24 @@ namespace octa {
typedef typename T::type::reference reference;
};
namespace internal {
template<typename T>
struct RangeIterator {
RangeIterator(): p_range() {}
explicit RangeIterator(const T &range): p_range(range) {}
RangeIterator &operator++() {
p_range.pop_first();
return *this;
}
typename RangeTraits<T>::reference operator*() {
return p_range.first();
}
typename RangeTraits<T>::reference operator*() const {
return p_range.first();
}
bool operator!=(RangeIterator) const { return !p_range.empty(); }
private:
T p_range;
};
}
template<typename T>
struct __OctaRangeIterator {
__OctaRangeIterator(): p_range() {}
explicit __OctaRangeIterator(const T &range): p_range(range) {}
__OctaRangeIterator &operator++() {
p_range.pop_first();
return *this;
}
typename RangeTraits<T>::reference operator*() {
return p_range.first();
}
typename RangeTraits<T>::reference operator*() const {
return p_range.first();
}
bool operator!=(__OctaRangeIterator) const { return !p_range.empty(); }
private:
T p_range;
};
template<typename B, typename C, typename V, typename R = V &>
struct InputRangeBase {
@ -54,11 +52,11 @@ namespace octa {
typedef R reference;
};
internal::RangeIterator<B> begin() {
return internal::RangeIterator<B>((const B &)*this);
__OctaRangeIterator<B> begin() {
return __OctaRangeIterator<B>((const B &)*this);
}
internal::RangeIterator<B> end() {
return internal::RangeIterator<B>();
__OctaRangeIterator<B> end() {
return __OctaRangeIterator<B>();
}
};