Skip to content

Commit

Permalink
merge to single header
Browse files Browse the repository at this point in the history
  • Loading branch information
cooperlarson committed Aug 2, 2024
1 parent 4d43fbd commit 52af2e0
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 277 deletions.
23 changes: 21 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from conan import ConanFile
from conan.tools.meson import Meson
from conan.tools.files import copy
from conan.tools.files import copy, save


class Pkg(ConanFile):
Expand Down Expand Up @@ -36,7 +38,7 @@ def test(self):
meson.test()

def package(self):
copy(self, "*.h", self.source_folder, self.package_folder)
copy(self, "*.hpp", self.source_folder, self.package_folder)

def package_info(self):
self.cpp_info.includedirs = ['include']
Expand All @@ -46,3 +48,20 @@ def package_info(self):
def package_id(self):
self.info.clear()

def merge_headers(self, filepath1, filepath2, output_filename):
# Read files
with open(filepath1, 'r') as f1, open(filepath2, 'r') as f2:
content1 = f1.read()
content2 = f2.read()

# Create combined header content with include guards
guard_name = output_filename.upper().replace('.', '_') + '_HPP'
combined_content = f'#ifndef {guard_name}\n#define {guard_name}\n\n'
combined_content += content1 + '\n' + content2
combined_content += f'\n#endif // {guard_name}\n'

# Write to build directory
build_path = os.path.join(self.build_folder, output_filename)
save(self, build_path, combined_content)
self.output.info(f"Merged header file created at: {build_path}")

22 changes: 0 additions & 22 deletions include/BoundedMaxPriorityDeque.h

This file was deleted.

22 changes: 0 additions & 22 deletions include/BoundedMinPriorityDeque.h

This file was deleted.

23 changes: 0 additions & 23 deletions include/BoundedPriorityDeque.h

This file was deleted.

227 changes: 227 additions & 0 deletions include/BoundedPriorityDeque.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
//
// Created by Cooper Larson on 7/30/24.
//

#ifndef SERVER_BOUNDED_PRIORITY_DEQUE_BASE_H
#define SERVER_BOUNDED_PRIORITY_DEQUE_BASE_H

#include <vector>
#include <utility>
#include <type_traits>

#ifdef ENABLE_DEBUG
#include <stdexcept>
#endif

// Helper type traits to check if a type has a comparison operator
template <typename, typename T>
struct has_comparison_operator {
static_assert(
std::integral_constant<T, false>::value,
"Second template parameter needs to be of function type.");
};

template <typename C, typename Ret, typename... Args>
struct has_comparison_operator<C, Ret(Args...)> {
private:
template <typename T>
static constexpr auto check(T*) ->
typename std::is_same<decltype(std::declval<T>().operator()(std::declval<Args>()...)), Ret>::type;

template <typename>
static constexpr std::false_type check(...);

typedef decltype(check<C>(0)) type;

public:
static constexpr bool value = type::value;
};

template <typename T>
constexpr bool has_comparison_operator_v = has_comparison_operator<T, bool(const T&, const T&)>::value;

// BoundingPair class template
template<typename K, typename V, typename Enable = void>
class BoundingPair : public std::pair<K, V> {
using pair = std::pair<K, V>;
public:
using pair::pair;
using pair::first;
using pair::second;

// Comparison operator
bool operator<(const BoundingPair& other) const {
return first < other.first;
}
};

// Specialization for comparator objects
template<typename K, typename V>
class BoundingPair<K, V, std::enable_if_t<has_comparison_operator_v<K>>> : public std::pair<K, V> {
using pair = std::pair<K, V>;
public:
using pair::pair;
using pair::first;
using pair::second;

// Comparison operator using the comparator
bool operator<(const BoundingPair& other) const {
return K()(first, other.first);
}
};

template<typename K, typename V>
class BoundedPriorityDequeBase {
protected:
std::vector<BoundingPair<K, V>> _buffer;
size_t _k, _size = 0, _head = 0, _tail = 0;

virtual bool compare(K a, K b) const = 0;

[[nodiscard]] size_t nextIndex(size_t current) const { return (current + 1) % _k; }

[[nodiscard]] size_t prevIndex(size_t current) const { return (current + _k - 1) % _k; }

size_t binarySearch(const BoundingPair<K, V>& target) const {
auto start = _head, end = _tail + 1;
while (start != end) {
size_t mid = (start + (end - start) / 2) % _buffer.size();
if (compare(_buffer[mid].first, target.first)) start = (mid + 1) % _buffer.size();
else end = mid;
}
return start;
}

public:
explicit BoundedPriorityDequeBase(size_t capacity) : _buffer(capacity), _k(capacity) {}

BoundingPair<K, V> top() const {
#ifdef ENABLE_DEBUG
if (empty()) throw std::runtime_error("Attempted to access top element of empty BoundedPriorityDeque");
#endif
return _buffer[_head];
}

BoundingPair<K, V> bottom() const {
#ifdef ENABLE_DEBUG
if (empty()) throw std::runtime_error("Attempted to access bottom element of empty BoundedPriorityDeque");
#endif
return _buffer[_tail];
}

[[nodiscard]] K& bottomK() const {
#ifdef ENABLE_DEBUG
if (empty()) throw std::runtime_error("Attempted to access bottom element of empty BoundedPriorityDeque");
#endif
return _buffer[_tail].first;
}

void push(const BoundingPair<K, V>& element) {
if (_size == _k) {
if (compare(element.first, _buffer[_tail].first)) popBottom();
else return;
} else if (_size == 0) {
_buffer[0] = element;
_head = 0;
_tail = 0;
_size = 1;
return;
}

auto pos = binarySearch(element);
if (pos != nextIndex(_tail)) {
if (_head <= _tail) {
if (_head > 0) std::move(_buffer.begin() + _head, _buffer.begin() + pos + 1, _buffer.begin() + pos + 2);
else std::move_backward(_buffer.begin() + pos, _buffer.begin() + _tail + 1, _buffer.begin() + _tail + 2);
} else {
if (pos > 0) std::move_backward(_buffer.begin() + pos, _buffer.begin() + _tail + 1, _buffer.begin() + _tail + 2);
else std::move(_buffer.begin() + _head, _buffer.begin() + pos + 1, _buffer.begin() + _head - 1);
}
}

_buffer[pos] = element;
_tail = nextIndex(_tail);
_size++;
}

BoundingPair<K, V> pop() {
#ifdef ENABLE_DEBUG
if (empty()) throw std::runtime_error("Attempted to pop from empty BoundedPriorityDeque");
#endif
BoundingPair<K, V> result = _buffer[_head];
_head = nextIndex(_head);
--_size;
return result;
}

BoundingPair<K, V> popBottom() {
#ifdef ENABLE_DEBUG
if (empty()) throw std::runtime_error("Attempted to pop from empty BoundedPriorityDeque");
#endif
BoundingPair<K, V> result = _buffer[_tail];
_tail = prevIndex(_tail);
--_size;
return result;
}

void emplace(K key, const V& value) { push({ key, value }); }

void operator+=(const BoundedPriorityDequeBase<K, V>& rhs) {
for (size_t i = 0; i < rhs._size; ++i) {
size_t index = (rhs._head + i) % rhs._k;
if (_size == _k && compare(bottom().first, rhs._buffer[index].first)) return;
push(rhs._buffer[index]);
}
}

void clear() {
_head = 0;
_tail = 0;
_size = 0;
}

[[nodiscard]] size_t size() const { return _size; }
[[nodiscard]] size_t capacity() const { return _k; }
[[nodiscard]] bool empty() const { return _size == 0; }
[[nodiscard]] bool full() const { return _size == _k; }

void setCapacity(unsigned int k) {
_k = k;
_buffer.resize(k);
clear();
}
};

template<typename K, typename V>
class BoundedMinPriorityDeque : public BoundedPriorityDequeBase<K, V> {
protected:
[[nodiscard]] bool compare(K a, K b) const override { return a < b; }

public:
explicit BoundedMinPriorityDeque(unsigned int capacity = 0) : BoundedPriorityDequeBase<K, V>(capacity) {}

};

template<typename K, typename V>
class BoundedMaxPriorityDeque : public BoundedPriorityDequeBase<K, V> {
protected:
[[nodiscard]] bool compare(K a, K b) const override { return a > b; }

public:
explicit BoundedMaxPriorityDeque(unsigned int capacity = 0) : BoundedPriorityDequeBase<K, V>(capacity) {}
};


template<typename K, typename V, typename Comparator = std::less<K>>
class BoundedPriorityDeque : public BoundedPriorityDequeBase<K, V> {
protected:
Comparator comparator;

[[nodiscard]] bool compare(K a, K b) const override { return comparator(a, b); }

public:
explicit BoundedPriorityDeque(unsigned int capacity = 0, Comparator comp = Comparator()) :
BoundedPriorityDequeBase<K, V>(capacity), comparator(comp) {}
};

#endif // SERVER_BOUNDED_PRIORITY_DEQUE_BASE_H
Loading

0 comments on commit 52af2e0

Please sign in to comment.