First import

Files taken directly from dindexer
This commit is contained in:
King_DuckZ 2016-07-14 14:59:15 +01:00
commit ccb2fc7ae5
15 changed files with 2336 additions and 0 deletions

View file

@ -0,0 +1,117 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef idBC9F804ADD33468A9C7657E823FFC706
#define idBC9F804ADD33468A9C7657E823FFC706
#include "implem/AutomemBase.hpp"
#include "implem/IteratorOnPtr.hpp"
#include <memory>
#include <cstddef>
#include <type_traits>
#include <cassert>
#include <utility>
namespace dhandy {
const size_t MAXSZARR_MAX_STACK_ALLOC_SIZE = MAX_STACK_ALLOC_SIZE;
//TODO: add a template parameter to force stack allocation regardless of
//sizeof(T) * S
template <typename T, size_t S, typename A=std::allocator<T> >
class MaxSizedArray :
private std::conditional<
(sizeof(T) * S > (MAXSZARR_MAX_STACK_ALLOC_SIZE > 4 * sizeof(T*) ? MAXSZARR_MAX_STACK_ALLOC_SIZE - sizeof(T*) : MAXSZARR_MAX_STACK_ALLOC_SIZE)),
AutomemRawBase_heap<T, S, A>,
AutomemRawBase_stack<T, S>
>::type
{
typedef typename std::conditional<
(sizeof(T) * S > (MAXSZARR_MAX_STACK_ALLOC_SIZE > 4 * sizeof(T*) ? MAXSZARR_MAX_STACK_ALLOC_SIZE - sizeof(T*) : MAXSZARR_MAX_STACK_ALLOC_SIZE)),
AutomemRawBase_heap<T, S, A>,
AutomemRawBase_stack<T, S>
>::type parent_type;
public:
typedef IteratorOnPtr<T*, T, false> iterator;
typedef IteratorOnPtr<const T*, const T, false> const_iterator;
typedef IteratorOnPtr<T*, T, true> reverse_iterator;
typedef IteratorOnPtr<const T*, const T, true> const_reverse_iterator;
typedef T& reference;
typedef T&& mov_reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
enum MAX_SIZE_ENUM {
MAX_SIZE = S
};
MaxSizedArray ( void );
MaxSizedArray ( const MaxSizedArray& parOther );
MaxSizedArray ( MaxSizedArray&& parOther );
~MaxSizedArray ( void );
bool empty ( void ) const;
size_type size ( void ) const;
size_type capacity ( void ) const { return S; }
size_type max_size ( void ) const { return S; }
void push_back ( const value_type& parNewItem );
void push_back ( value_type&& parNewItem );
void pop_back ( void );
iterator erase ( const iterator& parDele );
iterator erase ( const iterator& parFrom, const iterator& parToExcl );
void clear ( void );
reference operator[] ( size_type parIndex ) &;
mov_reference operator[] ( size_type parIndex ) &&;
const_reference operator[] ( size_type parIndex ) const &;
MaxSizedArray& operator= ( const MaxSizedArray& parOther );
bool operator== ( const MaxSizedArray& parOther ) const;
bool operator!= ( const MaxSizedArray& parOther ) const;
pointer GetPointer ( void );
const_pointer GetPointer ( void ) const;
void reserve ( size_type parReserve );
iterator begin ( void );
const_iterator begin ( void ) const;
iterator end ( void );
const_iterator end ( void ) const;
reverse_iterator rbegin ( void );
const_reverse_iterator rbegin ( void ) const;
reverse_iterator rend ( void );
const_reverse_iterator rend ( void ) const;
reference front ( void ) & { return (*this)[0]; }
reference back ( void ) & { return (*this)[size() - 1]; }
mov_reference front ( void ) && { return (*this)[0]; }
mov_reference back ( void ) && { return (*this)[size() - 1]; }
const_reference front ( void ) const & { return (*this)[0]; }
const_reference back ( void ) const & { return (*this)[size() - 1]; }
private:
pointer GetPointer_NoAssert ( void ) { return m_localMem; }
const_pointer GetPointer_NoAssert ( void ) const { return m_localMem; }
T* m_localMem; //A copy of memory pointer is required
size_type m_used;
};
} //namespace dhandy
#include "MaxSizedArray.inl"
#endif

View file

@ -0,0 +1,289 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
namespace dhandy {
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
MaxSizedArray<T, S, A>::MaxSizedArray() {
m_localMem = this->AllocMemory();
m_used = 0;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
MaxSizedArray<T, S, A>::MaxSizedArray (const MaxSizedArray& parOther) :
parent_type(),
m_used(0)
{
m_localMem = this->AllocMemory();
const size_type count = parOther.size();
for (size_type z = 0; z < count; ++z) {
this->push_back(parOther[z]);
}
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
MaxSizedArray<T, S, A>::MaxSizedArray (MaxSizedArray&& parOther) :
parent_type(),
m_used(0)
{
m_localMem = this->AllocMemory();
const size_type count = parOther.size();
for (size_type z = 0; z < count; ++z) {
this->push_back(std::move(parOther[z]));
}
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
MaxSizedArray<T, S, A>::~MaxSizedArray() {
this->clear();
this->FreeMemory();
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
bool MaxSizedArray<T, S, A>::empty() const {
return 0 == m_used;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::size_type MaxSizedArray<T, S, A>::size() const {
return m_used;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void MaxSizedArray<T, S, A>::push_back (value_type&& parNewItem) {
assert(size() < capacity());
this->GetNewT(m_used, std::move(parNewItem));
++m_used;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void MaxSizedArray<T, S, A>::push_back (const value_type& parNewItem) {
assert(size() < capacity());
this->GetNewT(m_used, parNewItem);
++m_used;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void MaxSizedArray<T, S, A>::pop_back() {
assert(not empty());
m_localMem[m_used - 1].~T();
--m_used;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::reference MaxSizedArray<T, S, A>::operator[] (size_type parIndex) & {
assert(parIndex < size());
return m_localMem[parIndex];
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::mov_reference MaxSizedArray<T, S, A>::operator[] (size_type parIndex) && {
assert(parIndex < size());
return std::move(m_localMem[parIndex]);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_reference MaxSizedArray<T, S, A>::operator[] (size_type parIndex) const & {
assert(parIndex < size());
return m_localMem[parIndex];
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
MaxSizedArray<T, S, A>& MaxSizedArray<T, S, A>::operator= (const MaxSizedArray& parOther) {
m_used = parOther.m_used;
std::copy(parOther.GetMemPtr(), parOther.GetMemPtr() + parOther.size(), this->GetMemPtr());
return *this;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
bool MaxSizedArray<T, S, A>::operator== (const MaxSizedArray& parOther) const {
if (size() != parOther.size())
return false;
for (size_type z = 0; z < size(); ++z) {
if ((*this)[z] != parOther[z])
return false;
}
return true;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
bool MaxSizedArray<T, S, A>::operator!= (const MaxSizedArray& parOther) const {
return not (*this == parOther);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::pointer MaxSizedArray<T, S, A>::GetPointer() {
assert(size() > 0);
return GetPointer_NoAssert();
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_pointer MaxSizedArray<T, S, A>::GetPointer() const {
assert(size() > 0);
return GetPointer_NoAssert();
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void MaxSizedArray<T, S, A>::clear() {
const size_type count = this->size();
for (size_type z = 0; z < count; ++z) {
(*this)[z].~T();
}
m_used = 0;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::iterator MaxSizedArray<T, S, A>::begin() {
return iterator(GetPointer_NoAssert(), size());
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_iterator MaxSizedArray<T, S, A>::begin() const {
return const_iterator(GetPointer_NoAssert(), size());
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::iterator MaxSizedArray<T, S, A>::end() {
return iterator(GetPointer_NoAssert() + size(), 0);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_iterator MaxSizedArray<T, S, A>::end() const {
return const_iterator(GetPointer_NoAssert() + size(), 0);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::reverse_iterator MaxSizedArray<T, S, A>::rbegin() {
return reverse_iterator(GetPointer_NoAssert() + size() - 1, size());
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_reverse_iterator MaxSizedArray<T, S, A>::rbegin() const {
return const_reverse_iterator(GetPointer_NoAssert() + size() - 1, size());
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::reverse_iterator MaxSizedArray<T, S, A>::rend() {
return reverse_iterator(GetPointer_NoAssert() - 1, 0);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::const_reverse_iterator MaxSizedArray<T, S, A>::rend() const {
return const_reverse_iterator(GetPointer_NoAssert() - 1, 0);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::iterator MaxSizedArray<T, S, A>::erase (const iterator& parDele) {
assert(end() != parDele);
return erase(parDele, parDele + 1);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
typename MaxSizedArray<T, S, A>::iterator MaxSizedArray<T, S, A>::erase (const iterator& parFrom, const iterator& parToExcl) {
assert(parFrom >= begin());
assert(parToExcl <= end());
assert(parToExcl >= parFrom);
//I'm doing this in two passes: first, I'm deleting as many elements as
//the ones that would be left at the end (that is, delete and move),
//then delete everything to the end of the buffer, if necessary.
const size_type deleCount = static_cast<size_type>(parToExcl - parFrom);
const size_type firstIndexToDele = static_cast<size_type>(parFrom - begin());
const size_type& sz = m_used;
assert(firstIndexToDele + deleCount <= sz);
const size_type deleAndCopyCount = sz - (firstIndexToDele + deleCount);
//As said, make room and copy from the cut tail
for (size_type z = firstIndexToDele; z < firstIndexToDele + deleAndCopyCount; z++) {
(*this)[z].~T();
new(&(*this)[z]) T((*this)[z + deleCount]);
}
//Any leftover is rubbish
for (size_type z = firstIndexToDele + deleAndCopyCount; z < sz; z++) {
(*this)[z].~T();
}
m_used -= deleCount;
return begin() + firstIndexToDele;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void MaxSizedArray<T, S, A>::reserve (size_type parReserve) {
assert(parReserve <= S);
if (parReserve > S) {
throw std::length_error("Unable to reserve more memory than the build-time size for MaxSizedArray");
}
}
} //namespace dhandy

View file

@ -0,0 +1,38 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id9B6B373E88404330ADEE51A4EC861787
#define id9B6B373E88404330ADEE51A4EC861787
#if !defined(CMAKE_ON)
# define CMAKE_ON 1
# define CMAKE_on 1
# define CMAKE_On 1
# define CMAKE_oN 1
#endif
#if !defined(CMAKE_OFF)
# define CMAKE_OFF 0
# define CMAKE_OFf 0
# define CMAKE_OfF 0
# define CMAKE_Off 0
# define CMAKE_oFF 0
# define CMAKE_oFf 0
# define CMAKE_ofF 0
# define CMAKE_off 0
#endif
#endif

View file

@ -0,0 +1,62 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id45CDD1DAEF4F42968E3C89F68FDDA9BC
#define id45CDD1DAEF4F42968E3C89F68FDDA9BC
#if defined(__GNUC__)
# if defined(__clang__)
# if !defined(__has_attribute)
//Fall back to version number comparing
# else
# if __has_attribute(flatten)
# define a_flatten __attribute__((flatten))
# else
# define a_flatten
# endif
# if __has_attribute(always_inline)
# define a_always_inline __attribute__((always_inline))
# else
# define a_always_inline
# endif
# if __has_attribute(pure)
# define a_pure __attribute__((pure))
# else
# define a_pure
# endif
# if __has_attribute(deprecated)
# define a_deprecated __attribute__((deprecated))
# else
# define a_deprecated
#endif
# endif
# else
//Fix here if you get warnings about unsupported attributes on your compiler
# define a_flatten __attribute__((flatten))
# define a_always_inline __attribute__((always_inline))
# define a_pure __attribute__((pure))
# define a_deprecated __attribute__((deprecated))
# endif
#else
# warning "Unsupported compiler, please fill this section or file a bug"
# define a_flatten
# define a_always_inline
# define a_pure
# define a_deprecated
#endif
#endif

View file

@ -0,0 +1,54 @@
/*
* Copyright 2015 Michele "King_DuckZ" Santullo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef idFBC29C5127784D35BE62F7BAC16E3687
#define idFBC29C5127784D35BE62F7BAC16E3687
#define define_has_method(method_name,pretty_name) \
template <typename T> \
struct Has ## pretty_name ## Method { \
private: \
struct TrueType { int a[2]; }; \
typedef int FalseType; \
template <typename C> static TrueType has_method ( decltype(&C::method_name) ); \
template <typename C> static FalseType has_method ( ... ); \
public: \
enum { value = sizeof(has_method<T>(0)) == sizeof(TrueType) }; \
}
#define define_has_typedef(typedef_name,pretty_name) \
template <typename T> \
struct Has ## pretty_name ## Typedef { \
private: \
struct TrueType { int a[2]; }; \
typedef int FalseType; \
template <typename C> static TrueType has_typedef ( const typename C::typedef_name* ); \
template <typename C> static FalseType has_typedef ( ... ); \
public: \
enum { value = sizeof(has_typedef<T>(nullptr)) == sizeof(TrueType) }; \
}
#define define_has_enum(enum_name,pretty_name) \
template <typename T> \
struct Has ## pretty_name ## Enum { \
private: \
struct TrueType { int a[2]; }; \
typedef int FalseType; \
template <typename C> static TrueType has_enum ( decltype(C::enum_name)* ); \
template <typename C> static FalseType has_enum ( ... ); \
public:\
enum { value = sizeof(has_enum<T>(nullptr)) == sizeof(TrueType) }; \
}
#endif

View file

@ -0,0 +1,91 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef idDB299AE3079F4830BB1D543C07F7B594
#define idDB299AE3079F4830BB1D543C07F7B594
//Classes in this file are low level and only intended to be used by library
//code. They don't do much by themselves and shoud never be used from outside.
#include <memory>
#include <algorithm>
#include <cassert>
#include <cstdint>
#if !defined(NDEBUG)
# define ASSERTIONSENABLED
#endif
namespace dhandy {
const size_t MAX_STACK_ALLOC_SIZE = 128;
///-------------------------------------------------------------------------
///Heap-based allocation, only gets raw memory
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A=std::allocator<T> >
class AutomemRawBase_heap {
protected:
AutomemRawBase_heap ( void );
AutomemRawBase_heap ( const AutomemRawBase_heap& ) = delete; //Copy ctor can't be implemented at this level
AutomemRawBase_heap ( AutomemRawBase_heap&& parOther );
template <typename... Args>
T* GetNewT ( size_t parIndex, Args&&... parArgs );
T* AllocMemory ( void );
void FreeMemory ( void ) noexcept;
void swap ( AutomemRawBase_heap& parOther ) noexcept { std::swap(m_localMem, parOther.m_localMem); }
private:
void operator= (const AutomemRawBase_heap&);
#if defined(ASSERTIONSENABLED)
typedef uintptr_t PTR_INT_TYPE;
static_assert(sizeof(PTR_INT_TYPE) == sizeof(char*), "Wrong uintptr_t size");
#endif
T* m_localMem;
};
///-------------------------------------------------------------------------
///Stack-based allocation, only gets raw memory
///-------------------------------------------------------------------------
template <typename T, size_t S>
class AutomemRawBase_stack {
protected:
AutomemRawBase_stack ( void ) = default;
AutomemRawBase_stack ( const AutomemRawBase_stack& ) = delete; //Copy ctor can't be implemented at this level
AutomemRawBase_stack ( AutomemRawBase_stack&& ) = delete;
~AutomemRawBase_stack ( void ) = default;
template <typename... Args>
T* GetNewT ( size_t parIndex, Args&&... parArgs );
T* AllocMemory ( void );
void FreeMemory ( void ) noexcept { return; }
private:
#if defined(ASSERTIONSENABLED)
typedef uintptr_t PTR_INT_TYPE;
static_assert(sizeof(PTR_INT_TYPE) == sizeof(char*), "Wrong uintptr_t size");
#endif
void operator= (const AutomemRawBase_stack&);
typename std::aligned_storage<sizeof(T), alignof(T)>::type m_localMem[S];
};
} //namespace dhandy
#include "AutomemBase.inl"
#if defined(ASSERTIONSENABLED)
# undef ASSERTIONSENABLED
#endif
#endif

View file

@ -0,0 +1,118 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
namespace dhandy {
namespace {
#if defined(ASSERTIONSENABLED)
const char g_guard = 0xAB;
#endif
} //unnamed namespace
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
AutomemRawBase_heap<T, S, A>::AutomemRawBase_heap() {
#if !defined(NDEBUG)
m_localMem = nullptr;
#endif
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
AutomemRawBase_heap<T, S, A>::AutomemRawBase_heap (AutomemRawBase_heap&& parOther) {
#if !defined(NDEBUG)
m_localMem = nullptr;
#endif
this->swap(parOther);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
T* AutomemRawBase_heap<T, S, A>::AllocMemory() {
#if !defined(NDEBUG)
assert(nullptr == m_localMem);
#endif
m_localMem = A().allocate(S);
#if defined(ASSERTIONSENABLED)
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
std::fill(
reinterpret_cast<char*>(&m_localMem[0]),
reinterpret_cast<char*>(&m_localMem[0]) + sizeof(m_localMem),
g_guard
);
#endif
return m_localMem;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
void AutomemRawBase_heap<T, S, A>::FreeMemory() noexcept {
#if !defined(NDEBUG)
assert(nullptr != m_localMem);
#endif
A().deallocate(m_localMem, S);
#if !defined(NDEBUG)
m_localMem = nullptr;
#endif
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S, typename A>
template <typename... Args>
T* AutomemRawBase_heap<T, S, A>::GetNewT (size_t parIndex, Args&&... parArgs) {
assert(parIndex < S);
T* const location = m_localMem + parIndex;
#if defined(ASSERTIONSENABLED)
assert(reinterpret_cast<PTR_INT_TYPE>(location) % alignof(T) == 0);
assert(g_guard == *reinterpret_cast<const char*>(location));
#endif
return new(location) T(std::forward<Args...>(parArgs)...);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S>
T* AutomemRawBase_stack<T, S>::AllocMemory() {
#if defined(ASSERTIONSENABLED)
assert(reinterpret_cast<PTR_INT_TYPE>(m_localMem) % alignof(T) == 0); //Make sure alignment is correct
std::fill(
reinterpret_cast<char*>(&m_localMem[0]),
reinterpret_cast<char*>(&m_localMem[0]) + sizeof(m_localMem),
g_guard
);
#endif
return reinterpret_cast<T*>(&m_localMem[0]);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename T, size_t S>
template <typename... Args>
T* AutomemRawBase_stack<T, S>::GetNewT (size_t parIndex, Args&&... parArgs) {
assert(parIndex < S);
auto* const location = &m_localMem[parIndex];
#if defined(ASSERTIONSENABLED)
assert(reinterpret_cast<PTR_INT_TYPE>(location) % alignof(T) == 0);
assert(g_guard == *reinterpret_cast<const char*>(location));
#endif
return new(location) T(std::forward<Args...>(parArgs)...);
}
} //namespace dhandy

View file

@ -0,0 +1,314 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id1B822B1775424D879AA6AD1739B5BC91
#define id1B822B1775424D879AA6AD1739B5BC91
#include <iterator>
#include <cstdint>
#include <type_traits>
#include <cassert>
namespace dhandy {
namespace implem_iop {
template <typename P, typename T, int32_t I>
class IteratorOnPtr_base : public std::iterator<std::random_access_iterator_tag, T> {
typedef std::iterator<std::random_access_iterator_tag, T> parent_type;
public:
//Typedefs to be STL-compliant
typedef typename parent_type::iterator_category iterator_category;
typedef typename parent_type::value_type value_type;
typedef typename parent_type::difference_type difference_type;
typedef typename parent_type::pointer pointer;
typedef typename std::remove_reference<T>::type& reference;
IteratorOnPtr_base ( P parPointer, difference_type parSize );
IteratorOnPtr_base ( const IteratorOnPtr_base& parOther );
template <typename P1, typename T1>
explicit IteratorOnPtr_base ( const IteratorOnPtr_base<P1, T1, I>& parOther );
~IteratorOnPtr_base ( void );
difference_type operator- ( const IteratorOnPtr_base& parOther ) const;
bool operator== ( const IteratorOnPtr_base& parOther ) const { return m_pointer == parOther.m_pointer; }
bool operator!= ( const IteratorOnPtr_base& parOther ) const { return not operator==(parOther); }
bool operator< ( const IteratorOnPtr_base& parOther ) const { return m_pointer < parOther.m_pointer; }
bool operator>= ( const IteratorOnPtr_base& parOther ) const { return not operator<(parOther); }
bool operator> ( const IteratorOnPtr_base& parOther ) const { return parOther < *this; }
bool operator<= ( const IteratorOnPtr_base& parOther ) const { return not operator>(parOther); }
P GetPointer ( void ) { return m_pointer; }
const P GetPointer ( void ) const { return m_pointer; }
#if !defined(NDEBUG)
difference_type GetSize ( void ) const { return GetSize(0); }
#endif
protected:
enum {
STEP = (I < 0 ? -I : I)
};
#if !defined(NDEBUG)
difference_type GetSize ( difference_type parAdvance ) const;
bool CanAdvance ( difference_type parAdvance ) const;
void AlterSize ( difference_type parAdvance );
#endif
void MoveIterator ( difference_type parAdvance );
P m_pointer;
private:
#if !defined(NDEBUG)
difference_type m_size;
#endif
};
} //namespace implem_iop
template <typename P, typename T, bool R>
class IteratorOnPtr : public implem_iop::IteratorOnPtr_base<P, T, (R ? -1 : 1)> {
typedef implem_iop::IteratorOnPtr_base<P, T, (R ? -1 : 1)> parent_type;
enum {
STEP = parent_type::STEP
};
public:
typedef typename parent_type::iterator_category iterator_category;
typedef typename parent_type::value_type value_type;
typedef typename parent_type::difference_type difference_type;
typedef typename parent_type::pointer pointer;
typedef typename parent_type::reference reference;
IteratorOnPtr ( void );
IteratorOnPtr ( P parPointer, difference_type parSize );
IteratorOnPtr ( const IteratorOnPtr& parOther ) : parent_type(parOther) { return; }
template <typename P1, typename T1>
IteratorOnPtr ( const IteratorOnPtr<P1, T1, R>& parOther ) : parent_type(parOther) {}
~IteratorOnPtr ( void );
IteratorOnPtr& operator++ ( void ); //pre
IteratorOnPtr operator++ ( int ); //post
IteratorOnPtr& operator-- ( void );
IteratorOnPtr operator-- ( int );
reference operator* ( void );
pointer operator-> ( void );
using parent_type::operator-;
IteratorOnPtr operator+ ( difference_type parOther ) const;
IteratorOnPtr operator- ( difference_type parOther ) const;
IteratorOnPtr& operator+= ( difference_type parOther );
IteratorOnPtr& operator-= ( difference_type parOther );
protected:
private:
};
namespace implem_iop {
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
#if !defined(NDEBUG)
IteratorOnPtr_base<P, T, I>::IteratorOnPtr_base (P parPointer, difference_type parSize) :
m_pointer(parPointer),
m_size(parSize)
#else
IteratorOnPtr_base<P, T, I>::IteratorOnPtr_base (P parPointer, difference_type) :
m_pointer(parPointer)
#endif
{
static_assert(I != 0, "Step must be non-zero");
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
template <typename P1, typename T1>
IteratorOnPtr_base<P, T, I>::IteratorOnPtr_base (const IteratorOnPtr_base<P1, T1, I>& parOther) {
m_pointer = parOther.GetPointer();
#if !defined(NDEBUG)
m_size = parOther.GetSize();
#endif
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
IteratorOnPtr_base<P, T, I>::IteratorOnPtr_base (const IteratorOnPtr_base& parOther) {
m_pointer = parOther.m_pointer;
#if !defined(NDEBUG)
m_size = parOther.m_size;
#endif
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
IteratorOnPtr_base<P, T, I>::~IteratorOnPtr_base() {
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
typename IteratorOnPtr_base<P, T, I>::difference_type IteratorOnPtr_base<P, T, I>::operator- (const IteratorOnPtr_base& parOther) const {
if (I > 0)
return m_pointer - parOther.m_pointer;
else
return parOther.m_pointer - m_pointer;
}
#if !defined(NDEBUG)
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
typename IteratorOnPtr_base<P, T, I>::difference_type IteratorOnPtr_base<P, T, I>::GetSize (difference_type parAdvance) const {
return m_size - STEP * parAdvance;
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
bool IteratorOnPtr_base<P, T, I>::CanAdvance (difference_type parAdvance) const {
return (m_size >= STEP * parAdvance);
}
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
void IteratorOnPtr_base<P, T, I>::AlterSize (difference_type parAdvance) {
m_size = GetSize(parAdvance);
}
#endif
///---------------------------------------------------------------------
///---------------------------------------------------------------------
template <typename P, typename T, int32_t I>
void IteratorOnPtr_base<P, T, I>::MoveIterator (difference_type parAdvance) {
#if !defined(NDEBUG)
assert(CanAdvance(parAdvance));
AlterSize(parAdvance);
#endif
m_pointer += I * parAdvance;
}
} //namespace implem_iop
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>::IteratorOnPtr() :
parent_type(NULL, 0)
{
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>::IteratorOnPtr (P parPointer, difference_type parSize) :
parent_type(parPointer, parSize)
{
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>::~IteratorOnPtr() {
}
///-------------------------------------------------------------------------
///Pre-increment.
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>& IteratorOnPtr<P, T, R>::operator++() {
this->MoveIterator(1);
return *this;
}
///-------------------------------------------------------------------------
///Post-increment.
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R> IteratorOnPtr<P, T, R>::operator++ (int) {
IteratorOnPtr<P, T, R> retVal(*this);
this->MoveIterator(1);
return retVal;
}
///-------------------------------------------------------------------------
///Pre-decrement.
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>& IteratorOnPtr<P, T, R>::operator--() {
this->MoveIterator(-1);
return *this;
}
///-------------------------------------------------------------------------
///Post-decrement.
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R> IteratorOnPtr<P, T, R>::operator-- (int) {
IteratorOnPtr<P, T, R> retVal(*this);
this->MoveIterator(-1);
return retVal;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
typename IteratorOnPtr<P, T, R>::reference IteratorOnPtr<P, T, R>::operator*() {
return *(this->m_pointer);
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
typename IteratorOnPtr<P, T, R>::pointer IteratorOnPtr<P, T, R>::operator->() {
return this->m_pointer;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R> IteratorOnPtr<P, T, R>::operator+ (difference_type parOther) const {
IteratorOnPtr<P, T, R> retVal(*this);
retVal += parOther;
return retVal;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R> IteratorOnPtr<P, T, R>::operator- (difference_type parOther) const {
IteratorOnPtr<P, T, R> retVal(*this);
retVal -= parOther;
return retVal;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>& IteratorOnPtr<P, T, R>::operator+= (difference_type parOther) {
this->MoveIterator(parOther);
return *this;
}
///-------------------------------------------------------------------------
///-------------------------------------------------------------------------
template <typename P, typename T, bool R>
IteratorOnPtr<P, T, R>& IteratorOnPtr<P, T, R>::operator-= (difference_type parOther) {
this->MoveIterator(-parOther);
return *this;
}
} //namespace dhandy
#endif

View file

@ -0,0 +1,48 @@
// see http://stackoverflow.com/questions/3496982/printing-lists-with-commas-c/3497021#3497021
// infix_iterator.h
//
// Lifted from Jerry Coffin's 's prefix_ostream_iterator
#if !defined(INFIX_ITERATOR_H_)
#define INFIX_ITERATOR_H_
#include <ostream>
#include <iterator>
template <class T,
class charT=char,
class traits=std::char_traits<charT> >
class infix_ostream_iterator :
public std::iterator<std::output_iterator_tag,void,void,void,void>
{
std::basic_ostream<charT,traits> *os;
charT const* delimiter;
bool first_elem;
public:
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream<charT,traits> ostream_type;
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{}
infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s),delimiter(d), first_elem(true)
{}
infix_ostream_iterator<T,charT,traits>& operator=(T const &item)
{
// Here's the only real change from ostream_iterator:
// Normally, the '*os << item;' would come before the 'if'.
if (!first_elem && delimiter != 0)
*os << delimiter;
*os << item;
first_elem = false;
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator*() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++() {
return *this;
}
infix_ostream_iterator<T,charT,traits> &operator++(int) {
return *this;
}
};
#endif

View file

@ -0,0 +1,37 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id19B690A53A9546D5BD95D89FFF388283
#define id19B690A53A9546D5BD95D89FFF388283
#if defined(__cplusplus)
# include <cstddef>
#else
# include <stddef.h>
#endif
#if defined(lengthof)
# undef lengthof
#endif
//http://stackoverflow.com/questions/4415524/common-array-length-macro-for-c#4415646
#if defined(__cplusplus)
# define lengthof(x) ((sizeof(x)/sizeof(0[x])) / ((std::size_t)(!(sizeof(x) % sizeof(0[x])))))
#else
# define lengthof(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#endif
#endif

View file

@ -0,0 +1,304 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id942A6B5AB2AF443C82D4321775BFC9E8
#define id942A6B5AB2AF443C82D4321775BFC9E8
#include "compatibility.h"
#include "helpers/sequence_bt.hpp"
#include "helpers/MaxSizedArray.hpp"
#include "sprout/math/log10.hpp"
#include "sprout/math/log2.hpp"
#include "sprout/math/pow.hpp"
#include <type_traits>
#include <utility>
#include <limits>
#include <cstdint>
#include <algorithm>
#include <string>
#include <ciso646>
#include <climits>
#include <boost/range/adaptor/reversed.hpp>
#include <cstddef>
namespace dhandy {
namespace customize {
template<typename T>
struct index_array_to_string;
template<typename C, typename T>
struct char_to_int;
} //namespace customize
namespace implem {
template <typename T>
typename std::make_unsigned<T>::type abs ( T parValue ) a_pure;
template <typename T> int count_leading_zeroes ( typename std::enable_if<std::numeric_limits<T>::is_signed, T>::type parValue ) a_always_inline;
template <typename T> int count_leading_zeroes ( typename std::enable_if<not std::numeric_limits<T>::is_signed, T>::type parValue ) a_always_inline;
int count_leading_zeroes_overload ( unsigned char parValue ) a_always_inline;
int count_leading_zeroes_overload ( unsigned short int parValue ) a_always_inline;
int count_leading_zeroes_overload ( unsigned int parValue ) a_always_inline;
int count_leading_zeroes_overload ( unsigned long parValue ) a_always_inline;
int count_leading_zeroes_overload ( unsigned long long parValue ) a_always_inline;
template <std::size_t Base, std::size_t Val>
struct power {
enum { value = Base * power<Base, Val - 1>::value };
};
template <std::size_t Base>
struct power<Base, 0> {
enum { value = 1 };
};
template <typename T, bool=std::numeric_limits<T>::is_signed>
struct is_negative;
template <typename T>
struct is_negative<T, true> {
static int check (T parValue) { return (parValue < 0 ? 1 : 0); }
};
template <typename T>
struct is_negative<T, false> {
static constexpr int check (T) { return 0; }
};
template <template <typename> class Tag, typename T, typename F>
inline auto int_to_string (const F parFrom) -> MaxSizedArray<uint8_t, Tag<F>::count_digits_bt(std::numeric_limits<typename std::make_unsigned<F>::type>::max())> {
using ArrayRetType = MaxSizedArray<uint8_t, Tag<F>::count_digits_bt(std::numeric_limits<typename std::make_unsigned<F>::type>::max())>;
ArrayRetType retval;
F div = 1;
constexpr const std::size_t charset_offs = (Tag<F>::lower_case ? Tag<F>::base : 0);
const auto sign_length = (is_negative<F>::check(parFrom) and Tag<F>::sign_allowed ? 1 : 0);
for (std::size_t z = 0; z < Tag<F>::count_digits(parFrom) - sign_length; ++z) {
retval.push_back(static_cast<uint8_t>(((Tag<F>::make_unsigned(parFrom) / div) % Tag<F>::base) + charset_offs));
div *= Tag<F>::base;
}
std::reverse(retval.begin(), retval.end());
return retval;
};
template <template <typename> class Tag, typename T, typename F>
inline T string_to_int (const F& parFrom) {
T retval(0);
T mul(1);
for (auto chara : boost::adaptors::reverse(parFrom)) {
retval += dhandy::customize::char_to_int<decltype(chara), T>::make(chara) * mul;
mul *= Tag<T>::base;
}
return retval * dhandy::customize::char_to_int<typename F::value_type, T>::sgn(parFrom);
};
template <typename T, bool LowerCase>
struct hex {
enum {
base = 16,
sign_allowed = 0,
lower_case = (LowerCase ? 1 : 0)
};
static std::size_t count_digits ( T parValue ) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(static_cast<double>(parNum)) / sprout::log10(static_cast<double>(base)))) + 1;
}
};
} //namespace implem
namespace tags {
template <typename T>
struct dec {
enum {
base = 10,
sign_allowed = 1,
lower_case = 0
};
template <std::size_t... Powers, std::size_t... Digits>
static std::size_t count_digits_implem (T parValue, dhandy::bt::index_seq<Powers...>, dhandy::bt::index_seq<Digits...>) a_pure;
static std::size_t count_digits (T parValue) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log10(static_cast<double>(parNum)))) + 1 + (std::numeric_limits<T>::is_signed ? 1 : 0);
}
};
template <typename T>
using hex = dhandy::implem::hex<T, false>;
template <typename T>
using hexl = dhandy::implem::hex<T, true>;
template <typename T>
struct bin {
enum {
base = 2,
sign_allowed = 0,
lower_case = 0
};
static std::size_t count_digits ( T parValue ) a_pure;
static typename std::make_unsigned<T>::type make_unsigned ( T parValue ) a_pure;
static constexpr std::size_t count_digits_bt (std::size_t parNum) {
return (parNum == 0 ? 0 : static_cast<std::size_t>(sprout::log2(static_cast<double>(parNum)))) + 1;
}
};
//See: http://stackoverflow.com/questions/9721042/count-number-of-digits-which-method-is-most-efficient#9721113
template <typename T>
template <std::size_t... Powers, std::size_t... Digits>
std::size_t dec<T>::count_digits_implem (T parValue, dhandy::bt::index_seq<Powers...>, dhandy::bt::index_seq<Digits...>) {
typedef typename std::make_unsigned<T>::type UT;
static constexpr UT powers[] = { 0, static_cast<UT>(dhandy::implem::power<10, Powers + 1>::value)... };
static constexpr std::size_t maxdigits[] = { count_digits_bt(static_cast<std::size_t>(sprout::pow(2.0, Digits))) - (std::numeric_limits<T>::is_signed ? 1 : 0)... };
const auto bits = sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes<T>(dhandy::implem::abs(parValue));
static_assert(std::is_same<UT, decltype(dhandy::implem::abs(parValue))>::value, "Unexpected type");
return (dhandy::implem::abs(parValue) < powers[maxdigits[bits] - 1] ? maxdigits[bits] - 1 : maxdigits[bits]) + dhandy::implem::is_negative<T>::check(parValue);
}
template <typename T>
std::size_t dec<T>::count_digits (T parValue) {
return count_digits_implem(
parValue,
dhandy::bt::index_range<0, count_digits_bt(std::numeric_limits<T>::max()) - (std::numeric_limits<T>::is_signed ? 1 : 0) - 1>(),
dhandy::bt::index_range<0, CHAR_BIT * sizeof(T) + 1>()
);
}
template <typename T>
typename std::make_unsigned<T>::type dec<T>::make_unsigned (T parValue) {
return dhandy::implem::abs(parValue);
}
template <typename T>
std::size_t bin<T>::count_digits (T parValue) {
return std::max<std::size_t>((sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes<typename std::make_unsigned<T>::type>(make_unsigned(parValue))), 1);
}
template <typename T>
typename std::make_unsigned<T>::type bin<T>::make_unsigned (T parValue) {
return static_cast<typename std::make_unsigned<T>::type>(parValue);
}
} //namespace tags
namespace implem {
template <template <typename> class Tag>
struct lexical_cast {
template <typename T, typename F>
static T convert ( const typename std::enable_if<std::is_integral<F>::value, F>::type& parFrom ) {
const auto indices = int_to_string<Tag, T, F>(parFrom);
return dhandy::customize::index_array_to_string<T>::make(indices, is_negative<F>::check(parFrom) bitand Tag<F>::sign_allowed);
}
template <typename T, typename F>
static typename std::enable_if<std::is_integral<T>::value, T>::type convert ( const F& parFrom ) {
return string_to_int<Tag, T, F>(parFrom);
}
};
template <typename T>
inline int count_leading_zeroes (typename std::enable_if<std::numeric_limits<T>::is_signed, T>::type parValue) {
return count_leading_zeroes<decltype(dhandy::implem::abs(parValue))>(dhandy::implem::abs(parValue));
}
template <typename T>
inline int count_leading_zeroes (typename std::enable_if<not std::numeric_limits<T>::is_signed, T>::type parValue) {
return count_leading_zeroes_overload(parValue) + sizeof(T) * CHAR_BIT;
}
inline int count_leading_zeroes_overload (unsigned char parValue) {
return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
}
inline int count_leading_zeroes_overload (unsigned short int parValue) {
return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
}
inline int count_leading_zeroes_overload (unsigned int parValue) {
return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
}
inline int count_leading_zeroes_overload (unsigned long parValue) {
return __builtin_clzl(parValue) - sizeof(unsigned long) * CHAR_BIT;
}
inline int count_leading_zeroes_overload (unsigned long long parValue) {
return __builtin_clzll(parValue) - sizeof(unsigned long long) * CHAR_BIT;
}
//See: http://stackoverflow.com/questions/16101062/why-does-stdabs-return-signed-types
template <typename T>
typename std::make_unsigned<T>::type abs (T parValue) {
//We need to cast before negating x to avoid the overflow.
return (parValue < 0 ? -static_cast<typename std::make_unsigned<T>::type>(parValue) : parValue);
}
template <typename T, bool LowerCase>
std::size_t hex<T, LowerCase>::count_digits (T parValue) {
return std::max<std::size_t>(((sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes<typename std::make_unsigned<T>::type>(make_unsigned(parValue))) + (CHAR_BIT / 2 - 1)) / (CHAR_BIT / 2), 1);
}
template <typename T, bool LowerCase>
typename std::make_unsigned<T>::type hex<T, LowerCase>::make_unsigned (T parValue) {
return static_cast<typename std::make_unsigned<T>::type>(parValue);
}
} //namespace implem
template <typename T, template <typename> class Tag=tags::dec, typename F=void>
inline T lexical_cast (const F& parFrom) {
return dhandy::implem::lexical_cast<Tag>::template convert<T, F>(parFrom);
}
namespace customize {
template<>
struct index_array_to_string<std::string> {
template<std::size_t N>
static std::string make (const MaxSizedArray<uint8_t, N> &parIndices, int parNegative) {
static const char symbols[] = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F',
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
std::string retval(parIndices.size() + parNegative, '-');
for (auto z = parNegative; z < static_cast<int>(parIndices.size()) + parNegative; ++z) {
retval[z] = symbols[parIndices[z - parNegative]];
}
return retval;
}
};
template<typename T>
struct char_to_int<char, T> {
static T make (char parChar) {
if (parChar >= '0' and parChar <= '9')
return parChar - '0';
else if (parChar >= 'a' and parChar <= 'f')
return 10 + parChar - 'a';
else if (parChar >= 'A' and parChar <= 'F')
return 10 + parChar - 'A';
else if (parChar == '-')
return 0;
return 0;
}
template <typename Container>
static T sgn (const Container& parString) {
return static_cast<T>(std::numeric_limits<T>::is_signed and parString.begin() != parString.end() and *parString.begin() == '-' ? -1 : 1);
}
};
} //namespace customize
} //namespace dhandy
#endif

View file

@ -0,0 +1,54 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id4FAEF395B9ED47CB9D6B50B54C9A289A
#define id4FAEF395B9ED47CB9D6B50B54C9A289A
#include <cstddef>
namespace dhandy {
namespace bt {
template <typename T, T... I>
struct number_seq {
};
template <std::size_t... I>
using index_seq = number_seq<std::size_t, I...>;
namespace implem {
template <typename T, T MIN, T MAX, T... I>
struct range_builder;
template <typename T, T MIN, T... I>
struct range_builder<T, MIN, MIN, I...> {
typedef number_seq<T, I...> type;
};
template <typename T, T MIN, T N, T... I>
struct range_builder : public range_builder<T, MIN, N - 1, N - 1, I...> {
};
} //namespace implem
template <typename T, T MIN, T MAX>
using number_range = typename implem::range_builder<T, MIN, MAX>::type;
template <std::size_t MIN, std::size_t MAX>
using index_range = number_range<std::size_t, MIN, MAX>;
} //namespace bt
} //namespace dhandy
#endif

View file

@ -0,0 +1,112 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id170B0E6C34D14EBA9B92A35977BDBFB3
#define id170B0E6C34D14EBA9B92A35977BDBFB3
#include "sequence_bt.hpp"
#include <cstddef>
#include <iostream>
#include <stdexcept>
namespace dhandy {
namespace bt {
template <std::size_t S>
class string;
template <std::size_t S>
std::ostream& operator<< ( std::ostream& parStream, const string<S>& parString );
template <std::size_t S>
class string {
public:
friend std::ostream& operator<< <>( std::ostream& parStream, const string<S>& parString );
constexpr string ( const char* parString );
constexpr std::size_t size ( void ) const { return S - 1; }
template <std::size_t S2>
constexpr string<S + S2 - 1> operator+ ( const string<S2>& parOther ) const;
constexpr char operator[] ( std::size_t parIndex ) const;
template <typename... Args>
constexpr string ( Args... );
constexpr const char (&data_arr() const)[S] { return m_data; }
constexpr const char* data() const { return m_data; }
private:
template <std::size_t... I>
constexpr string ( const index_seq<I...>&, const char* parString );
const char m_data[S];
};
namespace implem {
template <std::size_t S, std::size_t S2, std::size_t... I>
constexpr string<S + S2 - 1> concat ( const index_seq<I...>&, const string<S>& parLeft, const string<S2>& parRight ) {
return string<S + S2 - 1>(
(I < S - 1 ? parLeft[I] : (I < S + S2 - 2 ? parRight[I - (S - 1)] : '\0'))...
);
}
} //namespace implem
template <std::size_t S>
template <std::size_t... I>
constexpr string<S>::string (const index_seq<I...>&, const char* parString) :
m_data{parString[I]...}
{
}
template <std::size_t S>
inline constexpr string<S>::string (const char* parString) :
string(index_range<0, S>(), parString)
{
}
template <std::size_t S>
template <typename... Args>
inline constexpr string<S>::string (Args... parArgs) :
m_data{parArgs...}
{
}
template <std::size_t S>
template <std::size_t S2>
constexpr inline string<S + S2 - 1> string<S>::operator+ (const string<S2>& parOther) const {
return implem::concat(index_range<0, S + S2 - 1>(), string<S>(m_data), parOther);
}
template <std::size_t S>
inline std::ostream& operator<< (std::ostream& parStream, const string<S>& parString) {
parStream << parString.m_data;
return parStream;
}
template <std::size_t S>
constexpr char string<S>::operator[] (std::size_t parIndex) const {
return (parIndex < S ? m_data[parIndex] : throw std::out_of_range(""));
}
template <std::size_t S>
constexpr string<S> make_string (const char (&parData)[S]) {
return string<S>(parData);
}
} //namespace bt
} //namespace dhandy
#endif

View file

@ -0,0 +1,24 @@
/* Copyright 2016, Michele Santullo
* This file is part of "duckhandy".
*
* "duckhandy" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "duckhandy" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "duckhandy". If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id8B9FF1807C05459DAE8CD05312147416
#define id8B9FF1807C05459DAE8CD05312147416
#define STRINGIZE_IMPL(s) #s
#define STRINGIZE(s) STRINGIZE_IMPL(s)
#endif