/* @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 concept bpu_node_concept = requires(BpuList bpulist) { typename BpuList::front_type; typename BpuList::rest_type; } && (native_bpu_concept && (std::is_integral_v) //&& (std::same_as // or nonempty_bpu_list_concept)) ); 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 : public std::true_type {}; /* non-void must satisfy bpu-list rules */ template struct bpu_list_traits { /* checks everything except BpuList::rest_type */ static constexpr bool _value1 = bpu_node_concept; static constexpr bool _value2 = bpu_list_traits::value; static constexpr bool value = (_value1 && _value2); }; // ---------------------------------------------------------------- template constexpr bool bpu_list_v = bpu_list_traits::value; } /* may want to rename this -> native_bpu_list */ template concept bpu_list_concept = detail::bpu_list_v; // ---------------------------------------------------------------- /* TODO: retire in favor of unit_concept? */ template concept dimension_concept = requires(Dimension dim) { typename Dimension::dim_type; typename Dimension::canon_type; } && (bpu_list_concept && bpu_list_concept ); } /*namespace unit*/ } /*namespace xo*/ /* end dimension_concept.hpp */