mirror of
https://github.com/boostorg/hana.git
synced 2026-02-18 02:02:09 +00:00
77 lines
1.8 KiB
C++
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() {
|
|
|
|
}
|