Skip to content

Instantly share code, notes, and snippets.

@airglow923
Last active October 29, 2021 05:12
Show Gist options
  • Save airglow923/8460888c04ae46e6249e8eb1ddeb7ed9 to your computer and use it in GitHub Desktop.
Save airglow923/8460888c04ae46e6249e8eb1ddeb7ed9 to your computer and use it in GitHub Desktop.
Simplified version of LLVM libcxx allocator-aware container node implementation
// This header is redistributed under the Apache License v2.0 with LLVM Exceptions.
// The whole license can be found:
// https://releases.llvm.org/12.0.0/LICENSE.TXT
// The entire implementation of forward_list can be found:
// https://github.com/llvm-mirror/libcxx/blob/master/include/forward_list
#include <memory>
#include <type_traits>
using std::allocator_traits;
using std::is_same;
using std::pointer_traits;
template <class _From, class _To>
struct __rebind_pointer {
#ifndef _LIBCPP_CXX03_LANG
typedef typename pointer_traits<_From>::template rebind<_To> type;
#else
typedef typename pointer_traits<_From>::template rebind<_To>::other type;
#endif
};
template <class _Traits, class _Tp>
struct __rebind_alloc_helper {
#ifndef _LIBCPP_CXX03_LANG
typedef typename _Traits::template rebind_alloc<_Tp> type;
#else
typedef typename _Traits::template rebind_alloc<_Tp>::other type;
#endif
};
template <class _Tp, class _VoidPtr>
struct __forward_list_node;
template <class _NodePtr>
struct __forward_begin_node;
template <class _NodePtr>
struct __forward_begin_node {
typedef _NodePtr pointer;
typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type
__begin_node_pointer;
pointer __next_;
__forward_begin_node() : __next_(nullptr) {}
__begin_node_pointer __next_as_begin() const {
return static_cast<__begin_node_pointer>(__next_);
}
};
template <class _Tp, class _VoidPtr>
struct __begin_node_of {
typedef __forward_begin_node<typename __rebind_pointer<
_VoidPtr, __forward_list_node<_Tp, _VoidPtr>>::type>
type;
};
template <class _Tp, class _VoidPtr>
struct __forward_list_node : public __begin_node_of<_Tp, _VoidPtr>::type {
typedef _Tp value_type;
value_type __value_;
};
template <class _Tp, class _Alloc>
class __forward_list_base {
protected:
typedef _Tp value_type;
typedef _Alloc allocator_type;
typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
typedef __forward_list_node<value_type, void_pointer> __node;
typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
__node>::type __node_allocator;
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
typedef
typename __rebind_alloc_helper<allocator_traits<allocator_type>,
__begin_node>::type __begin_node_allocator;
typedef typename allocator_traits<__begin_node_allocator>::pointer
__begin_node_pointer;
static_assert((!is_same<allocator_type, __node_allocator>::value),
"internal allocator type must differ from user-specified "
"type; otherwise overload resolution breaks");
// __compressed_pair<__begin_node, __node_allocator> __before_begin_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment