xo-expression2/include/xo/unit/dimension_concept.hpp

88 lines
3.2 KiB
C++

/* @file dimension_concept.hpp */
#pragma once
#include "native_bpu_concept.hpp"
namespace xo {
namespace unit {
/** checks most non-empty BPU (basis power unit) node types;
* cannot check BpuList::rest_type, because concept definition
* can't (as of c++23) be recursive.
*
* As workaround, revert to type traits, seend below.
**/
template <typename BpuList>
concept bpu_node_concept = requires(BpuList bpulist)
{
typename BpuList::front_type;
typename BpuList::rest_type;
}
&& (native_bpu_concept<typename BpuList::front_type>
&& (std::is_integral_v<decltype(BpuList::n_dimension)>)
//&& (std::same_as<typename BpuList::front_type, void>
// or nonempty_bpu_list_concept<BpuList::rest_type>))
);
namespace detail {
// ------------------------------------------------------------
/* check for 'list of native_bpu_concept'.
* Need type trait for this, to access partial specializations
*/
template < typename BpuList >
struct bpu_list_traits;
/* void (representing empty list) is fine */
template <>
struct bpu_list_traits<void> : public std::true_type {};
/* non-void must satisfy bpu-list rules */
template <typename BpuList>
struct bpu_list_traits {
/* checks everything except BpuList::rest_type */
static constexpr bool _value1 = bpu_node_concept<BpuList>;
static constexpr bool _value2 = bpu_list_traits<typename BpuList::rest_type>::value;
static constexpr bool value = (_value1 && _value2);
};
// ----------------------------------------------------------------
template <typename BpuList>
constexpr bool bpu_list_v = bpu_list_traits<BpuList>::value;
}
/* may want to rename this -> native_bpu_list */
template <typename BpuList>
concept bpu_list_concept = detail::bpu_list_v<BpuList>;
// ----------------------------------------------------------------
/* TODO: retire in favor of unit_concept? */
template <typename Dimension>
concept dimension_concept = requires(Dimension dim)
{
typename Dimension::dim_type;
typename Dimension::canon_type;
}
&& (bpu_list_concept<typename Dimension::dim_type>
&& bpu_list_concept<typename Dimension::canon_type>
);
// ----------------------------------------------------------------
template <typename Unit>
concept unit_concept = requires(Unit unit)
{
typename Unit::scalefactor_type;
typename Unit::dim_type;
typename Unit::canon_type;
}
&& (ratio_concept<typename Unit::scalefactor_type>
&& bpu_list_concept<typename Unit::dim_type>
&& bpu_list_concept<typename Unit::canon_type>);
} /*namespace unit*/
} /*namespace xo*/
/* end dimension_concept.hpp */