Preparing for XCode project. Removing now obsolete files.

This commit is contained in:
meeh
2018-09-18 15:19:23 +00:00
parent b74abbe4de
commit beede9505e
36 changed files with 0 additions and 605 deletions

View File

@@ -0,0 +1,461 @@
//
// Implementation of N4562 std::experimental::any (merged into C++17) for C++11 compilers.
//
// See also:
// + http://en.cppreference.com/w/cpp/any
// + http://en.cppreference.com/w/cpp/experimental/any
// + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#any
// + https://cplusplus.github.io/LWG/lwg-active.html#2509
//
//
// Copyright (c) 2016 Denilson das Merc<72>s Amorim
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef LINB_ANY_HPP
#define LINB_ANY_HPP
#pragma once
#include <typeinfo>
#include <type_traits>
#include <stdexcept>
namespace linb
{
class bad_any_cast : public std::bad_cast
{
public:
const char* what() const noexcept override
{
return "bad any cast";
}
};
class any final
{
public:
/// Constructs an object of type any with an empty state.
any() :
vtable(nullptr)
{
}
/// Constructs an object of type any with an equivalent state as other.
any(const any& rhs) :
vtable(rhs.vtable)
{
if(!rhs.empty())
{
rhs.vtable->copy(rhs.storage, this->storage);
}
}
/// Constructs an object of type any with a state equivalent to the original state of other.
/// rhs is left in a valid but otherwise unspecified state.
any(any&& rhs) noexcept :
vtable(rhs.vtable)
{
if(!rhs.empty())
{
rhs.vtable->move(rhs.storage, this->storage);
rhs.vtable = nullptr;
}
}
/// Same effect as this->clear().
~any()
{
this->clear();
}
/// Constructs an object of type any that contains an object of type T direct-initialized with std::forward<ValueType>(value).
///
/// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed.
/// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed.
template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type, any>::value>::type>
any(ValueType&& value)
{
static_assert(std::is_copy_constructible<typename std::decay<ValueType>::type>::value,
"T shall satisfy the CopyConstructible requirements.");
this->construct(std::forward<ValueType>(value));
}
/// Has the same effect as any(rhs).swap(*this). No effects if an exception is thrown.
any& operator=(const any& rhs)
{
any(rhs).swap(*this);
return *this;
}
/// Has the same effect as any(std::move(rhs)).swap(*this).
///
/// The state of *this is equivalent to the original state of rhs and rhs is left in a valid
/// but otherwise unspecified state.
any& operator=(any&& rhs) noexcept
{
any(std::move(rhs)).swap(*this);
return *this;
}
/// Has the same effect as any(std::forward<ValueType>(value)).swap(*this). No effect if a exception is thrown.
///
/// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed.
/// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed.
template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type, any>::value>::type>
any& operator=(ValueType&& value)
{
static_assert(std::is_copy_constructible<typename std::decay<ValueType>::type>::value,
"T shall satisfy the CopyConstructible requirements.");
any(std::forward<ValueType>(value)).swap(*this);
return *this;
}
/// If not empty, destroys the contained object.
void clear() noexcept
{
if(!empty())
{
this->vtable->destroy(storage);
this->vtable = nullptr;
}
}
/// Returns true if *this has no contained object, otherwise false.
bool empty() const noexcept
{
return this->vtable == nullptr;
}
/// If *this has a contained object of type T, typeid(T); otherwise typeid(void).
const std::type_info& type() const noexcept
{
return empty()? typeid(void) : this->vtable->type();
}
/// Exchange the states of *this and rhs.
void swap(any& rhs) noexcept
{
if(this->vtable != rhs.vtable)
{
any tmp(std::move(rhs));
// move from *this to rhs.
rhs.vtable = this->vtable;
if(this->vtable != nullptr)
{
this->vtable->move(this->storage, rhs.storage);
//this->vtable = nullptr; -- uneeded, see below
}
// move from tmp (previously rhs) to *this.
this->vtable = tmp.vtable;
if(tmp.vtable != nullptr)
{
tmp.vtable->move(tmp.storage, this->storage);
tmp.vtable = nullptr;
}
}
else // same types
{
if(this->vtable != nullptr)
this->vtable->swap(this->storage, rhs.storage);
}
}
private: // Storage and Virtual Method Table
union storage_union
{
using stack_storage_t = typename std::aligned_storage<2 * sizeof(void*), std::alignment_of<void*>::value>::type;
void* dynamic;
stack_storage_t stack; // 2 words for e.g. shared_ptr
};
/// Base VTable specification.
struct vtable_type
{
// Note: The caller is responssible for doing .vtable = nullptr after destructful operations
// such as destroy() and/or move().
/// The type of the object this vtable is for.
const std::type_info& (*type)() noexcept;
/// Destroys the object in the union.
/// The state of the union after this call is unspecified, caller must ensure not to use src anymore.
void(*destroy)(storage_union&) noexcept;
/// Copies the **inner** content of the src union into the yet unitialized dest union.
/// As such, both inner objects will have the same state, but on separate memory locations.
void(*copy)(const storage_union& src, storage_union& dest);
/// Moves the storage from src to the yet unitialized dest union.
/// The state of src after this call is unspecified, caller must ensure not to use src anymore.
void(*move)(storage_union& src, storage_union& dest) noexcept;
/// Exchanges the storage between lhs and rhs.
void(*swap)(storage_union& lhs, storage_union& rhs) noexcept;
};
/// VTable for dynamically allocated storage.
template<typename T>
struct vtable_dynamic
{
static const std::type_info& type() noexcept
{
return typeid(T);
}
static void destroy(storage_union& storage) noexcept
{
//assert(reinterpret_cast<T*>(storage.dynamic));
delete reinterpret_cast<T*>(storage.dynamic);
}
static void copy(const storage_union& src, storage_union& dest)
{
dest.dynamic = new T(*reinterpret_cast<const T*>(src.dynamic));
}
static void move(storage_union& src, storage_union& dest) noexcept
{
dest.dynamic = src.dynamic;
src.dynamic = nullptr;
}
static void swap(storage_union& lhs, storage_union& rhs) noexcept
{
// just exchage the storage pointers.
std::swap(lhs.dynamic, rhs.dynamic);
}
};
/// VTable for stack allocated storage.
template<typename T>
struct vtable_stack
{
static const std::type_info& type() noexcept
{
return typeid(T);
}
static void destroy(storage_union& storage) noexcept
{
reinterpret_cast<T*>(&storage.stack)->~T();
}
static void copy(const storage_union& src, storage_union& dest)
{
new (&dest.stack) T(reinterpret_cast<const T&>(src.stack));
}
static void move(storage_union& src, storage_union& dest) noexcept
{
// one of the conditions for using vtable_stack is a nothrow move constructor,
// so this move constructor will never throw a exception.
new (&dest.stack) T(std::move(reinterpret_cast<T&>(src.stack)));
destroy(src);
}
static void swap(storage_union& lhs, storage_union& rhs) noexcept
{
storage_union tmp_storage;
move(rhs, tmp_storage);
move(lhs, rhs);
move(tmp_storage, lhs);
}
};
/// Whether the type T must be dynamically allocated or can be stored on the stack.
template<typename T>
struct requires_allocation :
std::integral_constant<bool,
!(std::is_nothrow_move_constructible<T>::value // N4562 <20>6.3/3 [any.class]
&& sizeof(T) <= sizeof(storage_union::stack)
&& std::alignment_of<T>::value <= std::alignment_of<storage_union::stack_storage_t>::value)>
{};
/// Returns the pointer to the vtable of the type T.
template<typename T>
static vtable_type* vtable_for_type()
{
using VTableType = typename std::conditional<requires_allocation<T>::value, vtable_dynamic<T>, vtable_stack<T>>::type;
static vtable_type table = {
VTableType::type, VTableType::destroy,
VTableType::copy, VTableType::move,
VTableType::swap,
};
return &table;
}
protected:
template<typename T>
friend const T* any_cast(const any* operand) noexcept;
template<typename T>
friend T* any_cast(any* operand) noexcept;
/// Same effect as is_same(this->type(), t);
bool is_typed(const std::type_info& t) const
{
return is_same(this->type(), t);
}
/// Checks if two type infos are the same.
///
/// If ANY_IMPL_FAST_TYPE_INFO_COMPARE is defined, checks only the address of the
/// type infos, otherwise does an actual comparision. Checking addresses is
/// only a valid approach when there's no interaction with outside sources
/// (other shared libraries and such).
static bool is_same(const std::type_info& a, const std::type_info& b)
{
#ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE
return &a == &b;
#else
return a == b;
#endif
}
/// Casts (with no type_info checks) the storage pointer as const T*.
template<typename T>
const T* cast() const noexcept
{
return requires_allocation<typename std::decay<T>::type>::value?
reinterpret_cast<const T*>(storage.dynamic) :
reinterpret_cast<const T*>(&storage.stack);
}
/// Casts (with no type_info checks) the storage pointer as T*.
template<typename T>
T* cast() noexcept
{
return requires_allocation<typename std::decay<T>::type>::value?
reinterpret_cast<T*>(storage.dynamic) :
reinterpret_cast<T*>(&storage.stack);
}
private:
storage_union storage; // on offset(0) so no padding for align
vtable_type* vtable;
template<typename ValueType, typename T>
typename std::enable_if<requires_allocation<T>::value>::type
do_construct(ValueType&& value)
{
storage.dynamic = new T(std::forward<ValueType>(value));
}
template<typename ValueType, typename T>
typename std::enable_if<!requires_allocation<T>::value>::type
do_construct(ValueType&& value)
{
new (&storage.stack) T(std::forward<ValueType>(value));
}
/// Chooses between stack and dynamic allocation for the type decay_t<ValueType>,
/// assigns the correct vtable, and constructs the object on our storage.
template<typename ValueType>
void construct(ValueType&& value)
{
using T = typename std::decay<ValueType>::type;
this->vtable = vtable_for_type<T>();
do_construct<ValueType,T>(std::forward<ValueType>(value));
}
};
namespace detail
{
template<typename ValueType>
inline ValueType any_cast_move_if_true(typename std::remove_reference<ValueType>::type* p, std::true_type)
{
return std::move(*p);
}
template<typename ValueType>
inline ValueType any_cast_move_if_true(typename std::remove_reference<ValueType>::type* p, std::false_type)
{
return *p;
}
}
/// Performs *any_cast<add_const_t<remove_reference_t<ValueType>>>(&operand), or throws bad_any_cast on failure.
template<typename ValueType>
inline ValueType any_cast(const any& operand)
{
auto p = any_cast<typename std::add_const<typename std::remove_reference<ValueType>::type>::type>(&operand);
if(p == nullptr) throw bad_any_cast();
return *p;
}
/// Performs *any_cast<remove_reference_t<ValueType>>(&operand), or throws bad_any_cast on failure.
template<typename ValueType>
inline ValueType any_cast(any& operand)
{
auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand);
if(p == nullptr) throw bad_any_cast();
return *p;
}
///
/// If ANY_IMPL_ANYCAST_MOVEABLE is not defined, does as N4562 specifies:
/// Performs *any_cast<remove_reference_t<ValueType>>(&operand), or throws bad_any_cast on failure.
///
/// If ANY_IMPL_ANYCAST_MOVEABLE is defined, does as LWG Defect 2509 specifies:
/// If ValueType is MoveConstructible and isn't a lvalue reference, performs
/// std::move(*any_cast<remove_reference_t<ValueType>>(&operand)), otherwise
/// *any_cast<remove_reference_t<ValueType>>(&operand). Throws bad_any_cast on failure.
///
template<typename ValueType>
inline ValueType any_cast(any&& operand)
{
#ifdef ANY_IMPL_ANY_CAST_MOVEABLE
// https://cplusplus.github.io/LWG/lwg-active.html#2509
using can_move = std::integral_constant<bool,
std::is_move_constructible<ValueType>::value
&& !std::is_lvalue_reference<ValueType>::value>;
#else
using can_move = std::false_type;
#endif
auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand);
if(p == nullptr) throw bad_any_cast();
return detail::any_cast_move_if_true<ValueType>(p, can_move());
}
/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object
/// contained by operand, otherwise nullptr.
template<typename T>
inline const T* any_cast(const any* operand) noexcept
{
if(operand == nullptr || !operand->is_typed(typeid(T)))
return nullptr;
else
return operand->cast<T>();
}
/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object
/// contained by operand, otherwise nullptr.
template<typename T>
inline T* any_cast(any* operand) noexcept
{
if(operand == nullptr || !operand->is_typed(typeid(T)))
return nullptr;
else
return operand->cast<T>();
}
}
namespace std
{
inline void swap(linb::any& lhs, linb::any& rhs) noexcept
{
lhs.swap(rhs);
}
}
#endif

View File

@@ -0,0 +1,168 @@
#ifndef FN_H
#define FN_H
#include <functional>
#include <algorithm>
/*
* higher-order functions
*
* Read
* http://blog.madhukaraphatak.com/functional-programming-in-c++/
*
*
* Lamda fingerprint:
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
*
*
*
template <typename Collection,typename unop>
void for_each(Collection col, unop op){
std::for_each(col.begin(),col.end(),op);
}
Usage:
auto lambda_echo = [](int i ) { std::cout << i << std::endl; };
std::vector<int> col{20,24,37,42,23,45,37};
for_each(col,lambda_echo);
*/
template <typename Collection,typename unop>
void for_each(Collection col, unop op){
std::for_each(col.begin(),col.end(),op);
}
/**
* map
*
* Usage example:
auto addOne = [](int i) { return i+1;};
auto returnCol = map(col,addOne);
for_each(returnCol,lambda_echo);
*
*
*
*/
template <typename Collection,typename unop>
Collection map(Collection col,unop op) {
std::transform(col.begin(),col.end(),col.begin(),op);
return col;
}
/*
Filter usage:
auto filteredCol = filter(col,[](int value){ return value > 30;});
for_each(filteredCol,lambda_echo);
*/
template <typename Collection,typename Predicate>
Collection filterNot(Collection col,Predicate predicate ) {
auto returnIterator = std::remove_if(col.begin(),col.end(),predicate);
col.erase(returnIterator,std::end(col));
return col;
}
template <typename Collection,typename Predicate>
Collection filter(Collection col,Predicate predicate) {
//capture the predicate in order to be used inside function
auto fnCol = filterNot(col,[predicate](typename Collection::value_type i) { return !predicate(i);});
return fnCol;
}
/**
*
* Alternative map implementations
*
**/
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::vector<U> fmap(F f, const std::vector<T>& vec)
{
std::vector<U> result;
std::transform(vec.begin(), vec.end(), std::back_inserter(result), f);
return result;
}
template<class F, class T, class U=decltype(std::declval<F>()(std::declval<T>()))>
std::shared_ptr<U> fmap(F f, const std::shared_ptr<T>& p)
{
if (p == nullptr) return nullptr;
else return std::shared_ptr<U>(new U(f(*p)));
}
/**
* Experimental code - should not be in production
*/
namespace Experimental {
template <typename T>
T min3(const T& a, const T& b, const T& c)
{
return std::min(std::min(a, b), c);
}
class LevenshteinDistance
{
mutable std::vector<std::vector<unsigned int> > matrix_;
public:
explicit LevenshteinDistance(size_t initial_size = 8)
: matrix_(initial_size, std::vector<unsigned int>(initial_size))
{
}
unsigned int operator()(const std::string& s, const std::string& t) const
{
const size_t m = s.size();
const size_t n = t.size();
// The distance between a string and the empty string is the string's length
if (m == 0) {
return n;
}
if (n == 0) {
return m;
}
// Size the matrix as necessary
if (matrix_.size() < m + 1) {
matrix_.resize(m + 1, matrix_[0]);
}
if (matrix_[0].size() < n + 1) {
for (auto& mat : matrix_) {
mat.resize(n + 1);
}
}
// The top row and left column are prefixes that can be reached by
// insertions and deletions alone
unsigned int i, j;
for (i = 1; i <= m; ++i) {
matrix_[i][0] = i;
}
for (j = 1; j <= n; ++j) {
matrix_[0][j] = j;
}
// Fill in the rest of the matrix
for (j = 1; j <= n; ++j) {
for (i = 1; i <= m; ++i) {
unsigned int substitution_cost = s[i - 1] == t[j - 1] ? 0 : 1;
matrix_[i][j] =
min3(matrix_[i - 1][j] + 1, // Deletion
matrix_[i][j - 1] + 1, // Insertion
matrix_[i - 1][j - 1] + substitution_cost); // Substitution
}
}
return matrix_[m][n];
}
};
}
#endif // FN_H

View File

@@ -0,0 +1,105 @@
#ifndef __STRUTIL_HPP__
#define __STRUTIL_HPP__
#include <algorithm>
#include <functional>
#include <string>
#include <memory>
#include <iostream>
#include <cctype>
#include <locale>
#include "optional.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFString.h>
inline std::string strprintf(const char *fromat, ...)
{
std::string s;
s.resize(128); // best guess
char *buff = const_cast<char *>(s.data());
va_list arglist;
va_start(arglist, fromat);
auto len = vsnprintf(buff, 128, fromat, arglist);
va_end(arglist);
if (len > 127)
{
va_start(arglist, fromat);
s.resize(len + 1); // leave room for null terminator
buff = const_cast<char *>(s.data());
len = vsnprintf(buff, len+1, fromat, arglist);
va_end(arglist);
}
s.resize(len);
return s; // move semantics FTW
}
inline std::string extractString(CFStringRef value)
{
const char * data = CFStringGetCStringPtr(value, kCFStringEncodingUTF8);
if (data != NULL)
{
return std::string(data, strlen(data));
} else {
CFIndex strSize = CFStringGetLength(value)+1;
char * retry = (char *)malloc((int)strSize);
if (CFStringGetCString(value, retry, strSize, kCFStringEncodingUTF8)) {
return std::string(retry, strlen(retry));
}
return std::string("[null]");
}
}
using std::experimental::optional;
// Use CFStringRef instead of NSString*, otherwise disable ARC
inline optional<CFStringRef> optionalString(bool val) {
optional<CFStringRef> myOptString;
if(val) {
// Cast to corresponding CoreFoundation object
myOptString = (CFStringRef)@"String";
}
return myOptString;
}
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}
// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}
// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
return s;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
#ifndef NEITHER_TRAITS_HPP
#define NEITHER_TRAITS_HPP
namespace neither {
template<class L, class R>
struct Either;
template<class T>
struct Maybe;
template<class L,class...Xs>
auto isCopyable (L l, Xs...) -> L {
return l;
}
template<class L, class R>
auto ensureEither ( Either<L,R> const& e) -> Either<L,R> {
return e;
}
template<class L, class R>
auto ensureEither ( Either<L,R> && e) -> Either<L,R> {
return e;
}
template<class L, class R>
auto ensureEitherRight ( Either<L,R> const& e, R) -> Either<L, R> {
return e;
}
template<class L, class R>
auto ensureEitherRight ( Either<L,R>&& e, R&&) -> Either<L, R> {
return e;
}
template<class L, class R>
auto ensureEitherLeft ( Either<L,R> const& e, L) -> Either<L, R> {
return e;
}
template<class L, class R>
auto ensureEitherLeft ( Either<L,R>&& e, L&& ) -> Either<L, R> {
return e;
}
template<class T>
auto ensureMaybe ( Maybe<T> const& e) -> Maybe<T> {
return e;
}
}
#endif