c++ - Swapping two elements in a template type list. Seeking most efficient algorithm -


swap<t, position1, position2, pack>::type, pack consists of elements of type t, return pack elements in position1 , position2 swapped. solution below not efficient. there should way accomplish cleanly, without visiting element twice. can think of it?

// replaceelement replaces element of pack specified position (0 being first position) specified value. template <typename t, std::size_t, std::size_t, t, typename, typename> struct replaceelementhelper;  template <typename t, std::size_t position, std::size_t currentposition, t newvalue, template <t...> class z, t first, t... rest, t... accumulated> struct replaceelementhelper<t, position, currentposition, newvalue, z<first, rest...>, z<accumulated...>>     : replaceelementhelper<t, position, currentposition + 1, newvalue, z<rest...>, z<accumulated..., first>> {};  template <typename t, std::size_t position, t newvalue, template <t...> class z, t first, t... rest, t... accumulated> struct replaceelementhelper<t, position, position, newvalue, z<first, rest...>, z<accumulated...>> {     using type = z<accumulated..., newvalue, rest...>; };  template <typename t, std::size_t, t, typename> struct replaceelement;  template <typename t, std::size_t position, t newvalue, template <t...> class z, t... ts> struct replaceelement<t, position, newvalue, z<ts...>> : replaceelementhelper<t, position, 0, newvalue, z<ts...>, z<>> {     static_assert (position < sizeof...(ts), "error!  invalid position replaceelement."); };  // swapping 2 elements of specified positions in pack. template <typename, std::size_t, std::size_t, typename> struct swap;  template <typename t, std::size_t position1, std::size_t position2, template <t...> class z, t... ts> struct swap<t, position1, position2, z<ts...>> {     static constexpr t a[sizeof...(ts)] = {ts...};     using type = typename replaceelement<t, position2, a[position1], typename replaceelement<t, position1, a[position2], z<ts...>>::type>::type; }; 

you can tell solution visits all elements before position1 (or position2) twice. there should no need that. know there must solution avoids this, can't think of it.

provided value_pack defined like

template <typename t, t... v> struct value_pack {     static constexpr t array[] {v...};     static constexpr std::size_t len = sizeof...(v);     using type = value_pack; }; template <typename t, t... v> constexpr t value_pack<t, v...>::array[]; 

then solution in c++14 looks this:

template <typename t, std::size_t p1, std::size_t p2,           typename pack,           typename=std::make_index_sequence<pack::len>> struct swap; template <typename t, std::size_t p1, std::size_t p2,           typename pack, std::size_t...indices> struct swap<t, p1, p2, pack, std::index_sequence<indices...>> :     value_pack<t,  pack::array[indices==p1? p2 : indices==p2? p1 : indices]...> {}; 

demo. if c++14 standard library not available, can implement make_index_sequence - numerous examples scattered across so.


Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -