Skip to content

Commit

Permalink
Make isHeap function acting on valuues not comparing after first mism…
Browse files Browse the repository at this point in the history
…atch.
  • Loading branch information
HaxyM authored Oct 1, 2024
1 parent f9e6f47 commit 02e6f46
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 92 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ crap_test(hassinglebitvalue)
crap_test(innerproductvalue)
crap_test(isheapuntilltype)
crap_test(isheapuntillvalue)
crap_test(isheapuvalue)
crap_test(lowerboundtype)
crap_test(lowerboundvalue)
crap_test(mismatchtype)
Expand Down
105 changes: 13 additions & 92 deletions include/crap/algorithm.d/isheapvalue.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef CRAP_ALGORITHM_ISHEAPVALUE
#define CRAP_ALGORITHM_ISHEAPVALUE

#include "../algorithm.d/findifvalue.h"
#include "../numeric.d/iotavalue.h"
#include "../utility.d/valuelist.h"

namespace crap
Expand Down Expand Up @@ -46,13 +48,13 @@ namespace crap
template <class Type, template <Type, Type> class Operator, Type ... Values> struct isHeapValue
{
private:
template <std :: size_t Index, bool LeftChildIn, bool RightChildIn> struct Implementation;
template <std :: size_t Index> struct Implementation<Index, false, false>;
template <std :: size_t Index> struct Implementation<Index, true, false>;
template <std :: size_t Index> struct Implementation<Index, true, true>;
template <std :: size_t Index> struct CheckIfFails;
template <std :: size_t ... Indices> using CheckIndices =
findIfValue<std :: size_t, CheckIfFails, Indices...>;
using Implementation =
iotaValue <sizeof...(Values), std :: size_t, 1u> :: template type<ChqckIndices>;
public:
constexpr const static bool value =
Implementation <0u, (1u < sizeof...(Values)), (2u < sizeof...(Values))> :: value;
constexpr const static bool value = (Implementation :: value == Impementation :: npos);
using value_type = decltype(value);
constexpr operator value_type () const noexcept;
};
Expand All @@ -73,97 +75,16 @@ namespace crap

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
struct isHeapValue <Type, Operator, Values...> :: Implementation<Index, false, false>
{
constexpr const static bool value = true;
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
struct isHeapValue <Type, Operator, Values...> :: Implementation<Index, true, false>
{
private:
constexpr const static Type parent =
valueList <Type, Values...> :: template At <Index> :: value;
constexpr const static Type leftChild =
valueList <Type, Values...> :: template At <(2u * Index) + 1u> :: value;
public:
constexpr const static bool value = !(Operator <parent, leftChild> :: value);
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
struct isHeapValue <Type, Operator, Values...> :: Implementation<Index, true, true>
struct isHeapValue <Type, Operator, Values...> :: CheckIfFails
{
private:
constexpr const static std :: size_t parentIndex = (Index - 1u) / 2u;
constexpr const static Type parent =
valueList <Type, Values...> :: template At <parentIndex> :: value;
constexpr const static Type child =
valueList <Type, Values...> :: template At <Index> :: value;
constexpr const static Type leftChild =
valueList <Type, Values...> :: template At <(2u * Index) + 1u> :: value;
template <bool, Type> struct CheckRight;
template <Type Parent> struct CheckRight<true, Parent>;
template <Type Parent> struct CheckRight<false, Parent>;
template <bool, std :: size_t> struct CheckSubTree;
template <std :: size_t SubIndex> struct CheckSubTree<true, SubIndex>;
template <std :: size_t SubIndex> struct CheckSubTree<false, SubIndex>;
constexpr const static bool rightFine =
CheckRight <!(Operator <parent, leftChild> :: value), parent> :: value;
constexpr const static bool leftSubTreeFine =
CheckSubTree <rightFine, (2u * Index) + 1u> :: value;
public:
constexpr const static bool value =
CheckSubTree <leftSubTreeFine, (2u * Index) + 2u> :: value;
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
template <Type Parent>
struct isHeapValue <Type, Operator, Values...> ::
Implementation <Index, true, true> ::
CheckRight<true, Parent>
{
private:
constexpr const static Type rightChild =
CheckRight <!(Operator <parent, leftChild> :: value), parent> :: value;
public:
constexpr const static bool value = !(Operator <Parent, rightChild> :: value);
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
template <Type Parent>
struct isHeapValue <Type, Operator, Values...> ::
Implementation <Index, true, true> ::
CheckRight<false, Parent>
{
constexpr const static bool value = false;
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
template <std :: size_t SubIndex>
struct isHeapValue <Type, Operator, Values...> ::
Implementation <Index, true, true> ::
CheckSubTree<true, SubIndex>
#if (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ < 10))
: isHeapValue <Type, Operator, Values...> :: template
#else
: isHeapValue <Type, Operator, Values...> ::
#endif
Implementation<SubIndex,
(((2u * SubIndex) + 1u) < sizeof...(Values)),
(((2u * SubIndex) + 2u) < sizeof...(Values))>
{
};

template <class Type, template <Type, Type> class Operator, Type ... Values>
template <std :: size_t Index>
template <std :: size_t SubIndex>
struct isHeapValue <Type, Operator, Values...> ::
Implementation <Index, true, true> ::
CheckSubTree<false, SubIndex>
{
constexpr const static bool value = false;
constexpr const static bool value = Operator <parent, leftChild> :: value;
};
}

Expand Down
55 changes: 55 additions & 0 deletions test/isheapvaluetest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "../include/crap/algorithm.d/isheapfortype.h"

#include <cstdlib>
#include <functional>
#include <iterator>
#include <numeric>

#include "testutils.h"
#include "../include/crap/functional.d/comparatorsfortype.h"

bool test_isHeapValueTrivialPassingTest()
{
using valueTestType = unsigned int;

//TODO: Make sequence random.
using testList1 =
crap :: valueList<valueTestType, 9u, 8u, 7u, 7u, 7u, 7u, 5u, 5u, 3u>;
using testedFun = crap :: isHeapForType<
valueTestType,
lessConstrainedForType <valueTestType, Constrain> :: template type>;
using testResult_t = typename testList1 :: copy <testedFun :: template type>;
constexpr const static auto testResult = testResult_t :: value;
static_assert(testResult, "Set is a heap!");
return true;
}

bool test_isHeapValueTrivialFailingTest()
{
using valueTestType = unsigned int;
constexpr const static valueTestType Constrain = 42u;
constexpr const static valueTestType Subject = 101u;

//TODO: Make sequence random.
using testList1 =
crap :: valueList<valueTestType, 9u, 8u, 7u, 7u, 7u, 7u, 5u, Subject, Constrain>;
using testedFun = crap :: isHeapForType<
valueTestType,
crap :: comparatorsForType <valueTestType> :: template Less>;
using testResult_t = typename testList1 :: copy <testedFun :: template type>;
constexpr const static auto testResult = testResult_t :: value;
static_assert(!testResult, "Set is not a heap!");
return true;
}

int main()
{
const bool results[] = {
test_isHeapValueTrivialPassingTest(),
test_isHeapValueTrivialFailingTest()
};
return std :: accumulate(std :: begin(results), std :: end(results), true, std :: logical_and<bool>())
? EXIT_SUCCESS
: EXIT_FAILURE;
}

0 comments on commit 02e6f46

Please sign in to comment.