Utils moved to uavcan/util/*

This commit is contained in:
Pavel Kirienko
2014-03-09 21:46:21 +04:00
parent 0aa76d71e3
commit ce618f6436
21 changed files with 20 additions and 23 deletions
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <cassert>
namespace uavcan
{
/**
* Usage:
* StaticAssert<expression>::check();
*/
template <bool Value>
struct StaticAssert;
template <>
struct StaticAssert<true>
{
static void check() { }
};
/**
* Usage:
* ShowIntegerAsError<integer_expression>::foobar();
*/
template<long N> struct ShowIntegerAsError;
/**
* Prevents copying when inherited
*/
class Noncopyable
{
Noncopyable(const Noncopyable&);
Noncopyable& operator=(const Noncopyable&);
protected:
Noncopyable() { }
};
/**
* Compile time conditions
*/
template<bool B, typename T = void>
struct EnableIf { };
template<typename T>
struct EnableIf<true, T> { typedef T Type; };
template<typename T, typename R = void>
struct EnableIfType { typedef R Type; };
template <bool Condition, typename TrueType, typename FalseType>
struct StaticIf;
template <typename TrueType, typename FalseType>
struct StaticIf<true, TrueType, FalseType>
{
typedef TrueType Result;
};
template <typename TrueType, typename FalseType>
struct StaticIf<false, TrueType, FalseType>
{
typedef FalseType Result;
};
/**
* Value types
*/
template<bool> struct BooleanType { };
typedef BooleanType<true> TrueType;
typedef BooleanType<false> FalseType;
/**
* Relations
*/
template <typename T1, typename T2>
class IsImplicitlyConvertibleFromTo
{
template <typename U> static U returner();
struct True_ { char x[2]; };
struct False_ { };
static True_ test(const T2 &);
static False_ test(...);
public:
enum { Result = sizeof(True_) == sizeof(IsImplicitlyConvertibleFromTo<T1, T2>::test(returner<T1>())) };
};
template <typename From, typename To>
struct TryImplicitCastImpl
{
static To impl(const From& from, const To&, TrueType) { return To(from); }
static To impl(const From&, const To& default_, FalseType) { return default_; }
};
template <typename To, typename From>
To try_implicit_cast(const From& from, const To& default_ = To())
{
return TryImplicitCastImpl<From, To>::impl(from, default_,
BooleanType<IsImplicitlyConvertibleFromTo<From, To>::Result>());
}
}
@@ -0,0 +1,148 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <cstdlib>
#include <uavcan/internal/fatal_error.hpp>
#include <uavcan/internal/impl_constants.hpp>
namespace uavcan
{
template <typename T>
class LazyConstructor
{
unsigned char data_[sizeof(T)] __attribute__((aligned(16))); // TODO: compiler-independent alignment
T* ptr_;
void ensureConstructed() const
{
if (!ptr_)
handleFatalError("LazyConstructor<T> is not constructed");
}
void ensureNotConstructed() const
{
if (ptr_)
handleFatalError("LazyConstructor<T> is already constructed");
}
template <typename U> struct ParamType { typedef const U& Type; };
template <typename U> struct ParamType<U&> { typedef U& Type; };
#if __cplusplus > 201100
template <typename U> struct ParamType<U&&> { typedef U&& Type; };
#endif
public:
LazyConstructor()
: ptr_(NULL)
{
std::fill(data_, data_ + sizeof(T), 0);
}
LazyConstructor(const LazyConstructor<T>& rhs)
: ptr_(NULL)
{
std::fill(data_, data_ + sizeof(T), 0);
if (rhs)
construct<const T&>(*rhs); // Invoke copy constructor
}
~LazyConstructor() { destroy(); }
LazyConstructor<T>& operator=(const LazyConstructor<T>& rhs)
{
destroy();
if (rhs)
construct<const T&>(*rhs); // Invoke copy constructor
return *this;
}
bool isConstructed() const { return ptr_ != NULL; }
operator T*() const { return ptr_; }
const T* operator->() const { ensureConstructed(); return ptr_; }
T* operator->() { ensureConstructed(); return ptr_; }
const T& operator*() const { ensureConstructed(); return *ptr_; }
T& operator*() { ensureConstructed(); return *ptr_; }
void destroy()
{
if (ptr_)
ptr_->~T();
ptr_ = NULL;
std::fill(data_, data_ + sizeof(T), 0);
}
void construct()
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T();
}
// MAX_ARGS = 6
// TEMPLATE = '''
// template <%s>
// void construct(%s)
// {
// ensureNotConstructed();
// ptr_ = new (static_cast<void*>(data_)) T(%s);
// }'''
// for nargs in range(1, MAX_ARGS + 1):
// nums = [(x + 1) for x in range(nargs)]
// l1 = ['typename P%d' % x for x in nums]
// l2 = ['typename ParamType<P%d>::Type p%d' % (x, x) for x in nums]
// l3 = ['p%d' % x for x in nums]
// print(TEMPLATE % (', '.join(l1), ', '.join(l2), ', '.join(l3)))
template <typename P1>
void construct(typename ParamType<P1>::Type p1)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1);
}
template <typename P1, typename P2>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2);
}
template <typename P1, typename P2, typename P3>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3);
}
template <typename P1, typename P2, typename P3, typename P4>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
typename ParamType<P4>::Type p4)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4);
}
template <typename P1, typename P2, typename P3, typename P4, typename P5>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5);
}
template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
void construct(typename ParamType<P1>::Type p1, typename ParamType<P2>::Type p2, typename ParamType<P3>::Type p3,
typename ParamType<P4>::Type p4, typename ParamType<P5>::Type p5, typename ParamType<P6>::Type p6)
{
ensureNotConstructed();
ptr_ = new (static_cast<void*>(data_)) T(p1, p2, p3, p4, p5, p6);
}
};
}
@@ -0,0 +1,63 @@
/*
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#pragma once
#include <uavcan/internal/fatal_error.hpp>
#include <uavcan/internal/impl_constants.hpp>
#include <uavcan/util/compile_time.hpp>
namespace uavcan
{
template <typename ObjectPtr, typename MemFunPtr>
class MethodBinder
{
ObjectPtr obj_;
MemFunPtr fun_;
void validateBeforeCall() const
{
if (!operator bool())
handleFatalError("Null method binder");
}
public:
MethodBinder()
: obj_()
, fun_()
{ }
MethodBinder(ObjectPtr o, MemFunPtr f)
: obj_(o)
, fun_(f)
{ }
operator bool() const
{
return try_implicit_cast<bool>(obj_, true) && try_implicit_cast<bool>(fun_, true);
}
void operator()()
{
validateBeforeCall();
(obj_->*fun_)();
}
template <typename Par1>
void operator()(Par1 p1)
{
validateBeforeCall();
(obj_->*fun_)(p1);
}
template <typename Par1, typename Par2>
void operator()(Par1 p1, Par2 p2)
{
validateBeforeCall();
(obj_->*fun_)(p1, p2);
}
};
}