/* * 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-2017 Danny Robson */ #ifndef CRUFT_UTIL_COORD_TRAITS_HPP #define CRUFT_UTIL_COORD_TRAITS_HPP #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<_S,T>; }; template struct redim_type> { template using type = vector<_S,T>; }; template struct redim_type> { template using type = extent<_S,T>; }; //--------------------------------------------------------------------- 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; } #endif