Program Listing for File templateMeta.h

Return to documentation for file (src/misc/pv/templateMeta.h)

/*
 * Copyright information and license terms for this software can be
 * found in the file LICENSE that is included with the distribution
 */
#ifndef TEMPLATEMETA_H
#define TEMPLATEMETA_H

// gently nudge the compiler to inline our wrappers
// Warning: Only use this when the template body is *small*.
//          You have been warned!
#if defined(__MINGW32__)
# define FORCE_INLINE inline
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 402)
# define FORCE_INLINE __attribute__((always_inline)) inline
#elif defined(_MSC_VER)
# define FORCE_INLINE __forceinline
#else
# define FORCE_INLINE inline
#endif

namespace epics { namespace pvData {
namespace meta {

template<typename T> struct decorate_const { typedef const T type; };
template<typename T> struct decorate_const<const T> { typedef const T type; };

template<typename T> struct strip_const { typedef T type; };
template<typename T> struct strip_const<const T> { typedef T type; };

template<typename A, typename B, typename R = void>
struct not_same_type {typedef R type;};
template<typename A>
struct not_same_type<A,A> {};

template<typename A, typename B, class R = void> struct same_root {};
template<typename T, class R> struct same_root<T,T,R> { typedef R type; };
template<typename T, class R> struct same_root<const T,T,R> { typedef R type; };
template<typename T, class R> struct same_root<T,const T,R> { typedef R type; };

namespace detail {
    struct _const_yes {};
    struct _const_no {};
    template<typename T> struct _has_const { typedef _const_no type; };
    template<typename T> struct _has_const<const T> { typedef _const_yes type; };

    template<typename A, typename B, class R = void>  struct _same_type {};
    template<typename T, class R> struct _same_type<T,T,R> { typedef R type; };
} // namespace detail

template<typename A, typename B, class R = void>
struct same_const :
        public detail::_same_type<typename detail::_has_const<A>::type,
                                  typename detail::_has_const<B>::type,
                                  R>
{};

template<typename T, class R = void> struct is_void {};
template<class R> struct is_void<void,R> { typedef R type; };
template<class R> struct is_void<const void,R> { typedef R type; };

template<typename T, class R = void> struct is_not_void { typedef R type; };
template<> struct is_not_void<void> {};
template<> struct is_not_void<const void> {};

template<typename A, typename B, class EnableA = void, class EnableB = void, class R = void>
struct _and {};
template<typename A, typename B, class R>
struct _and<A,B, typename A::type, typename B::type, R> { typedef R type; };

template<typename T>
struct arg_type {typedef const T& type;};
#define SIMPLE_ARG_TYPE(TYPE) template<> struct arg_type<TYPE> { typedef TYPE type; };
SIMPLE_ARG_TYPE(bool)
SIMPLE_ARG_TYPE(char)
SIMPLE_ARG_TYPE(signed char)
SIMPLE_ARG_TYPE(unsigned char)
SIMPLE_ARG_TYPE(short)
SIMPLE_ARG_TYPE(unsigned short)
SIMPLE_ARG_TYPE(int)
SIMPLE_ARG_TYPE(unsigned int)
SIMPLE_ARG_TYPE(long)
SIMPLE_ARG_TYPE(unsigned long)
SIMPLE_ARG_TYPE(long long)
SIMPLE_ARG_TYPE(unsigned long long)
SIMPLE_ARG_TYPE(float)
SIMPLE_ARG_TYPE(double)
SIMPLE_ARG_TYPE(long double)
#undef SIMPLE_ARG_TYPE

}}}

#endif // TEMPLATEMETA_H