Skip to content

Instantly share code, notes, and snippets.

@sqbi-q
Created May 6, 2024 11:05
Show Gist options
  • Save sqbi-q/fd516fc9a08f799f8e5c756844e11c0a to your computer and use it in GitHub Desktop.
Save sqbi-q/fd516fc9a08f799f8e5c756844e11c0a to your computer and use it in GitHub Desktop.
Head Tail List implementation in C++17
#include <iostream>
#include <memory>
#include <optional>
class not_found_error : public std::logic_error {
using std::logic_error::logic_error;
};
// Head - Tail List
// Inspired by Prolog lists
template<typename T>
class List {
public:
List() = default;
List(std::initializer_list<T> l) {
insert(l.begin(), l.end());
}
void insert(const T* it, const T* end_it) {
if (it == end_it) return;
m_head = *it;
m_tail = std::make_unique<List<T>>();
(*m_tail)->insert(std::next(it), end_it);
}
int getElementIndex(const T& element, size_t starting_index=0) const {
if (element == m_head) {
return starting_index;
}
else if (!m_tail) {
throw not_found_error("value not found in list");
return -1;
}
else
return (*m_tail)->getElementIndex(element, starting_index+1);
}
T head() const { return m_head; }
List<T>& tail() const { return *(m_tail.value()); }
private:
T m_head;
std::optional<std::unique_ptr<List<T>>> m_tail = std::nullopt;
};
int main() {
List<int> list{1, 2, 3}; // could also be represented as [1, 2, 3] or [1, [2, [3]]
// get first element
std::cout << list.head() << std::endl;
// get first element of tail (that is second element)
std::cout << list.tail().head() << std::endl;
std::cout << "element 1, index: " << list.getElementIndex(1) << std::endl;
std::cout << "element 4, index: " << list.getElementIndex(4) << std::endl; // throws error - there is no 4 in [1, 2, 3]
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment