mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-26 16:53:34 +08:00
Utils moved to uavcan/util/*
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user