Determining if two packs are permutations of each other during compile-time

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
1












Often we need to find out if two tuples, or two packs in general, are the same as each other up to permutation. If there are no repeat types, then implementing is_permutation_no_repeats is quite straightforward. For example, simply remove each type in the first pack from the second pack and check if the second pack becomes empty or not. If the two packs have repeated types, then simply group those repeated types into num_types<T, Count>, where Count is the number of times T occurs in the pack. Then we've reduced the two packs into packs of num_types<T, Count>s types, and thus have no repeat types any more, and then is_permutation_no_repeats can be invoked. Here is my implementation and test:



#include <type_traits>
#include <utility>

namespace utilities
template <typename T, typename Pack, typename... Ts> struct remove_first_found;

template <typename T, template <typename...> class P, typename... Ts>
struct remove_first_found<T, P<>, Ts...>
using type = P<Ts...>; // T was never found.
;

template <typename T, template <typename...> class P, typename... Rest, typename... Ts>
struct remove_first_found<T, P<T, Rest...>, Ts...>
using type = P<Ts..., Rest...>; // First T found and removed.
;

template <typename T, template <typename...> class P, typename First, typename... Rest, typename... Ts>
struct remove_first_found<T, P<First, Rest...>, Ts...> : remove_first_found<T, P<Rest...>, Ts..., First> ;


template <typename T, std::size_t Count> struct num_types;

template <typename T, typename Pack, std::size_t Count, typename... Ts> struct get_num_types;

template <typename T, template <typename...> class P, std::size_t Count, typename... Ts>
struct get_num_types<T, P<>, Count, Ts...>
using type = num_types<T, Count>;
using remaining = P<Ts...>;
;

template <typename T, template <typename...> class P, typename First, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<First, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count, Ts..., First> ;

template <typename T, template <typename...> class P, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<T, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count + 1, Ts...> ;

template <typename Pack, typename... NumTypes> struct count_types;

template <template <typename...> class P, typename... NumTypes>
struct count_types<P<>, NumTypes...>
using type = P<NumTypes...>;
;

template <template <typename...> class P, typename First, typename... Rest, typename... NumTypes>
struct count_types<P<First, Rest...>, NumTypes...>
using meta = get_num_types<First, P<Rest...>, 1>;
using type = typename count_types<typename meta::remaining, NumTypes..., typename meta::type>::type;
;

template <typename Pack1, typename Pack2>
struct is_permutation_no_repeats : std::false_type ;

template <template <typename...> class P, template <typename...> class Q>
struct is_permutation_no_repeats<P<>, Q<>> : std::true_type ;

template <template <typename...> class P, typename First, typename... Rest, typename Pack2>
struct is_permutation_no_repeats<P<First, Rest...>, Pack2>
using meta = typename utilities::remove_first_found<First, Pack2>::type;
static constexpr bool value = std::is_same_v<meta, Pack2> ? false : is_permutation_no_repeats<P<Rest...>, meta>::value;
;

template <typename Pack1, typename Pack2>
struct is_permutation : is_permutation_no_repeats<typename count_types<Pack1>::type, typename count_types<Pack2>::type> ;

template <typename Pack1, typename Pack2>
constexpr bool is_permutation_v = is_permutation<Pack1, Pack2>::value;

// Testing
template <typename...> struct P;
template <typename...> struct Q;

int main()
static_assert(std::is_same_v<
count_types<P<int, char, long, int, bool, char, bool, int, double, int, bool>>::type,
P<num_types<int, 4>, num_types<char, 2>, num_types<long, 1>, num_types<bool, 3>, num_types<double, 1>>
>);

static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<int, char, long, int, bool, char, bool, int, double, int, bool>>); // Identical contents in the two packs.
static_assert(is_permutation_v<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>); // Permutation with no repeats types.
static_assert(is_permutation_no_repeats<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>::value);
static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long, double>>); // Permutations with repeat types.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, float, int, char, int, int, bool, char, long, double>>); // Second pack has float when the first pack does not.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long>>); // Second pack is one type less than the first pack.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, double, long, double>>); // Second pack 2 doubles instead of 1 and 1 char instead of 2.







share|improve this question

















  • 1




    Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
    – user8426627
    Jan 25 at 0:12











  • @user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
    – Martin York
    Jan 25 at 18:06

















up vote
3
down vote

favorite
1












Often we need to find out if two tuples, or two packs in general, are the same as each other up to permutation. If there are no repeat types, then implementing is_permutation_no_repeats is quite straightforward. For example, simply remove each type in the first pack from the second pack and check if the second pack becomes empty or not. If the two packs have repeated types, then simply group those repeated types into num_types<T, Count>, where Count is the number of times T occurs in the pack. Then we've reduced the two packs into packs of num_types<T, Count>s types, and thus have no repeat types any more, and then is_permutation_no_repeats can be invoked. Here is my implementation and test:



#include <type_traits>
#include <utility>

namespace utilities
template <typename T, typename Pack, typename... Ts> struct remove_first_found;

template <typename T, template <typename...> class P, typename... Ts>
struct remove_first_found<T, P<>, Ts...>
using type = P<Ts...>; // T was never found.
;

template <typename T, template <typename...> class P, typename... Rest, typename... Ts>
struct remove_first_found<T, P<T, Rest...>, Ts...>
using type = P<Ts..., Rest...>; // First T found and removed.
;

template <typename T, template <typename...> class P, typename First, typename... Rest, typename... Ts>
struct remove_first_found<T, P<First, Rest...>, Ts...> : remove_first_found<T, P<Rest...>, Ts..., First> ;


template <typename T, std::size_t Count> struct num_types;

template <typename T, typename Pack, std::size_t Count, typename... Ts> struct get_num_types;

template <typename T, template <typename...> class P, std::size_t Count, typename... Ts>
struct get_num_types<T, P<>, Count, Ts...>
using type = num_types<T, Count>;
using remaining = P<Ts...>;
;

template <typename T, template <typename...> class P, typename First, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<First, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count, Ts..., First> ;

template <typename T, template <typename...> class P, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<T, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count + 1, Ts...> ;

template <typename Pack, typename... NumTypes> struct count_types;

template <template <typename...> class P, typename... NumTypes>
struct count_types<P<>, NumTypes...>
using type = P<NumTypes...>;
;

template <template <typename...> class P, typename First, typename... Rest, typename... NumTypes>
struct count_types<P<First, Rest...>, NumTypes...>
using meta = get_num_types<First, P<Rest...>, 1>;
using type = typename count_types<typename meta::remaining, NumTypes..., typename meta::type>::type;
;

template <typename Pack1, typename Pack2>
struct is_permutation_no_repeats : std::false_type ;

template <template <typename...> class P, template <typename...> class Q>
struct is_permutation_no_repeats<P<>, Q<>> : std::true_type ;

template <template <typename...> class P, typename First, typename... Rest, typename Pack2>
struct is_permutation_no_repeats<P<First, Rest...>, Pack2>
using meta = typename utilities::remove_first_found<First, Pack2>::type;
static constexpr bool value = std::is_same_v<meta, Pack2> ? false : is_permutation_no_repeats<P<Rest...>, meta>::value;
;

template <typename Pack1, typename Pack2>
struct is_permutation : is_permutation_no_repeats<typename count_types<Pack1>::type, typename count_types<Pack2>::type> ;

template <typename Pack1, typename Pack2>
constexpr bool is_permutation_v = is_permutation<Pack1, Pack2>::value;

// Testing
template <typename...> struct P;
template <typename...> struct Q;

int main()
static_assert(std::is_same_v<
count_types<P<int, char, long, int, bool, char, bool, int, double, int, bool>>::type,
P<num_types<int, 4>, num_types<char, 2>, num_types<long, 1>, num_types<bool, 3>, num_types<double, 1>>
>);

static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<int, char, long, int, bool, char, bool, int, double, int, bool>>); // Identical contents in the two packs.
static_assert(is_permutation_v<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>); // Permutation with no repeats types.
static_assert(is_permutation_no_repeats<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>::value);
static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long, double>>); // Permutations with repeat types.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, float, int, char, int, int, bool, char, long, double>>); // Second pack has float when the first pack does not.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long>>); // Second pack is one type less than the first pack.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, double, long, double>>); // Second pack 2 doubles instead of 1 and 1 char instead of 2.







share|improve this question

















  • 1




    Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
    – user8426627
    Jan 25 at 0:12











  • @user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
    – Martin York
    Jan 25 at 18:06













up vote
3
down vote

favorite
1









up vote
3
down vote

favorite
1






1





Often we need to find out if two tuples, or two packs in general, are the same as each other up to permutation. If there are no repeat types, then implementing is_permutation_no_repeats is quite straightforward. For example, simply remove each type in the first pack from the second pack and check if the second pack becomes empty or not. If the two packs have repeated types, then simply group those repeated types into num_types<T, Count>, where Count is the number of times T occurs in the pack. Then we've reduced the two packs into packs of num_types<T, Count>s types, and thus have no repeat types any more, and then is_permutation_no_repeats can be invoked. Here is my implementation and test:



#include <type_traits>
#include <utility>

namespace utilities
template <typename T, typename Pack, typename... Ts> struct remove_first_found;

template <typename T, template <typename...> class P, typename... Ts>
struct remove_first_found<T, P<>, Ts...>
using type = P<Ts...>; // T was never found.
;

template <typename T, template <typename...> class P, typename... Rest, typename... Ts>
struct remove_first_found<T, P<T, Rest...>, Ts...>
using type = P<Ts..., Rest...>; // First T found and removed.
;

template <typename T, template <typename...> class P, typename First, typename... Rest, typename... Ts>
struct remove_first_found<T, P<First, Rest...>, Ts...> : remove_first_found<T, P<Rest...>, Ts..., First> ;


template <typename T, std::size_t Count> struct num_types;

template <typename T, typename Pack, std::size_t Count, typename... Ts> struct get_num_types;

template <typename T, template <typename...> class P, std::size_t Count, typename... Ts>
struct get_num_types<T, P<>, Count, Ts...>
using type = num_types<T, Count>;
using remaining = P<Ts...>;
;

template <typename T, template <typename...> class P, typename First, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<First, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count, Ts..., First> ;

template <typename T, template <typename...> class P, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<T, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count + 1, Ts...> ;

template <typename Pack, typename... NumTypes> struct count_types;

template <template <typename...> class P, typename... NumTypes>
struct count_types<P<>, NumTypes...>
using type = P<NumTypes...>;
;

template <template <typename...> class P, typename First, typename... Rest, typename... NumTypes>
struct count_types<P<First, Rest...>, NumTypes...>
using meta = get_num_types<First, P<Rest...>, 1>;
using type = typename count_types<typename meta::remaining, NumTypes..., typename meta::type>::type;
;

template <typename Pack1, typename Pack2>
struct is_permutation_no_repeats : std::false_type ;

template <template <typename...> class P, template <typename...> class Q>
struct is_permutation_no_repeats<P<>, Q<>> : std::true_type ;

template <template <typename...> class P, typename First, typename... Rest, typename Pack2>
struct is_permutation_no_repeats<P<First, Rest...>, Pack2>
using meta = typename utilities::remove_first_found<First, Pack2>::type;
static constexpr bool value = std::is_same_v<meta, Pack2> ? false : is_permutation_no_repeats<P<Rest...>, meta>::value;
;

template <typename Pack1, typename Pack2>
struct is_permutation : is_permutation_no_repeats<typename count_types<Pack1>::type, typename count_types<Pack2>::type> ;

template <typename Pack1, typename Pack2>
constexpr bool is_permutation_v = is_permutation<Pack1, Pack2>::value;

// Testing
template <typename...> struct P;
template <typename...> struct Q;

int main()
static_assert(std::is_same_v<
count_types<P<int, char, long, int, bool, char, bool, int, double, int, bool>>::type,
P<num_types<int, 4>, num_types<char, 2>, num_types<long, 1>, num_types<bool, 3>, num_types<double, 1>>
>);

static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<int, char, long, int, bool, char, bool, int, double, int, bool>>); // Identical contents in the two packs.
static_assert(is_permutation_v<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>); // Permutation with no repeats types.
static_assert(is_permutation_no_repeats<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>::value);
static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long, double>>); // Permutations with repeat types.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, float, int, char, int, int, bool, char, long, double>>); // Second pack has float when the first pack does not.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long>>); // Second pack is one type less than the first pack.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, double, long, double>>); // Second pack 2 doubles instead of 1 and 1 char instead of 2.







share|improve this question













Often we need to find out if two tuples, or two packs in general, are the same as each other up to permutation. If there are no repeat types, then implementing is_permutation_no_repeats is quite straightforward. For example, simply remove each type in the first pack from the second pack and check if the second pack becomes empty or not. If the two packs have repeated types, then simply group those repeated types into num_types<T, Count>, where Count is the number of times T occurs in the pack. Then we've reduced the two packs into packs of num_types<T, Count>s types, and thus have no repeat types any more, and then is_permutation_no_repeats can be invoked. Here is my implementation and test:



#include <type_traits>
#include <utility>

namespace utilities
template <typename T, typename Pack, typename... Ts> struct remove_first_found;

template <typename T, template <typename...> class P, typename... Ts>
struct remove_first_found<T, P<>, Ts...>
using type = P<Ts...>; // T was never found.
;

template <typename T, template <typename...> class P, typename... Rest, typename... Ts>
struct remove_first_found<T, P<T, Rest...>, Ts...>
using type = P<Ts..., Rest...>; // First T found and removed.
;

template <typename T, template <typename...> class P, typename First, typename... Rest, typename... Ts>
struct remove_first_found<T, P<First, Rest...>, Ts...> : remove_first_found<T, P<Rest...>, Ts..., First> ;


template <typename T, std::size_t Count> struct num_types;

template <typename T, typename Pack, std::size_t Count, typename... Ts> struct get_num_types;

template <typename T, template <typename...> class P, std::size_t Count, typename... Ts>
struct get_num_types<T, P<>, Count, Ts...>
using type = num_types<T, Count>;
using remaining = P<Ts...>;
;

template <typename T, template <typename...> class P, typename First, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<First, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count, Ts..., First> ;

template <typename T, template <typename...> class P, typename... Rest, std::size_t Count, typename... Ts>
struct get_num_types<T, P<T, Rest...>, Count, Ts...> : get_num_types<T, P<Rest...>, Count + 1, Ts...> ;

template <typename Pack, typename... NumTypes> struct count_types;

template <template <typename...> class P, typename... NumTypes>
struct count_types<P<>, NumTypes...>
using type = P<NumTypes...>;
;

template <template <typename...> class P, typename First, typename... Rest, typename... NumTypes>
struct count_types<P<First, Rest...>, NumTypes...>
using meta = get_num_types<First, P<Rest...>, 1>;
using type = typename count_types<typename meta::remaining, NumTypes..., typename meta::type>::type;
;

template <typename Pack1, typename Pack2>
struct is_permutation_no_repeats : std::false_type ;

template <template <typename...> class P, template <typename...> class Q>
struct is_permutation_no_repeats<P<>, Q<>> : std::true_type ;

template <template <typename...> class P, typename First, typename... Rest, typename Pack2>
struct is_permutation_no_repeats<P<First, Rest...>, Pack2>
using meta = typename utilities::remove_first_found<First, Pack2>::type;
static constexpr bool value = std::is_same_v<meta, Pack2> ? false : is_permutation_no_repeats<P<Rest...>, meta>::value;
;

template <typename Pack1, typename Pack2>
struct is_permutation : is_permutation_no_repeats<typename count_types<Pack1>::type, typename count_types<Pack2>::type> ;

template <typename Pack1, typename Pack2>
constexpr bool is_permutation_v = is_permutation<Pack1, Pack2>::value;

// Testing
template <typename...> struct P;
template <typename...> struct Q;

int main()
static_assert(std::is_same_v<
count_types<P<int, char, long, int, bool, char, bool, int, double, int, bool>>::type,
P<num_types<int, 4>, num_types<char, 2>, num_types<long, 1>, num_types<bool, 3>, num_types<double, 1>>
>);

static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<int, char, long, int, bool, char, bool, int, double, int, bool>>); // Identical contents in the two packs.
static_assert(is_permutation_v<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>); // Permutation with no repeats types.
static_assert(is_permutation_no_repeats<P<int, char, long, bool, double>,
Q<double, bool, int, long, char>>::value);
static_assert(is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long, double>>); // Permutations with repeat types.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, float, int, char, int, int, bool, char, long, double>>); // Second pack has float when the first pack does not.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, char, long>>); // Second pack is one type less than the first pack.
static_assert(!is_permutation_v<P<int, char, long, int, bool, char, bool, int, double, int, bool>,
Q<bool, int, bool, int, char, int, int, bool, double, long, double>>); // Second pack 2 doubles instead of 1 and 1 char instead of 2.









share|improve this question












share|improve this question




share|improve this question








edited Jan 25 at 1:37









200_success

123k14143401




123k14143401









asked Jan 24 at 23:33









prestokeys

572317




572317







  • 1




    Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
    – user8426627
    Jan 25 at 0:12











  • @user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
    – Martin York
    Jan 25 at 18:06













  • 1




    Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
    – user8426627
    Jan 25 at 0:12











  • @user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
    – Martin York
    Jan 25 at 18:06








1




1




Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
– user8426627
Jan 25 at 0:12





Ok, nice example of building Prolog with templates. Just tell me the example when you need that in real project and what you will do after having the knoledge about "permutations". Cause "slightly" better would be define the order of types in template, so other people, and you after some time would not have headacke about what parameter is on what position. With the thing above, you can heal the wrong order only of different types.
– user8426627
Jan 25 at 0:12













@user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
– Martin York
Jan 25 at 18:06





@user8426627 I believe Scott Meyers did something similar when he was adding concepts to the language. This kind of stuff is useful when building library features that provide extension like features to the language (like boost::MPL or feature like that). It may not be needed by an external user of the library but to provide internal consistency within the library it is very useful.
– Martin York
Jan 25 at 18:06
















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185924%2fdetermining-if-two-packs-are-permutations-of-each-other-during-compile-time%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185924%2fdetermining-if-two-packs-are-permutations-of-each-other-during-compile-time%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?