2
0
mirror of https://github.com/boostorg/hana.git synced 2026-02-18 02:02:09 +00:00
Files
hana/test/sandbox/llist.cpp
2014-06-05 16:24:14 -04:00

77 lines
1.8 KiB
C++

/*
@copyright Louis Dionne 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <cstddef>
template <typename T>
struct llist {
union {
struct {
T head_;
llist const* next_;
} it_;
std::nullptr_t nil_;
} storage_;
enum class Which { NIL, NEXT } which_;
constexpr llist()
: storage_{.nil_ = nullptr}, which_{Which::NIL}
{ }
constexpr llist(T x, llist const* nxt)
: storage_{{x, nxt}}, which_{Which::NEXT}
{ }
friend constexpr bool is_empty(llist self)
{ return self.which_ == Which::NIL; }
friend constexpr T head(llist self) {
if (is_empty(self))
throw "head on empty list";
return self.storage_.it_.head_;
}
friend constexpr llist tail(llist self) {
if (is_empty(self))
throw "tail on empty list";
return *self.storage_.it_.next_;
}
friend constexpr llist cons(T x, llist const& xs) {
return llist{x, &xs};
}
template <typename F, typename State>
friend constexpr auto foldr(F f, State s, llist xs) {
if (is_empty(xs))
return s;
else
return f(head(xs), foldr(f, s, tail(xs)));
}
};
//////////////////////////////////////////////////////////////////////////////
#include <functional>
constexpr llist<int> xs{};
static_assert(is_empty(xs), "");
static_assert(!is_empty(cons(1, xs)), "");
static_assert(head(cons(1, xs)) == 1, "");
static_assert(head(cons(0, cons(1, xs))) == 0, "");
static_assert(head(tail(cons(0, cons(1, xs)))) == 1, "");
static_assert(foldr(std::plus<>{}, 0, cons(1, cons(2, cons(3, llist<int>{})))) == 1 + 2 + 3 + 0, "");
int main() {
}