89 lines
2.2 KiB
C++
89 lines
2.2 KiB
C++
|
/*
|
||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||
|
*
|
||
|
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <utility>
|
||
|
|
||
|
|
||
|
namespace cruft::list::node {
|
||
|
/// A node that stores the value and successor in the same object together
|
||
|
template <typename ValueT>
|
||
|
struct compound {
|
||
|
using value_type = ValueT;
|
||
|
|
||
|
compound *next;
|
||
|
ValueT data;
|
||
|
};
|
||
|
|
||
|
|
||
|
/// A node that stores either a value, or a successor pointer. Not both.
|
||
|
///
|
||
|
/// This is quite useful for node based pool allocators and similar.
|
||
|
///
|
||
|
/// The copying semantics of this node assume that the live member is
|
||
|
/// always only the 'next' pointer; it is the user's responsibility to
|
||
|
/// manage the lifetime of the `data` member and prevent copying of nodes
|
||
|
/// with a live `data` member.
|
||
|
template <typename ValueT>
|
||
|
union disjoint {
|
||
|
using value_type = ValueT;
|
||
|
|
||
|
disjoint () { }
|
||
|
|
||
|
disjoint (disjoint const &rhs) { next = rhs.next; }
|
||
|
disjoint& operator= (disjoint const &rhs) { next = rhs.next; }
|
||
|
|
||
|
~disjoint () { }
|
||
|
|
||
|
disjoint *next;
|
||
|
ValueT data;
|
||
|
};
|
||
|
|
||
|
|
||
|
/// A comparator object that returns the result of a supplied child
|
||
|
/// comparator on the data members of two node pointers.
|
||
|
template <typename ComparatorT>
|
||
|
class value_comparator {
|
||
|
public:
|
||
|
value_comparator (ComparatorT &&_comparator)
|
||
|
: m_comparator (std::move (_comparator))
|
||
|
{ ; }
|
||
|
|
||
|
value_comparator (ComparatorT const &_comparator)
|
||
|
: m_comparator (_comparator)
|
||
|
{ ; }
|
||
|
|
||
|
|
||
|
template <typename NodeT>
|
||
|
constexpr bool
|
||
|
operator() [[gnu::nonnull]] (
|
||
|
NodeT const *a,
|
||
|
NodeT const *b
|
||
|
) {
|
||
|
return m_comparator (a->data, b->data);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
ComparatorT m_comparator;
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
struct pointer_comparator {
|
||
|
template <typename NodeT>
|
||
|
constexpr bool
|
||
|
operator() [[gnu::nonnull]] (
|
||
|
NodeT const *a,
|
||
|
NodeT const *b
|
||
|
) {
|
||
|
return a < b;
|
||
|
}
|
||
|
};
|
||
|
};
|