82 lines
1.9 KiB
C++
82 lines
1.9 KiB
C++
#ifndef ALSK_ALSK_SKELETON_TRAITS_H
|
|
#define ALSK_ALSK_SKELETON_TRAITS_H
|
|
|
|
#include <type_traits>
|
|
|
|
#include "tags.h"
|
|
|
|
namespace alsk {
|
|
|
|
/**
|
|
* @brief true if the given type is a Skeleton
|
|
*/
|
|
template<typename T, typename = void>
|
|
struct IsSkeleton: std::false_type {};
|
|
|
|
template<typename T>
|
|
struct IsSkeleton<T, std::enable_if_t<std::is_same<typename std::decay_t<T>::IsSkeleton, tag::SkeletonTag>{}>>: std::true_type {};
|
|
|
|
template<typename T>
|
|
constexpr bool isSkeleton = IsSkeleton<T>::value;
|
|
|
|
|
|
/**
|
|
* @brief class to determine a skeleton traits
|
|
* @param serial true if the skeleton cannot be run in parallel
|
|
*/
|
|
template<template<typename...> class S>
|
|
struct SkeletonTraits {
|
|
static constexpr bool serial = true;
|
|
};
|
|
|
|
template<typename> struct SkeletonTraitsTImpl;
|
|
|
|
template<template<typename...> class S, typename... Ts>
|
|
struct SkeletonTraitsTImpl<S<Ts...>> {
|
|
using type = SkeletonTraits<S>;
|
|
};
|
|
|
|
template<typename S>
|
|
using SkeletonTraitsT = typename SkeletonTraitsTImpl<std::decay_t<S>>::type;
|
|
|
|
/**
|
|
* @brief function to dynamically traverse a skeleton tree
|
|
*
|
|
* by default, do nothing (typically muscle case)
|
|
*/
|
|
template<typename Muscle, typename F,
|
|
std::enable_if_t<not isSkeleton<std::decay_t<Muscle>>>* = nullptr
|
|
>
|
|
void skeletonTraversal(Muscle&&, F&&) {}
|
|
|
|
/**
|
|
* @brief template to specialize to implement a bone
|
|
*/
|
|
template<typename Skeleton, typename Tag, typename Executor, typename Context> struct Impl;
|
|
|
|
/**
|
|
* @brief template to specialize to define how to traverse a bone
|
|
*/
|
|
template<typename Skeleton, typename=void>
|
|
struct SkeletonTraversal;
|
|
|
|
/**
|
|
* @brief returns steps between two instances of the skeleton
|
|
*/
|
|
template<typename Skeleton, std::enable_if_t<isSkeleton<Skeleton>>* = nullptr>
|
|
constexpr std::size_t skeletonStep(Skeleton const& s) {
|
|
return s.step;
|
|
}
|
|
|
|
/**
|
|
* @brief returns 0
|
|
*/
|
|
template<typename Skeleton, std::enable_if_t<not isSkeleton<Skeleton>>* = nullptr>
|
|
constexpr std::size_t skeletonStep(Skeleton const&) {
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|