Compile time implementation sorting

Sorting during compilation

  • I can barely understand what I saw on station b with a little knowledge of c + +

thinking

  • The implementation of Values puts (expands) the object type of the base class in the tuple. STD:: tuple < > is an aggregation class. It can mix different element types in the parameter package into one type. Sorting is done on the tuple
  1. Template class implementation judgment, template < bool, typename then, typename else > if

  2. It is encapsulated as a Compare function template class to Compare values of the same or different types,

    // Template class members in a template class
    template<typename T1> struct Less {
    	template<typename T2>  struct Apply {};
    };
    
  3. Through recursive derivation of type during compilation (in fact, this is traversal), and comparison with Compare, we get the extreme value of type STD:: tuple < >

    1. Write the recursive termination derivation of template
    2. Write the general situation of recursion,
  4. Since we can get the extremum of STD:: tuple < > and order, we must adjust the position to implement a template class that removes one element from the tuple

    Using STD:: tuple Fu cat() and findlimit < comp, STD:: tuple < > >

  5. Using findlimit < > and poplimit < > to find the smallest type (:: value) in a tuple, separate it from the tuple < > and recurse the remaining tuples,

  • In essence, we use the derivation of type, so we should pay attention to many details in the process of writing
#include <type_traits>
#include <tuple>
#include <iostream>

template<int ...values>
struct Values {
	// Convert values to types and expand them into tuple s
	using type = std::tuple<std::integral_constant<int,values>...>;
};

template<bool,typename Then,typename Else> struct If;

// Result state
template<typename Then,typename Else>
struct If<true,Then,Else> {
	using type = Then;
};

template<typename Then,typename Else>
struct If<false,Then,Else> {
	using type = Else;
};

template<typename T1>
struct Less {
	template<typename T2> struct Apply {
		using type = typename If<(T1::value < T2::value),T1,T2>::type;
	};
};

template<typename T1>
struct GE {
	template<typename T2> struct Apply {
		using type = typename If<(T1::value >= T2::value),T1,T2>::type;
	};
};

// Find the extremum in STD:: tuple < > by recursive comparison,
template<template <typename T1> class Comp, typename Tuples> struct FindLimit;
template<template <typename T1> class Comp, typename Head>
struct FindLimit<Comp,std::tuple<Head>> { // 
	using type = Head;
};
template<template<typename T1> class Comp,typename Head,typename ...Tails>
struct FindLimit<Comp,std::tuple<Head,Tails...>> {
	using type =typename Comp<Head>::template Apply<
		typename FindLimit<Comp,std::tuple<Tails...>>::type
		>::type;
};

//Pop extremum from std::tuple
template<typename Limit,typename ...Tuples> struct PopLimit;
// The tuple is empty. Now there is only one value without pop-up
template<typename Limit>
struct PopLimit<Limit,std::tuple<>> {
	// The results are as follows
	using type = std::tuple<>;
};
// Give the value (type) and all values to Pop
template<typename Limit,typename ...Others>
//Template parameter derivation found Limit from tuple
struct PopLimit<Limit,std::tuple<Limit,Others...>> {
	using type = std::tuple<Others...>;
};
// Not found from the first parameter in the current parameter package, continue to find
template<typename Limit,typename Head,typename ...Others>
struct PopLimit<Limit,std::tuple<Head,Others...>> {
	//using type = decltype(std::tuple_cat(std::tuple<Head>(),
	//			PopLimit<Limit,std::tuple<Others...>>::type));
	//using type = decltype(std::tuple_cat(std::tuple<Head>{},
	//(typename PopLimit<Limit,std::tuple<Others...>>::type){}));
	using type = decltype(std::tuple_cat(std::tuple<Head>{},
				typename PopLimit<Limit,std::tuple<Others...>>::type{}));
};

// sort
template<template <typename T1> class Comp,typename T> struct bSort;
// The type to be pushed in class Comp is template < typename T1 > class Comp
template<template <typename T1> class Comp> 
struct bSort<Comp,std::tuple<>> {
	using type = std::tuple<>;
};

template<template <typename T1> class Comp,typename ...values>
struct bSort<Comp,std::tuple<values...>> {
	// Find the extremum recursively
	using limit = typename FindLimit<Comp,std::tuple<values...>>::type;
	using others = typename PopLimit<limit,std::tuple<values...>>::type;
	using type = decltype(std::tuple_cat(std::tuple<limit>{},typename bSort<Comp,others>::type{}));

};

void test() {
	// They are all tuple.
	using lst_1_3 = Values<1,2,3>::type;
	using lst_1_2 = Values<1,2>::type;
	using lst_3_1 = Values<3,2,1>::type;
	using lst = Values<1,99,9,4,2,6,100>::type;
	using ans = Values<1,2,4,6,9,99,100>::type;

	using i1 = std::integral_constant<int,1>::type;
	using i2 = std::integral_constant<int,2>::type;
	using i3 = std::integral_constant<int,3>::type;

	// 1. Test If judgment or Less
	//static_assert(!std::is_same<If<(i1::value < i2::value),i1,i2>::type,i1>::value,"no problem");
	//static_assert(!std::is_same<Less<i2>::Apply<i3>::type,i2>::value,"i2 < i3");
//	if (std::is_same<If<(i1::value < i2::value),i1,i2>::type,i1>::value)
//		std::cout << "i1 < i2";
	
	// 2. Test the extremum found by compilation
	static_assert(!std::is_same<FindLimit<GE,lst>::type,i1>::value, "The minimum value is i1");
	
	// 3. Test sorting results
//	Static_assert (! STD:: is_same < bsort < less, lst >:: type, ans >:: value, "sorting succeeded");

}

int main(int argc,char *argv[]) {
	test();
    return 0;
}
226 original articles published, 10 praised, 9199 visited
Private letter follow

Tags: less

Posted on Wed, 05 Feb 2020 09:49:30 -0500 by Reaper0167