Browse Source

More documentation

channel
Ludovic 'Archivist' Lagouardette 4 years ago
parent
commit
96078a2c51
8 changed files with 242 additions and 6 deletions
  1. +61
    -0
      include/gp/algorithm/tmp_manip.hpp
  2. +16
    -1
      include/gp/allocator/aggregator.hpp
  3. +28
    -0
      include/gp/allocator/allocator.hpp
  4. +10
    -0
      include/gp/allocator/arena.hpp
  5. +22
    -1
      include/gp/allocator/buddy.hpp
  6. +9
    -0
      include/gp/allocator/dummy.hpp
  7. +17
    -0
      include/gp/rendering/bmp_viewport.hpp
  8. +79
    -4
      include/gp_config.hpp

+ 61
- 0
include/gp/algorithm/tmp_manip.hpp View File

@ -8,6 +8,13 @@
namespace gp{ namespace gp{
/**
* @brief Picks either of the types depending on the condition
*
* @tparam cond the condition
* @tparam T the type picked when the condition is true
* @tparam U the type picked when the condition is false
*/
template<bool cond, typename T, typename U> template<bool cond, typename T, typename U>
struct either struct either
{ {
@ -25,6 +32,9 @@ namespace gp{
typedef U type; typedef U type;
}; };
/**
* @brief Checks if the provided booleans are all true at compile time
*/
template<bool first, bool ...list> template<bool first, bool ...list>
struct constexpr_all_of struct constexpr_all_of
{ {
@ -37,6 +47,9 @@ namespace gp{
static constexpr bool value = first; static constexpr bool value = first;
}; };
/**
* @brief Checks if at least one of the provided booleans is true at compile time
*/
template<bool first, bool ...list> template<bool first, bool ...list>
struct constexpr_any_of struct constexpr_any_of
{ {
@ -49,6 +62,13 @@ namespace gp{
static constexpr bool value = first; static constexpr bool value = first;
}; };
/**
* @brief Checks if the provided type has a compile time defined size
*
* @tparam T the tested type
* @return true if it has a defined size
* @return false if its size may change due to inheritance or other factors
*/
template<typename T> template<typename T>
constexpr bool is_fixed_size() constexpr bool is_fixed_size()
{ {
@ -56,6 +76,9 @@ namespace gp{
|| std::is_fundamental<T>::value; || std::is_fundamental<T>::value;
} }
/**
* @brief Checks if the provided typelist is all of fixed size
*/
template<typename T, typename ...rest> template<typename T, typename ...rest>
struct all_of_fixed_size struct all_of_fixed_size
{ {
@ -68,6 +91,11 @@ namespace gp{
static constexpr bool value = is_fixed_size<T>(); static constexpr bool value = is_fixed_size<T>();
}; };
/**
* @brief Checks if the provided list contains the provided class
*
* @tparam Univ the class to look for
*/
template<typename Univ, typename T, typename ...rest> template<typename Univ, typename T, typename ...rest>
struct list_contains_class struct list_contains_class
{ {
@ -82,6 +110,11 @@ namespace gp{
static constexpr bool value = std::is_same<T, Univ>::value; static constexpr bool value = std::is_same<T, Univ>::value;
}; };
/**
* @brief gives the index of Univ from the end of the argument list
*
* @tparam Univ The type to look for
*/
template<typename Univ, typename T, typename ...rest> template<typename Univ, typename T, typename ...rest>
struct r_index_of struct r_index_of
{ {
@ -94,6 +127,12 @@ namespace gp{
static constexpr std::size_t value = std::is_same<T, Univ>::value ? 0 : std::numeric_limits<std::size_t>::max(); static constexpr std::size_t value = std::is_same<T, Univ>::value ? 0 : std::numeric_limits<std::size_t>::max();
}; };
/**
* @brief gives the type of the idx value from the end of the argument list
*
* @tparam idx The index to return the type of
*/
template<size_t idx, typename T, typename ...rest> template<size_t idx, typename T, typename ...rest>
struct r_index_at struct r_index_at
{ {
@ -105,11 +144,19 @@ namespace gp{
>::type; >::type;
}; };
/**
* @brief extracts the first type of the list
*/
template<typename U, typename ...rest> template<typename U, typename ...rest>
struct first_of { struct first_of {
using type = U; using type = U;
}; };
/**
* @brief gives the size of the largest element in the provided list
*
* @return constexpr std::size_t equal to the largest size of all
*/
template<typename T, typename U, typename ...rest> template<typename T, typename U, typename ...rest>
constexpr std::size_t max_size() constexpr std::size_t max_size()
{ {
@ -129,6 +176,9 @@ namespace gp{
} }
} }
/**
* @brief remove reference state from the provided type
*/
template<typename T> template<typename T>
struct remove_reference struct remove_reference
{ {
@ -147,6 +197,9 @@ namespace gp{
using type = T; using type = T;
}; };
/**
* @brief Has a value of true if the provided type has a size() function member
*/
template<typename T> template<typename T>
struct has_size_interface struct has_size_interface
{ {
@ -164,6 +217,9 @@ namespace gp{
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value;
}; };
/**
* @brief Has a value of true if the provided type has a begin() function member
*/
template<typename T> template<typename T>
struct has_begin_interface struct has_begin_interface
{ {
@ -181,6 +237,9 @@ namespace gp{
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value;
}; };
/**
* @brief Has a value of true if the provided type has a end() function member
*/
template<typename T> template<typename T>
struct has_end_interface struct has_end_interface
{ {
@ -198,6 +257,8 @@ namespace gp{
static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value; static constexpr bool value = std::is_same<yes,decltype(test<T>(nullptr))>::value;
}; };
// TODO: Replace those with concepts
template<typename T> template<typename T>
using has_range_interface = constexpr_all_of<has_begin_interface<T>::value,has_end_interface<T>::value>; using has_range_interface = constexpr_all_of<has_begin_interface<T>::value,has_end_interface<T>::value>;

+ 16
- 1
include/gp/allocator/aggregator.hpp View File

@ -13,6 +13,12 @@ namespace gp {
local_container::explorer mark; local_container::explorer mark;
public: public:
/**
* @brief Construct a new aggregator object from a bootstraping allocator
*
* @tparam bootstrapper the type of allocator pushed in
* @param allocator_v the allocator moved inside the new aggregator
*/
template<typename bootstrapper> template<typename bootstrapper>
aggregator(bootstrapper&& allocator_v) aggregator(bootstrapper&& allocator_v)
: contents{ : contents{
@ -25,6 +31,14 @@ namespace gp {
, mark{contents.explore()} , mark{contents.explore()}
{} {}
/**
* @brief inserts a new allocator within the aggregator
*
* @tparam s_allocator the type of newly inserted allocator
* @param value the inserted allocator
* @return true if the insertion was successful
* @return false if the insertion failed and the allocator is lost to the abyss of time
*/
template<typename s_allocator> template<typename s_allocator>
bool insert(s_allocator&& value) { bool insert(s_allocator&& value) {
return contents.insert< return contents.insert<
@ -34,7 +48,6 @@ namespace gp {
>(gp::forward<s_allocator>(value)); >(gp::forward<s_allocator>(value));
} }
virtual void* allocate(size_t sz) { virtual void* allocate(size_t sz) {
auto cpy = mark; auto cpy = mark;
do{ do{
@ -46,6 +59,7 @@ namespace gp {
}while(cpy != mark); }while(cpy != mark);
return nullptr; return nullptr;
} }
virtual bool deallocate(void* ptr) { virtual bool deallocate(void* ptr) {
auto cpy = mark; auto cpy = mark;
do{ do{
@ -57,6 +71,7 @@ namespace gp {
}while(cpy != mark); }while(cpy != mark);
return false; return false;
} }
virtual bool try_reallocate(void* ptr, size_t sz) { virtual bool try_reallocate(void* ptr, size_t sz) {
auto cpy = mark; auto cpy = mark;
do{ do{

+ 28
- 0
include/gp/allocator/allocator.hpp View File

@ -3,11 +3,39 @@
#include <stddef.h> #include <stddef.h>
namespace gp { namespace gp {
/**
* @brief The base for all polymorphic allocators
*/
struct allocator{ struct allocator{
/**
* @brief Allocates memory
*
* @param sz the amount of bytes to allocate
*
* @return the allocated memory as a pointer on success
* @return nullptr if it failed allocating
*/
virtual void* allocate(size_t) = 0; virtual void* allocate(size_t) = 0;
/**
* @brief Deallocates memory
*
* @param ptr the memory to deallocate
*
* @return true if the memory was successfully deallocated
* @return false if the memory was not deallocated
*/
virtual bool deallocate(void*) = 0; virtual bool deallocate(void*) = 0;
/**
* @brief Tries to reallocate memory
*
* @param ptr The memory to reallocate
* @param sz The new size we want to give the memory
*
* @return true if reallocation was successful
* @return false if the reallocation failed
*/
virtual bool try_reallocate(void*, size_t) = 0; virtual bool try_reallocate(void*, size_t) = 0;
virtual ~allocator() = default; virtual ~allocator() = default;

+ 10
- 0
include/gp/allocator/arena.hpp View File

@ -67,10 +67,20 @@ namespace gp {
} }
} }
/**
* @return false whatever happens
*/
virtual bool try_reallocate(void*, size_t) { virtual bool try_reallocate(void*, size_t) {
return false; return false;
} }
/**
* @brief Deallocates the memory if every deallocated block as been deallocated, else marks one deallocation
*
* @param ptr the memory to deallocate
* @return true if either a deallocation or block release happened
* @return false if the pointer was not within the managed area
*/
virtual bool deallocate(void* ptr) virtual bool deallocate(void* ptr)
{ {
if(data.contains((char*)ptr)) if(data.contains((char*)ptr))

+ 22
- 1
include/gp/allocator/buddy.hpp View File

@ -206,13 +206,22 @@ namespace gp{
p.used | p.used_children p.used | p.used_children
); );
} }
public:
public:
/**
* @brief Construct a new empty buddy object
*/
buddy() buddy()
: data(gp::buffer<char>(nullptr,nullptr)) : data(gp::buffer<char>(nullptr,nullptr))
, max_depth(0) , max_depth(0)
, twig_explore_length(1 << max_depth) , twig_explore_length(1 << max_depth)
{} {}
/**
* @brief Construct a new buddy object from another allocator
*
* @param sz the size to allocate
* @param allocator_p the source of the allocated memory
*/
buddy(size_t sz, allocator& allocator_p) buddy(size_t sz, allocator& allocator_p)
: allocator_v(allocator_p) : allocator_v(allocator_p)
, data(nullptr,nullptr) , data(nullptr,nullptr)
@ -236,6 +245,12 @@ namespace gp{
} }
} }
/**
* @brief Construct a new buddy object from a memory location
*
* @param pos the location of the memory to manage
* @param sz the size of the span to manage
*/
buddy(char* pos, size_t sz) buddy(char* pos, size_t sz)
: data(pos,pos+sz) : data(pos,pos+sz)
, max_depth(gp::math::msb(sz)-gp::math::msb(align)) , max_depth(gp::math::msb(sz)-gp::math::msb(align))
@ -303,6 +318,12 @@ namespace gp{
return false; return false;
} }
/**
* @brief Checks if anything is still allocated in
*
* @return true if the allocator is completely empty
* @return false if anything is still allocated in there
*/
bool empty() const { bool empty() const {
buddy* addr = (buddy*)this; buddy* addr = (buddy*)this;
auto prepred = not_fn(&buddy::empty_node); auto prepred = not_fn(&buddy::empty_node);

+ 9
- 0
include/gp/allocator/dummy.hpp View File

@ -5,16 +5,25 @@
namespace gp { namespace gp {
struct dummy_allocator : public allocator { struct dummy_allocator : public allocator {
/**
* @return nullptr, always
*/
virtual void* allocate(size_t) virtual void* allocate(size_t)
{ {
return nullptr; return nullptr;
} }
/**
* @return false, always
*/
virtual bool deallocate(void*) virtual bool deallocate(void*)
{ {
return false; return false;
} }
/**
* @return false, always
*/
virtual bool try_reallocate(void*, size_t) { virtual bool try_reallocate(void*, size_t) {
return false; return false;
} }

+ 17
- 0
include/gp/rendering/bmp_viewport.hpp View File

@ -19,6 +19,9 @@ namespace gp{
template<bool lazy, typename color_type> template<bool lazy, typename color_type>
class bmp_viewport { class bmp_viewport {
public: public:
/**
* @brief The type of data source expected
*/
using src_t = typename gp::either<lazy, using src_t = typename gp::either<lazy,
gp::function<color_type(gp::vec2_g<int32_t>)>, gp::function<color_type(gp::vec2_g<int32_t>)>,
gp::buffer<gp::buffer<color_type>> gp::buffer<gp::buffer<color_type>>
@ -37,11 +40,25 @@ namespace gp{
} }
} }
public: public:
/**
* @brief Construct a new bmp viewport object
*
* @param res The viewport size in pixels
* @param src The viewport source @see src_t
*/
bmp_viewport(gp::vec2_g<int32_t> res, src_t src) bmp_viewport(gp::vec2_g<int32_t> res, src_t src)
: source{src} : source{src}
, resolution{res} , resolution{res}
{} {}
/**
* @brief Wtrites the viewport into a buffer in the bmp file format
*
* Failure is not currently handled, hence more than enough buffer space is expected.
*
* @param destination a buffer wide enough to write the entire data on it at once
* @return gp::buffer<char>::associated_iterator the byte after the last one that was written by the function
*/
gp::buffer<char>::associated_iterator write(gp::buffer<char> destination) { gp::buffer<char>::associated_iterator write(gp::buffer<char> destination) {
using sle16 = gp::endian_wrapper<int16_t, gp::endian::little>; using sle16 = gp::endian_wrapper<int16_t, gp::endian::little>;
using sbe16 = gp::endian_wrapper<int16_t, gp::endian::big>; using sbe16 = gp::endian_wrapper<int16_t, gp::endian::big>;

+ 79
- 4
include/gp_config.hpp View File

@ -15,19 +15,64 @@ namespace gp {
} }
#endif #endif
/**
* @brief This namespace contains the configuration.
*
* This namespace is expected to be fully defined in an include accessible from the root
* of your header list:
* \code{.cpp}
* #include "gp_config.hpp"
* \endcode
*
* The code line above should always be the one including that config and that namespace.
*/
namespace gp_config{ namespace gp_config{
namespace rendering { namespace rendering {
/**
* @brief The default type used for rendering processes
*/
using default_type = float; using default_type = float;
/**
* @brief The small enough value used in signed distance function resolution
*/
constexpr default_type epsilon = 0.001; constexpr default_type epsilon = 0.001;
#define GP_CONFIG__RENDERING__COLOR_T vec4
/**
* @brief The default color type
*/
#define GP_CONFIG__RENDERING__COLOR_T vec4
} }
/**
* @brief This namespace contains artificial limitations put on the runtime
*/
namespace limits { namespace limits {
/**
* @brief the total number of processes the system is allowed to have
*/
constexpr size_t max_processes = 4096; constexpr size_t max_processes = 4096;
/**
* @brief the number of open files each process is allowed to have
*/
constexpr size_t max_fd_per_process = 128; constexpr size_t max_fd_per_process = 128;
/**
* @brief the stack size for the new stacks generated by the concurrency system
*/
constexpr size_t process_stack = 1024; constexpr size_t process_stack = 1024;
/**
* @brief expected stack alignment
*/
constexpr size_t process_stack_align_to = 16; constexpr size_t process_stack_align_to = 16;
/**
* @brief presents the direction of stack growth
*/
constexpr size_t stack_grow_upwards = false; constexpr size_t stack_grow_upwards = false;
#if __cpp_lib_hardware_interference_size >= 201603 #if __cpp_lib_hardware_interference_size >= 201603
constexpr size_t hardware_constructive_interference_size = std::hardware_constructive_interference_size; constexpr size_t hardware_constructive_interference_size = std::hardware_constructive_interference_size;
constexpr size_t hardware_destructive_interference_size = std::hardware_destructive_interference_size; constexpr size_t hardware_destructive_interference_size = std::hardware_destructive_interference_size;
@ -43,14 +88,31 @@ namespace gp_config{
typedef uint32_t file_descriptor_t; typedef uint32_t file_descriptor_t;
/**
* @brief set to true to enable exceptions
*/
constexpr bool has_exceptions = true; constexpr bool has_exceptions = true;
/**
* @brief set to true to activate bounds checking
*/
constexpr bool has_buffer_bounds = true; constexpr bool has_buffer_bounds = 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
//
//
//
/**
* @brief A value used to determine the strength used by random number generators
*
* 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 arc4random_strength = 20;
/**
* @brief an exception that represents an assertion failure
*/
struct assert_failure{ struct assert_failure{
assert_failure(const char* reason) assert_failure(const char* reason)
: what_str{reason} : what_str{reason}
@ -59,13 +121,26 @@ namespace gp_config{
const char* what() {return what_str;} const char* what() {return what_str;}
}; };
/**
* @brief UNUSED
*/
constexpr size_t assert_buffer_size = 0; constexpr size_t assert_buffer_size = 0;
/**
* @brief an assertion function
*/
constexpr auto assertion = [](bool pred, const char* reason) -> void{ constexpr auto assertion = [](bool pred, const char* reason) -> void{
if constexpr (has_exceptions) if constexpr (has_exceptions)
if(!pred) throw assert_failure(reason); if(!pred) throw assert_failure(reason);
}; };
} }
/**
* @brief a list of error codes
*/
enum class gp_errorcodes : int { enum class gp_errorcodes : int {
/**
* @brief this error code is activated upon reaching a skipstone limit that seems like infinity.
*/
infinite_skipstone = 3000 infinite_skipstone = 3000
}; };

Loading…
Cancel
Save