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