瀏覽代碼

Initial commit of the intrusive_list git repo. Originally part of a more generic 'collections' project.

Samuel Jaffe 9 年之前
當前提交
909dfd4490
共有 5 個文件被更改,包括 728 次插入0 次删除
  1. 139 0
      intrusive_iterator.hpp
  2. 332 0
      intrusive_list.hpp
  3. 0 0
      intrusive_list.t.h
  4. 237 0
      intrusive_list.xcodeproj/project.pbxproj
  5. 20 0
      intrusive_node.hpp

+ 139 - 0
intrusive_iterator.hpp

@@ -0,0 +1,139 @@
+//
+//  intrusive_iterator.hpp
+//  utilities
+//
+//  Created by Sam Jaffe on 5/10/13.
+//  Copyright (c) 2013 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+template <typename N>
+intrusive_iterator<N>::intrusive_iterator(N* node) :
+node_(node) {
+    
+}
+
+template <typename N>
+auto intrusive_iterator<N>::operator*() -> reference {
+    return *(node_->ptr_);
+}
+
+template <typename N>
+auto intrusive_iterator<N>::operator*() const -> const_reference {
+    return *(node_->ptr_);
+}
+
+template <typename N>
+auto intrusive_iterator<N>::operator->() -> pointer {
+    return node_->ptr_;
+}
+
+template <typename N>
+auto intrusive_iterator<N>::operator->() const -> const_pointer {
+    return node_->ptr_;
+}
+
+template <typename N>
+intrusive_iterator<N> intrusive_iterator<N>::operator++(int) {
+    intrusive_iterator<N> it{*this};
+    node_ = node_->next_;
+    return it;
+}
+
+template <typename N>
+intrusive_iterator<N>& intrusive_iterator<N>::operator++() {
+    node_ = node_->next_;
+    return *this;
+}
+
+template <typename N>
+intrusive_iterator<N> intrusive_iterator<N>::operator--(int) {
+    intrusive_iterator<N> it{*this};
+    node_ = node_->prev_;
+    return it;
+}
+
+template <typename N>
+intrusive_iterator<N>& intrusive_iterator<N>::operator--() {
+    node_ = node_->prev_;
+    return *this;
+}
+
+template <typename N>
+N* intrusive_iterator<N>::get() {
+    return node_;
+}
+
+template <typename N>
+const N* intrusive_iterator<N>::get() const {
+    return node_;
+}
+
+template <typename N>
+bool intrusive_iterator<N>::operator==(const intrusive_iterator<N>& other) const {
+    return node_ == other.node_;
+}
+
+template <typename N>
+bool intrusive_iterator<N>::operator!=(const intrusive_iterator<N>& other) const {
+    return node_ != other.node_;
+}
+
+#pragma mark const_intrusive_iterator
+template <typename N>
+const_intrusive_iterator<N>::const_intrusive_iterator(const N* node) :
+node_(node) {
+    
+}
+
+template <typename N>
+auto const_intrusive_iterator<N>::operator*() const -> const_reference {
+    return *(node_->ptr_);
+}
+
+template <typename N>
+auto const_intrusive_iterator<N>::operator->() const -> const_pointer {
+    return node_->ptr_;
+}
+
+template <typename N>
+const_intrusive_iterator<N> const_intrusive_iterator<N>::operator++(int) {
+    const_intrusive_iterator<N> it{*this};
+    node_ = node_->next_;
+    return it;
+}
+
+template <typename N>
+const_intrusive_iterator<N>& const_intrusive_iterator<N>::operator++() {
+    node_ = node_->next_;
+    return *this;
+}
+
+template <typename N>
+const_intrusive_iterator<N> const_intrusive_iterator<N>::operator--(int) {
+    const_intrusive_iterator<N> it{*this};
+    node_ = node_->prev_;
+    return it;
+}
+
+template <typename N>
+const_intrusive_iterator<N>& const_intrusive_iterator<N>::operator--() {
+    node_ = node_->prev_;
+    return *this;
+}
+
+template <typename N>
+const N* const_intrusive_iterator<N>::get() const {
+    return node_;
+}
+
+template <typename N>
+bool const_intrusive_iterator<N>::operator==(const const_intrusive_iterator<N>& other) const {
+    return node_ == other.node_;
+}
+
+template <typename N>
+bool const_intrusive_iterator<N>::operator!=(const const_intrusive_iterator<N>& other) const {
+    return node_ != other.node_;
+}

+ 332 - 0
intrusive_list.hpp

@@ -0,0 +1,332 @@
+//
+//  intrusive_iterator.h
+//  utilities
+//
+//  Created by Sam Jaffe on 9/26/14.
+//  Copyright (c) 2014 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+#include <iterator>
+#include <limits>
+#include <cstddef>
+
+template <typename T>
+class intrusive_node;
+
+template <typename T>
+class intrusive_list;
+
+template <typename T>
+class intrusive_iterator;
+
+template <typename T>
+class const_intrusive_iterator;
+
+template <typename T>
+class intrusive_node {
+public:
+    typedef T value_type;
+    typedef T& reference;
+    typedef const T& const_reference;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+private:
+    typedef intrusive_node<T>* self;
+public:
+    intrusive_node() = delete;
+    intrusive_node(const intrusive_node&) = delete;
+    intrusive_node(intrusive_node&&) = delete;
+    intrusive_node& operator=(const intrusive_node&) = delete;
+    intrusive_node& operator=(intrusive_node&&) = delete;
+    
+    intrusive_node(pointer ptr);
+    ~intrusive_node();
+    
+private:
+    friend intrusive_list<T>;
+    friend intrusive_iterator<intrusive_node<T> >;
+    friend const_intrusive_iterator<intrusive_node<T> >;
+    
+    pointer ptr_ = nullptr;
+    intrusive_list<T>* list_ = nullptr;
+    self next_ = nullptr;
+    self prev_ = nullptr;
+};
+
+template <typename N>
+class intrusive_iterator : public std::iterator<std::bidirectional_iterator_tag, typename N::value_type> {
+public:
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef typename N::value_type value_type;
+    typedef typename N::reference reference;
+    typedef typename N::const_reference const_reference;
+    typedef typename N::pointer pointer;
+    typedef typename N::const_pointer const_pointer;
+public:
+    intrusive_iterator(N* node);
+    
+    reference operator*();
+    const_reference operator*() const;
+    
+    pointer operator->();
+    const_pointer operator->() const;
+    
+    intrusive_iterator operator++(int);
+    intrusive_iterator& operator++();
+    
+    intrusive_iterator operator--(int);
+    intrusive_iterator& operator--();
+    
+    bool operator==(const intrusive_iterator& other) const;
+    bool operator!=(const intrusive_iterator& other) const;
+    
+private:
+    friend intrusive_list<value_type>;
+    
+    N* get();
+    const N* get() const;
+
+    N* node_;
+};
+
+template <typename N>
+class const_intrusive_iterator : public std::iterator<std::bidirectional_iterator_tag, typename N::value_type> {
+public:
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef typename N::value_type value_type;
+    typedef typename N::reference reference;
+    typedef typename N::const_reference const_reference;
+    typedef typename N::pointer pointer;
+    typedef typename N::const_pointer const_pointer;
+public:
+    const_intrusive_iterator(const N* node);
+    
+    const_reference operator*() const;
+    
+    const_pointer operator->() const;
+    
+    const_intrusive_iterator operator++(int);
+    const_intrusive_iterator& operator++();
+    
+    const_intrusive_iterator operator--(int);
+    const_intrusive_iterator& operator--();
+    
+    bool operator==(const const_intrusive_iterator& other) const;
+    bool operator!=(const const_intrusive_iterator& other) const;
+    
+private:
+    friend intrusive_list<value_type>;
+    
+    const N* get() const;
+    
+    const N* node_;
+};
+
+template <typename T>
+class intrusive_list {
+public:
+    typedef T value_type;
+    typedef intrusive_node<value_type> node_type;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef intrusive_iterator<node_type> iterator;
+    typedef const_intrusive_iterator<node_type> const_iterator;
+    typedef typename std::reverse_iterator<iterator> reverse_iterator;
+    typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
+public:
+    constexpr intrusive_list( node_type T::*node ) :
+    node_(node) {
+        
+    }
+    intrusive_list( const intrusive_list& ) = delete;
+    intrusive_list( intrusive_list&& other ) = default;
+    intrusive_list( std::initializer_list<pointer> ilist, node_type T::*node ) :
+    node_(node) {
+        assign(ilist);
+    }
+    ~intrusive_list() {
+        clear();
+    }
+    
+    intrusive_list& operator=( const intrusive_list& ) = delete;
+    intrusive_list& operator=( intrusive_list&& other ) {
+        clear(); // other than this, default
+        node_ = other.node_;
+        size_ = other.size_;
+        head_ = other.head_;
+        other.head_ = &other.end_;
+    }
+    intrusive_list& operator=( std::initializer_list<pointer> ilist ) {
+        assign(ilist);
+    }
+    
+    void assign( std::initializer_list<pointer> ilist ) {
+        clear();
+        for (pointer p : ilist) {
+            push_back(p);
+        }
+    }
+    
+    inline pointer front() {
+        return head_->get();
+    }
+    inline const_pointer front() const {
+        return head_->get();
+    }
+    
+    inline pointer back() {
+        return end_.prev_->get();
+    }
+    inline const_pointer back() const {
+        return end_.prev_->get();
+    }
+    
+    inline iterator begin() noexcept {
+        return iterator{head_};
+    }
+    inline const_iterator begin() const noexcept {
+        return const_iterator{head_};
+    }
+    inline const_iterator cbegin() const noexcept {
+        return const_iterator{head_};
+    }
+    
+    inline iterator end() noexcept {
+        return iterator{&end_};
+    }
+    inline const_iterator end() const noexcept {
+        return const_iterator{&end_};
+    }
+    inline const_iterator cend() const noexcept {
+        return const_iterator{&end_};
+    }
+    
+    inline reverse_iterator rbegin() {
+        return reverse_iterator{end()};
+    }
+    inline const_reverse_iterator rbegin() const noexcept {
+        return const_reverse_iterator{end()};
+    }
+    inline const_reverse_iterator crbegin() const noexcept {
+        return const_reverse_iterator{cend()};
+    }
+    
+    inline reverse_iterator rend() noexcept {
+        return reverse_iterator{begin()};
+    }
+    inline const_reverse_iterator rend() const noexcept {
+        return const_reverse_iterator{begin()};
+    }
+    inline const_reverse_iterator crend() const noexcept{
+        return const_reverse_iterator{cbegin()};
+    }
+    
+    inline bool empty() const noexcept {
+        return size_ = 0;
+    }
+    inline size_type size() const noexcept {
+        return size_;
+    }
+    inline size_type max_size() const noexcept {
+        return std::numeric_limits<size_type>::max();
+    }
+    
+    void clear() noexcept {
+        erase(begin(), end());
+    }
+    
+    iterator insert(const_iterator pos, pointer value) {
+        node_type* n = &(value->*node_);
+        link(pos.get()->prev_, n);
+        link(n, pos.get());
+        n->list_ = this;
+        ++size_;
+        return iterator{n};
+    }
+    iterator insert(const_iterator pos, std::initializer_list<pointer> ilist) {
+        for (pointer p : ilist) {
+            link(pos.get()->prev_, p->*node_);
+            link(p->*node_, pos.get());
+            p->*node_->list_ = this;
+        }
+        size_ += ilist.size();
+        return iterator{pos.get()};
+    }
+    
+    iterator erase(iterator pos) {
+        unlink(pos.get());
+        pos.get()->list_ = nullptr;
+        --size_;
+        return iterator{pos.get()->next_};
+    }
+    iterator erase(iterator first, iterator last) {
+        while (first != last) {
+            first = erase(first);
+        }
+        return last;
+    }
+    
+    inline void push_back(pointer value) {
+        link(end_.prev_, &(value->*node_));
+        ++size_;
+    }
+    
+    inline void pop_back() {
+        intrusive_node<T> *old = end_.prev_;
+        end_.prev_ = old->prev_;
+        unlink(old);
+        --size_;
+    }
+    
+    inline void push_front(pointer value) {
+        insert(begin(), value);
+    }
+    
+    inline void pop_front() {
+        erase(begin());
+    }
+    
+    void remove( pointer value ) {
+        node_type* n = &(value->*node_);
+        if (n->list_ == this) {
+            unlink(n);
+            --size_;
+        }
+    }
+    template< class UnaryPredicate >
+    void remove_if( UnaryPredicate pred ) {
+        auto it = begin();
+        while (it != end()) {
+            pointer p = it.get()->ptr_;
+            ++it;
+            if (pred(p)) {
+                remove(p);
+            }
+        }
+    }
+private:
+    inline void link(node_type* lhs, node_type* rhs) {
+        lhs->next_ = rhs;
+        rhs->prev_ = lhs;
+    }
+    inline void unlink(node_type* node) {
+        if (node->next_) {
+            node->next_->prev_ = node->prev_;
+        }
+        if (node->prev_) {
+            node->prev_->next_ = node->next_;
+        }
+    }
+    
+    node_type T::*node_;
+    node_type end_{nullptr}; // secretly const
+    node_type *head_ = &end_;
+    size_type size_;
+};
+
+#include "intrusive_iterator.hpp"
+#include "intrusive_node.hpp"

+ 0 - 0
intrusive_list.t.h


+ 237 - 0
intrusive_list.xcodeproj/project.pbxproj

@@ -0,0 +1,237 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXCopyFilesBuildPhase section */
+		CD0364731E20852F003B7B84 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		CD0364751E20852F003B7B84 /* intrusive_list */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = intrusive_list; sourceTree = BUILT_PRODUCTS_DIR; };
+		CD0364AA1E208591003B7B84 /* intrusive_iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = intrusive_iterator.hpp; sourceTree = "<group>"; };
+		CD0364AB1E208591003B7B84 /* intrusive_list.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = intrusive_list.hpp; sourceTree = "<group>"; };
+		CD0364AC1E208591003B7B84 /* intrusive_list.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = intrusive_list.t.h; sourceTree = "<group>"; };
+		CD0364AD1E208591003B7B84 /* intrusive_node.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = intrusive_node.hpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		CD0364721E20852F003B7B84 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		CD03646C1E20852F003B7B84 = {
+			isa = PBXGroup;
+			children = (
+				CD0364AA1E208591003B7B84 /* intrusive_iterator.hpp */,
+				CD0364AB1E208591003B7B84 /* intrusive_list.hpp */,
+				CD0364AC1E208591003B7B84 /* intrusive_list.t.h */,
+				CD0364AD1E208591003B7B84 /* intrusive_node.hpp */,
+				CD0364761E20852F003B7B84 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		CD0364761E20852F003B7B84 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CD0364751E20852F003B7B84 /* intrusive_list */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		CD0364741E20852F003B7B84 /* intrusive_list */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = CD03647C1E20852F003B7B84 /* Build configuration list for PBXNativeTarget "intrusive_list" */;
+			buildPhases = (
+				CD0364711E20852F003B7B84 /* Sources */,
+				CD0364721E20852F003B7B84 /* Frameworks */,
+				CD0364731E20852F003B7B84 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = intrusive_list;
+			productName = intrusive_list;
+			productReference = CD0364751E20852F003B7B84 /* intrusive_list */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		CD03646D1E20852F003B7B84 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0720;
+				ORGANIZATIONNAME = "Sam Jaffe";
+				TargetAttributes = {
+					CD0364741E20852F003B7B84 = {
+						CreatedOnToolsVersion = 7.2.1;
+					};
+				};
+			};
+			buildConfigurationList = CD0364701E20852F003B7B84 /* Build configuration list for PBXProject "intrusive_list" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = CD03646C1E20852F003B7B84;
+			productRefGroup = CD0364761E20852F003B7B84 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				CD0364741E20852F003B7B84 /* intrusive_list */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		CD0364711E20852F003B7B84 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		CD03647A1E20852F003B7B84 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		CD03647B1E20852F003B7B84 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		CD03647D1E20852F003B7B84 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		CD03647E1E20852F003B7B84 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		CD0364701E20852F003B7B84 /* Build configuration list for PBXProject "intrusive_list" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				CD03647A1E20852F003B7B84 /* Debug */,
+				CD03647B1E20852F003B7B84 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		CD03647C1E20852F003B7B84 /* Build configuration list for PBXNativeTarget "intrusive_list" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				CD03647D1E20852F003B7B84 /* Debug */,
+				CD03647E1E20852F003B7B84 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = CD03646D1E20852F003B7B84 /* Project object */;
+}

+ 20 - 0
intrusive_node.hpp

@@ -0,0 +1,20 @@
+//
+//  intrusive_node.hpp
+//  utilities
+//
+//  Created by Sam Jaffe on 5/10/13.
+//  Copyright (c) 2013 Sam Jaffe. All rights reserved.
+//
+
+#pragma once
+
+template <typename T>
+intrusive_node<T>::intrusive_node(pointer ptr) :
+ptr_(ptr) {
+    
+}
+
+template <typename T>
+intrusive_node<T>::~intrusive_node() {
+    if (list_) { list_->remove(ptr_); }
+}