Rename the extracted boost subdirectory to ndnboost
diff --git a/ndnboost/smart_ptr/detail/allocate_array_helper.hpp b/ndnboost/smart_ptr/detail/allocate_array_helper.hpp
new file mode 100644
index 0000000..a67e6e8
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/allocate_array_helper.hpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
+#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
+
+#include <ndnboost/type_traits/alignment_of.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename A, typename T, typename Y = char>
+ class allocate_array_helper;
+ template<typename A, typename T, typename Y>
+ class allocate_array_helper<A, T[], Y> {
+ template<typename A9, typename T9, typename Y9>
+ friend class allocate_array_helper;
+ typedef typename A::template rebind<Y> ::other A2;
+ typedef typename A::template rebind<char>::other A3;
+ public:
+ typedef typename A2::value_type value_type;
+ typedef typename A2::pointer pointer;
+ typedef typename A2::const_pointer const_pointer;
+ typedef typename A2::reference reference;
+ typedef typename A2::const_reference const_reference;
+ typedef typename A2::size_type size_type;
+ typedef typename A2::difference_type difference_type;
+ template<typename U>
+ struct rebind {
+ typedef allocate_array_helper<A, T[], U> other;
+ };
+ allocate_array_helper(const A& allocator, std::size_t size, T** data)
+ : allocator(allocator),
+ size(sizeof(T) * size),
+ data(data) {
+ }
+ template<class U>
+ allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
+ : allocator(other.allocator),
+ size(other.size),
+ data(other.data) {
+ }
+ pointer address(reference value) const {
+ return allocator.address(value);
+ }
+ const_pointer address(const_reference value) const {
+ return allocator.address(value);
+ }
+ size_type max_size() const {
+ return allocator.max_size();
+ }
+ pointer allocate(size_type count, const void* value = 0) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ char* p1 = A3(allocator).allocate(n1 + size, value);
+ char* p2 = p1 + n1;
+ while (std::size_t(p2) % a1 != 0) {
+ p2--;
+ }
+ *data = reinterpret_cast<T*>(p2);
+ return reinterpret_cast<Y*>(p1);
+ }
+ void deallocate(pointer memory, size_type count) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ char* p1 = reinterpret_cast<char*>(memory);
+ A3(allocator).deallocate(p1, n1 + size);
+ }
+ void construct(pointer memory, const Y& value) {
+ allocator.construct(memory, value);
+ }
+ void destroy(pointer memory) {
+ allocator.destroy(memory);
+ }
+ template<typename U>
+ bool operator==(const allocate_array_helper<A, T[], U>& other) const {
+ return allocator == other.allocator;
+ }
+ template<typename U>
+ bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
+ return !(*this == other);
+ }
+ private:
+ A2 allocator;
+ std::size_t size;
+ T** data;
+ };
+ template<typename A, typename T, std::size_t N, typename Y>
+ class allocate_array_helper<A, T[N], Y> {
+ template<typename A9, typename T9, typename Y9>
+ friend class allocate_array_helper;
+ typedef typename A::template rebind<Y> ::other A2;
+ typedef typename A::template rebind<char>::other A3;
+ public:
+ typedef typename A2::value_type value_type;
+ typedef typename A2::pointer pointer;
+ typedef typename A2::const_pointer const_pointer;
+ typedef typename A2::reference reference;
+ typedef typename A2::const_reference const_reference;
+ typedef typename A2::size_type size_type;
+ typedef typename A2::difference_type difference_type;
+ template<typename U>
+ struct rebind {
+ typedef allocate_array_helper<A, T[N], U> other;
+ };
+ allocate_array_helper(const A& allocator, T** data)
+ : allocator(allocator),
+ data(data) {
+ }
+ template<class U>
+ allocate_array_helper(const allocate_array_helper<A, T[N], U>& other)
+ : allocator(other.allocator),
+ data(other.data) {
+ }
+ pointer address(reference value) const {
+ return allocator.address(value);
+ }
+ const_pointer address(const_reference value) const {
+ return allocator.address(value);
+ }
+ size_type max_size() const {
+ return allocator.max_size();
+ }
+ pointer allocate(size_type count, const void* value = 0) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ char* p1 = A3(allocator).allocate(n1 + N1, value);
+ char* p2 = p1 + n1;
+ while (std::size_t(p2) % a1 != 0) {
+ p2--;
+ }
+ *data = reinterpret_cast<T*>(p2);
+ return reinterpret_cast<Y*>(p1);
+ }
+ void deallocate(pointer memory, size_type count) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ char* p1 = reinterpret_cast<char*>(memory);
+ A3(allocator).deallocate(p1, n1 + N1);
+ }
+ void construct(pointer memory, const Y& value) {
+ allocator.construct(memory, value);
+ }
+ void destroy(pointer memory) {
+ allocator.destroy(memory);
+ }
+ template<typename U>
+ bool operator==(const allocate_array_helper<A, T[N], U>& other) const {
+ return allocator == other.allocator;
+ }
+ template<typename U>
+ bool operator!=(const allocate_array_helper<A, T[N], U>& other) const {
+ return !(*this == other);
+ }
+ private:
+ enum {
+ N1 = N * sizeof(T)
+ };
+ A2 allocator;
+ T** data;
+ };
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/array_deleter.hpp b/ndnboost/smart_ptr/detail/array_deleter.hpp
new file mode 100644
index 0000000..2afe96c
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/array_deleter.hpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
+#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
+
+#include <ndnboost/smart_ptr/detail/array_utility.hpp>
+#include <ndnboost/smart_ptr/detail/sp_forward.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename T>
+ class array_deleter;
+ template<typename T>
+ class array_deleter<T[]> {
+ public:
+ array_deleter(std::size_t size)
+ : size(size),
+ object(0) {
+ }
+ ~array_deleter() {
+ if (object) {
+ array_destroy(object, size);
+ }
+ }
+ void init(T* memory) {
+ array_init(memory, size);
+ object = memory;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ void init(T* memory, T&& value) {
+ array_init_value(memory, size, sp_forward<T>(value));
+ object = memory;
+ }
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename... Args>
+ void init(T* memory, Args&&... args) {
+ array_init_args(memory, size, sp_forward<Args>(args)...);
+ object = memory;
+ }
+#endif
+#endif
+ void init_list(T* memory, const T* list) {
+ array_init_list(memory, size, list);
+ object = memory;
+ }
+ template<std::size_t M>
+ void init_list(T* memory, const T* list) {
+ array_init_list<T, M>(memory, size, list);
+ object = memory;
+ }
+ void noinit(T* memory) {
+ array_noinit(memory, size);
+ object = memory;
+ }
+ void operator()(const void*) {
+ if (object) {
+ array_destroy(object, size);
+ object = 0;
+ }
+ }
+ private:
+ std::size_t size;
+ T* object;
+ };
+ template<typename T, std::size_t N>
+ class array_deleter<T[N]> {
+ public:
+ array_deleter()
+ : object(0) {
+ }
+ ~array_deleter() {
+ if (object) {
+ array_destroy(object, N);
+ }
+ }
+ void init(T* memory) {
+ array_init(memory, N);
+ object = memory;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ void init(T* memory, T&& value) {
+ array_init_value(memory, N, sp_forward<T>(value));
+ object = memory;
+ }
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename... Args>
+ void init(T* memory, Args&&... args) {
+ array_init_args(memory, N, sp_forward<Args>(args)...);
+ object = memory;
+ }
+#endif
+#endif
+ void init_list(T* memory, const T* list) {
+ array_init_list(memory, N, list);
+ object = memory;
+ }
+ template<std::size_t M>
+ void init_list(T* memory, const T* list) {
+ array_init_list<T, M>(memory, N, list);
+ object = memory;
+ }
+ void noinit(T* memory) {
+ array_noinit(memory, N);
+ object = memory;
+ }
+ void operator()(const void*) {
+ if (object) {
+ array_destroy(object, N);
+ object = 0;
+ }
+ }
+ private:
+ T* object;
+ };
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/array_traits.hpp b/ndnboost/smart_ptr/detail/array_traits.hpp
new file mode 100644
index 0000000..70d2391
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/array_traits.hpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
+#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
+
+#include <ndnboost/type_traits/remove_cv.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename T>
+ struct array_base {
+ typedef typename ndnboost::remove_cv<T>::type type;
+ };
+ template<typename T>
+ struct array_base<T[]> {
+ typedef typename array_base<T>::type type;
+ };
+ template<typename T, std::size_t N>
+ struct array_base<T[N]> {
+ typedef typename array_base<T>::type type;
+ };
+ template<typename T>
+ struct array_total {
+ enum {
+ size = 1
+ };
+ };
+ template<typename T, std::size_t N>
+ struct array_total<T[N]> {
+ enum {
+ size = N * array_total<T>::size
+ };
+ };
+ template<typename T>
+ struct array_inner;
+ template<typename T>
+ struct array_inner<T[]> {
+ typedef T type;
+ };
+ template<typename T, std::size_t N>
+ struct array_inner<T[N]> {
+ typedef T type;
+ };
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/array_utility.hpp b/ndnboost/smart_ptr/detail/array_utility.hpp
new file mode 100644
index 0000000..c482b54
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/array_utility.hpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
+#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/type_traits/has_trivial_constructor.hpp>
+#include <ndnboost/type_traits/has_trivial_destructor.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename T>
+ inline void array_destroy(T*, std::size_t, ndnboost::true_type) {
+ }
+ template<typename T>
+ inline void array_destroy(T* memory, std::size_t size, ndnboost::false_type) {
+ for (std::size_t i = size; i > 0; ) {
+ memory[--i].~T();
+ }
+ }
+ template<typename T>
+ inline void array_destroy(T* memory, std::size_t size) {
+ ndnboost::has_trivial_destructor<T> type;
+ array_destroy(memory, size, type);
+ }
+ template<typename T>
+ inline void array_init(T* memory, std::size_t size, ndnboost::true_type) {
+ for (std::size_t i = 0; i < size; i++) {
+ memory[i] = T();
+ }
+ }
+ template<typename T>
+ inline void array_init(T* memory, std::size_t size, ndnboost::false_type) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T();
+ }
+#endif
+ }
+ template<typename T>
+ inline void array_init(T* memory, std::size_t size) {
+ ndnboost::has_trivial_default_constructor<T> type;
+ array_init(memory, size, type);
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template<typename T>
+ inline void array_init_value(T* memory, std::size_t size, T&& value) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(value);
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(value);
+ }
+#endif
+ }
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<typename T, typename... Args>
+ inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(args...);
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(args...);
+ }
+#endif
+ }
+#endif
+#endif
+ template<typename T>
+ inline void array_init_list(T* memory, std::size_t size, const T* list) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i]);
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i]);
+ }
+#endif
+ }
+ template<typename T, std::size_t N>
+ inline void array_init_list(T* memory, std::size_t size, const T* list) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i % N]);
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T(list[i % N]);
+ }
+#endif
+ }
+ template<typename T>
+ inline void array_noinit(T*, std::size_t, ndnboost::true_type) {
+ }
+ template<typename T>
+ inline void array_noinit(T* memory, std::size_t size, ndnboost::false_type) {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ std::size_t i = 0;
+ try {
+ for (; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T;
+ }
+ } catch (...) {
+ array_destroy(memory, i);
+ throw;
+ }
+#else
+ for (std::size_t i = 0; i < size; i++) {
+ void* p1 = memory + i;
+ ::new(p1) T;
+ }
+#endif
+ }
+ template<typename T>
+ inline void array_noinit(T* memory, std::size_t size) {
+ ndnboost::has_trivial_default_constructor<T> type;
+ array_noinit(memory, size, type);
+ }
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/atomic_count.hpp b/ndnboost/smart_ptr/detail/atomic_count.hpp
new file mode 100644
index 0000000..01b661b
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count.hpp
@@ -0,0 +1,119 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
+//
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// typedef <implementation-defined> ndnboost::detail::atomic_count;
+//
+// atomic_count a(n);
+//
+// (n is convertible to long)
+//
+// Effects: Constructs an atomic_count with an initial value of n
+//
+// a;
+//
+// Returns: (long) the current value of a
+//
+// ++a;
+//
+// Effects: Atomically increments the value of a
+// Returns: (long) the new value of a
+//
+// --a;
+//
+// Effects: Atomically decrements the value of a
+// Returns: (long) the new value of a
+//
+// Important note: when --a returns zero, it must act as a
+// read memory barrier (RMB); i.e. the calling thread must
+// have a synchronized view of the memory
+//
+// On Intel IA-32 (x86) memory is always synchronized, so this
+// is not a problem.
+//
+// On many architectures the atomic instructions already act as
+// a memory barrier.
+//
+// This property is necessary for proper reference counting, since
+// a thread can update the contents of a shared object, then
+// release its reference, and another thread may immediately
+// release the last reference causing object destruction.
+//
+// The destructor needs to have a synchronized view of the
+// object to perform proper cleanup.
+//
+// Original example by Alexander Terekhov:
+//
+// Given:
+//
+// - a mutable shared object OBJ;
+// - two threads THREAD1 and THREAD2 each holding
+// a private smart_ptr object pointing to that OBJ.
+//
+// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
+// and a few cycles later (after "unlock") destroys smart_ptr;
+//
+// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
+// with respect to shared mutable object OBJ; OBJ destructors
+// are called driven by smart_ptr interface...
+//
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/smart_ptr/detail/sp_has_sync.hpp>
+
+#ifndef BOOST_HAS_THREADS
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+typedef long atomic_count;
+
+}
+
+}
+
+#elif defined(BOOST_AC_USE_PTHREADS)
+# include <ndnboost/smart_ptr/detail/atomic_count_pthreads.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+# include <ndnboost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
+
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# include <ndnboost/smart_ptr/detail/atomic_count_win32.hpp>
+
+#elif defined( BOOST_SP_HAS_SYNC )
+# include <ndnboost/smart_ptr/detail/atomic_count_sync.hpp>
+
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+# include <ndnboost/smart_ptr/detail/atomic_count_gcc.hpp>
+
+#elif defined(BOOST_HAS_PTHREADS)
+
+# define BOOST_AC_USE_PTHREADS
+# include <ndnboost/smart_ptr/detail/atomic_count_pthreads.hpp>
+
+#else
+
+// Use #define BOOST_DISABLE_THREADS to avoid the error
+#error Unrecognized threading platform
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/atomic_count_gcc.hpp b/ndnboost/smart_ptr/detail/atomic_count_gcc.hpp
new file mode 100644
index 0000000..0d87bde
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count_gcc.hpp
@@ -0,0 +1,72 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
+
+//
+// boost/detail/atomic_count_gcc.hpp
+//
+// atomic_count for GNU libstdc++ v3
+//
+// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
+//
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org>
+// Copyright 2003-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
+# include <ext/atomicity.h>
+#else
+# include <bits/atomicity.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if defined(__GLIBCXX__) // g++ 3.4+
+
+using __gnu_cxx::__atomic_add;
+using __gnu_cxx::__exchange_and_add;
+
+#endif
+
+class atomic_count
+{
+public:
+
+ explicit atomic_count( long v ) : value_( v ) {}
+
+ long operator++()
+ {
+ return __exchange_and_add( &value_, +1 ) + 1;
+ }
+
+ long operator--()
+ {
+ return __exchange_and_add( &value_, -1 ) - 1;
+ }
+
+ operator long() const
+ {
+ return __exchange_and_add( &value_, 0 );
+ }
+
+private:
+
+ atomic_count(atomic_count const &);
+ atomic_count & operator=(atomic_count const &);
+
+ mutable _Atomic_word value_;
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/atomic_count_gcc_x86.hpp b/ndnboost/smart_ptr/detail/atomic_count_gcc_x86.hpp
new file mode 100644
index 0000000..664a2b9
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count_gcc_x86.hpp
@@ -0,0 +1,77 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
+
+//
+// boost/detail/atomic_count_gcc_x86.hpp
+//
+// atomic_count for g++ on 486+/AMD64
+//
+// Copyright 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class atomic_count
+{
+public:
+
+ explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
+
+ long operator++()
+ {
+ return atomic_exchange_and_add( &value_, +1 ) + 1;
+ }
+
+ long operator--()
+ {
+ return atomic_exchange_and_add( &value_, -1 ) - 1;
+ }
+
+ operator long() const
+ {
+ return atomic_exchange_and_add( &value_, 0 );
+ }
+
+private:
+
+ atomic_count(atomic_count const &);
+ atomic_count & operator=(atomic_count const &);
+
+ mutable int value_;
+
+private:
+
+ static int atomic_exchange_and_add( int * pw, int dv )
+ {
+ // int r = *pw;
+ // *pw += dv;
+ // return r;
+
+ int r;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "+m"( *pw ), "=r"( r ): // outputs (%0, %1)
+ "1"( dv ): // inputs (%2 == %1)
+ "memory", "cc" // clobbers
+ );
+
+ return r;
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/atomic_count_pthreads.hpp b/ndnboost/smart_ptr/detail/atomic_count_pthreads.hpp
new file mode 100644
index 0000000..0945566
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count_pthreads.hpp
@@ -0,0 +1,96 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
+
+//
+// boost/detail/atomic_count_pthreads.hpp
+//
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <pthread.h>
+
+//
+// The generic pthread_mutex-based implementation sometimes leads to
+// inefficiencies. Example: a class with two atomic_count members
+// can get away with a single mutex.
+//
+// Users can detect this situation by checking BOOST_AC_USE_PTHREADS.
+//
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class atomic_count
+{
+private:
+
+ class scoped_lock
+ {
+ public:
+
+ scoped_lock(pthread_mutex_t & m): m_(m)
+ {
+ pthread_mutex_lock(&m_);
+ }
+
+ ~scoped_lock()
+ {
+ pthread_mutex_unlock(&m_);
+ }
+
+ private:
+
+ pthread_mutex_t & m_;
+ };
+
+public:
+
+ explicit atomic_count(long v): value_(v)
+ {
+ pthread_mutex_init(&mutex_, 0);
+ }
+
+ ~atomic_count()
+ {
+ pthread_mutex_destroy(&mutex_);
+ }
+
+ long operator++()
+ {
+ scoped_lock lock(mutex_);
+ return ++value_;
+ }
+
+ long operator--()
+ {
+ scoped_lock lock(mutex_);
+ return --value_;
+ }
+
+ operator long() const
+ {
+ scoped_lock lock(mutex_);
+ return value_;
+ }
+
+private:
+
+ atomic_count(atomic_count const &);
+ atomic_count & operator=(atomic_count const &);
+
+ mutable pthread_mutex_t mutex_;
+ long value_;
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/atomic_count_sync.hpp b/ndnboost/smart_ptr/detail/atomic_count_sync.hpp
new file mode 100644
index 0000000..39300e1
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count_sync.hpp
@@ -0,0 +1,61 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
+
+//
+// boost/detail/atomic_count_sync.hpp
+//
+// atomic_count for g++ 4.1+
+//
+// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
+//
+// Copyright 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include <ia64intrin.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class atomic_count
+{
+public:
+
+ explicit atomic_count( long v ) : value_( v ) {}
+
+ long operator++()
+ {
+ return __sync_add_and_fetch( &value_, 1 );
+ }
+
+ long operator--()
+ {
+ return __sync_add_and_fetch( &value_, -1 );
+ }
+
+ operator long() const
+ {
+ return __sync_fetch_and_add( &value_, 0 );
+ }
+
+private:
+
+ atomic_count(atomic_count const &);
+ atomic_count & operator=(atomic_count const &);
+
+ mutable long value_;
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/atomic_count_win32.hpp b/ndnboost/smart_ptr/detail/atomic_count_win32.hpp
new file mode 100644
index 0000000..0d0477a
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/atomic_count_win32.hpp
@@ -0,0 +1,63 @@
+#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/atomic_count_win32.hpp
+//
+// Copyright (c) 2001-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/detail/interlocked.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class atomic_count
+{
+public:
+
+ explicit atomic_count( long v ): value_( v )
+ {
+ }
+
+ long operator++()
+ {
+ return BOOST_INTERLOCKED_INCREMENT( &value_ );
+ }
+
+ long operator--()
+ {
+ return BOOST_INTERLOCKED_DECREMENT( &value_ );
+ }
+
+ operator long() const
+ {
+ return static_cast<long const volatile &>( value_ );
+ }
+
+private:
+
+ atomic_count( atomic_count const & );
+ atomic_count & operator=( atomic_count const & );
+
+ long value_;
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/lightweight_mutex.hpp b/ndnboost/smart_ptr/detail/lightweight_mutex.hpp
new file mode 100644
index 0000000..a48bb45
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/lightweight_mutex.hpp
@@ -0,0 +1,42 @@
+#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/lightweight_mutex.hpp - lightweight mutex
+//
+// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// typedef <unspecified> ndnboost::detail::lightweight_mutex;
+//
+// ndnboost::detail::lightweight_mutex is a header-only implementation of
+// a subset of the Mutex concept requirements:
+//
+// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
+//
+// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
+//
+
+#include <ndnboost/config.hpp>
+
+#if !defined(BOOST_HAS_THREADS)
+# include <ndnboost/smart_ptr/detail/lwm_nop.hpp>
+#elif defined(BOOST_HAS_PTHREADS)
+# include <ndnboost/smart_ptr/detail/lwm_pthreads.hpp>
+#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# include <ndnboost/smart_ptr/detail/lwm_win32_cs.hpp>
+#else
+// Use #define BOOST_DISABLE_THREADS to avoid the error
+# error Unrecognized threading platform
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/lwm_nop.hpp b/ndnboost/smart_ptr/detail/lwm_nop.hpp
new file mode 100644
index 0000000..94d1fc5
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/lwm_nop.hpp
@@ -0,0 +1,37 @@
+#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/lwm_nop.hpp
+//
+// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class lightweight_mutex
+{
+public:
+
+ typedef lightweight_mutex scoped_lock;
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/lwm_pthreads.hpp b/ndnboost/smart_ptr/detail/lwm_pthreads.hpp
new file mode 100644
index 0000000..38bbc91
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/lwm_pthreads.hpp
@@ -0,0 +1,87 @@
+#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/lwm_pthreads.hpp
+//
+// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/assert.hpp>
+#include <pthread.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class lightweight_mutex
+{
+private:
+
+ pthread_mutex_t m_;
+
+ lightweight_mutex(lightweight_mutex const &);
+ lightweight_mutex & operator=(lightweight_mutex const &);
+
+public:
+
+ lightweight_mutex()
+ {
+
+// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
+
+#if defined(__hpux) && defined(_DECTHREADS_)
+ BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
+#else
+ BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
+#endif
+ }
+
+ ~lightweight_mutex()
+ {
+ BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
+ }
+
+ class scoped_lock;
+ friend class scoped_lock;
+
+ class scoped_lock
+ {
+ private:
+
+ pthread_mutex_t & m_;
+
+ scoped_lock(scoped_lock const &);
+ scoped_lock & operator=(scoped_lock const &);
+
+ public:
+
+ scoped_lock(lightweight_mutex & m): m_(m.m_)
+ {
+ BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
+ }
+
+ ~scoped_lock()
+ {
+ BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
+ }
+ };
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/lwm_win32_cs.hpp b/ndnboost/smart_ptr/detail/lwm_win32_cs.hpp
new file mode 100644
index 0000000..e976c32
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/lwm_win32_cs.hpp
@@ -0,0 +1,108 @@
+#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/lwm_win32_cs.hpp
+//
+// Copyright (c) 2002, 2003 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef BOOST_USE_WINDOWS_H
+# include <windows.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#ifndef BOOST_USE_WINDOWS_H
+
+struct critical_section
+{
+ struct critical_section_debug * DebugInfo;
+ long LockCount;
+ long RecursionCount;
+ void * OwningThread;
+ void * LockSemaphore;
+#if defined(_WIN64)
+ unsigned __int64 SpinCount;
+#else
+ unsigned long SpinCount;
+#endif
+};
+
+extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
+extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
+
+#else
+
+typedef ::CRITICAL_SECTION critical_section;
+
+#endif // #ifndef BOOST_USE_WINDOWS_H
+
+class lightweight_mutex
+{
+private:
+
+ critical_section cs_;
+
+ lightweight_mutex(lightweight_mutex const &);
+ lightweight_mutex & operator=(lightweight_mutex const &);
+
+public:
+
+ lightweight_mutex()
+ {
+ InitializeCriticalSection(&cs_);
+ }
+
+ ~lightweight_mutex()
+ {
+ DeleteCriticalSection(&cs_);
+ }
+
+ class scoped_lock;
+ friend class scoped_lock;
+
+ class scoped_lock
+ {
+ private:
+
+ lightweight_mutex & m_;
+
+ scoped_lock(scoped_lock const &);
+ scoped_lock & operator=(scoped_lock const &);
+
+ public:
+
+ explicit scoped_lock(lightweight_mutex & m): m_(m)
+ {
+ EnterCriticalSection(&m_.cs_);
+ }
+
+ ~scoped_lock()
+ {
+ LeaveCriticalSection(&m_.cs_);
+ }
+ };
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/make_array_helper.hpp b/ndnboost/smart_ptr/detail/make_array_helper.hpp
new file mode 100644
index 0000000..e989f22
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/make_array_helper.hpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
+#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
+
+#include <ndnboost/type_traits/alignment_of.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename T, typename Y = char>
+ class make_array_helper;
+ template<typename T, typename Y>
+ class make_array_helper<T[], Y> {
+ template<typename T2, typename Y2>
+ friend class make_array_helper;
+ public:
+ typedef Y value_type;
+ typedef Y* pointer;
+ typedef const Y* const_pointer;
+ typedef Y& reference;
+ typedef const Y& const_reference;
+ typedef std::size_t size_type;
+ typedef ptrdiff_t difference_type;
+ template<typename U>
+ struct rebind {
+ typedef make_array_helper<T[], U> other;
+ };
+ make_array_helper(std::size_t size, T** data)
+ : size(sizeof(T) * size),
+ data(data) {
+ }
+ template<class U>
+ make_array_helper(const make_array_helper<T[], U>& other)
+ : size(other.size),
+ data(other.data) {
+ }
+ pointer address(reference value) const {
+ return &value;
+ }
+ const_pointer address(const_reference value) const {
+ return &value;
+ }
+ size_type max_size() const {
+ return static_cast<std::size_t>(-1) / sizeof(Y);
+ }
+ pointer allocate(size_type count, const void* = 0) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ void* p1 = ::operator new(n1 + size);
+ char* p2 = static_cast<char*>(p1) + n1;
+ while (std::size_t(p2) % a1 != 0) {
+ p2--;
+ }
+ *data = reinterpret_cast<T*>(p2);
+ return reinterpret_cast<Y*>(p1);
+ }
+ void deallocate(pointer memory, size_type) {
+ void* p1 = memory;
+ ::operator delete(p1);
+ }
+ void construct(pointer memory, const Y& value) {
+ void* p1 = memory;
+ ::new(p1) Y(value);
+ }
+ void destroy(pointer memory) {
+ memory->~Y();
+ }
+ template<typename U>
+ bool operator==(const make_array_helper<T[], U>& other) const {
+ return true;
+ }
+ template<typename U>
+ bool operator!=(const make_array_helper<T[], U>& other) const {
+ return !(*this == other);
+ }
+ private:
+ std::size_t size;
+ T** data;
+ };
+ template<typename T, std::size_t N, typename Y>
+ class make_array_helper<T[N], Y> {
+ template<typename T2, typename Y2>
+ friend class make_array_helper;
+ public:
+ typedef Y value_type;
+ typedef Y* pointer;
+ typedef const Y* const_pointer;
+ typedef Y& reference;
+ typedef const Y& const_reference;
+ typedef std::size_t size_type;
+ typedef ptrdiff_t difference_type;
+ template<typename U>
+ struct rebind {
+ typedef make_array_helper<T[N], U> other;
+ };
+ make_array_helper(T** data)
+ : data(data) {
+ }
+ template<class U>
+ make_array_helper(const make_array_helper<T[N], U>& other)
+ : data(other.data) {
+ }
+ pointer address(reference value) const {
+ return &value;
+ }
+ const_pointer address(const_reference value) const {
+ return &value;
+ }
+ size_type max_size() const {
+ return static_cast<std::size_t>(-1) / sizeof(Y);
+ }
+ pointer allocate(size_type count, const void* = 0) {
+ std::size_t a1 = ndnboost::alignment_of<T>::value;
+ std::size_t n1 = count * sizeof(Y) + a1 - 1;
+ void* p1 = ::operator new(n1 + N1);
+ char* p2 = static_cast<char*>(p1) + n1;
+ while (std::size_t(p2) % a1 != 0) {
+ p2--;
+ }
+ *data = reinterpret_cast<T*>(p2);
+ return reinterpret_cast<Y*>(p1);
+ }
+ void deallocate(pointer memory, size_type) {
+ void* p1 = memory;
+ ::operator delete(p1);
+ }
+ void construct(pointer memory, const Y& value) {
+ void* p1 = memory;
+ ::new(p1) Y(value);
+ }
+ void destroy(pointer memory) {
+ memory->~Y();
+ }
+ template<typename U>
+ bool operator==(const make_array_helper<T[N], U>& other) const {
+ return true;
+ }
+ template<typename U>
+ bool operator!=(const make_array_helper<T[N], U>& other) const {
+ return !(*this == other);
+ }
+ private:
+ enum {
+ N1 = N * sizeof(T)
+ };
+ T** data;
+ };
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/operator_bool.hpp b/ndnboost/smart_ptr/detail/operator_bool.hpp
new file mode 100644
index 0000000..8ae1527
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/operator_bool.hpp
@@ -0,0 +1,63 @@
+// This header intentionally has no include guards.
+//
+// Copyright (c) 2001-2009, 2012 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
+
+ explicit operator bool () const BOOST_NOEXCEPT
+ {
+ return px != 0;
+ }
+
+#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
+
+ operator bool () const BOOST_NOEXCEPT
+ {
+ return px != 0;
+ }
+
+#elif defined( _MANAGED )
+
+ static void unspecified_bool( this_type*** )
+ {
+ }
+
+ typedef void (*unspecified_bool_type)( this_type*** );
+
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
+ {
+ return px == 0? 0: unspecified_bool;
+ }
+
+#elif \
+ ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
+ ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
+ ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
+
+ typedef element_type * (this_type::*unspecified_bool_type)() const;
+
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
+ {
+ return px == 0? 0: &this_type::get;
+ }
+
+#else
+
+ typedef element_type * this_type::*unspecified_bool_type;
+
+ operator unspecified_bool_type() const BOOST_NOEXCEPT
+ {
+ return px == 0? 0: &this_type::px;
+ }
+
+#endif
+
+ // operator! is redundant, but some compilers need it
+ bool operator! () const BOOST_NOEXCEPT
+ {
+ return px == 0;
+ }
diff --git a/ndnboost/smart_ptr/detail/quick_allocator.hpp b/ndnboost/smart_ptr/detail/quick_allocator.hpp
new file mode 100644
index 0000000..637c4ec
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/quick_allocator.hpp
@@ -0,0 +1,199 @@
+#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/quick_allocator.hpp
+//
+// Copyright (c) 2003 David Abrahams
+// Copyright (c) 2003 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/config.hpp>
+
+#include <ndnboost/smart_ptr/detail/lightweight_mutex.hpp>
+#include <ndnboost/type_traits/type_with_alignment.hpp>
+#include <ndnboost/type_traits/alignment_of.hpp>
+
+#include <new> // ::operator new, ::operator delete
+#include <cstddef> // std::size_t
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+template<unsigned size, unsigned align_> union freeblock
+{
+ typedef typename ndnboost::type_with_alignment<align_>::type aligner_type;
+ aligner_type aligner;
+ char bytes[size];
+ freeblock * next;
+};
+
+template<unsigned size, unsigned align_> struct allocator_impl
+{
+ typedef freeblock<size, align_> block;
+
+ // It may seem odd to use such small pages.
+ //
+ // However, on a typical Windows implementation that uses
+ // the OS allocator, "normal size" pages interact with the
+ // "ordinary" operator new, slowing it down dramatically.
+ //
+ // 512 byte pages are handled by the small object allocator,
+ // and don't interfere with ::new.
+ //
+ // The other alternative is to use much bigger pages (1M.)
+ //
+ // It is surprisingly easy to hit pathological behavior by
+ // varying the page size. g++ 2.96 on Red Hat Linux 7.2,
+ // for example, passionately dislikes 496. 512 seems OK.
+
+#if defined(BOOST_QA_PAGE_SIZE)
+
+ enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
+
+#else
+
+ enum { items_per_page = 512 / size }; // 1048560 / size
+
+#endif
+
+#ifdef BOOST_HAS_THREADS
+
+ static lightweight_mutex & mutex()
+ {
+ static freeblock< sizeof( lightweight_mutex ), ndnboost::alignment_of< lightweight_mutex >::value > fbm;
+ static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
+ return *pm;
+ }
+
+ static lightweight_mutex * mutex_init;
+
+#endif
+
+ static block * free;
+ static block * page;
+ static unsigned last;
+
+ static inline void * alloc()
+ {
+#ifdef BOOST_HAS_THREADS
+ lightweight_mutex::scoped_lock lock( mutex() );
+#endif
+ if(block * x = free)
+ {
+ free = x->next;
+ return x;
+ }
+ else
+ {
+ if(last == items_per_page)
+ {
+ // "Listen to me carefully: there is no memory leak"
+ // -- Scott Meyers, Eff C++ 2nd Ed Item 10
+ page = ::new block[items_per_page];
+ last = 0;
+ }
+
+ return &page[last++];
+ }
+ }
+
+ static inline void * alloc(std::size_t n)
+ {
+ if(n != size) // class-specific new called for a derived object
+ {
+ return ::operator new(n);
+ }
+ else
+ {
+#ifdef BOOST_HAS_THREADS
+ lightweight_mutex::scoped_lock lock( mutex() );
+#endif
+ if(block * x = free)
+ {
+ free = x->next;
+ return x;
+ }
+ else
+ {
+ if(last == items_per_page)
+ {
+ page = ::new block[items_per_page];
+ last = 0;
+ }
+
+ return &page[last++];
+ }
+ }
+ }
+
+ static inline void dealloc(void * pv)
+ {
+ if(pv != 0) // 18.4.1.1/13
+ {
+#ifdef BOOST_HAS_THREADS
+ lightweight_mutex::scoped_lock lock( mutex() );
+#endif
+ block * pb = static_cast<block *>(pv);
+ pb->next = free;
+ free = pb;
+ }
+ }
+
+ static inline void dealloc(void * pv, std::size_t n)
+ {
+ if(n != size) // class-specific delete called for a derived object
+ {
+ ::operator delete(pv);
+ }
+ else if(pv != 0) // 18.4.1.1/13
+ {
+#ifdef BOOST_HAS_THREADS
+ lightweight_mutex::scoped_lock lock( mutex() );
+#endif
+ block * pb = static_cast<block *>(pv);
+ pb->next = free;
+ free = pb;
+ }
+ }
+};
+
+#ifdef BOOST_HAS_THREADS
+
+template<unsigned size, unsigned align_>
+ lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
+
+#endif
+
+template<unsigned size, unsigned align_>
+ freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
+
+template<unsigned size, unsigned align_>
+ freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
+
+template<unsigned size, unsigned align_>
+ unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
+
+template<class T>
+struct quick_allocator: public allocator_impl< sizeof(T), ndnboost::alignment_of<T>::value >
+{
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/shared_count.hpp b/ndnboost/smart_ptr/detail/shared_count.hpp
new file mode 100644
index 0000000..ad53ec0
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/shared_count.hpp
@@ -0,0 +1,603 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/shared_count.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef __BORLANDC__
+# pragma warn -8027 // Functions containing try are not expanded inline
+#endif
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/checked_delete.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/smart_ptr/bad_weak_ptr.hpp>
+#include <ndnboost/smart_ptr/detail/sp_counted_base.hpp>
+#include <ndnboost/smart_ptr/detail/sp_counted_impl.hpp>
+#include <ndnboost/detail/workaround.hpp>
+// In order to avoid circular dependencies with Boost.TR1
+// we make sure that our include of <memory> doesn't try to
+// pull in the TR1 headers: that's why we use this header
+// rather than including <memory> directly:
+#include <ndnboost/config/no_tr1/memory.hpp> // std::auto_ptr
+#include <functional> // std::less
+
+#ifdef BOOST_NO_EXCEPTIONS
+# include <new> // std::bad_alloc
+#endif
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+# include <ndnboost/utility/addressof.hpp>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+int const shared_count_id = 0x2C35F101;
+int const weak_count_id = 0x298C38A4;
+
+#endif
+
+struct sp_nothrow_tag {};
+
+template< class D > struct sp_inplace_tag
+{
+};
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+template< class T > class sp_reference_wrapper
+{
+public:
+
+ explicit sp_reference_wrapper( T & t): t_( ndnboost::addressof( t ) )
+ {
+ }
+
+ template< class Y > void operator()( Y * p ) const
+ {
+ (*t_)( p );
+ }
+
+private:
+
+ T * t_;
+};
+
+template< class D > struct sp_convert_reference
+{
+ typedef D type;
+};
+
+template< class D > struct sp_convert_reference< D& >
+{
+ typedef sp_reference_wrapper< D > type;
+};
+
+#endif
+
+class weak_count;
+
+class shared_count
+{
+private:
+
+ sp_counted_base * pi_;
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ int id_;
+#endif
+
+ friend class weak_count;
+
+public:
+
+ shared_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ }
+
+ template<class Y> explicit shared_count( Y * p ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = new sp_counted_impl_p<Y>( p );
+ }
+ catch(...)
+ {
+ ndnboost::checked_delete( p );
+ throw;
+ }
+
+#else
+
+ pi_ = new sp_counted_impl_p<Y>( p );
+
+ if( pi_ == 0 )
+ {
+ ndnboost::checked_delete( p );
+ ndnboost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+ }
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+ template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
+#else
+ template<class P, class D> shared_count( P p, D d ): pi_(0)
+#endif
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+ typedef Y* P;
+#endif
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = new sp_counted_impl_pd<P, D>(p, d);
+ }
+ catch(...)
+ {
+ d(p); // delete p
+ throw;
+ }
+
+#else
+
+ pi_ = new sp_counted_impl_pd<P, D>(p, d);
+
+ if(pi_ == 0)
+ {
+ d(p); // delete p
+ ndnboost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+ }
+
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+ template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = new sp_counted_impl_pd< P, D >( p );
+ }
+ catch( ... )
+ {
+ D()( p ); // delete p
+ throw;
+ }
+
+#else
+
+ pi_ = new sp_counted_impl_pd< P, D >( p );
+
+ if( pi_ == 0 )
+ {
+ D()( p ); // delete p
+ ndnboost::throw_exception( std::bad_alloc() );
+ }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+ }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+ template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef sp_counted_impl_pda<P, D, A> impl_type;
+ typedef typename A::template rebind< impl_type >::other A2;
+
+ A2 a2( a );
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+ new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+ }
+ catch(...)
+ {
+ d( p );
+
+ if( pi_ != 0 )
+ {
+ a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
+ }
+
+ throw;
+ }
+
+#else
+
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+
+ if( pi_ != 0 )
+ {
+ new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+ }
+ else
+ {
+ d( p );
+ ndnboost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+ }
+
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+ template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef sp_counted_impl_pda< P, D, A > impl_type;
+ typedef typename A::template rebind< impl_type >::other A2;
+
+ A2 a2( a );
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try
+ {
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+ new( static_cast< void* >( pi_ ) ) impl_type( p, a );
+ }
+ catch(...)
+ {
+ D()( p );
+
+ if( pi_ != 0 )
+ {
+ a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
+ }
+
+ throw;
+ }
+
+#else
+
+ pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+
+ if( pi_ != 0 )
+ {
+ new( static_cast< void* >( pi_ ) ) impl_type( p, a );
+ }
+ else
+ {
+ D()( p );
+ ndnboost::throw_exception( std::bad_alloc() );
+ }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+ }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+#ifndef BOOST_NO_AUTO_PTR
+
+ // auto_ptr<Y> is special cased to provide the strong guarantee
+
+ template<class Y>
+ explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ ndnboost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+
+ r.release();
+ }
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+ template<class Y, class D>
+ explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ typedef typename sp_convert_reference<D>::type D2;
+
+ D2 d2( r.get_deleter() );
+ pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+ if( pi_ == 0 )
+ {
+ ndnboost::throw_exception( std::bad_alloc() );
+ }
+
+#endif
+
+ r.release();
+ }
+
+#endif
+
+ ~shared_count() // nothrow
+ {
+ if( pi_ != 0 ) pi_->release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ id_ = 0;
+#endif
+ }
+
+ shared_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ if( pi_ != 0 ) pi_->add_ref_copy();
+ }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ shared_count(shared_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ r.pi_ = 0;
+ }
+
+#endif
+
+ explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
+ shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
+
+ shared_count & operator= (shared_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if( tmp != 0 ) tmp->add_ref_copy();
+ if( pi_ != 0 ) pi_->release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ void swap(shared_count & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+ r.pi_ = pi_;
+ pi_ = tmp;
+ }
+
+ long use_count() const // nothrow
+ {
+ return pi_ != 0? pi_->use_count(): 0;
+ }
+
+ bool unique() const // nothrow
+ {
+ return use_count() == 1;
+ }
+
+ bool empty() const // nothrow
+ {
+ return pi_ == 0;
+ }
+
+ friend inline bool operator==(shared_count const & a, shared_count const & b)
+ {
+ return a.pi_ == b.pi_;
+ }
+
+ friend inline bool operator<(shared_count const & a, shared_count const & b)
+ {
+ return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
+ }
+
+ void * get_deleter( sp_typeinfo const & ti ) const
+ {
+ return pi_? pi_->get_deleter( ti ): 0;
+ }
+
+ void * get_untyped_deleter() const
+ {
+ return pi_? pi_->get_untyped_deleter(): 0;
+ }
+};
+
+
+class weak_count
+{
+private:
+
+ sp_counted_base * pi_;
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ int id_;
+#endif
+
+ friend class shared_count;
+
+public:
+
+ weak_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ }
+
+ weak_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ if(pi_ != 0) pi_->weak_add_ref();
+ }
+
+ weak_count(weak_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ if(pi_ != 0) pi_->weak_add_ref();
+ }
+
+// Move support
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+ weak_count(weak_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(weak_count_id)
+#endif
+ {
+ r.pi_ = 0;
+ }
+
+#endif
+
+ ~weak_count() // nothrow
+ {
+ if(pi_ != 0) pi_->weak_release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ id_ = 0;
+#endif
+ }
+
+ weak_count & operator= (shared_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if(tmp != 0) tmp->weak_add_ref();
+ if(pi_ != 0) pi_->weak_release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ weak_count & operator= (weak_count const & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+
+ if( tmp != pi_ )
+ {
+ if(tmp != 0) tmp->weak_add_ref();
+ if(pi_ != 0) pi_->weak_release();
+ pi_ = tmp;
+ }
+
+ return *this;
+ }
+
+ void swap(weak_count & r) // nothrow
+ {
+ sp_counted_base * tmp = r.pi_;
+ r.pi_ = pi_;
+ pi_ = tmp;
+ }
+
+ long use_count() const // nothrow
+ {
+ return pi_ != 0? pi_->use_count(): 0;
+ }
+
+ bool empty() const // nothrow
+ {
+ return pi_ == 0;
+ }
+
+ friend inline bool operator==(weak_count const & a, weak_count const & b)
+ {
+ return a.pi_ == b.pi_;
+ }
+
+ friend inline bool operator<(weak_count const & a, weak_count const & b)
+ {
+ return std::less<sp_counted_base *>()(a.pi_, b.pi_);
+ }
+};
+
+inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+{
+ if( pi_ == 0 || !pi_->add_ref_lock() )
+ {
+ ndnboost::throw_exception( ndnboost::bad_weak_ptr() );
+ }
+}
+
+inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+{
+ if( pi_ != 0 && !pi_->add_ref_lock() )
+ {
+ pi_ = 0;
+ }
+}
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#ifdef __BORLANDC__
+# pragma warn .8027 // Functions containing try are not expanded inline
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/shared_ptr_nmt.hpp b/ndnboost/smart_ptr/detail/shared_ptr_nmt.hpp
new file mode 100644
index 0000000..76e6fdd
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/shared_ptr_nmt.hpp
@@ -0,0 +1,182 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
+
+//
+// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
+//
+// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
+//
+
+#include <ndnboost/assert.hpp>
+#include <ndnboost/checked_delete.hpp>
+#include <ndnboost/throw_exception.hpp>
+#include <ndnboost/smart_ptr/detail/atomic_count.hpp>
+
+#ifndef BOOST_NO_AUTO_PTR
+# include <memory> // for std::auto_ptr
+#endif
+
+#include <algorithm> // for std::swap
+#include <functional> // for std::less
+#include <new> // for std::bad_alloc
+
+namespace ndnboost
+{
+
+template<class T> class shared_ptr
+{
+private:
+
+ typedef detail::atomic_count count_type;
+
+public:
+
+ typedef T element_type;
+ typedef T value_type;
+
+ explicit shared_ptr(T * p = 0): px(p)
+ {
+#ifndef BOOST_NO_EXCEPTIONS
+
+ try // prevent leak if new throws
+ {
+ pn = new count_type(1);
+ }
+ catch(...)
+ {
+ ndnboost::checked_delete(p);
+ throw;
+ }
+
+#else
+
+ pn = new count_type(1);
+
+ if(pn == 0)
+ {
+ ndnboost::checked_delete(p);
+ ndnboost::throw_exception(std::bad_alloc());
+ }
+
+#endif
+ }
+
+ ~shared_ptr()
+ {
+ if(--*pn == 0)
+ {
+ ndnboost::checked_delete(px);
+ delete pn;
+ }
+ }
+
+ shared_ptr(shared_ptr const & r): px(r.px) // never throws
+ {
+ pn = r.pn;
+ ++*pn;
+ }
+
+ shared_ptr & operator=(shared_ptr const & r)
+ {
+ shared_ptr(r).swap(*this);
+ return *this;
+ }
+
+#ifndef BOOST_NO_AUTO_PTR
+
+ explicit shared_ptr(std::auto_ptr<T> & r)
+ {
+ pn = new count_type(1); // may throw
+ px = r.release(); // fix: moved here to stop leak if new throws
+ }
+
+ shared_ptr & operator=(std::auto_ptr<T> & r)
+ {
+ shared_ptr(r).swap(*this);
+ return *this;
+ }
+
+#endif
+
+ void reset(T * p = 0)
+ {
+ BOOST_ASSERT(p == 0 || p != px);
+ shared_ptr(p).swap(*this);
+ }
+
+ T & operator*() const // never throws
+ {
+ BOOST_ASSERT(px != 0);
+ return *px;
+ }
+
+ T * operator->() const // never throws
+ {
+ BOOST_ASSERT(px != 0);
+ return px;
+ }
+
+ T * get() const // never throws
+ {
+ return px;
+ }
+
+ long use_count() const // never throws
+ {
+ return *pn;
+ }
+
+ bool unique() const // never throws
+ {
+ return *pn == 1;
+ }
+
+ void swap(shared_ptr<T> & other) // never throws
+ {
+ std::swap(px, other.px);
+ std::swap(pn, other.pn);
+ }
+
+private:
+
+ T * px; // contained pointer
+ count_type * pn; // ptr to reference counter
+};
+
+template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
+{
+ return a.get() == b.get();
+}
+
+template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
+{
+ return a.get() != b.get();
+}
+
+template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
+{
+ return std::less<T*>()(a.get(), b.get());
+}
+
+template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
+{
+ a.swap(b);
+}
+
+// get_pointer() enables ndnboost::mem_fn to recognize shared_ptr
+
+template<class T> inline T * get_pointer(shared_ptr<T> const & p)
+{
+ return p.get();
+}
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_convertible.hpp b/ndnboost/smart_ptr/detail/sp_convertible.hpp
new file mode 100644
index 0000000..f4e5463
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_convertible.hpp
@@ -0,0 +1,91 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_convertible.hpp
+//
+// Copyright 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <ndnboost/config.hpp>
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+template< class Y, class T > struct sp_convertible
+{
+ typedef char (&yes) [1];
+ typedef char (&no) [2];
+
+ static yes f( T* );
+ static no f( ... );
+
+ enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
+};
+
+template< class Y, class T > struct sp_convertible< Y, T[] >
+{
+ enum _vt { value = false };
+};
+
+template< class Y, class T > struct sp_convertible< Y[], T[] >
+{
+ enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
+template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
+{
+ enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
+struct sp_empty
+{
+};
+
+template< bool > struct sp_enable_if_convertible_impl;
+
+template<> struct sp_enable_if_convertible_impl<true>
+{
+ typedef sp_empty type;
+};
+
+template<> struct sp_enable_if_convertible_impl<false>
+{
+};
+
+template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
+{
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base.hpp b/ndnboost/smart_ptr/detail/sp_counted_base.hpp
new file mode 100644
index 0000000..a9b5b81
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base.hpp
@@ -0,0 +1,79 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base.hpp
+//
+// Copyright 2005, 2006 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/smart_ptr/detail/sp_has_sync.hpp>
+
+#if defined( BOOST_SP_DISABLE_THREADS )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#elif defined( BOOST_SP_USE_SPINLOCK )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_spin.hpp>
+
+#elif defined( BOOST_SP_USE_PTHREADS )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_pt.hpp>
+
+#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#elif defined( __SNC__ )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
+# include <ndnboost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
+
+#elif defined(__HP_aCC) && defined(__ia64)
+# include <ndnboost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
+
+#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
+# include <ndnboost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
+
+#elif defined( __IBMCPP__ ) && defined( __powerpc )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
+
+#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
+# include <ndnboost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
+
+#elif defined( BOOST_SP_HAS_SYNC )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_sync.hpp>
+
+#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
+
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
+# include <ndnboost/smart_ptr/detail/sp_counted_base_w32.hpp>
+
+#elif defined( _AIX )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_aix.hpp>
+
+#elif !defined( BOOST_HAS_THREADS )
+# include <ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#else
+# include <ndnboost/smart_ptr/detail/sp_counted_base_spin.hpp>
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
new file mode 100644
index 0000000..a4dadf6
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
@@ -0,0 +1,151 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
+//
+// Copyright 2007 Baruch Zilber
+// Copyright 2007 Boris Gubenko
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <machine/sys/inline.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
+ if (1 == r)
+ {
+ _Asm_mf();
+ }
+
+ return r - 1;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int v = *pw;
+
+ for (;;)
+ {
+ if (0 == v)
+ {
+ return 0;
+ }
+
+ _Asm_mov_to_ar(_AREG_CCV,
+ v,
+ (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
+ int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
+ if (r == v)
+ {
+ return r + 1;
+ }
+
+ v = r;
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_aix.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_aix.hpp
new file mode 100644
index 0000000..a9a72cc
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_aix.hpp
@@ -0,0 +1,143 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_aix.hpp
+// based on: detail/sp_counted_base_w32.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+// Copyright 2006 Michael van der Westhuizen
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <builtins.h>
+#include <sys/atomic_op.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int32_t* pw )
+{
+ // ++*pw;
+
+ fetch_and_add( pw, 1 );
+}
+
+inline int32_t atomic_decrement( int32_t * pw )
+{
+ // return --*pw;
+
+ int32_t originalValue;
+
+ __lwsync();
+ originalValue = fetch_and_add( pw, -1 );
+ __isync();
+
+ return (originalValue - 1);
+}
+
+inline int32_t atomic_conditional_increment( int32_t * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int32_t tmp = fetch_and_add( pw, 0 );
+ for( ;; )
+ {
+ if( tmp == 0 ) return 0;
+ if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int32_t use_count_; // #shared
+ int32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
new file mode 100644
index 0000000..af43e37
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
@@ -0,0 +1,171 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+loop:
+
+ lwarx a, 0, pw
+ addi a, a, 1
+ stwcx. a, 0, pw
+ bne- loop
+ }
+}
+
+inline long atomic_decrement( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+ sync
+
+loop:
+
+ lwarx a, 0, pw
+ addi a, a, -1
+ stwcx. a, 0, pw
+ bne- loop
+
+ isync
+ }
+
+ return a;
+}
+
+inline long atomic_conditional_increment( register long * pw )
+{
+ register int a;
+
+ asm
+ {
+loop:
+
+ lwarx a, 0, pw
+ cmpwi a, 0
+ beq store
+
+ addi a, a, 1
+
+store:
+
+ stwcx. a, 0, pw
+ bne- loop
+ }
+
+ return a;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<long const volatile &>( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
new file mode 100644
index 0000000..c3652f4
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
@@ -0,0 +1,158 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2006 Peter Dimov
+// Copyright 2005 Ben Hutchings
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ // No barrier is required here but fetchadd always has an acquire or
+ // release barrier associated with it. We choose release as it should be
+ // cheaper.
+ __asm__ ("fetchadd4.rel %0=%1,1" :
+ "=r"(tmp), "=m"(*pw) :
+ "m"( *pw ));
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv;
+
+ __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
+ " cmp.eq p7,p0=1,%0 ;; \n"
+ "(p7) ld4.acq %0=%1 " :
+ "=&r"(rv), "=m"(*pw) :
+ "m"( *pw ) :
+ "p7");
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv, tmp, tmp2;
+
+ __asm__ ("0: ld4 %0=%3 ;; \n"
+ " cmp.eq p7,p0=0,%0 ;; \n"
+ "(p7) br.cond.spnt 1f \n"
+ " mov ar.ccv=%0 \n"
+ " add %1=1,%0 ;; \n"
+ " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
+ " cmp.ne p7,p0=%0,%2 ;; \n"
+ "(p7) br.cond.spnt 0b \n"
+ " mov %0=%1 ;; \n"
+ "1:" :
+ "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
+ "m"( *pw ) :
+ "ar.ccv", "p7");
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
new file mode 100644
index 0000000..e11b25a
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
@@ -0,0 +1,182 @@
+#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
+#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
+//
+// Copyright (c) 2009, Spirent Communications, Inc.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
+ "ll %0, %1\n\t"
+ "addiu %0, 1\n\t"
+ "sc %0, %1\n\t"
+ ".set pop\n\t"
+ "beqz %0, 0b":
+ "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw )
+ );
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv, tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
+ "ll %1, %2\n\t"
+ "addiu %0, %1, -1\n\t"
+ "sc %0, %2\n\t"
+ ".set pop\n\t"
+ "beqz %0, 0b\n\t"
+ "addiu %0, %1, -1":
+ "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw ):
+ "memory"
+ );
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv, tmp;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ ".set push\n\t"
+ ".set mips2\n\t"
+ "ll %0, %2\n\t"
+ "beqz %0, 1f\n\t"
+ "addiu %1, %0, 1\n\t"
+ "sc %1, %2\n\t"
+ ".set pop\n\t"
+ "beqz %1, 0b\n\t"
+ "addiu %0, %0, 1\n\t"
+ "1:":
+ "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
+ "m"( *pw ):
+ "memory"
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<int const volatile &>( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
new file mode 100644
index 0000000..9beacd0
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
@@ -0,0 +1,182 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+ // ++*pw;
+
+ int tmp;
+
+ __asm__
+ (
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "addi %1, %1, 1\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b":
+
+ "=m"( *pw ), "=&b"( tmp ):
+ "r"( pw ), "m"( *pw ):
+ "cc"
+ );
+}
+
+inline int atomic_decrement( int * pw )
+{
+ // return --*pw;
+
+ int rv;
+
+ __asm__ __volatile__
+ (
+ "sync\n\t"
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "addi %1, %1, -1\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b\n\t"
+ "isync":
+
+ "=m"( *pw ), "=&b"( rv ):
+ "r"( pw ), "m"( *pw ):
+ "memory", "cc"
+ );
+
+ return rv;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ int rv;
+
+ __asm__
+ (
+ "0:\n\t"
+ "lwarx %1, 0, %2\n\t"
+ "cmpwi %1, 0\n\t"
+ "beq 1f\n\t"
+ "addi %1, %1, 1\n\t"
+ "1:\n\t"
+ "stwcx. %1, 0, %2\n\t"
+ "bne- 0b":
+
+ "=m"( *pw ), "=&b"( rv ):
+ "r"( pw ), "m"( *pw ):
+ "cc"
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<int const volatile &>( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
new file mode 100644
index 0000000..a9e1b4e
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
@@ -0,0 +1,167 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
+//
+// Copyright (c) 2006 Piotr Wyderski
+// Copyright (c) 2006 Tomas Puverle
+// Copyright (c) 2006 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+// Thanks to Michael van der Westhuizen
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <inttypes.h> // int32_t
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
+{
+ __asm__ __volatile__( "cas [%1], %2, %0"
+ : "+r" (swap_)
+ : "r" (dest_), "r" (compare_)
+ : "memory" );
+
+ return swap_;
+}
+
+inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
+{
+ // long r = *pw;
+ // *pw += dv;
+ // return r;
+
+ for( ;; )
+ {
+ int32_t r = *pw;
+
+ if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
+ {
+ return r;
+ }
+ }
+}
+
+inline void atomic_increment( int32_t * pw )
+{
+ atomic_fetch_and_add( pw, 1 );
+}
+
+inline int32_t atomic_decrement( int32_t * pw )
+{
+ return atomic_fetch_and_add( pw, -1 );
+}
+
+inline int32_t atomic_conditional_increment( int32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ for( ;; )
+ {
+ int32_t r = *pw;
+
+ if( r == 0 )
+ {
+ return r;
+ }
+
+ if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
+ {
+ return r;
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int32_t use_count_; // #shared
+ int32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return const_cast< int32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
new file mode 100644
index 0000000..24a3798
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
@@ -0,0 +1,174 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+ // int r = *pw;
+ // *pw += dv;
+ // return r;
+
+ int r;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
+ "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
+ "memory", "cc" // clobbers
+ );
+
+ return r;
+}
+
+inline void atomic_increment( int * pw )
+{
+ //atomic_exchange_and_add( pw, 1 );
+
+ __asm__
+ (
+ "lock\n\t"
+ "incl %0":
+ "=m"( *pw ): // output (%0)
+ "m"( *pw ): // input (%1)
+ "cc" // clobbers
+ );
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ // int rv = *pw;
+ // if( rv != 0 ) ++*pw;
+ // return rv;
+
+ int rv, tmp;
+
+ __asm__
+ (
+ "movl %0, %%eax\n\t"
+ "0:\n\t"
+ "test %%eax, %%eax\n\t"
+ "je 1f\n\t"
+ "movl %%eax, %2\n\t"
+ "incl %2\n\t"
+ "lock\n\t"
+ "cmpxchgl %2, %0\n\t"
+ "jne 0b\n\t"
+ "1:":
+ "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
+ "m"( *pw ): // input (%3)
+ "cc" // clobbers
+ );
+
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<int const volatile &>( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp
new file mode 100644
index 0000000..3442f1f
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_nt.hpp
@@ -0,0 +1,108 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_nt.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ ++use_count_;
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ if( use_count_ == 0 ) return false;
+ ++use_count_;
+ return true;
+ }
+
+ void release() // nothrow
+ {
+ if( --use_count_ == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ ++weak_count_;
+ }
+
+ void weak_release() // nothrow
+ {
+ if( --weak_count_ == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return use_count_;
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_pt.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_pt.hpp
new file mode 100644
index 0000000..51c42a3
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_pt.hpp
@@ -0,0 +1,136 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_pt.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <pthread.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+ mutable pthread_mutex_t m_;
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
+
+#if defined(__hpux) && defined(_DECTHREADS_)
+ pthread_mutex_init( &m_, pthread_mutexattr_default );
+#else
+ pthread_mutex_init( &m_, 0 );
+#endif
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ pthread_mutex_destroy( &m_ );
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ pthread_mutex_lock( &m_ );
+ ++use_count_;
+ pthread_mutex_unlock( &m_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ pthread_mutex_lock( &m_ );
+ bool r = use_count_ == 0? false: ( ++use_count_, true );
+ pthread_mutex_unlock( &m_ );
+ return r;
+ }
+
+ void release() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long new_use_count = --use_count_;
+ pthread_mutex_unlock( &m_ );
+
+ if( new_use_count == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ ++weak_count_;
+ pthread_mutex_unlock( &m_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long new_weak_count = --weak_count_;
+ pthread_mutex_unlock( &m_ );
+
+ if( new_weak_count == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ pthread_mutex_lock( &m_ );
+ long r = use_count_;
+ pthread_mutex_unlock( &m_ );
+
+ return r;
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
new file mode 100644
index 0000000..4609d7d
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
@@ -0,0 +1,162 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
+//
+// Copyright (c) 2006 Piotr Wyderski
+// Copyright (c) 2006 Tomas Puverle
+// Copyright (c) 2006 Peter Dimov
+// Copyright (c) 2011 Emil Dotchevski
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+// Thanks to Michael van der Westhuizen
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <inttypes.h> // uint32_t
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
+{
+ return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
+}
+
+inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
+{
+ // long r = *pw;
+ // *pw += dv;
+ // return r;
+
+ for( ;; )
+ {
+ uint32_t r = *pw;
+
+ if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
+ {
+ return r;
+ }
+ }
+}
+
+inline void atomic_increment( uint32_t * pw )
+{
+ (void) __builtin_cellAtomicIncr32( pw );
+}
+
+inline uint32_t atomic_decrement( uint32_t * pw )
+{
+ return __builtin_cellAtomicDecr32( pw );
+}
+
+inline uint32_t atomic_conditional_increment( uint32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ for( ;; )
+ {
+ uint32_t r = *pw;
+
+ if( r == 0 )
+ {
+ return r;
+ }
+
+ if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
+ {
+ return r;
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ uint32_t use_count_; // #shared
+ uint32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return const_cast< uint32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_spin.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_spin.hpp
new file mode 100644
index 0000000..29d3a84
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_spin.hpp
@@ -0,0 +1,132 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <ndnboost/smart_ptr/detail/spinlock_pool.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+
+ int r = *pw;
+ *pw += dv;
+ return r;
+}
+
+inline void atomic_increment( int * pw )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+ ++*pw;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+ spinlock_pool<1>::scoped_lock lock( pw );
+
+ int rv = *pw;
+ if( rv != 0 ) ++*pw;
+ return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ spinlock_pool<1>::scoped_lock lock( &use_count_ );
+ return use_count_;
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_sync.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_sync.hpp
new file mode 100644
index 0000000..6ee7fac
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_sync.hpp
@@ -0,0 +1,156 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
+//
+// Copyright (c) 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+#include <limits.h>
+
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include <ia64intrin.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if INT_MAX >= 2147483647
+
+typedef int sp_int32_t;
+
+#else
+
+typedef long sp_int32_t;
+
+#endif
+
+inline void atomic_increment( sp_int32_t * pw )
+{
+ __sync_fetch_and_add( pw, 1 );
+}
+
+inline sp_int32_t atomic_decrement( sp_int32_t * pw )
+{
+ return __sync_fetch_and_add( pw, -1 );
+}
+
+inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
+{
+ // long r = *pw;
+ // if( r != 0 ) ++*pw;
+ // return r;
+
+ sp_int32_t r = *pw;
+
+ for( ;; )
+ {
+ if( r == 0 )
+ {
+ return r;
+ }
+
+ sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
+
+ if( r2 == r )
+ {
+ return r;
+ }
+ else
+ {
+ r = r2;
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ sp_int32_t use_count_; // #shared
+ sp_int32_t weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 1 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 1 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return const_cast< sp_int32_t const volatile & >( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
new file mode 100644
index 0000000..9ffae4d
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
@@ -0,0 +1,151 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
+
+//
+// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
+// based on: detail/sp_counted_base_w32.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+// Copyright 2006 Michael van der Westhuizen
+// Copyright 2012 IBM Corp.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+extern "builtin" void __lwsync(void);
+extern "builtin" void __isync(void);
+extern "builtin" int __fetch_and_add(volatile int* addr, int val);
+extern "builtin" int __compare_and_swap(volatile int*, int*, int);
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int *pw )
+{
+ // ++*pw;
+ __lwsync();
+ __fetch_and_add(pw, 1);
+ __isync();
+}
+
+inline int atomic_decrement( int *pw )
+{
+ // return --*pw;
+ __lwsync();
+ int originalValue = __fetch_and_add(pw, -1);
+ __isync();
+
+ return (originalValue - 1);
+}
+
+inline int atomic_conditional_increment( int *pw )
+{
+ // if( *pw != 0 ) ++*pw;
+ // return *pw;
+
+ __lwsync();
+ int v = *const_cast<volatile int*>(pw);
+ for (;;)
+ // loop until state is known
+ {
+ if (v == 0) return 0;
+ if (__compare_and_swap(pw, &v, v + 1))
+ {
+ __isync(); return (v + 1);
+ }
+ }
+}
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ int use_count_; // #shared
+ int weak_count_; // #weak + (#shared != 0)
+ char pad[64] __attribute__((__aligned__(64)));
+ // pad to prevent false sharing
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ atomic_increment( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ return atomic_conditional_increment( &use_count_ ) != 0;
+ }
+
+ void release() // nothrow
+ {
+ if( atomic_decrement( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ atomic_increment( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( atomic_decrement( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return *const_cast<volatile int*>(&use_count_);
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_base_w32.hpp b/ndnboost/smart_ptr/detail/sp_counted_base_w32.hpp
new file mode 100644
index 0000000..283fc79
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_base_w32.hpp
@@ -0,0 +1,131 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_base_w32.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// Lock-free algorithm by Alexander Terekhov
+//
+// Thanks to Ben Hitchings for the #weak + (#shared != 0)
+// formulation
+//
+
+#include <ndnboost/detail/interlocked.hpp>
+#include <ndnboost/detail/workaround.hpp>
+#include <ndnboost/detail/sp_typeinfo.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class sp_counted_base
+{
+private:
+
+ sp_counted_base( sp_counted_base const & );
+ sp_counted_base & operator= ( sp_counted_base const & );
+
+ long use_count_; // #shared
+ long weak_count_; // #weak + (#shared != 0)
+
+public:
+
+ sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+ {
+ }
+
+ virtual ~sp_counted_base() // nothrow
+ {
+ }
+
+ // dispose() is called when use_count_ drops to zero, to release
+ // the resources managed by *this.
+
+ virtual void dispose() = 0; // nothrow
+
+ // destroy() is called when weak_count_ drops to zero.
+
+ virtual void destroy() // nothrow
+ {
+ delete this;
+ }
+
+ virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+ virtual void * get_untyped_deleter() = 0;
+
+ void add_ref_copy()
+ {
+ BOOST_INTERLOCKED_INCREMENT( &use_count_ );
+ }
+
+ bool add_ref_lock() // true on success
+ {
+ for( ;; )
+ {
+ long tmp = static_cast< long const volatile& >( use_count_ );
+ if( tmp == 0 ) return false;
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
+
+ // work around a code generation bug
+
+ long tmp2 = tmp + 1;
+ if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
+
+#else
+
+ if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
+
+#endif
+ }
+ }
+
+ void release() // nothrow
+ {
+ if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
+ {
+ dispose();
+ weak_release();
+ }
+ }
+
+ void weak_add_ref() // nothrow
+ {
+ BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
+ }
+
+ void weak_release() // nothrow
+ {
+ if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
+ {
+ destroy();
+ }
+ }
+
+ long use_count() const // nothrow
+ {
+ return static_cast<long const volatile &>( use_count_ );
+ }
+};
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_counted_impl.hpp b/ndnboost/smart_ptr/detail/sp_counted_impl.hpp
new file mode 100644
index 0000000..9b03a26
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_counted_impl.hpp
@@ -0,0 +1,254 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// detail/sp_counted_impl.hpp
+//
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+// Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/config.hpp>
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
+#endif
+
+#include <ndnboost/checked_delete.hpp>
+#include <ndnboost/smart_ptr/detail/sp_counted_base.hpp>
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+#include <ndnboost/smart_ptr/detail/quick_allocator.hpp>
+#endif
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+#include <memory> // std::allocator
+#endif
+
+#include <cstddef> // std::size_t
+
+namespace ndnboost
+{
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
+void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
+
+#endif
+
+namespace detail
+{
+
+template<class X> class sp_counted_impl_p: public sp_counted_base
+{
+private:
+
+ X * px_;
+
+ sp_counted_impl_p( sp_counted_impl_p const & );
+ sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
+
+ typedef sp_counted_impl_p<X> this_type;
+
+public:
+
+ explicit sp_counted_impl_p( X * px ): px_( px )
+ {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ ndnboost::sp_scalar_constructor_hook( px, sizeof(X), this );
+#endif
+ }
+
+ virtual void dispose() // nothrow
+ {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ ndnboost::sp_scalar_destructor_hook( px_, sizeof(X), this );
+#endif
+ ndnboost::checked_delete( px_ );
+ }
+
+ virtual void * get_deleter( detail::sp_typeinfo const & )
+ {
+ return 0;
+ }
+
+ virtual void * get_untyped_deleter()
+ {
+ return 0;
+ }
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+
+ void * operator new( std::size_t )
+ {
+ return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
+ }
+
+ void operator delete( void * p )
+ {
+ std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
+ }
+
+#endif
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+
+ void * operator new( std::size_t )
+ {
+ return quick_allocator<this_type>::alloc();
+ }
+
+ void operator delete( void * p )
+ {
+ quick_allocator<this_type>::dealloc( p );
+ }
+
+#endif
+};
+
+//
+// Borland's Codeguard trips up over the -Vx- option here:
+//
+#ifdef __CODEGUARD__
+# pragma option push -Vx-
+#endif
+
+template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
+{
+private:
+
+ P ptr; // copy constructor must not throw
+ D del; // copy constructor must not throw
+
+ sp_counted_impl_pd( sp_counted_impl_pd const & );
+ sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
+
+ typedef sp_counted_impl_pd<P, D> this_type;
+
+public:
+
+ // pre: d(p) must not throw
+
+ sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
+ {
+ }
+
+ sp_counted_impl_pd( P p ): ptr( p ), del()
+ {
+ }
+
+ virtual void dispose() // nothrow
+ {
+ del( ptr );
+ }
+
+ virtual void * get_deleter( detail::sp_typeinfo const & ti )
+ {
+ return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
+ }
+
+ virtual void * get_untyped_deleter()
+ {
+ return &reinterpret_cast<char&>( del );
+ }
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+
+ void * operator new( std::size_t )
+ {
+ return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
+ }
+
+ void operator delete( void * p )
+ {
+ std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
+ }
+
+#endif
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+
+ void * operator new( std::size_t )
+ {
+ return quick_allocator<this_type>::alloc();
+ }
+
+ void operator delete( void * p )
+ {
+ quick_allocator<this_type>::dealloc( p );
+ }
+
+#endif
+};
+
+template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
+{
+private:
+
+ P p_; // copy constructor must not throw
+ D d_; // copy constructor must not throw
+ A a_; // copy constructor must not throw
+
+ sp_counted_impl_pda( sp_counted_impl_pda const & );
+ sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
+
+ typedef sp_counted_impl_pda<P, D, A> this_type;
+
+public:
+
+ // pre: d( p ) must not throw
+
+ sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
+ {
+ }
+
+ sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
+ {
+ }
+
+ virtual void dispose() // nothrow
+ {
+ d_( p_ );
+ }
+
+ virtual void destroy() // nothrow
+ {
+ typedef typename A::template rebind< this_type >::other A2;
+
+ A2 a2( a_ );
+
+ this->~this_type();
+ a2.deallocate( this, 1 );
+ }
+
+ virtual void * get_deleter( detail::sp_typeinfo const & ti )
+ {
+ return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
+ }
+
+ virtual void * get_untyped_deleter()
+ {
+ return &reinterpret_cast<char&>( d_ );
+ }
+};
+
+#ifdef __CODEGUARD__
+# pragma option pop
+#endif
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_forward.hpp b/ndnboost/smart_ptr/detail/sp_forward.hpp
new file mode 100644
index 0000000..d22d9a4
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_forward.hpp
@@ -0,0 +1,39 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_forward.hpp
+//
+// Copyright 2008,2012 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <ndnboost/config.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
+{
+ return static_cast< T&& >( t );
+}
+
+#endif
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_has_sync.hpp b/ndnboost/smart_ptr/detail/sp_has_sync.hpp
new file mode 100644
index 0000000..16de21d
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_has_sync.hpp
@@ -0,0 +1,69 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/smart_ptr/detail/sp_has_sync.hpp
+//
+// Copyright (c) 2008, 2009 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
+// are available.
+//
+
+#ifndef BOOST_SP_NO_SYNC
+
+#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+#define BOOST_SP_HAS_SYNC
+
+#if defined( __arm__ ) || defined( __armel__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __hppa ) || defined( __hppa__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __m68k__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __sh__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __sparc__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#endif
+
+#endif // #ifndef BOOST_SP_NO_SYNC
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/sp_if_array.hpp b/ndnboost/smart_ptr/detail/sp_if_array.hpp
new file mode 100644
index 0000000..8f9d56d
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_if_array.hpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012 Glen Joseph Fernandes
+ * glenfe at live dot com
+ *
+ * Distributed under the Boost Software License,
+ * Version 1.0. (See accompanying file LICENSE_1_0.txt
+ * or copy at http://boost.org/LICENSE_1_0.txt)
+ */
+#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
+#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
+
+#include <ndnboost/smart_ptr/shared_ptr.hpp>
+
+namespace ndnboost {
+ namespace detail {
+ template<typename T>
+ struct sp_if_array;
+ template<typename T>
+ struct sp_if_array<T[]> {
+ typedef ndnboost::shared_ptr<T[]> type;
+ };
+ template<typename T>
+ struct sp_if_size_array;
+ template<typename T, std::size_t N>
+ struct sp_if_size_array<T[N]> {
+ typedef ndnboost::shared_ptr<T[N]> type;
+ };
+ }
+}
+
+#endif
diff --git a/ndnboost/smart_ptr/detail/sp_nullptr_t.hpp b/ndnboost/smart_ptr/detail/sp_nullptr_t.hpp
new file mode 100644
index 0000000..13e2a9a
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/sp_nullptr_t.hpp
@@ -0,0 +1,45 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// detail/sp_nullptr_t.hpp
+//
+// Copyright 2013 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <ndnboost/config.hpp>
+#include <cstddef>
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
+
+ typedef decltype(nullptr) sp_nullptr_t;
+
+#else
+
+ typedef std::nullptr_t sp_nullptr_t;
+
+#endif
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif // !defined( BOOST_NO_CXX11_NULLPTR )
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock.hpp b/ndnboost/smart_ptr/detail/spinlock.hpp
new file mode 100644
index 0000000..ab6c807
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock.hpp
@@ -0,0 +1,56 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/spinlock.hpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// struct spinlock
+// {
+// void lock();
+// bool try_lock();
+// void unlock();
+//
+// class scoped_lock;
+// };
+//
+// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
+//
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/smart_ptr/detail/sp_has_sync.hpp>
+
+#if defined( BOOST_SP_USE_PTHREADS )
+# include <ndnboost/smart_ptr/detail/spinlock_pt.hpp>
+
+#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
+# include <ndnboost/smart_ptr/detail/spinlock_gcc_arm.hpp>
+
+#elif defined( BOOST_SP_HAS_SYNC )
+# include <ndnboost/smart_ptr/detail/spinlock_sync.hpp>
+
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# include <ndnboost/smart_ptr/detail/spinlock_w32.hpp>
+
+#elif defined(BOOST_HAS_PTHREADS)
+# include <ndnboost/smart_ptr/detail/spinlock_pt.hpp>
+
+#elif !defined(BOOST_HAS_THREADS)
+# include <ndnboost/smart_ptr/detail/spinlock_nt.hpp>
+
+#else
+# error Unrecognized threading platform
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_gcc_arm.hpp b/ndnboost/smart_ptr/detail/spinlock_gcc_arm.hpp
new file mode 100644
index 0000000..7155fbe
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_gcc_arm.hpp
@@ -0,0 +1,120 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
+
+//
+// Copyright (c) 2008, 2011 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/smart_ptr/detail/yield_k.hpp>
+
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
+
+# define BOOST_SP_ARM_BARRIER "dmb"
+# define BOOST_SP_ARM_HAS_LDREX
+
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+
+# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
+# define BOOST_SP_ARM_HAS_LDREX
+
+#else
+
+# define BOOST_SP_ARM_BARRIER ""
+
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ int v_;
+
+public:
+
+ bool try_lock()
+ {
+ int r;
+
+#ifdef BOOST_SP_ARM_HAS_LDREX
+
+ __asm__ __volatile__(
+ "ldrex %0, [%2]; \n"
+ "cmp %0, %1; \n"
+ "strexne %0, %1, [%2]; \n"
+ BOOST_SP_ARM_BARRIER :
+ "=&r"( r ): // outputs
+ "r"( 1 ), "r"( &v_ ): // inputs
+ "memory", "cc" );
+
+#else
+
+ __asm__ __volatile__(
+ "swp %0, %1, [%2];\n"
+ BOOST_SP_ARM_BARRIER :
+ "=&r"( r ): // outputs
+ "r"( 1 ), "r"( &v_ ): // inputs
+ "memory", "cc" );
+
+#endif
+
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ ndnboost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
+ *const_cast< int volatile* >( &v_ ) = 0;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#undef BOOST_SP_ARM_BARRIER
+#undef BOOST_SP_ARM_HAS_LDREX
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_nt.hpp b/ndnboost/smart_ptr/detail/spinlock_nt.hpp
new file mode 100644
index 0000000..59cc715
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_nt.hpp
@@ -0,0 +1,89 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/assert.hpp>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ bool locked_;
+
+public:
+
+ inline bool try_lock()
+ {
+ if( locked_ )
+ {
+ return false;
+ }
+ else
+ {
+ locked_ = true;
+ return true;
+ }
+ }
+
+ inline void lock()
+ {
+ BOOST_ASSERT( !locked_ );
+ locked_ = true;
+ }
+
+ inline void unlock()
+ {
+ BOOST_ASSERT( locked_ );
+ locked_ = false;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#define BOOST_DETAIL_SPINLOCK_INIT { false }
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_pool.hpp b/ndnboost/smart_ptr/detail/spinlock_pool.hpp
new file mode 100644
index 0000000..f23a045
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_pool.hpp
@@ -0,0 +1,91 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/detail/spinlock_pool.hpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
+// spinlock_pool<1> is reserved for shared_ptr reference counts
+// spinlock_pool<2> is reserved for shared_ptr atomic access
+//
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/smart_ptr/detail/spinlock.hpp>
+#include <cstddef>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+template< int I > class spinlock_pool
+{
+private:
+
+ static spinlock pool_[ 41 ];
+
+public:
+
+ static spinlock & spinlock_for( void const * pv )
+ {
+#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
+ std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
+#else
+ std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
+#endif
+ return pool_[ i ];
+ }
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
+ {
+ sp_.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
+{
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+ BOOST_DETAIL_SPINLOCK_INIT
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_pt.hpp b/ndnboost/smart_ptr/detail/spinlock_pt.hpp
new file mode 100644
index 0000000..c08b1eb
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_pt.hpp
@@ -0,0 +1,79 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <pthread.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ pthread_mutex_t v_;
+
+public:
+
+ bool try_lock()
+ {
+ return pthread_mutex_trylock( &v_ ) == 0;
+ }
+
+ void lock()
+ {
+ pthread_mutex_lock( &v_ );
+ }
+
+ void unlock()
+ {
+ pthread_mutex_unlock( &v_ );
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_sync.hpp b/ndnboost/smart_ptr/detail/spinlock_sync.hpp
new file mode 100644
index 0000000..fa1df85
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_sync.hpp
@@ -0,0 +1,87 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/smart_ptr/detail/yield_k.hpp>
+
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include <ia64intrin.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ int v_;
+
+public:
+
+ bool try_lock()
+ {
+ int r = __sync_lock_test_and_set( &v_, 1 );
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ ndnboost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ __sync_lock_release( &v_ );
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/spinlock_w32.hpp b/ndnboost/smart_ptr/detail/spinlock_w32.hpp
new file mode 100644
index 0000000..393b5a1
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/spinlock_w32.hpp
@@ -0,0 +1,113 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <ndnboost/detail/interlocked.hpp>
+#include <ndnboost/smart_ptr/detail/yield_k.hpp>
+
+// BOOST_COMPILER_FENCE
+
+#if defined(__INTEL_COMPILER)
+
+#define BOOST_COMPILER_FENCE __memory_barrier();
+
+#elif defined( _MSC_VER ) && _MSC_VER >= 1310
+
+extern "C" void _ReadWriteBarrier();
+#pragma intrinsic( _ReadWriteBarrier )
+
+#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
+
+#elif defined(__GNUC__)
+
+#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
+
+#else
+
+#define BOOST_COMPILER_FENCE
+
+#endif
+
+//
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+ long v_;
+
+public:
+
+ bool try_lock()
+ {
+ long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
+
+ BOOST_COMPILER_FENCE
+
+ return r == 0;
+ }
+
+ void lock()
+ {
+ for( unsigned k = 0; !try_lock(); ++k )
+ {
+ ndnboost::detail::yield( k );
+ }
+ }
+
+ void unlock()
+ {
+ BOOST_COMPILER_FENCE
+ *const_cast< long volatile* >( &v_ ) = 0;
+ }
+
+public:
+
+ class scoped_lock
+ {
+ private:
+
+ spinlock & sp_;
+
+ scoped_lock( scoped_lock const & );
+ scoped_lock & operator=( scoped_lock const & );
+
+ public:
+
+ explicit scoped_lock( spinlock & sp ): sp_( sp )
+ {
+ sp.lock();
+ }
+
+ ~scoped_lock()
+ {
+ sp_.unlock();
+ }
+ };
+};
+
+} // namespace detail
+} // namespace ndnboost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
diff --git a/ndnboost/smart_ptr/detail/yield_k.hpp b/ndnboost/smart_ptr/detail/yield_k.hpp
new file mode 100644
index 0000000..4dc447e
--- /dev/null
+++ b/ndnboost/smart_ptr/detail/yield_k.hpp
@@ -0,0 +1,149 @@
+#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// yield_k.hpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// void yield( unsigned k );
+//
+// Typical use:
+//
+// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+
+#include <ndnboost/config.hpp>
+
+// BOOST_SMT_PAUSE
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
+
+extern "C" void _mm_pause();
+#pragma intrinsic( _mm_pause )
+
+#define BOOST_SMT_PAUSE _mm_pause();
+
+#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+
+#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
+
+#endif
+
+//
+
+#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+#endif
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+#if !defined( BOOST_USE_WINDOWS_H )
+ extern "C" void __stdcall Sleep( unsigned long ms );
+#endif
+
+inline void yield( unsigned k )
+{
+ if( k < 4 )
+ {
+ }
+#if defined( BOOST_SMT_PAUSE )
+ else if( k < 16 )
+ {
+ BOOST_SMT_PAUSE
+ }
+#endif
+ else if( k < 32 )
+ {
+ Sleep( 0 );
+ }
+ else
+ {
+ Sleep( 1 );
+ }
+}
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#elif defined( BOOST_HAS_PTHREADS )
+
+#include <sched.h>
+#include <time.h>
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned k )
+{
+ if( k < 4 )
+ {
+ }
+#if defined( BOOST_SMT_PAUSE )
+ else if( k < 16 )
+ {
+ BOOST_SMT_PAUSE
+ }
+#endif
+ else if( k < 32 || k & 1 )
+ {
+ sched_yield();
+ }
+ else
+ {
+ // g++ -Wextra warns on {} or {0}
+ struct timespec rqtp = { 0, 0 };
+
+ // POSIX says that timespec has tv_sec and tv_nsec
+ // But it doesn't guarantee order or placement
+
+ rqtp.tv_sec = 0;
+ rqtp.tv_nsec = 1000;
+
+ nanosleep( &rqtp, 0 );
+ }
+}
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#else
+
+namespace ndnboost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned )
+{
+}
+
+} // namespace detail
+
+} // namespace ndnboost
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED