/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2012-2019 Danny Robson */ #pragma once #include "fwd.hpp" #include #include namespace cruft { /////////////////////////////////////////////////////////////////////// // operation traits template struct result { }; //------------------------------------------------------------------------- #define RESULT_T(ArgA,ArgB,ResultT) \ template < \ std::size_t S, \ typename ValueA,\ typename ValueB\ > struct result<\ ArgA,\ ArgB\ > {\ using type = ResultT>; \ }; #if 0 template < std::size_t S, typename ValueA, typename ValueB > struct result< srgba, srgba > { using type = srgba>; }; template struct result, vector> { using type = srgba; }; template struct result,srgba> { using type = srgba; }; template struct result,extent> { using type = extent; }; template struct result,vector> { using type = extent; }; template struct result, extent> { using type = point ; }; template struct result, vector> { using type = point ; }; template struct result,point> { using type = point ; }; template struct result,vector> { using type = vector; }; #endif RESULT_T(extent,extent,extent) RESULT_T(extent,vector,extent) RESULT_T(point,extent,point) RESULT_T(point,vector,point) RESULT_T(srgba,vector,srgba) RESULT_T(srgba,srgba,srgba) RESULT_T(vector,extent,extent) RESULT_T(vector,point,point) RESULT_T(vector,srgba,srgba) RESULT_T(vector,vector,vector) template < typename A, typename B > using result_t = typename result::type; /////////////////////////////////////////////////////////////////////////// template > struct has_result : public std::false_type {}; template struct has_result< CoordA, CoordB, std::void_t< result_t > > : public std::true_type {}; template constexpr auto has_result_v = has_result::value; //--------------------------------------------------------------------- template struct has_norm : public std::false_type { }; template struct has_norm> : public std::true_type { }; template constexpr auto has_norm_v = has_norm::value; //--------------------------------------------------------------------- template struct has_scalar_op : public std::false_type { }; template struct has_scalar_op> : public std::true_type { }; template struct has_scalar_op> : public std::true_type { }; template struct has_scalar_op> : public std::true_type { }; template struct has_scalar_op> : public std::true_type { }; template constexpr auto has_scalar_op_v = has_scalar_op::value; template struct is_coord : std::false_type { }; template struct is_coord : is_coord {}; template struct is_coord : is_coord {}; template struct is_coord> : std::true_type { }; template struct is_coord> : std::true_type { }; template struct is_coord> : std::true_type { }; template struct is_coord> : std::true_type { }; template constexpr bool is_coord_v = is_coord::value; /////////////////////////////////////////////////////////////////////////// template struct has_redim : std::false_type {}; //--------------------------------------------------------------------- template struct has_redim< point> : public std::true_type {}; template struct has_redim> : public std::true_type {}; template struct has_redim> : public std::true_type {}; //--------------------------------------------------------------------- template constexpr auto has_redim_v = has_redim::value; /////////////////////////////////////////////////////////////////////////// template struct redim_type {}; //--------------------------------------------------------------------- template struct redim_type> { template using type = point; }; template struct redim_type> { template using type = vector; }; template struct redim_type> { template using type = extent; }; //--------------------------------------------------------------------- template < typename Self, std::size_t S > using redim_t = typename redim_type::template type; /////////////////////////////////////////////////////////////////////////// template struct revalue_type {}; //------------------------------------------------------------------------- template struct revalue_type> { template using type = point; }; template struct revalue_type> { template using type = vector; }; template struct revalue_type> { template using type = extent; }; //------------------------------------------------------------------------- template using revalue_t = typename revalue_type::template type; /////////////////////////////////////////////////////////////////////////// template struct arity {}; //------------------------------------------------------------------------- template struct arity,void> > :std::integral_constant { }; //------------------------------------------------------------------------- template struct arity< T,std::enable_if_t,void> > :std::integral_constant { }; //------------------------------------------------------------------------- template constexpr auto arity_v = arity::value; /////////////////////////////////////////////////////////////////////////// template struct value_trait {}; //------------------------------------------------------------------------- template struct value_trait> { using value_type = T; }; template struct value_trait> { using value_type = T; }; template requires requires { typename ValueT::value_type; } struct value_trait { using value_type = typename ValueT::value_type; }; template requires std::is_arithmetic_v struct value_trait { using value_type = ValueT; }; //------------------------------------------------------------------------- template using value_trait_t = typename value_trait::value_type; } #include "../types/description.hpp" namespace cruft::types { template struct arity_trait< CoordT, std::enable_if_t< ::cruft::is_coord_v > > : public ::cruft::arity { }; }