Program Listing for File mpl.hpp

Return to documentation for file (rcppsw/mpl/mpl.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include "rcppsw/common/macros.hpp"
#include "rcppsw/rcppsw.hpp"
#include "rcppsw/mpl/detail/detector.hpp"

/*******************************************************************************
 * Macros
 ******************************************************************************/
#ifndef DOXYGEN_DOCUMENTATION_BUILD
#define RCPPSW_SFINAE_DECLDEF(...) \
  typename std::enable_if<__VA_ARGS__, int>::type = 0
#endif /* DOXYGEN_DOCUMENTATION_BUILD */

#ifndef DOXYGEN_DOCUMENTATION_BUILD
#define RCPPSW_SFINAE_DECL(...) \
  typename std::enable_if<__VA_ARGS__, int>::type = 0
#endif /* DOXYGEN_DOCUMENTATION_BUILD */

#ifndef DOXYGEN_DOCUMENTATION_BUILD
#define RCPPSW_SFINAE_DEF(...)                  \
  typename std::enable_if<__VA_ARGS__, int>::type
#endif /* DOXYGEN_DOCUMENTATION_BUILD */

#define RCPPSW_SFINAE_TYPE(...) typename std::enable_if<__VA_ARGS__>::value

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::mpl {

/*******************************************************************************
 * Trait Detection Templates
 ******************************************************************************/
struct no_such_trait {
  no_such_trait() = delete;
  ~no_such_trait() = delete;
  no_such_trait(no_such_trait const&) = delete;
  void operator=(no_such_trait const&) = delete;
};

template <template <class...> class TFuncDecltype, class... Args>
using is_detected =
    typename detail::detector<no_such_trait, void, TFuncDecltype, Args...>::value;

template <template <class...> class TFuncDecltype, class... Args>
using detected_t =
    typename detail::detector<no_such_trait, void, TFuncDecltype, Args...>::type;

template <class TFailType, template <class...> class TFuncDecltype, class... Args>
using detected_or = detail::detector<TFailType, void, TFuncDecltype, Args...>;

template <typename T, typename U, typename = void>
struct can_static_cast : std::false_type {};

template <typename T, typename U>
struct can_static_cast<T,
                       U,
                       std::void_t<decltype(static_cast<U>(std::declval<T>()))>>
    : std::true_type {};


template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

template<typename, typename = void>
struct is_complete_type : std::false_type {};

template<typename T>
struct is_complete_type<T, std::void_t<decltype(sizeof(T))>> : std::true_type {};

} /* namespace rcppsw::mpl */