templates - C++ Multiple sets of variadic function arguments -


i'm trying optimize low level , used function in compute intensive application. let's have following type :

template<typename t, int n>  class elem {...}; 

i'd write function called such :

template<typename t, int n> void func(const elem<t, n> & ... /*n elements*/, elem<t, n> & ... /* n elements*/) 

i'm looking approach can sure compilers able remove temporary introduced function signature.

the elements typically elements taken different places of vector/array. e.g. :

elem<float, 3> inputs[10]; elem<float, 3> outputs[10]; ... func(input[4], input[2], input[9], output[6], output[8], output[1]); 

the answer might initializer lists fear might have overhead...

nb : indirection indexes above compile-time computed function , in short ranges.


edit

in fact, i'd :

template<typename... t, int n> void func(const elem<t, n>&... inputs, const elem<t, n>&... outputs) {   static_assert(sizeof...(inputs) == n, "invalid number of arguments");   static_assert(sizeof...(outputs) == n, "invalid number of arguments");   static_assert(std::is_same<std::integral_constant<int n>...>::value, "invalid arguments"); } 

but can't have code compile on vs2017. answer can c++17.

i'd write function called such :

template<typename t, int n> void func(const elem<t, n> & ... /*n elements*/,            elem<t, n> & ... /* n elements*/) 

as far know, ask isn't easy express available language.

the best can imagine, write func() function follows

template <typename ... es> typename std::enable_if<checkelems<es...>::value>::type    func (es & ... es)  {    using type = typename checkelems<es ...>::type;   // former t     constexpr std::size_t num { sizeof...(es) >> 1 }; // former n     // ...  } 

where func() receives list (es & ... es) of arguments , function sfinae enabled if relative list of types (es ...) satisfy list of requirements implemented in custom type-traits checkelems (see following example).

so following checkelems check that:

  • there @ least argument type
  • the first argument in form elem<t, n> const
  • the number of argument type 2 * n
  • the first n types equal each other
  • the following n types equal each other
  • adding const following n types, equal first n
  • without adding const, following n types different first n

inside func() you're able use type (see example), t type in elem<t, n>, , num, n value in elem<t, n>.

you can checks don't know if it's idea.

a compilable example

#include <tuple> #include <type_traits>  template<typename t, std::size_t n>  struct elem {};  template <typename> struct extrelem;  template <typename t, std::size_t n> struct extrelem<elem<t, n> const>  {    using type = t;     static constexpr std::size_t num { n };  };  template <std::size_t, std::size_t, typename ...> struct extrtypes;  template <std::size_t skip, std::size_t num, typename ... es, typename t0,           typename ... ts> struct extrtypes<skip, num, std::tuple<es...>, t0, ts...>  { using type = typename extrtypes<       skip-1u, num, std::tuple<es...>, ts...>::type; };  template <std::size_t num, typename ... es, typename t0, typename ... ts> struct extrtypes<0u, num, std::tuple<es...>, t0, ts...>  { using type = typename extrtypes<       0u, num-1u, std::tuple<es..., t0>, ts...>::type; };  template <typename ... es, typename t0, typename ... ts> struct extrtypes<0u, 0u, std::tuple<es...>, t0, ts...>  { using type = std::tuple<es...>; };  template <typename ... es> struct extrtypes<0u, 0u, std::tuple<es...>>  { using type = std::tuple<es...>; };  template <typename> struct sameconttypes : public std::false_type  { };  template <template <typename ...> class c, typename t0, typename ... ts> struct sameconttypes<c<t0, ts...>>    : public std::is_same<c<t0, ts...>, c<ts..., t0>>  { };  template <typename e0, typename ... es> struct checkelems  {    static constexpr std::size_t num { extrelem<e0>::num };     using type = typename extrelem<e0>::type;    using lt1 = typename extrtypes<0u, num, std::tuple<>, e0, es...>::type;    using lt2 = typename extrtypes<num, num, std::tuple<>, e0, es...>::type;     static constexpr bool value {          ( (num << 1) == 1u + sizeof...(es) )       && sameconttypes<lt1>::value       && sameconttypes<lt2>::value       && (true == std::is_same<e0,              typename std::tuple_element<0u, lt2>::type const>::value)       && (false == std::is_same<e0,              typename std::tuple_element<0u, lt2>::type>::value) };  };  template <typename ... es> typename std::enable_if<checkelems<es...>::value>::type    func (es & ... es)  {    using type = typename checkelems<es ...>::type;   // former t     constexpr std::size_t num { sizeof...(es) >> 1 }; // former n     // ...  }  int main()  {    elem<int, 3>        ei3;    elem<int, 4>        ei4;    elem<int, 3> const  eci3;    elem<int, 4> const  eci4;     func(eci3, eci3, eci3, ei3, ei3, ei3);    // compile    //func(eci3, eci3, eci3, ei3, eci3, ei3); // compilation error    //func(eci3, eci3, eci3, ei3, ei3, ei4); // compilation error    //func(eci3, eci3, eci4, ei3, ei3, ei3); // compilation error    //func(eci4, eci4, eci4, ei4, ei4, ei4); // compilation error    //func(eci4, eci4, eci4, eci4, ei4, ei4, ei4); // compilation error    func(eci4, eci4, eci4, eci4, ei4, ei4, ei4, ei4); // compile  } 

Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -