@ -0,0 +1,29 @@ | |||||
#pragma once | |||||
namespace gp{ | |||||
template<typename T, typename U, typename ...rest> | |||||
constexpr T max(T first, U second, rest... args) | |||||
{ | |||||
if constexpr (sizeof...(args) == 0) | |||||
{ | |||||
return first > second ? first : second; | |||||
} | |||||
else | |||||
{ | |||||
return max(first > second ? first : second, args...); | |||||
} | |||||
} | |||||
template<typename T, typename U, typename ...rest> | |||||
constexpr T min(T first, U second, rest... args) | |||||
{ | |||||
if constexpr (sizeof...(args) == 0) | |||||
{ | |||||
return first < second ? first : second; | |||||
} | |||||
else | |||||
{ | |||||
return min(first < second ? first : second, args...); | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,64 @@ | |||||
#pragma once | |||||
#include "gp/algorithm/tmp_manip.hpp" | |||||
#include "gp/range.hpp" | |||||
namespace gp{ | |||||
template<typename T> | |||||
typename gp::remove_reference<T>::type&& move(T&& value) | |||||
{ | |||||
return (typename gp::remove_reference<T>::type&&)value; | |||||
} | |||||
template<typename T> | |||||
constexpr T&& forward(typename gp::remove_reference<T>::type& t) noexcept | |||||
{ | |||||
return static_cast<T&&>(t); | |||||
} | |||||
template<typename T> | |||||
constexpr T&& forward(typename gp::remove_reference<T>::type&& t) noexcept | |||||
{ | |||||
static_assert(!std::is_lvalue_reference_v<T>,"bad forward of rvalue as lvalue"); | |||||
return static_cast<T&&>(t); | |||||
} | |||||
template<typename T> | |||||
constexpr void swap( | |||||
T& lhs, | |||||
T& rhs | |||||
) | |||||
{ | |||||
auto tmp = lhs; | |||||
lhs = rhs; | |||||
rhs = tmp; | |||||
} | |||||
template<typename range_in, typename range_out> | |||||
nameless_range<typename range_out::associated_iterator> move(range_in src, range_out dest) | |||||
{ | |||||
if(src.size()>dest.size()) | |||||
return nameless_range<typename range_out::associated_iterator>(dest.begin(), dest.end()); | |||||
auto in = src.begin(); | |||||
auto in_close = src.end(); | |||||
auto out = dest.begin(); | |||||
while(in != in_close) | |||||
{ | |||||
*(out++) = gp::move(*(in++)); | |||||
} | |||||
return nameless_range<typename range_out::associated_iterator>{out, dest.end()}; | |||||
} | |||||
template<typename T, typename range_in, typename range_out> | |||||
nameless_range<typename range_out::associated_iterator> move_uninitialized(range_in src, range_out dest) | |||||
{ | |||||
if(src.size()>dest.size()) | |||||
return nameless_range<typename range_out::associated_iterator>(dest.begin(), dest.end()); | |||||
auto in = src.begin(); | |||||
auto in_close = src.end(); | |||||
auto out = dest.begin(); | |||||
while(in != in_close) | |||||
{ | |||||
new(&*(out++)) T{gp::move(*(in++))}; | |||||
} | |||||
return nameless_range<typename range_out::associated_iterator>{out, dest.end()}; | |||||
} | |||||
} |
@ -0,0 +1,234 @@ | |||||
#pragma once | |||||
#include <type_traits> | |||||
#include <typeinfo> | |||||
#include <cstddef> | |||||
#include <limits> | |||||
#include "gp/algorithm/min_max.hpp" | |||||
namespace gp{ | |||||
template<bool cond, typename T, typename U> | |||||
struct either | |||||
{ | |||||
}; | |||||
template<typename T, typename U> | |||||
struct either<true,T,U> | |||||
{ | |||||
typedef T type; | |||||
}; | |||||
template<typename T, typename U> | |||||
struct either<false,T,U> | |||||
{ | |||||
typedef U type; | |||||
}; | |||||
template<bool first, bool ...list> | |||||
struct constexpr_all_of | |||||
{ | |||||
static constexpr bool value = first && constexpr_all_of<list...>::value; | |||||
}; | |||||
template<bool first> | |||||
struct constexpr_all_of<first> | |||||
{ | |||||
static constexpr bool value = first; | |||||
}; | |||||
template<bool first, bool ...list> | |||||
struct constexpr_any_of | |||||
{ | |||||
static constexpr bool value = first || constexpr_any_of<list...>::value; | |||||
}; | |||||
template<bool first> | |||||
struct constexpr_any_of<first> | |||||
{ | |||||
static constexpr bool value = first; | |||||
}; | |||||
template<typename T> | |||||
constexpr bool is_fixed_size() | |||||
{ | |||||
return std::is_final<T>::value | |||||
|| std::is_fundamental<T>::value; | |||||
} | |||||
template<typename T, typename ...rest> | |||||
struct all_of_fixed_size | |||||
{ | |||||
static constexpr bool value = is_fixed_size<T>() && all_of_fixed_size<rest...>::value; | |||||
}; | |||||
template<typename T> | |||||
struct all_of_fixed_size<T> | |||||
{ | |||||
static constexpr bool value = is_fixed_size<T>(); | |||||
}; | |||||
template<typename Univ, typename T, typename ...rest> | |||||
struct list_contains_class | |||||
{ | |||||
static constexpr bool value = ( | |||||
std::is_same<T, Univ>::value | |||||
) || list_contains_class<Univ, rest...>::value; | |||||
}; | |||||
template<typename Univ, typename T> | |||||
struct list_contains_class<Univ, T> | |||||
{ | |||||
static constexpr bool value = std::is_same<T, Univ>::value; | |||||
}; | |||||
template<typename Univ, typename T, typename ...rest> | |||||
struct r_index_of | |||||
{ | |||||
static constexpr std::size_t value = std::is_same<T, Univ>::value ? sizeof...(rest) : r_index_of<Univ, rest...>::value; | |||||
}; | |||||
template<typename Univ, typename T> | |||||
struct r_index_of<Univ, T> | |||||
{ | |||||
static constexpr std::size_t value = std::is_same<T, Univ>::value ? 0 : std::numeric_limits<std::size_t>::max(); | |||||
}; | |||||
template<size_t idx, typename T, typename ...rest> | |||||
struct r_index_at | |||||
{ | |||||
using type = typename either<idx==sizeof...(rest),T,typename r_index_at<idx,rest...>::type>::type; | |||||
}; | |||||
template<typename T, typename U, typename ...rest> | |||||
constexpr std::size_t max_size() | |||||
{ | |||||
if constexpr (sizeof...(rest) == 0) | |||||
{ | |||||
return gp::max(sizeof(T),sizeof(U)); | |||||
} | |||||
else | |||||
{ | |||||
return max_size< | |||||
either< | |||||
( sizeof(T) > sizeof(U) ), | |||||
T, | |||||
U | |||||
>::type, | |||||
rest...>(); | |||||
} | |||||
} | |||||
template<typename T> | |||||
struct remove_reference | |||||
{ | |||||
using type = T; | |||||
}; | |||||
template<typename T> | |||||
struct remove_reference<T&> | |||||
{ | |||||
using type = T; | |||||
}; | |||||
template<typename T> | |||||
struct remove_reference<T&&> | |||||
{ | |||||
using type = T; | |||||
}; | |||||
template<typename T> | |||||
struct has_size_interface | |||||
{ | |||||
private: | |||||
typedef std::true_type yes; | |||||
typedef std::false_type no; | |||||
template<typename U, size_t (U::*f)() const> struct SFINAE{}; | |||||
template<class C> static yes test(SFINAE<C,&C::size>*); | |||||
template<class C> static no test(...); | |||||
public: | |||||
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; | |||||
}; | |||||
template<typename T> | |||||
struct has_begin_interface | |||||
{ | |||||
private: | |||||
typedef std::true_type yes; | |||||
typedef std::false_type no; | |||||
template<typename U, auto (U::*f)() const> struct SFINAE{}; | |||||
template<class C> static yes test(SFINAE<C,&C::begin>*); | |||||
template<class C> static no test(...); | |||||
public: | |||||
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; | |||||
}; | |||||
template<typename T> | |||||
struct has_end_interface | |||||
{ | |||||
private: | |||||
typedef std::true_type yes; | |||||
typedef std::false_type no; | |||||
template<typename U, auto (U::*f)() const> struct SFINAE{}; | |||||
template<class C> static yes test(SFINAE<C,&C::end>*); | |||||
template<class C> static no test(...); | |||||
public: | |||||
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; | |||||
}; | |||||
template<typename T> | |||||
using has_range_interface = constexpr_all_of<has_begin_interface<T>::value,has_end_interface<T>::value>; | |||||
template<typename T> | |||||
using has_measurable_range_interface = constexpr_all_of<has_range_interface<T>::value,has_size_interface<T>::value>; | |||||
template<typename T> | |||||
struct has_allocate_interface | |||||
{ | |||||
private: | |||||
typedef std::true_type yes; | |||||
typedef std::false_type no; | |||||
template<typename U, void* (U::*f)(size_t) const> struct SFINAE{}; | |||||
template<class C> static yes test(SFINAE<C,&C::allocate>*); | |||||
template<class C> static no test(...); | |||||
public: | |||||
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; | |||||
}; | |||||
template<typename T> | |||||
struct has_deallocate_interface | |||||
{ | |||||
private: | |||||
typedef std::true_type yes; | |||||
typedef std::false_type no; | |||||
template<typename U, void (U::*f)(void*) const> struct SFINAE{}; | |||||
template<class C> static yes test(SFINAE<C,&C::deallocate>*); | |||||
template<class C> static no test(...); | |||||
public: | |||||
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; | |||||
}; | |||||
template<typename T> | |||||
using has_allocator_interface = constexpr_all_of<has_allocate_interface<T>::value,has_deallocate_interface<T>::value>; | |||||
} |
@ -0,0 +1,95 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include "gp/buffer.hpp" | |||||
#include <type_traits> | |||||
#include <gp/algorithm/tmp_manip.hpp> | |||||
namespace gp{ | |||||
template<typename page_allocator, size_t align = 1> | |||||
class arena{ | |||||
page_allocator allocator; | |||||
fel::buffer<char> data; | |||||
size_t last; | |||||
size_t count; | |||||
public: | |||||
arena() | |||||
:last(0) | |||||
,count(0) | |||||
,data(fel::buffer<char>(nullptr,nullptr)) | |||||
{} | |||||
template<typename T = typename std::enable_if<fel::has_allocator_interface<page_allocator>::value,int>::type> | |||||
arena(size_t sz) | |||||
:last(0) | |||||
,count(0) | |||||
,data(nullptr,nullptr) | |||||
{ | |||||
if(sz!=0) | |||||
{ | |||||
auto v=allocator.allocate(sz); | |||||
if(v!=nullptr) | |||||
{ | |||||
data=fel::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz); | |||||
} | |||||
} | |||||
} | |||||
arena(char* pos,size_t sz) | |||||
:last(0) | |||||
,count(0) | |||||
,data(pos,pos+sz) | |||||
{ | |||||
} | |||||
void* allocate(size_t sz) | |||||
{ | |||||
[[maybe_unused]] | |||||
size_t mod = 0; | |||||
if constexpr (align != 1) | |||||
{ | |||||
mod = align - ((intptr_t)data.begin())%align; | |||||
} | |||||
auto ret=data.begin()+last+mod; | |||||
if(data.contains(ret)) | |||||
{ | |||||
count++; | |||||
last+=sz+mod; | |||||
return &*(ret); | |||||
} | |||||
else | |||||
{ | |||||
return nullptr; | |||||
} | |||||
} | |||||
bool deallocate(void* ptr) | |||||
{ | |||||
if(data.contains((char*)ptr)) | |||||
{ | |||||
count--; | |||||
if(count==0) | |||||
{ | |||||
for(auto& i : data) | |||||
{ | |||||
i=0; | |||||
} | |||||
last=0; | |||||
} | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
~arena() | |||||
{ | |||||
if constexpr(fel::has_allocator_interface<page_allocator>::value) | |||||
{ | |||||
allocator.deallocate(&data[0]); | |||||
} | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,48 @@ | |||||
#pragma once | |||||
#include <gp/buffer.hpp> | |||||
namespace gp{ | |||||
template<typename T, std::size_t sz> | |||||
class array{ | |||||
T ary[sz]; | |||||
public: | |||||
using associated_iterator = typename buffer<T>::associated_iterator; | |||||
constexpr T& operator[] (size_t off) | |||||
{ | |||||
return ary[off]; | |||||
} | |||||
constexpr size_t size() const | |||||
{ | |||||
return sz; | |||||
} | |||||
constexpr associated_iterator begin() const | |||||
{ | |||||
return gp::buffer<T>{(T*)ary, (T*)ary+sz}.begin(); | |||||
} | |||||
constexpr associated_iterator end() const | |||||
{ | |||||
return gp::buffer<T>{(T*)ary, (T*)ary+sz}.end(); | |||||
} | |||||
constexpr bool operator==(const array& oth) const | |||||
{ | |||||
for(size_t idx = 0; idx<sz; idx++) | |||||
{ | |||||
if(ary[idx] != oth.ary[idx]) | |||||
{ | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
gp::buffer<T> as_buffer() | |||||
{ | |||||
return gp::buffer<T>{(T*)ary, (T*)ary+sz}; | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,49 @@ | |||||
#pragma once | |||||
#include <stdint.h> | |||||
#include <atomic> | |||||
#include <gp/array.hpp> | |||||
#include <gp/algorithm/tmp_manip.hpp> | |||||
namespace gp { | |||||
template<typename hash_type = uint64_t, uint8_t magnitude = 19, bool threading = false> | |||||
class bloomfilter { | |||||
constexpr static size_t phys_size = (1 << magnitude) / 32; | |||||
gp::array< | |||||
typename gp::either< threading, | |||||
std::atomic_uint32_t, | |||||
uint32_t | |||||
>::type, | |||||
phys_size | |||||
> data; | |||||
template<typename T> | |||||
static void set_bit(T* value, const int v_pos) { | |||||
*value |= (1 << v_pos); | |||||
} | |||||
template<typename T> | |||||
static bool get_bit(T* value, const int v_pos) { | |||||
return (*value >> v_pos) & 1; | |||||
} | |||||
public: | |||||
void set_hash(hash_type v) | |||||
{ | |||||
const size_t modulo = v & ((1 << magnitude)-1); | |||||
const size_t p_pos = modulo / 32; | |||||
const size_t v_pos = modulo % 32; | |||||
set_bit(&data[p_pos], v_pos); | |||||
} | |||||
bool test_hash(hash_type v) | |||||
{ | |||||
const size_t modulo = v & ((1 << magnitude)-1); | |||||
const size_t p_pos = modulo / 32; | |||||
const size_t v_pos = modulo % 32; | |||||
return get_bit(&data[p_pos], v_pos); | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,205 @@ | |||||
#pragma once | |||||
#include <cstddef> | |||||
#include <cstdint> | |||||
#include <gp/optional.hpp> | |||||
#include <gp/iterator.hpp> | |||||
#include <gp/function.hpp> | |||||
#include <gp/exception.hpp> | |||||
#include <gp/algorithm/move.hpp> | |||||
namespace gp{ | |||||
template<typename T> | |||||
class buffer final{ | |||||
public: | |||||
struct buffer_iterator final | |||||
{ | |||||
T* data; | |||||
typedef T value_type; | |||||
typedef std::size_t difference_type; | |||||
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; | |||||
constexpr buffer_iterator(const buffer_iterator& oth) | |||||
: data{oth.data} | |||||
{} | |||||
constexpr buffer_iterator(T* ptr) | |||||
: data{ptr} | |||||
{} | |||||
constexpr operator T&() | |||||
{ | |||||
return *data; | |||||
} | |||||
constexpr T& operator*(){ | |||||
return *data; | |||||
} | |||||
constexpr buffer_iterator operator++() | |||||
{ | |||||
return buffer_iterator{++data}; | |||||
} | |||||
constexpr buffer_iterator operator++(int) | |||||
{ | |||||
return buffer_iterator{data++}; | |||||
} | |||||
constexpr buffer_iterator operator--() | |||||
{ | |||||
return buffer_iterator{--data}; | |||||
} | |||||
constexpr buffer_iterator operator--(int) | |||||
{ | |||||
return buffer_iterator{data--}; | |||||
} | |||||
constexpr buffer_iterator operator+(const std::size_t offset) | |||||
{ | |||||
return buffer_iterator{data+offset}; | |||||
} | |||||
constexpr buffer_iterator operator+(const int offset) | |||||
{ | |||||
return buffer_iterator{data+offset}; | |||||
} | |||||
constexpr buffer_iterator operator-(const std::size_t offset) | |||||
{ | |||||
return buffer_iterator{data-offset}; | |||||
} | |||||
constexpr buffer_iterator operator-(const int offset) | |||||
{ | |||||
return buffer_iterator{data-offset}; | |||||
} | |||||
constexpr difference_type operator-(const buffer_iterator& oth) const | |||||
{ | |||||
return (T*)data-(T*)oth.data; | |||||
} | |||||
constexpr bool operator==(const buffer_iterator& oth) | |||||
{ | |||||
return data==oth.data; | |||||
} | |||||
constexpr bool operator!=(buffer_iterator& oth) | |||||
{ | |||||
return data!=oth.data; | |||||
} | |||||
constexpr bool before_or_equal(const buffer_iterator& oth) | |||||
{ | |||||
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data); | |||||
} | |||||
constexpr bool operator<=(const buffer_iterator& oth) | |||||
{ | |||||
return before_or_equal(oth); | |||||
} | |||||
}; | |||||
private: | |||||
buffer_iterator begin_elem; | |||||
buffer_iterator end_elem; | |||||
public: | |||||
using associated_iterator = buffer_iterator; | |||||
constexpr buffer(T* beg_ptr, T* end_ptr) | |||||
: begin_elem{beg_ptr} | |||||
, end_elem{end_ptr} | |||||
{} | |||||
constexpr buffer(T* beg_ptr, std::size_t sz) | |||||
: begin_elem{beg_ptr} | |||||
, end_elem{beg_ptr+sz} | |||||
{} | |||||
constexpr typename buffer_iterator::difference_type size() const | |||||
{ | |||||
return end_elem - begin_elem; | |||||
} | |||||
constexpr associated_iterator begin() const | |||||
{ | |||||
return begin_elem; | |||||
} | |||||
constexpr associated_iterator end() const | |||||
{ | |||||
return end_elem; | |||||
} | |||||
constexpr T& operator[](std::size_t offset) | |||||
{ | |||||
return *(begin_elem+offset); | |||||
} | |||||
optional<buffer_iterator> at(std::size_t offset) | |||||
{ | |||||
auto elem = begin()+offset; | |||||
if(!contains(elem)) | |||||
{ | |||||
return nullopt; | |||||
} | |||||
return elem; | |||||
} | |||||
constexpr bool contains(buffer_iterator ptr) | |||||
{ | |||||
return | |||||
ptr.data < end_elem.data | |||||
&& ptr.data >= begin_elem.data; | |||||
} | |||||
template<typename U> | |||||
buffer<U> cast() | |||||
{ | |||||
if constexpr(sizeof(T)%sizeof(U) == 0) | |||||
{ | |||||
return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*(sizeof(T)/sizeof(U))); | |||||
} | |||||
else | |||||
{ | |||||
if(size()*sizeof(T)/sizeof(U)) | |||||
{ | |||||
return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*sizeof(T)/sizeof(U)); | |||||
} | |||||
else if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
throw bad_buffer_cast<T, U>{}; | |||||
} | |||||
else | |||||
{ | |||||
return buffer<U>(reinterpret_cast<U*>(nullptr), 0); | |||||
} | |||||
} | |||||
} | |||||
buffer slice_start(size_t new_sz) | |||||
{ | |||||
if(new_sz<=size()) | |||||
{ | |||||
return buffer{&*begin(), &*(begin()+new_sz)}; | |||||
} | |||||
else | |||||
{ | |||||
return buffer{(T*)nullptr,(size_t)0}; | |||||
} | |||||
} | |||||
buffer slice_end(size_t new_sz) | |||||
{ | |||||
if(new_sz<=size()) | |||||
{ | |||||
return buffer{&*(end()-(1+new_sz)), &*end()}; | |||||
} | |||||
else | |||||
{ | |||||
return buffer{(T*)nullptr,(size_t)0}; | |||||
} | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,117 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include <new> | |||||
namespace gp{ | |||||
class runtime_error{ | |||||
protected: | |||||
const char* what_str; | |||||
public: | |||||
runtime_error(const char* what) | |||||
: what_str{what} | |||||
{} | |||||
runtime_error() | |||||
{ | |||||
what_str = "an unknown error has occured"; | |||||
} | |||||
const char* what() | |||||
{ | |||||
return what_str; | |||||
} | |||||
}; | |||||
class out_of_range : public runtime_error{ | |||||
public: | |||||
out_of_range(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
out_of_range() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "out_of_range error has occured"; | |||||
} | |||||
}; | |||||
class bad_optional : public runtime_error{ | |||||
public: | |||||
bad_optional(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_optional() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_optional error has occured"; | |||||
} | |||||
}; | |||||
template<typename orig, typename target> | |||||
class bad_buffer_cast : public runtime_error{ | |||||
public: | |||||
bad_buffer_cast(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_buffer_cast() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_buffer_cast error has occured"; | |||||
} | |||||
}; | |||||
template<typename Expected> | |||||
class bad_variant_access : public runtime_error{ | |||||
public: | |||||
bad_variant_access(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_variant_access() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_variant_access error has occured"; | |||||
} | |||||
}; | |||||
class bad_hashmap_access : public runtime_error{ | |||||
public: | |||||
bad_hashmap_access(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_hashmap_access() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_hashmap_access error has occured"; | |||||
} | |||||
}; | |||||
class bad_alloc : public runtime_error{ | |||||
public: | |||||
bad_alloc(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_alloc() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_alloc error has occured"; | |||||
} | |||||
}; | |||||
class bad_functor : public runtime_error{ | |||||
public: | |||||
bad_functor(const char* what) | |||||
: runtime_error{what} | |||||
{} | |||||
bad_functor() | |||||
: runtime_error{} | |||||
{ | |||||
what_str = "bad_functor error has occured"; | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,140 @@ | |||||
#pragma once | |||||
#include "gp/memory.hpp" | |||||
#include "gp/exception.hpp" | |||||
namespace gp{ | |||||
template <typename> | |||||
class function; | |||||
template <typename ret, typename ...args> | |||||
class function<ret(args...)>{ | |||||
struct virtual_callable | |||||
{ | |||||
virtual ~virtual_callable() = default; | |||||
virtual ret operator() (args...) = 0; | |||||
}; | |||||
template<typename fn> | |||||
class callable : virtual_callable{ | |||||
fn internal_representation; | |||||
public: | |||||
callable(const fn& func) | |||||
: internal_representation{func} | |||||
{} | |||||
virtual ~callable() override = default; | |||||
ret operator() (args... arg_list) | |||||
{ | |||||
return internal_representation(arg_list...); | |||||
} | |||||
}; | |||||
enum state_t : uint8_t{ | |||||
INACTIVE = 0, | |||||
ACTIVE = 1, | |||||
NO_SOO = 0, | |||||
SOO = 2 | |||||
}; | |||||
state_t state = 0; | |||||
union{ | |||||
virtual_callable* functor = nullptr; | |||||
char inplace[12]; | |||||
} self; | |||||
public: | |||||
template <typename T> | |||||
function& operator=(T& t) | |||||
{ | |||||
if(state & ACTIVE) | |||||
{ | |||||
if(state & SOO) | |||||
{ | |||||
((virtual_callable*)&self)->~virtual_callable(); | |||||
} | |||||
else | |||||
{ | |||||
delete self.functor; | |||||
} | |||||
} | |||||
if constexpr (sizeof(callable<T>) <= sizeof(self)) | |||||
{ | |||||
new((void*)&self) callable(t); | |||||
state = ACTIVE | SOO; | |||||
} | |||||
else | |||||
{ | |||||
self = new callable(t); | |||||
state = ACTIVE | NO_SOO; | |||||
} | |||||
} | |||||
template <typename T> | |||||
function(T t) | |||||
{ | |||||
if constexpr (sizeof(callable<T>) <= sizeof(self)) | |||||
{ | |||||
new((void*)&self) callable(t); | |||||
state = ACTIVE | SOO; | |||||
} | |||||
else | |||||
{ | |||||
self = new callable(t); | |||||
state = ACTIVE | NO_SOO; | |||||
} | |||||
} | |||||
template <typename T> | |||||
function(T& t) | |||||
{ | |||||
if constexpr (sizeof(callable<T>) <= sizeof(self)) | |||||
{ | |||||
new((void*)&self) callable(t); | |||||
state = ACTIVE | SOO; | |||||
} | |||||
else | |||||
{ | |||||
self = new callable(t); | |||||
state = ACTIVE | NO_SOO; | |||||
} | |||||
} | |||||
ret operator()(args... arg_list) const { | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(!(state & ACTIVE)) | |||||
{ | |||||
throw bad_functor{}; | |||||
} | |||||
} | |||||
if(state & SOO) | |||||
{ | |||||
return (*(virtual_callable*)&self)(arg_list...); | |||||
} | |||||
else | |||||
{ | |||||
return (*(self.functor))(arg_list...); | |||||
} | |||||
} | |||||
~function() | |||||
{ | |||||
if(state & ACTIVE) | |||||
{ | |||||
if(state & SOO) | |||||
{ | |||||
((virtual_callable*)&self)->~virtual_callable(); | |||||
} | |||||
else | |||||
{ | |||||
delete self.functor; | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,7 @@ | |||||
#pragma once | |||||
enum class iterator_type_t{ | |||||
contiguous_iterator, | |||||
non_contiguous_iterator, | |||||
lazy_iterator | |||||
}; |
@ -0,0 +1,56 @@ | |||||
#pragma once | |||||
#include "gp_config.hpp" | |||||
#include "gp/exception.hpp" | |||||
#include <type_traits> | |||||
namespace gp{ | |||||
template<class T, typename I = std::enable_if_t<gp_config::memory_module::is_ok,int>> | |||||
class default_memory_allocator | |||||
{ | |||||
public: | |||||
using pointer_type = T*; | |||||
using reference_type = T&; | |||||
using const_pointer_type = const T*; | |||||
using const_reference_type = const T&; | |||||
pointer_type allocate(size_t sz) | |||||
{ | |||||
return reinterpret_cast <pointer_type> (gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sizeof(T) * sz)); | |||||
} | |||||
void deallocate(pointer_type ptr) | |||||
{ | |||||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||||
} | |||||
template<typename ...params> | |||||
pointer_type construct(pointer_type ptr, params... args) | |||||
{ | |||||
new(ptr) T(args...); | |||||
return ptr; | |||||
} | |||||
void destroy(pointer_type v) | |||||
{ | |||||
v->~T(); | |||||
} | |||||
}; | |||||
} | |||||
void* operator new(size_t sz) | |||||
{ | |||||
auto ptr = gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sz); | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(!ptr) | |||||
{ | |||||
throw gp::bad_alloc{}; | |||||
} | |||||
} | |||||
return ptr; | |||||
} | |||||
void operator delete (void* ptr) noexcept | |||||
{ | |||||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||||
} |
@ -0,0 +1,100 @@ | |||||
#pragma once | |||||
#include <type_traits> | |||||
#include "gp_config.hpp" | |||||
#include "gp/exception.hpp" | |||||
#include "gp/memory.hpp" | |||||
namespace gp{ | |||||
struct nullopt_t{}; | |||||
constexpr nullopt_t nullopt; | |||||
template<typename T, bool B = std::is_final<T>::value || std::is_fundamental<T>::value> | |||||
class optional; | |||||
template<typename T> | |||||
class optional<T,true>{ | |||||
bool ready = false; | |||||
char buffer[sizeof(T)]; | |||||
public: | |||||
constexpr optional() | |||||
: ready{false} | |||||
{} | |||||
constexpr optional(nullopt_t) | |||||
: ready{false} | |||||
{} | |||||
constexpr optional(T& value) | |||||
: ready{true} | |||||
{ | |||||
new(buffer) T(value); | |||||
} | |||||
constexpr optional(T&& value) | |||||
: ready{true} | |||||
{ | |||||
new(buffer) T(std::move(value)); | |||||
} | |||||
constexpr bool has_value() | |||||
{ | |||||
return ready; | |||||
} | |||||
constexpr T& value() | |||||
{ | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(!ready) | |||||
{ | |||||
throw bad_optional{}; | |||||
} | |||||
} | |||||
return *reinterpret_cast<T*>(buffer); | |||||
} | |||||
}; | |||||
template<typename T> | |||||
class optional<T,false>{ | |||||
bool ready = false; | |||||
void* ptr; | |||||
public: | |||||
constexpr optional() | |||||
: ready{false} | |||||
{} | |||||
constexpr optional(nullopt_t) | |||||
: ready{false} | |||||
{} | |||||
constexpr optional(T& value) | |||||
: ready{true} | |||||
{ | |||||
ptr = (void*)new T(value); | |||||
} | |||||
constexpr optional(T&& value) | |||||
: ready{true} | |||||
{ | |||||
ptr = (void*)new T(std::move(value)); | |||||
} | |||||
constexpr bool has_value() | |||||
{ | |||||
return ready; | |||||
} | |||||
constexpr T& value() | |||||
{ | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(!ready) | |||||
{ | |||||
throw bad_optional{}; | |||||
} | |||||
} | |||||
return *reinterpret_cast<T*>(ptr); | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,65 @@ | |||||
#pragma once | |||||
#include "gp/algorithm/tmp_manip.hpp" | |||||
namespace gp{ | |||||
template<typename it, bool Enable = std::is_same<typename it::difference_type,std::size_t>::value> | |||||
class nameless_range; | |||||
template<typename it> | |||||
class nameless_range<it, false> | |||||
{ | |||||
it _begin; | |||||
it _end; | |||||
friend nameless_range<it, true>; | |||||
public: | |||||
using associated_iterator = it; | |||||
nameless_range() = delete; | |||||
template<typename othT> | |||||
nameless_range(const nameless_range<othT>& oth) | |||||
: _begin(oth._begin) | |||||
, _end(oth._end) | |||||
{} | |||||
nameless_range(it sbegin, it send) | |||||
: _begin(sbegin) | |||||
, _end(send) | |||||
{} | |||||
it begin() const | |||||
{ | |||||
return _begin; | |||||
} | |||||
it end() const | |||||
{ | |||||
return _end; | |||||
} | |||||
}; | |||||
template<typename it> | |||||
class nameless_range<it, true> : public nameless_range<it, false> | |||||
{ | |||||
public: | |||||
nameless_range() = delete; | |||||
template<typename othT> | |||||
nameless_range(const nameless_range<othT>& oth) | |||||
: nameless_range<it,false>(oth._begin,oth._end) | |||||
{} | |||||
nameless_range(it sbegin, it send) | |||||
: nameless_range<it,false>(sbegin, send) | |||||
{} | |||||
std::size_t size() const | |||||
{ | |||||
return this->_end-this->_begin; | |||||
} | |||||
}; | |||||
} | |||||
@ -0,0 +1,182 @@ | |||||
#pragma once | |||||
#include <gp/algorithm/tmp_manip.hpp> | |||||
#include <type_traits> | |||||
#include <new> | |||||
#include "gp_config.hpp" | |||||
#include "gp/exception.hpp" | |||||
#include "gp/memory.hpp" | |||||
#include "gp/function.hpp" | |||||
namespace gp{ | |||||
template< typename Enable, typename ...T> | |||||
class variant; | |||||
template<typename ...T> | |||||
class variant<typename std::enable_if<!gp_config::memory_module::is_ok && all_of_fixed_size<T...>::value,int>::type, T...>{ | |||||
std::size_t index = std::numeric_limits<std::size_t>::max(); | |||||
char buffer[max_size<T...>]; | |||||
gp::function<void(void*)> dtor = [](void*){}; | |||||
public: | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
constexpr variant(U& value) | |||||
: index{r_index_of<U, T...>::value} | |||||
{ | |||||
new(buffer) U(value); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
constexpr variant(U&& value) | |||||
: index{r_index_of<U, T...>::value} | |||||
{ | |||||
new(buffer) U(std::move(value)); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
void operator=(U& value) | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor((void*)buffer); | |||||
} | |||||
index = r_index_of<U, T...>::value; | |||||
new(buffer) U(value); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
void operator=(U&& value) | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor((void*)buffer); | |||||
} | |||||
index = r_index_of<U, T...>::value; | |||||
new(buffer) U(std::move(value)); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
~variant() | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor((void*)buffer); | |||||
} | |||||
} | |||||
template<typename U> | |||||
constexpr U& value() | |||||
{ | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(r_index_of<U, T...>::value != index) | |||||
{ | |||||
throw bad_variant_access<U>{}; | |||||
} | |||||
} | |||||
return *reinterpret_cast<U*>(buffer); | |||||
} | |||||
template<typename U> | |||||
constexpr U& is_a() | |||||
{ | |||||
if(r_index_of<U, T...>::value == index) | |||||
{ | |||||
return true; | |||||
} | |||||
else | |||||
{ | |||||
return false; | |||||
} | |||||
} | |||||
}; | |||||
template<typename ...T> | |||||
class variant<typename std::enable_if<gp_config::memory_module::is_ok,default_memory_allocator<>>::type, T...>{ | |||||
std::size_t index = std::numeric_limits<std::size_t>::max(); | |||||
void* ptr; | |||||
gp::function<void(void*)> dtor = [](void*){}; | |||||
public: | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
constexpr variant(U& value) | |||||
: index{r_index_of<U, T...>::value} | |||||
{ | |||||
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(value); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
constexpr variant(U&& value) | |||||
: index{r_index_of<U, T...>::value} | |||||
{ | |||||
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(std::move(value)); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
void operator=(U& value) | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor(ptr); | |||||
default_memory_allocator<>{}.deallocate(ptr); | |||||
} | |||||
index = r_index_of<U, T...>::value; | |||||
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(value); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
template<typename U, typename std::enable_if<list_contains_class<U,T...>::value,int>::type> | |||||
void operator=(U&& value) | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor(ptr); | |||||
default_memory_allocator<>{}.deallocate(ptr); | |||||
} | |||||
index = r_index_of<U, T...>::value; | |||||
ptr = (void*)new(default_memory_allocator<>{}.allocate(sizeof(U))) U(std::move(value)); | |||||
dtor = gp::function([](void* thing){((U*)thing)->~U();}); | |||||
} | |||||
~variant() | |||||
{ | |||||
if(index != std::numeric_limits<std::size_t>::max()) | |||||
{ | |||||
dtor(ptr); | |||||
default_memory_allocator<>{}.deallocate(ptr); | |||||
} | |||||
} | |||||
template<typename U> | |||||
constexpr U& value() | |||||
{ | |||||
if constexpr (gp_config::has_exceptions) | |||||
{ | |||||
if(r_index_of<U, T...>::value != index) | |||||
{ | |||||
throw bad_variant_access<U>{}; | |||||
} | |||||
} | |||||
return *reinterpret_cast<U*>(ptr); | |||||
} | |||||
template<typename U> | |||||
constexpr U& is_a() | |||||
{ | |||||
if(r_index_of<U, T...>::value == index) | |||||
{ | |||||
return true; | |||||
} | |||||
else | |||||
{ | |||||
return false; | |||||
} | |||||
} | |||||
}; | |||||
} |
@ -0,0 +1,64 @@ | |||||
#pragma once | |||||
#include <cstdint> | |||||
#include <cstddef> | |||||
#include <cstdlib> | |||||
#include <type_traits> | |||||
namespace gp_config{ | |||||
namespace memory_module{ | |||||
enum class memory_mode_t{ | |||||
other, | |||||
clib, | |||||
buffer, | |||||
arena_buffer | |||||
}; | |||||
constexpr memory_mode_t memory_mode = memory_mode_t::clib; | |||||
template<memory_mode_t T = memory_mode_t::other> | |||||
constexpr void*(*memory_allocator)(std::size_t)=nullptr; | |||||
template<memory_mode_t T = memory_mode_t::other> | |||||
constexpr void(*memory_deallocator)(void*)=nullptr; | |||||
// C Standard library memory usage | |||||
template<> | |||||
constexpr void*(*memory_allocator<memory_mode_t::clib>)(std::size_t) = malloc; | |||||
template<> | |||||
constexpr void(*memory_deallocator<memory_mode_t::clib>)(void*) = free; | |||||
// Buffer memory usage only | |||||
template<> | |||||
constexpr void*(*memory_allocator<memory_mode_t::buffer>)(std::size_t) = nullptr; | |||||
template<> | |||||
constexpr void(*memory_deallocator<memory_mode_t::buffer>)(void*) = nullptr; | |||||
// Buffer of arena memory usage | |||||
template<> | |||||
constexpr void*(*memory_allocator<memory_mode_t::arena_buffer>)(std::size_t) = nullptr; | |||||
template<> | |||||
constexpr void(*memory_deallocator<memory_mode_t::arena_buffer>)(void*) = nullptr; | |||||
constexpr bool is_ok = | |||||
( memory_allocator<memory_mode> != nullptr ) | |||||
&& ( memory_deallocator<memory_mode> != nullptr ); | |||||
} | |||||
constexpr bool has_exceptions = true; | |||||
// Value of 8 is considered not cryptographically secure | |||||
// Value of 12 offers a good compromise of performance and robustness | |||||
// Value of 20 offers maximum robustness | |||||
constexpr size_t arc4random_strength = 20; | |||||
constexpr size_t assert_buffer_size = 0; | |||||
constexpr auto assert = [](bool, const char*) -> void{}; | |||||
/** Simple exit assert | |||||
constexpr auto assert = [](bool pred, const char*) -> void | |||||
{ | |||||
if(pred) | |||||
return; | |||||
else | |||||
std::exit(-1);}; | |||||
*/ | |||||
} |
@ -0,0 +1,132 @@ | |||||
#pragma once | |||||
#include <stdint.h> | |||||
#include <stddef.h> | |||||
#include <algorithm> | |||||
#include <array> | |||||
template<typename word_t> | |||||
size_t lg(word_t v); | |||||
/** | |||||
Sean Eron Anderson | |||||
seander@cs.stanford.edu | |||||
**/ | |||||
template<> | |||||
size_t lg<uint32_t>(uint32_t v) | |||||
{ | |||||
static const int MultiplyDeBruijnBitPosition[32] = | |||||
{ | |||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, | |||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 | |||||
}; | |||||
v |= v >> 1; | |||||
v |= v >> 2; | |||||
v |= v >> 4; | |||||
v |= v >> 8; | |||||
v |= v >> 16; | |||||
return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; | |||||
} | |||||
template<> | |||||
size_t lg<uint64_t>(uint64_t v) | |||||
{ | |||||
static const int MultiplyDeBruijnBitPosition[64] = | |||||
{ | |||||
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, | |||||
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, | |||||
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, | |||||
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63 | |||||
}; | |||||
v |= v >> 1; | |||||
v |= v >> 2; | |||||
v |= v >> 4; | |||||
v |= v >> 8; | |||||
v |= v >> 16; | |||||
v |= v >> 32; | |||||
return MultiplyDeBruijnBitPosition[(uint64_t)(v * 0x03f6eaf2cd271461) >> 58]; | |||||
} | |||||
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xB7E15163, word_t Q = 0x9E3779B9> | |||||
class RC6 { | |||||
static word_t r_l(const word_t& w, size_t v) { | |||||
return (w << v) | ( w >> (sizeof(w)-v)); | |||||
} | |||||
static word_t r_r(const word_t& w, size_t v) { | |||||
return (w >> v) | ( w << (sizeof(w)-v)); | |||||
} | |||||
class RC6_KeySched { | |||||
public: | |||||
static constexpr size_t c = b/sizeof(word_t)/8; | |||||
static constexpr size_t v_3 = std::max(c, 2*r+4); | |||||
static constexpr size_t v = v_3*3; | |||||
private: | |||||
std::array<word_t, v_3> S; | |||||
public: | |||||
RC6_KeySched(std::array<word_t, c> L) | |||||
{ | |||||
S[0] = P; | |||||
for(size_t i = 1; i < 2*r+3; ++i) | |||||
{ | |||||
S[i] = S[i - 1] + Q; | |||||
} | |||||
word_t A = 0; | |||||
word_t B = 0; | |||||
word_t i = 0; | |||||
word_t j = 0; | |||||
for(size_t s = 1; s < v; ++s) | |||||
{ | |||||
A = S[i] = r_l( S[i] + A + B, 3 ); | |||||
B = L[j] = r_l( L[j] + A + B, (A + B)%(8*sizeof(word_t))); | |||||
i = (i + 1) % (2*r+4); | |||||
j = (j + 1) % c; | |||||
} | |||||
} | |||||
const word_t& operator[](const size_t pos) { | |||||
return S[pos]; | |||||
} | |||||
}; | |||||
RC6_KeySched S; | |||||
public: | |||||
typedef std::array<word_t, RC6_KeySched::c> key_type; | |||||
typedef std::array<word_t, 4> block_type; | |||||
RC6(const key_type& key) | |||||
: S(key) | |||||
{} | |||||
void encrypt(block_type& plaintext) { | |||||
auto& A = plaintext[0]; | |||||
auto& B = plaintext[1]; | |||||
auto& C = plaintext[2]; | |||||
auto& D = plaintext[3]; | |||||
B += S[0]; | |||||
D += S[1]; | |||||
for(size_t i = 1; i < r; ++i) | |||||
{ | |||||
auto t = r_l( B * ( 2 * B + 1 ), 5); | |||||
auto u = r_l( D * ( 2 * D + 1 ), 5); | |||||
A = ((A ^ t) << u%(8*sizeof(word_t))) + S[2*i]; | |||||
C = ((C ^ u) << t%(8*sizeof(word_t))) + S[2*i+1]; | |||||
std::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end()); | |||||
} | |||||
A += S[2*r+3]; | |||||
C += S[2*r+2]; | |||||
} | |||||
}; |
@ -0,0 +1,111 @@ | |||||
#include "test_scaffold.h" | |||||
#include <random> | |||||
#include <string> | |||||
#include "gp/bloomfilter.hpp" | |||||
typedef std::linear_congruential_engine<uint_fast64_t, 128273, 13, 2147483647> cheap_rand; | |||||
typedef std::linear_congruential_engine<uint_fast64_t, 69857, 87541, 2147483647> cheap_rand_bis; | |||||
struct bfilter_test : public test_scaffold { | |||||
uint32_t seed; | |||||
bfilter_test() { | |||||
seed = std::random_device{}(); | |||||
name = __FILE__ ":1_seed"; | |||||
name += std::to_string(seed); | |||||
} | |||||
virtual int run() { | |||||
cheap_rand setter(seed); | |||||
cheap_rand getter(seed); | |||||
gp::bloomfilter test_filter; | |||||
for(int a = 0 ; a < 100; a++) | |||||
{ | |||||
test_filter.set_hash(setter()); | |||||
} | |||||
bool result = true; | |||||
for(int a = 0 ; a < 100; a++) | |||||
{ | |||||
result *= test_filter.test_hash(getter()); | |||||
} | |||||
return !result; | |||||
} | |||||
}; | |||||
append_test dummy_r21fg6r43(new bfilter_test{}); | |||||
struct bfilter2_test : public test_scaffold { | |||||
uint32_t seedA; | |||||
uint32_t seedB; | |||||
bfilter2_test() { | |||||
seedA = std::random_device{}(); | |||||
seedB = std::random_device{}(); | |||||
name = __FILE__ ":2_seedA"; | |||||
name += std::to_string(seedA); | |||||
name += "&seedB"; | |||||
name += std::to_string(seedB); | |||||
} | |||||
virtual int run() { | |||||
cheap_rand setter(seedA); | |||||
cheap_rand_bis getter(seedB); | |||||
gp::bloomfilter test_filter; | |||||
for(int a = 0 ; a < 10000; a++) | |||||
{ | |||||
test_filter.set_hash(setter()); | |||||
} | |||||
int interference = 0; | |||||
for(int a = 0 ; a < 10000; a++) | |||||
{ | |||||
interference += test_filter.test_hash(getter()); | |||||
} | |||||
return interference >= 550; | |||||
} | |||||
}; | |||||
append_test dummy_r2gflu3(new bfilter2_test{}); | |||||
struct bfilter3_test : public test_scaffold { | |||||
uint32_t seed; | |||||
bfilter3_test() { | |||||
seed = std::random_device{}(); | |||||
name = __FILE__ ":3_seed"; | |||||
name += std::to_string(seed); | |||||
} | |||||
virtual int run() { | |||||
cheap_rand setter(seed); | |||||
cheap_rand getter(seed); | |||||
gp::bloomfilter<uint32_t, 19, true> test_filter; | |||||
for(int a = 0 ; a < 1000; a++) | |||||
{ | |||||
test_filter.set_hash(setter()); | |||||
} | |||||
bool result = true; | |||||
for(int a = 0 ; a < 1000; a++) | |||||
{ | |||||
result *= test_filter.test_hash(getter()); | |||||
} | |||||
return !result; | |||||
} | |||||
}; | |||||
append_test dummy_56489flu3(new bfilter3_test{}); |
@ -0,0 +1,78 @@ | |||||
#include "test_scaffold.h" | |||||
#include "gp/array.hpp" | |||||
#include <thread> | |||||
#include <chrono> | |||||
#include <numeric> | |||||
#include <iomanip> | |||||
#include <fstream> | |||||
struct arraysum_test : public test_scaffold { | |||||
arraysum_test() { | |||||
name = __FILE__ ":1"; | |||||
} | |||||
virtual int run() { | |||||
gp::array<uint32_t, 16> test; | |||||
for(auto& elem : test) | |||||
{ | |||||
elem = 12; | |||||
} | |||||
return std::accumulate(test.begin(), test.end(), 0) != 12*test.size(); | |||||
} | |||||
}; | |||||
append_test dummy_sd45uisd3(new arraysum_test{}); | |||||
struct optional_test : public test_scaffold { | |||||
optional_test() { | |||||
name = __FILE__ ":1"; | |||||
} | |||||
virtual int run() { | |||||
int res = 0; | |||||
{ | |||||
gp::optional<uint32_t> test; | |||||
if(test.has_value()) | |||||
{ | |||||
res++; | |||||
} | |||||
test = 12; | |||||
if(test.has_value()) | |||||
{ | |||||
if(test.value()!=12) | |||||
{ | |||||
res++; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
res++; | |||||
} | |||||
} | |||||
{ | |||||
gp::optional<std::ifstream> test; | |||||
if(test.has_value()) | |||||
{ | |||||
res++; | |||||
} | |||||
test = std::ifstream("/proc/cpuinfo"); | |||||
if(!test.has_value()) | |||||
{ | |||||
res++; | |||||
} | |||||
} | |||||
return res; | |||||
} | |||||
}; | |||||
append_test dummy_mlyusisd3(new optional_test{}); |
@ -0,0 +1,43 @@ | |||||
#include "rc6_generic.hpp" | |||||
#include "test_scaffold.h" | |||||
#include <iostream> | |||||
#include <ios> | |||||
struct RC6test : public test_scaffold { | |||||
RC6test() { | |||||
name = __FILE__ ":1"; | |||||
} | |||||
virtual int run() { | |||||
using rc = RC6<uint32_t, 20, 128>; | |||||
rc::key_type key = {0,0,0,0}; | |||||
rc::block_type plaintext = {0,0,0,0}; | |||||
rc::block_type expected{0x8fc3a536,0x56b1f778,0xc129df4e,0x9848a41e}; | |||||
std::cout<<"plain:"; | |||||
for(auto a : plaintext) | |||||
std::cout << std::hex << a; | |||||
auto cipher = rc(key); | |||||
cipher.encrypt(plaintext); | |||||
std::cout<<"\nkey__:"; | |||||
for(auto a : key) | |||||
std::cout << std::hex << a; | |||||
std::cout<<"\nciphe:"; | |||||
for(auto a : plaintext) | |||||
std::cout << std::hex << a; | |||||
std::cout<<"\nexpec:"; | |||||
for(auto a : expected) | |||||
std::cout << std::hex << a; | |||||
std::cout << std::endl; | |||||
return plaintext != expected; | |||||
} | |||||
}; | |||||
append_test dummy_szfhu5463(new RC6test{}); |