mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-08-03 09:16:13 -04:00
More Doc (Murdoch ?) for TSTL
This commit is contained in:
parent
c9bb3ca9d7
commit
4d586bf1f8
@ -12,16 +12,37 @@
|
||||
|
||||
namespace std {
|
||||
|
||||
/*!
|
||||
* \brief Helper to handle a value as a bit field.
|
||||
* \param S The type of the source value
|
||||
* \param T The type of the bit value
|
||||
* \param Position The starting position from the right (LSB)
|
||||
* \param Size The number of bits
|
||||
*/
|
||||
template<typename S, typename T, size_t Position, size_t Size>
|
||||
struct bit_field {
|
||||
S* value;
|
||||
|
||||
/*!
|
||||
* \brief Construct a bit field around the given value
|
||||
*/
|
||||
bit_field(S* value) : value(value) {}
|
||||
|
||||
T operator*() const {
|
||||
/*!
|
||||
* \brief Extract the value of the bit field
|
||||
*/
|
||||
T get() const {
|
||||
return (*value >> Position) & ((1ULL << Size) - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extract the value of the bit field
|
||||
*/
|
||||
T operator*() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Assign a new value to the bit field
|
||||
*/
|
||||
bit_field& operator=(T new_value_real){
|
||||
S new_value(new_value_real);
|
||||
|
||||
@ -29,6 +50,9 @@ struct bit_field {
|
||||
*value = (*value & ~mask) | ((new_value << Position) & mask);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
S* value; ///< Pointer to the source value
|
||||
};
|
||||
|
||||
} //end of namespace std
|
||||
|
@ -13,35 +13,55 @@
|
||||
|
||||
namespace std {
|
||||
|
||||
/*!
|
||||
* \brief Container adapter to provide a queue (FIFO)
|
||||
*/
|
||||
template<typename T, typename C = std::list<T>>
|
||||
struct queue {
|
||||
private:
|
||||
C container;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Indicates if the queue is empty
|
||||
*/
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the size of the queue
|
||||
*/
|
||||
size_t size() const {
|
||||
return container.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Push a new element onto the queue
|
||||
*/
|
||||
void push(const T& value){
|
||||
container.push_back(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pop the top element from the queue
|
||||
*/
|
||||
void pop(){
|
||||
container.pop_front();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to the top element
|
||||
*/
|
||||
T& top(){
|
||||
return container.front();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const reference to the top element
|
||||
*/
|
||||
const T& top() const {
|
||||
return container.front();
|
||||
}
|
||||
|
||||
private:
|
||||
C container; ///< The underlying container
|
||||
};
|
||||
|
||||
} //end of namespace std
|
||||
|
@ -14,7 +14,7 @@
|
||||
namespace std {
|
||||
|
||||
/*!
|
||||
* \brief Container adapter to provide a stack
|
||||
* \brief Container adapter to provide a stack (LIFO)
|
||||
*/
|
||||
template<typename T, typename C = std::vector<T>>
|
||||
struct stack {
|
||||
|
@ -87,11 +87,15 @@ static_assert(min_capacity == sizeof(base_short<char>), "base_short must be the
|
||||
static_assert(min_capacity == sizeof(base_long<char>), "base_long must be the correct SSO size");
|
||||
static_assert(min_capacity == sizeof(base_raw), "base_raw must be the correct SSO size");
|
||||
|
||||
/*!
|
||||
* \brief A string of the given character type.
|
||||
*
|
||||
* This implementation uses SSO to not allocate any dynamic memory on short strings (<16 chars)
|
||||
*/
|
||||
template<typename CharT>
|
||||
struct basic_string {
|
||||
public:
|
||||
typedef CharT* iterator;
|
||||
typedef const CharT* const_iterator;
|
||||
using iterator = CharT*; ///< The iterator type
|
||||
using const_iterator = const CharT*; ///< The const iterator type
|
||||
|
||||
static constexpr const size_t npos = -1;
|
||||
|
||||
@ -137,12 +141,18 @@ private:
|
||||
public:
|
||||
//Constructors
|
||||
|
||||
/*!
|
||||
* \brief Construct an empty string
|
||||
*/
|
||||
basic_string() : _size(0){
|
||||
set_small(true);
|
||||
|
||||
(*this)[0] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new string from the given raw string
|
||||
*/
|
||||
basic_string(const CharT* s) : _size(str_len(s)) {
|
||||
auto capacity = size() + 1;
|
||||
|
||||
@ -155,6 +165,9 @@ public:
|
||||
std::copy_n(s, capacity, begin());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new string of the given capacity.
|
||||
*/
|
||||
explicit basic_string(size_t __capacity) : _size(0) {
|
||||
set_small(__capacity <= 16);
|
||||
|
||||
@ -165,6 +178,9 @@ public:
|
||||
(*this)[0] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new string from the given range of characters
|
||||
*/
|
||||
template <typename It>
|
||||
basic_string(It it, It end) {
|
||||
_size = std::distance(it, end);
|
||||
@ -262,6 +278,9 @@ public:
|
||||
|
||||
//Destructors
|
||||
|
||||
/*!
|
||||
* \brief Destructs the string and releases all its associated memory
|
||||
*/
|
||||
~basic_string(){
|
||||
if(is_long()){
|
||||
storage.big.~base_long();
|
||||
@ -274,20 +293,32 @@ public:
|
||||
set_size(size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clear the string
|
||||
*/
|
||||
void clear(){
|
||||
set_size(0);
|
||||
(*this)[0] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pop the last character of the string.
|
||||
*/
|
||||
void pop_back(){
|
||||
set_size(size() - 1);
|
||||
(*this)[size()] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Ensures a capacity of at least new_capacity
|
||||
*/
|
||||
void reserve(size_t new_capacity){
|
||||
ensure_capacity(new_capacity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a string resulting of the concatenation of this string the given char
|
||||
*/
|
||||
basic_string operator+(CharT c) const {
|
||||
basic_string copy(*this);
|
||||
|
||||
@ -296,6 +327,9 @@ public:
|
||||
return move(copy);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Concatenates the given char to the current string
|
||||
*/
|
||||
basic_string& operator+=(CharT c){
|
||||
ensure_capacity(size() + 2);
|
||||
|
||||
@ -307,29 +341,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ensure_capacity(size_t new_capacity){
|
||||
if(new_capacity > 0 && (capacity() < new_capacity)){
|
||||
auto new_cap = capacity() * 2;
|
||||
|
||||
if(new_cap < new_capacity){
|
||||
new_cap = new_capacity;
|
||||
}
|
||||
|
||||
auto new_data = new CharT[new_cap];
|
||||
|
||||
std::copy_n(begin(), size() + 1, new_data);
|
||||
|
||||
if(is_small()){
|
||||
new (&storage.big) base_long<CharT>(new_cap, new_data);
|
||||
|
||||
set_small(false);
|
||||
} else {
|
||||
storage.big.data.reset(new_data);
|
||||
storage.big.capacity = new_cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
basic_string& operator+=(const char* rhs){
|
||||
auto len = str_len(rhs);
|
||||
|
||||
@ -358,10 +369,16 @@ public:
|
||||
|
||||
//Accessors
|
||||
|
||||
/*!
|
||||
* \brief Returns the size of the string
|
||||
*/
|
||||
size_t size() const {
|
||||
return _size & ~(1UL << 63);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the capacity of the string
|
||||
*/
|
||||
size_t capacity() const {
|
||||
if(is_small()){
|
||||
return 16;
|
||||
@ -370,6 +387,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Indicates if the string is empty
|
||||
*/
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
@ -390,18 +410,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return the raw string
|
||||
*/
|
||||
CharT* c_str(){
|
||||
return data_ptr();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return the raw string
|
||||
*/
|
||||
const CharT* c_str() const {
|
||||
return data_ptr();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to the ith character
|
||||
*/
|
||||
CharT& operator[](size_t i){
|
||||
return *(data_ptr() + i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const reference to the ith character
|
||||
*/
|
||||
const CharT& operator[](size_t i) const {
|
||||
return *(data_ptr() + i);
|
||||
}
|
||||
@ -456,21 +488,57 @@ public:
|
||||
|
||||
//Iterators
|
||||
|
||||
/*!
|
||||
* \brief Returns an iterator to the first character of the string
|
||||
*/
|
||||
iterator begin(){
|
||||
return iterator(data_ptr());
|
||||
}
|
||||
|
||||
iterator end(){
|
||||
return iterator(data_ptr() + size());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const iterator to the first character of the string
|
||||
*/
|
||||
const_iterator begin() const {
|
||||
return const_iterator(data_ptr());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns an iterator the past-the-end character of the string
|
||||
*/
|
||||
iterator end(){
|
||||
return iterator(data_ptr() + size());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const iterator the past-the-end character of the string
|
||||
*/
|
||||
const_iterator end() const {
|
||||
return const_iterator(data_ptr() + size());
|
||||
}
|
||||
|
||||
private:
|
||||
void ensure_capacity(size_t new_capacity){
|
||||
if(new_capacity > 0 && (capacity() < new_capacity)){
|
||||
auto new_cap = capacity() * 2;
|
||||
|
||||
if(new_cap < new_capacity){
|
||||
new_cap = new_capacity;
|
||||
}
|
||||
|
||||
auto new_data = new CharT[new_cap];
|
||||
|
||||
std::copy_n(begin(), size() + 1, new_data);
|
||||
|
||||
if(is_small()){
|
||||
new (&storage.big) base_long<CharT>(new_cap, new_data);
|
||||
|
||||
set_small(false);
|
||||
} else {
|
||||
storage.big.data.reset(new_data);
|
||||
storage.big.capacity = new_cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
|
@ -8,15 +8,15 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
|
||||
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));
|
||||
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__)));
|
||||
typedef unsigned int uint64_t __attribute__ ((__mode__ (__DI__)));
|
||||
typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); ///< An unsigned 8-bit number
|
||||
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); ///< An unsigned 16-bit number
|
||||
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); ///< An unsigned 32-bit number
|
||||
typedef unsigned int uint64_t __attribute__ ((__mode__ (__DI__))); ///< An unsigned 64-bit number
|
||||
|
||||
typedef int int8_t __attribute__((__mode__(__QI__)));
|
||||
typedef int int16_t __attribute__ ((__mode__ (__HI__)));
|
||||
typedef int int32_t __attribute__ ((__mode__ (__SI__)));
|
||||
typedef int int64_t __attribute__ ((__mode__ (__DI__)));
|
||||
typedef int int8_t __attribute__((__mode__(__QI__))); ///< A signed 8-bit number
|
||||
typedef int int16_t __attribute__ ((__mode__ (__HI__))); ///< A signed 16-bit number
|
||||
typedef int int32_t __attribute__ ((__mode__ (__SI__))); ///< A signed 32-bit number
|
||||
typedef int int64_t __attribute__ ((__mode__ (__DI__))); ///< A signed 64-bit number
|
||||
|
||||
typedef uint64_t uintptr_t;
|
||||
typedef uint64_t size_t;
|
||||
|
@ -38,22 +38,30 @@ struct default_delete<T[]> {
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief An unique ptr of type T.
|
||||
*
|
||||
* An unique ptr represents unique ownership of dynamically allocated data.
|
||||
*/
|
||||
template <typename T, typename D = default_delete<T>>
|
||||
class unique_ptr {
|
||||
public:
|
||||
using pointer_type = T*;
|
||||
using element_type = T;
|
||||
using deleter_type = D;
|
||||
struct unique_ptr {
|
||||
using pointer_type = T*; ///< The pointer type
|
||||
using element_type = T; ///< The element type
|
||||
using deleter_type = D; ///< The deleter type
|
||||
|
||||
private:
|
||||
using data_impl = tuple<pointer_type, deleter_type>;
|
||||
|
||||
data_impl _data;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Construct an empty (nullptr) unique_ptr
|
||||
*/
|
||||
unique_ptr() : _data() {}
|
||||
|
||||
/*!
|
||||
* \brief Construct an empty (nullptr) unique_ptr
|
||||
*/
|
||||
unique_ptr(decltype(nullptr)) : unique_ptr() {}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new unique_ptr from the given pointer
|
||||
*/
|
||||
explicit unique_ptr(pointer_type p) : _data(make_tuple(p, deleter_type())) {}
|
||||
|
||||
unique_ptr(unique_ptr&& u) : _data(make_tuple(u.unlock(), u.get_deleter())) {}
|
||||
@ -63,6 +71,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and releases its memory if it still references any
|
||||
*/
|
||||
~unique_ptr(){
|
||||
reset();
|
||||
}
|
||||
@ -71,6 +82,9 @@ public:
|
||||
unique_ptr(const unique_ptr& rhs) = delete;
|
||||
unique_ptr& operator=(const unique_ptr& rhs) = delete;
|
||||
|
||||
/*!
|
||||
* \brief Assign nullptr to the unique ptr (reset it)
|
||||
*/
|
||||
unique_ptr& operator=(decltype(nullptr)){
|
||||
reset();
|
||||
return *this;
|
||||
@ -78,36 +92,63 @@ public:
|
||||
|
||||
//Access
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to the owned object
|
||||
*/
|
||||
element_type& operator*() const {
|
||||
return *get();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the owned object
|
||||
*/
|
||||
pointer_type operator->() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the owned object
|
||||
*/
|
||||
pointer_type get() const {
|
||||
return std::get<0>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to the deleter
|
||||
*/
|
||||
deleter_type& get_deleter(){
|
||||
return std::get<1>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const reference to the deleter
|
||||
*/
|
||||
const deleter_type& get_deleter() const {
|
||||
return std::get<1>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the unique ptr to a boolean, indicating if it points to something or not
|
||||
*/
|
||||
explicit operator bool() const {
|
||||
return get() == pointer_type() ? false : true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extract the owned object out of the unique ptr.
|
||||
*
|
||||
* After this, the unique ptr will not own the objet anymore.
|
||||
*/
|
||||
pointer_type unlock(){
|
||||
pointer_type p = get();
|
||||
std::get<0>(_data) = pointer_type();
|
||||
return p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Resets the unique pointer to a new state
|
||||
* \param p The new pointer value
|
||||
*/
|
||||
void reset(pointer_type p = pointer_type()){
|
||||
if(get() != pointer_type()){
|
||||
get_deleter()(get());
|
||||
@ -117,23 +158,30 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//Partial specialization for array
|
||||
/*!
|
||||
* \brief Unique pointer implementation for an array.
|
||||
*
|
||||
* This has the same semantics, but allow random accesss as an array.
|
||||
*/
|
||||
template <typename T, typename D>
|
||||
class unique_ptr<T[], D> {
|
||||
public:
|
||||
using pointer_type = T*;
|
||||
using element_type = T;
|
||||
using deleter_type = D;
|
||||
struct unique_ptr<T[], D> {
|
||||
using pointer_type = T*; ///< The pointer type
|
||||
using element_type = T; ///< The element type
|
||||
using deleter_type = D; ///< The deleter type
|
||||
|
||||
private:
|
||||
using data_impl = tuple<pointer_type, deleter_type>;
|
||||
|
||||
data_impl _data;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Construct an empty (nullptr) unique_ptr
|
||||
*/
|
||||
unique_ptr() : _data() {}
|
||||
|
||||
/*!
|
||||
* \brief Construct an empty (nullptr) unique_ptr
|
||||
*/
|
||||
unique_ptr(decltype(nullptr)) : unique_ptr() {}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new unique_ptr from the given pointer
|
||||
*/
|
||||
explicit unique_ptr(pointer_type p) : _data(make_tuple(p, deleter_type())) {}
|
||||
|
||||
unique_ptr(unique_ptr&& u) : _data(make_tuple(u.unlock(), u.get_deleter())) {}
|
||||
@ -143,6 +191,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object and releases its memory if it still references any
|
||||
*/
|
||||
~unique_ptr(){
|
||||
reset();
|
||||
}
|
||||
@ -156,36 +207,64 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the owned object
|
||||
*/
|
||||
pointer_type get() const {
|
||||
return std::get<0>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to the deleter
|
||||
*/
|
||||
deleter_type& get_deleter(){
|
||||
return std::get<1>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a const reference to the deleter
|
||||
*/
|
||||
const deleter_type& get_deleter() const {
|
||||
return std::get<1>(_data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a reference to an element of the array
|
||||
* \param i The index inside the array
|
||||
*/
|
||||
element_type& operator[](size_t i) const {
|
||||
return get()[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the unique ptr to a boolean, indicating if it points to something or not
|
||||
*/
|
||||
explicit operator bool() const {
|
||||
return get() == pointer_type() ? false : true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Extract the owned object out of the unique ptr.
|
||||
*
|
||||
* After this, the unique ptr will not own the objet anymore.
|
||||
*/
|
||||
pointer_type unlock(){
|
||||
pointer_type p = get();
|
||||
std::get<0>(_data) = pointer_type();
|
||||
return p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Resets the unique pointer to an empty state
|
||||
*/
|
||||
void reset(){
|
||||
reset(pointer_type());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Resets the unique pointer to a new state
|
||||
* \param p The new pointer value
|
||||
*/
|
||||
void reset(pointer_type p){
|
||||
auto tmp = get();
|
||||
std::get<0>(_data) = p;
|
||||
@ -193,11 +272,19 @@ public:
|
||||
get_deleter()(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
using data_impl = tuple<pointer_type, deleter_type>; ///< The type of internal data
|
||||
|
||||
data_impl _data; ///< The internal data storage
|
||||
};
|
||||
|
||||
static_assert(sizeof(unique_ptr<long>) == sizeof(long), "unique_ptr must have zero overhead with default deleter");
|
||||
static_assert(sizeof(unique_ptr<long[]>) == sizeof(long), "unique_ptr must have zero overhead with default deleter");
|
||||
|
||||
/*!
|
||||
* \brief Helper to create an unique_ptr from the args
|
||||
*/
|
||||
template <typename T, typename... Args>
|
||||
std::unique_ptr<T> make_unique(Args&&... args){
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
|
Loading…
x
Reference in New Issue
Block a user