1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
#include <iostream>
#include <type_traits>
const int NOT_FOUND = -1;
template <bool, int, template <int, int> class Compare, int, int, int, int...> struct B3;
template <bool, int, template <int, int> class Compare, int, int, int, int...> struct B4;
template <int Key, template <int, int> class Compare, int Position, int ValueAtPosition, int LowerBound, int UpperBound, int... Rest>
struct B2 : std::conditional< Compare<Key, ValueAtPosition>::value,
B3< Compare<UpperBound, LowerBound>::value, Key, Compare, Position, LowerBound, UpperBound, Rest...>,
B4< Compare<UpperBound, LowerBound>::value, Key, Compare, Position, LowerBound, UpperBound, Rest...>
>::type {};
template <int Key, template <int, int> class Compare, int Position, int ValueAtPosition, int LowerBound, int UpperBound, int... Rest>
struct B1 : std::conditional<ValueAtPosition == Key,
std::integral_constant<int, Position>,
std::integral_constant<int, B2<Key, Compare, Position, ValueAtPosition, LowerBound, UpperBound, Rest...>::value>
>::type {};
template <int Key, template <int, int> class Compare, int LowerBound, int UpperBound, int... Rest>
struct B0 {
static int constexpr array[] = {Rest...};
static constexpr int position = (LowerBound + UpperBound) / 2, value_at_position = array[position];
static constexpr int value = B1<Key, Compare, position, value_at_position, LowerBound, UpperBound, Rest...>::value;
};
template <int Key, template <int, int> class Compare, int Position, int LowerBound, int UpperBound, int... Rest>
struct B3<true, Key, Compare, Position, LowerBound, UpperBound, Rest...> : std::integral_constant<int, NOT_FOUND> {};
template <int Key, template <int, int> class Compare, int Position, int LowerBound, int UpperBound, int... Rest>
struct B3<false, Key, Compare, Position, LowerBound, UpperBound, Rest...> :
std::integral_constant<int, B0<Key, Compare, LowerBound, Position - 1, Rest...>::value> {};
template <int Key, template <int, int> class Compare, int Position, int LowerBound, int UpperBound, int... Rest>
struct B4<true, Key, Compare, Position, LowerBound, UpperBound, Rest...> : std::integral_constant<int, NOT_FOUND> {};
template <int Key, template <int, int> class Compare, int Position, int LowerBound, int UpperBound, int... Rest>
struct B4<false, Key, Compare, Position, LowerBound, UpperBound, Rest...> :
std::integral_constant<int, B0<Key, Compare, Position + 1, UpperBound, Rest...>::value> {};
template <int X, int Y>
struct Less : std::conditional<(X < Y), std::true_type, std::false_type>::type {};
template <int Key, int... Rest>
using BinarySearch = B0<Key, Less, 0, sizeof...(Rest) - 1, Rest...>;
template <int Key, template <int, int> class Compare, int... Rest>
using BinarySearchCustomCompare = B0<Key, Compare, 0, sizeof...(Rest) - 1, Rest...>;
// Testing ------------------------------------------------------
template <int X, int Y>
struct Greater : std::conditional<(X > Y), std::true_type, std::false_type>::type {};
int main() {
std::cout << BinarySearch<65, 1,5,7,8,11,12,18,25,32,65,111,150>::value << std::endl; // 9
std::cout << BinarySearchCustomCompare<65, Greater, 200,195,120,111,98,76,65,45,32,25,10,8,3,2>::value << std::endl; // 6
}
|