diff --git a/compatibility.htm b/compatibility.htm
deleted file mode 100644
index 6f57e4d..0000000
--- a/compatibility.htm
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
- Smart Pointer Changes
-
-
-
-
Smart Pointer Changes
- The February 2002 change to the Boost smart pointers introduced a number of
- changes. Since the previous version of the smart pointers was in use for a long
- time, it's useful to have a detailed list of what changed from a library user's
- point of view.
- Note that for compilers that don't support member templates well enough, a
- separate implementation is used that lacks many of the new features and is more
- like the old version.
- Features Requiring Code Changes to Take Advantage
-
- -
- The smart pointer class templates now each have their own header file. For
- compatibility, the <boost/smart_ptr.hpp>
- header now includes the headers for the four classic smart pointer class
- templates.
-
-
- The weak_ptr
- template was added.
-
-
- The new shared_ptr and shared_array relax the requirement that
- the pointed-to object's destructor must be visible when instantiating the shared_ptr
- destructor. This makes it easier to have shared_ptr members in classes without
- explicit destructors.
-
-
- A custom deallocator can be passed in when creating a shared_ptr or shared_array.
-
-
- shared_static_cast and shared_dynamic_cast function templates are
- provided which work for shared_ptr and weak_ptr as static_cast
- and dynamic_cast
- do for pointers.
-
-
- The self-assignment misfeature has been removed from shared_ptr::reset,
- although it is still present in scoped_ptr, and in std::auto_ptr.
- Calling reset with a pointer to the object that's already owned by the shared_ptr
- results in undefined behavior (an assertion, or eventually a double-delete if
- assertions are off).
-
-
- The BOOST_SMART_PTR_CONVERSION
- feature has been removed.
-
-
- shared_ptr<void> is now allowed.
-
- Features That Improve Robustness
-
- -
- The manipulation of use counts is now thread safe on
- Windows, Linux, and platforms that support pthreads. See the
- <boost/detail/atomic_count.hpp>
- file for details
-
-
- The new shared_ptr will always delete the object using the pointer it was
- originally constructed with. This prevents subtle problems that could happen if
- the last shared_ptr was a pointer to a sub-object of a class that did
- not have a virtual destructor.
-
- Implementation Details
-
- -
- Some bugs in the assignment operator implementations and in reset
- have been fixed by using the "copy and swap" idiom.
-
-
- Assertions have been added to check preconditions of various functions;
- however, since these use the new <boost/assert.hpp>
- header, the assertions are disabled by default.
-
-
- The partial specialization of std::less has been replaced by operator<
- overloads which accomplish the same thing without relying on undefined
- behavior.
-
-
- The incorrect overload of std::swap has been replaced by boost::swap,
- which has many of the same advantages for generic programming but does not
- violate the C++ standard.
-
-
- $Date$
- Copyright 2002 Darin Adler. 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.
-
-
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..0972e2d
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1,2 @@
+/html/
+/pdf/
diff --git a/doc/Jamfile b/doc/Jamfile
new file mode 100644
index 0000000..b6d2c35
--- /dev/null
+++ b/doc/Jamfile
@@ -0,0 +1,26 @@
+# Copyright 2017 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
+
+project doc/smart_ptr ;
+
+import asciidoctor ;
+
+html smart_ptr.html : smart_ptr.adoc ;
+
+install html_ : smart_ptr.html : html ;
+
+pdf smart_ptr.pdf : smart_ptr.adoc ;
+explicit smart_ptr.pdf ;
+
+install pdf_ : smart_ptr.pdf : pdf ;
+explicit pdf_ ;
+
+###############################################################################
+alias boostdoc ;
+explicit boostdoc ;
+alias boostrelease : html_ ;
+explicit boostrelease ;
diff --git a/doc/asciidoctor.jam b/doc/asciidoctor.jam
new file mode 100644
index 0000000..488670d
--- /dev/null
+++ b/doc/asciidoctor.jam
@@ -0,0 +1,50 @@
+# Copyright 2017 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)
+
+import type ;
+import scanner ;
+import generators ;
+import boostbook ;
+
+# File type
+
+type.register ASCIIDOC : asciidoc adoc ;
+
+# Define dependency scanner
+
+class asciidoc-scanner : common-scanner
+{
+ rule pattern ( )
+ {
+ return "include::([^[]+)\\[" ;
+ }
+}
+
+scanner.register asciidoc-scanner : include ;
+type.set-scanner ASCIIDOC : asciidoc-scanner ;
+
+# Define generators
+
+generators.register-standard asciidoctor.asciidoc-to-html : ASCIIDOC : HTML ;
+generators.register-standard asciidoctor.asciidoc-to-pdf : ASCIIDOC : PDF ;
+# generators.register-standard asciidoctor.asciidoc-to-docbook : ASCIIDOC : DOCBOOK ;
+
+# Define actions
+
+actions asciidoc-to-html
+{
+ asciidoctor -b html -o $(1) $(2)
+}
+
+actions asciidoc-to-pdf
+{
+ asciidoctor -r asciidoctor-pdf -b pdf -o $(1) $(2)
+}
+
+actions asciidoc-to-docbook
+{
+ asciidoctor -b docbook -o $(1) $(2)
+}
diff --git a/doc/smart_ptr-docinfo-footer.html b/doc/smart_ptr-docinfo-footer.html
new file mode 100644
index 0000000..8cf495c
--- /dev/null
+++ b/doc/smart_ptr-docinfo-footer.html
@@ -0,0 +1,33 @@
+
+
+
diff --git a/doc/smart_ptr.adoc b/doc/smart_ptr.adoc
new file mode 100644
index 0000000..5b452c7
--- /dev/null
+++ b/doc/smart_ptr.adoc
@@ -0,0 +1,70 @@
+////
+Copyright 2017 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
+////
+
+# Boost.SmartPtr: The Smart Pointer Library
+Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
+:toc: left
+:toclevels: 2
+:idprefix:
+:listing-caption: Code Example
+:docinfo: private-footer
+
+:leveloffset: +1
+
+include::smart_ptr/introduction.adoc[]
+
+include::smart_ptr/scoped_ptr.adoc[]
+
+include::smart_ptr/scoped_array.adoc[]
+
+include::smart_ptr/shared_ptr.adoc[]
+
+include::smart_ptr/weak_ptr.adoc[]
+
+include::smart_ptr/make_shared.adoc[]
+
+include::smart_ptr/enable_shared_from_this.adoc[]
+
+include::smart_ptr/make_unique.adoc[]
+
+include::smart_ptr/intrusive_ptr.adoc[]
+
+include::smart_ptr/intrusive_ref_counter.adoc[]
+
+include::smart_ptr/pointer_cast.adoc[]
+
+include::smart_ptr/pointer_to_other.adoc[]
+
+// appendix
+include::smart_ptr/techniques.adoc[]
+
+// appendix
+include::smart_ptr/history.adoc[]
+
+// appendix, deprecated
+include::smart_ptr/shared_array.adoc[]
+
+:leveloffset: -1
+
+[[copyright]]
+[appendix]
+## Copyright and License
+
+This documentation is
+
+* Copyright 1999 Greg Colvin
+* Copyright 1999 Beman Dawes
+* Copyright 2002 Darin Adler
+* Copyright 2003-2017 Peter Dimov
+* Copyright 2005, 2006 Ion Gaztañaga
+* Copyright 2008 Frank Mori Hess
+* Copyright 2012-2017 Glen Fernandes
+* Copyright 2013 Andrey Semashev
+
+and is distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
diff --git a/doc/smart_ptr/enable_shared_from_this.adoc b/doc/smart_ptr/enable_shared_from_this.adoc
new file mode 100644
index 0000000..757c1d4
--- /dev/null
+++ b/doc/smart_ptr/enable_shared_from_this.adoc
@@ -0,0 +1,144 @@
+////
+Copyright 2002, 2003, 2015, 2017 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
+////
+
+[#enable_shared_from_this]
+# enable_shared_from_this
+:toc:
+:toc-title:
+:idprefix: enable_shared_from_this_
+
+## Description
+
+The class template `enable_shared_from_this` is used as a base class that allows
+a `shared_ptr` or a `weak_ptr` to the current object to be obtained from within a
+member function.
+
+`enable_shared_from_this` defines two member functions called `shared_from_this`
+that return a `shared_ptr` and `shared_ptr`, depending on constness, to
+`this`. It also defines two member functions called `weak_from_this` that return a
+corresponding `weak_ptr`.
+
+## Example
+
+```
+#include
+#include
+#include
+
+class Y: public boost::enable_shared_from_this
+{
+public:
+
+ boost::shared_ptr f()
+ {
+ return shared_from_this();
+ }
+};
+
+int main()
+{
+ boost::shared_ptr p(new Y);
+ boost::shared_ptr q = p->f();
+ assert(p == q);
+ assert(!(p < q || q < p)); // p and q must share ownership
+}
+```
+
+## Synopsis
+
+`enable_shared_from_this` is defined in ``.
+
+```
+namespace boost {
+
+ template class enable_shared_from_this {
+ private:
+
+ // exposition only
+ weak_ptr weak_this_;
+
+ protected:
+
+ enable_shared_from_this() = default;
+ ~enable_shared_from_this() = default;
+
+ enable_shared_from_this(const enable_shared_from_this&) noexcept;
+ enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
+
+ public:
+
+ shared_ptr shared_from_this();
+ shared_ptr shared_from_this() const;
+
+ weak_ptr weak_from_this() noexcept;
+ weak_ptr weak_from_this() const noexcept;
+ }
+}
+```
+
+## Members
+
+```
+enable_shared_from_this(enable_shared_from_this const &) noexcept;
+```
+[none]
+* {blank}
++
+Effects:: Default-constructs `weak_this_`.
+
+NOTE: `weak_this_` is _not_ copied from the argument.
+
+```
+enable_shared_from_this& operator=(enable_shared_from_this const &) noexcept;
+```
+[none]
+* {blank}
++
+Returns:: `*this`.
+
+NOTE: `weak_this_` is unchanged.
+
+```
+template shared_ptr shared_from_this();
+```
+```
+template shared_ptr shared_from_this() const;
+```
+[none]
+* {blank}
++
+Returns:: `shared_ptr(weak_this_)`.
+
+NOTE: These members throw `bad_weak_ptr` when `*this` is not owned by a `shared_ptr`.
+
+[NOTE]
+====
+`weak_this_` is initialized by `shared_ptr` to a copy of itself when it's constructed by a pointer to `*this`.
+For example, in the following code:
+```
+class Y: public boost::enable_shared_from_this {};
+
+int main()
+{
+ boost::shared_ptr p(new Y);
+}
+```
+the construction of `p` will automatically initialize `p\->weak_this_` to `p`.
+====
+
+```
+template weak_ptr weak_from_this() noexcept;
+```
+```
+template weak_ptr weak_from_this() const noexcept;
+```
+[none]
+* {blank}
++
+Returns:: `weak_this_`.
diff --git a/doc/smart_ptr/history.adoc b/doc/smart_ptr/history.adoc
new file mode 100644
index 0000000..9e60a7a
--- /dev/null
+++ b/doc/smart_ptr/history.adoc
@@ -0,0 +1,108 @@
+////
+Copyright 1999 Greg Colvin and Beman Dawes
+Copyright 2002 Darin Adler
+Copyright 2017 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
+////
+
+[[history]]
+[appendix]
+# History and Acknowledgments
+:idprefix: history_
+
+## Summer 1994
+
+Greg Colvin http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf[proposed]
+to the {cpp} Standards Committee classes named `auto_ptr` and `counted_ptr` which were very
+similar to what we now call `scoped_ptr` and `shared_ptr`. In one of the very few cases
+where the Library Working Group's recommendations were not followed by the full committee,
+`counted_ptr` was rejected and surprising transfer-of-ownership semantics were added to `auto_ptr`.
+
+## October 1998
+
+Beman Dawes proposed reviving the original semantics under the names `safe_ptr` and `counted_ptr`,
+meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis,
+Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new class
+names were finalized, it was decided that there was no need to exactly follow the `std::auto_ptr`
+interface, and various function signatures and semantics were finalized.
+
+Over the next three months, several implementations were considered for `shared_ptr`, and discussed
+on the http://www.boost.org/[boost.org] mailing list. The implementation questions revolved around
+the reference count which must be kept, either attached to the pointed to object, or detached elsewhere.
+Each of those variants have themselves two major variants:
+
+* Direct detached: the `shared_ptr` contains a pointer to the object, and a pointer to the count.
+* Indirect detached: the `shared_ptr` contains a pointer to a helper object, which in turn contains a pointer to the object and the count.
+* Embedded attached: the count is a member of the object pointed to.
+* Placement attached: the count is attached via operator new manipulations.
+
+Each implementation technique has advantages and disadvantages. We went so far as to run various timings
+of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little
+measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kühl
+suggested an elegant partial template specialization technique to allow users to choose which implementation
+they preferred, and that was also experimented with.
+
+But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose
+to supply only the direct implementation.
+
+## May 1999
+
+In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.
+
+## September 1999
+
+Luis Coelho provided `shared_ptr::swap` and `shared_array::swap`.
+
+## November 1999
+
+Darin Adler provided `operator ==`, `operator !=`, and `std::swap` and `std::less` specializations for shared types.
+
+## May 2001
+
+Vladimir Prus suggested requiring a complete type on destruction. Refinement evolved in discussions including Dave Abrahams,
+Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others.
+
+## January 2002
+
+Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding
+`weak_ptr`.
+
+## March 2003
+
+Peter Dimov, Beman Dawes and Greg Colvin http://open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html[proposed] `shared_ptr`
+and `weak_ptr` for inclusion in the Standard Library via the first Library Technical Report (known as TR1). The proposal was
+accepted and eventually went on to become a part of the {cpp} standard in its 2011 iteration.
+
+## July 2007
+
+Peter Dimov and Beman Dawes http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm[proposed] a number of enhancements
+to `shared_ptr` as it was entering the working paper that eventually became the {cpp}11 standard.
+
+## November 2012
+
+Glen Fernandes provided implementations of `make_shared` and `allocate_shared` for arrays. They achieve a single allocation
+for an array that can be initialized with constructor arguments or initializer lists as well as overloads for default initialization
+and no value initialization.
+
+Peter Dimov aided this development by extending `shared_ptr` to support arrays via the syntax `shared_ptr` and `shared_ptr`.
+
+## April 2013
+
+Peter Dimov http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3640.html[proposed] the extension of `shared_ptr` to support
+arrays for inclusion into the standard, and it was accepted.
+
+## February 2014
+
+Glen Fernandes updated `make_shared` and `allocate_shared` to conform to the specification in {cpp} standard paper
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html[N3870], and implemented `make_unique` for arrays and objects.
+
+Peter Dimov and Glen Fernandes updated the scalar and array implementations, respectively, to resolve {cpp} standard library defect 2070.
+
+## February 2017
+
+Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more optimal and more maintainable implementation.
+
diff --git a/doc/smart_ptr/introduction.adoc b/doc/smart_ptr/introduction.adoc
new file mode 100644
index 0000000..ecbef1d
--- /dev/null
+++ b/doc/smart_ptr/introduction.adoc
@@ -0,0 +1,47 @@
+////
+Copyright 1999 Greg Colvin and Beman Dawes
+Copyright 2002 Darin Adler
+Copyright 2017 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
+////
+
+[#introduction]
+# Introduction
+:idprefix: intro
+
+Smart pointers are objects which store pointers to dynamically allocated (heap) objects.
+They behave much like built-in {cpp} pointers except that they automatically delete the object
+pointed to at the appropriate time. Smart pointers are particularly useful in the face of
+exceptions as they ensure proper destruction of dynamically allocated objects. They can also be
+used to keep track of dynamically allocated objects shared by multiple owners.
+
+Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for
+deletion of the object when it is no longer needed. As such, they are examples of the "resource
+acquisition is initialization" idiom described in Bjarne Stroustrup's "The C++ Programming Language",
+3rd edition, Section 14.4, Resource Management.
+
+This library provides five smart pointer class templates:
+
+* `<>`, used to contain ownership of a dynamically allocated object to the current scope;
+* `<>`, which provides scoped ownership for a dynamically allocated array;
+* `<>`, a versatile tool for managing shared ownership of an object or array;
+* `<>`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;
+* `<>`, a pointer to objects with an embedded reference count.
+
+`shared_ptr` and `weak_ptr` are part of the {cpp} standard since its 2011 iteration.
+
+In addition, the library contains the following supporting utility functions and classes:
+
+* `<>`, a factory function for creating objects that returns a `shared_ptr`;
+* `<>`, a factory function returning `std::unique_ptr`;
+* `<>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
+* `<>`, a helper trait for converting one smart pointer type to another;
+* `<>` and companions, generic smart pointer casts;
+* `<>`, a helper base class containing a reference count.
+
+As a general rule, the destructor or `operator delete` for an object managed by pointers in the library
+are not allowed to throw exceptions.
diff --git a/doc/smart_ptr/intrusive_ptr.adoc b/doc/smart_ptr/intrusive_ptr.adoc
new file mode 100644
index 0000000..1c729cd
--- /dev/null
+++ b/doc/smart_ptr/intrusive_ptr.adoc
@@ -0,0 +1,447 @@
+////
+Copyright 2003-2005, 2013, 2017 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
+////
+
+[#intrusive_ptr]
+# intrusive_ptr: Managing Objects with Embedded Counts
+:toc:
+:toc-title:
+:idprefix: intrusive_ptr_
+
+## Description
+
+The `intrusive_ptr` class template stores a pointer to an object with an embedded reference count.
+Every new `intrusive_ptr` instance increments the reference count by using an unqualified call to the
+function `intrusive_ptr_add_ref`, passing it the pointer as an argument. Similarly, when an `intrusive_ptr`
+is destroyed, it calls `intrusive_ptr_release`; this function is responsible for destroying the object when
+its reference count drops to zero. The user is expected to provide suitable definitions of these two functions.
+On compilers that support argument-dependent lookup, `intrusive_ptr_add_ref` and `intrusive_ptr_release` should
+be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace
+`boost`. The library provides a helper base class template `<>` which
+may help adding support for `intrusive_ptr` to user types.
+
+The class template is parameterized on `T`, the type of the object pointed to. `intrusive_ptr` can be implicitly
+converted to `intrusive_ptr` whenever `T*` can be implicitly converted to `U*`.
+
+The main reasons to use `intrusive_ptr` are:
+
+* Some existing frameworks or OSes provide objects with embedded reference counts;
+* The memory footprint of `intrusive_ptr` is the same as the corresponding raw pointer;
+* `intrusive_ptr` can be constructed from an arbitrary raw pointer of type `T*`.
+
+As a general rule, if it isn't obvious whether `intrusive_ptr` better fits your needs than `shared_ptr`, try a `shared_ptr`-based design first.
+
+## Synopsis
+
+`intrusive_ptr` is defined in ``.
+
+```
+namespace boost {
+
+ template class intrusive_ptr {
+ public:
+
+ typedef T element_type;
+
+ intrusive_ptr() noexcept;
+ intrusive_ptr(T * p, bool add_ref = true);
+
+ intrusive_ptr(intrusive_ptr const & r);
+ template intrusive_ptr(intrusive_ptr const & r);
+
+ ~intrusive_ptr();
+
+ intrusive_ptr & operator=(intrusive_ptr const & r);
+ template intrusive_ptr & operator=(intrusive_ptr const & r);
+ intrusive_ptr & operator=(T * r);
+
+ void reset();
+ void reset(T * r);
+ void reset(T * r, bool add_ref);
+
+ T & operator*() const noexcept;
+ T * operator->() const noexcept;
+ T * get() const noexcept;
+ T * detach() noexcept;
+
+ explicit operator bool () const noexcept;
+
+ void swap(intrusive_ptr & b) noexept;
+ };
+
+ template
+ bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+
+ template
+ bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+
+ template
+ bool operator==(intrusive_ptr const & a, U * b) noexcept;
+
+ template
+ bool operator!=(intrusive_ptr const & a, U * b) noexcept;
+
+ template
+ bool operator==(T * a, intrusive_ptr const & b) noexcept;
+
+ template
+ bool operator!=(T * a, intrusive_ptr const & b) noexcept;
+
+ template
+ bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+
+ template void swap(intrusive_ptr & a, intrusive_ptr & b) noexcept;
+
+ template T * get_pointer(intrusive_ptr const & p) noexcept;
+
+ template
+ intrusive_ptr static_pointer_cast(intrusive_ptr const & r) noexcept;
+
+ template
+ intrusive_ptr const_pointer_cast(intrusive_ptr const & r) noexcept;
+
+ template
+ intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & r) noexcept;
+
+ template
+ std::basic_ostream & operator<< (std::basic_ostream & os,
+ intrusive_ptr const & p);
+}
+```
+
+## Members
+
+### element_type
+
+```
+typedef T element_type;
+```
+
+Provides the type of the template parameter T.
+
+### constructors
+
+```
+intrusive_ptr() noexcept;
+```
+
+[none]
+* {blank}
++
+Postconditions:: `get() == 0`.
+
+```
+intrusive_ptr(T * p, bool add_ref = true);
+```
+
+[none]
+* {blank}
++
+Effects:: `if(p != 0 && add_ref) intrusive_ptr_add_ref(p);`.
+Postconditions:: `get() == p`.
+
+```
+intrusive_ptr(intrusive_ptr const & r);
+```
+```
+template intrusive_ptr(intrusive_ptr const & r);
+```
+
+[none]
+* {blank}
++
+Effects:: `if(r.get() != 0) intrusive_ptr_add_ref(r.get());`.
+Postconditions:: `get() == r.get()`.
+
+### destructor
+
+```
+~intrusive_ptr();
+```
+
+[none]
+* {blank}
++
+Effects:: `if(get() != 0) intrusive_ptr_release(get());`.
+
+### assignment
+
+```
+intrusive_ptr & operator=(intrusive_ptr const & r);
+```
+```
+template intrusive_ptr & operator=(intrusive_ptr const & r);
+```
+```
+intrusive_ptr & operator=(T * r);
+```
+
+[none]
+* {blank}
++
+Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`.
+Returns:: `*this`.
+
+### reset
+
+```
+void reset();
+```
+
+[none]
+* {blank}
++
+Effects:: Equivalent to `intrusive_ptr().swap(*this)`.
+
+```
+void reset(T * r);
+```
+
+[none]
+* {blank}
++
+Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`.
+
+```
+void reset(T * r, bool add_ref);
+```
+
+[none]
+* {blank}
++
+Effects:: Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
+
+### indirection
+
+```
+T & operator*() const noexcept;
+```
+
+[none]
+* {blank}
++
+Requirements:: `get() != 0`.
+Returns:: `*get()`.
+
+```
+T * operator->() const noexcept;
+```
+
+[none]
+* {blank}
++
+Requirements:: `get() != 0`.
+Returns:: `get()`.
+
+### get
+
+```
+T * get() const noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: the stored pointer.
+
+### detach
+
+```
+T * detach() noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: the stored pointer.
+Postconditions:: `get() == 0`.
+
+NOTE: The returned pointer has an elevated reference count. This allows conversion of an `intrusive_ptr`
+back to a raw pointer, without the performance overhead of acquiring and dropping an extra reference.
+It can be viewed as the complement of the non-reference-incrementing constructor.
+
+CAUTION: Using `detach` escapes the safety of automatic reference counting provided by `intrusive_ptr`.
+It should by used only where strictly necessary (such as when interfacing to an existing API), and when
+the implications are thoroughly understood.
+
+### conversions
+
+```
+explicit operator bool () const noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `get() != 0`.
+
+NOTE: This conversion operator allows `intrusive_ptr` objects to be used in boolean contexts,
+like `if (p && p\->valid()) {}`.
+
+NOTE: On C++03 compilers, the return value is of an unspecified type.
+
+### swap
+
+```
+void swap(intrusive_ptr & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Effects:: Exchanges the contents of the two smart pointers.
+
+## Free Functions
+
+### comparison
+
+```
+template
+ bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a.get() == b.get()`.
+
+```
+template
+ bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a.get() != b.get()`.
+
+```
+template
+ bool operator==(intrusive_ptr const & a, U * b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a.get() == b`.
+
+```
+template
+ bool operator!=(intrusive_ptr const & a, U * b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a.get() != b`.
+
+```
+template
+ bool operator==(T * a, intrusive_ptr const & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a == b.get()`.
+
+```
+template
+ bool operator!=(T * a, intrusive_ptr const & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `a != b.get()`.
+
+```
+template
+ bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `std::less()(a.get(), b.get())`.
+
+NOTE: Allows `intrusive_ptr` objects to be used as keys in associative containers.
+
+### swap
+
+```
+template void swap(intrusive_ptr & a, intrusive_ptr & b) noexcept;
+```
+
+[none]
+* {blank}
++
+Effects:: Equivalent to `a.swap(b)`.
+
+### get_pointer
+
+```
+template T * get_pointer(intrusive_ptr const & p) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `p.get()`.
+
+NOTE: Provided as an aid to generic programming. Used by `mem_fn`.
+
+### static_pointer_cast
+
+```
+template
+ intrusive_ptr static_pointer_cast(intrusive_ptr const & r) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `intrusive_ptr(static_cast(r.get()))`.
+
+### const_pointer_cast
+
+```
+template
+ intrusive_ptr const_pointer_cast(intrusive_ptr const & r) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `intrusive_ptr(const_cast(r.get()))`.
+
+### dynamic_pointer_cast
+
+```
+template
+ intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & r) noexcept;
+```
+
+[none]
+* {blank}
++
+Returns:: `intrusive_ptr(dynamic_cast(r.get()))`.
+
+### operator<<
+
+```
+template
+ std::basic_ostream & operator<< (std::basic_ostream & os,
+ intrusive_ptr const & p);
+```
+
+[none]
+* {blank}
++
+Effects:: `os << p.get();`.
+Returns:: `os`.
diff --git a/doc/smart_ptr/intrusive_ref_counter.adoc b/doc/smart_ptr/intrusive_ref_counter.adoc
new file mode 100644
index 0000000..1d33300
--- /dev/null
+++ b/doc/smart_ptr/intrusive_ref_counter.adoc
@@ -0,0 +1,142 @@
+////
+Copyright 2017 Peter Dimov
+Copyright 2013 Andrey Semashev
+
+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
+////
+
+[#intrusive_ref_counter]
+# intrusive_ref_counter
+:toc:
+:toc-title:
+:idprefix: intrusive_ref_counter_
+
+## Description
+
+The `intrusive_ref_counter` class template implements a reference counter for
+a derived user's class that is intended to be used with `intrusive_ptr`. The
+base class has associated `intrusive_ptr_add_ref` and `intrusive_ptr_release`
+functions which modify the reference counter as needed and destroy the user's
+object when the counter drops to zero.
+
+The class template is parameterized on `Derived` and `CounterPolicy`
+parameters. The first parameter is the user's class that derives from
+`intrusive_ref_counter`. This type is needed in order to destroy the object
+correctly when there are no references to it left.
+
+The second parameter is a policy that defines the nature of the reference
+counter. The library provides two such policies: `thread_unsafe_counter` and
+`thread_safe_counter`. The former instructs the `intrusive_ref_counter` base
+class to use a counter only suitable for a single-threaded use. Pointers to a
+single object that uses this kind of reference counter must not be used in
+different threads. The latter policy makes the reference counter thread-safe,
+unless the target platform doesn't support threading. Since in modern systems
+support for threading is common, the default counter policy is
+`thread_safe_counter`.
+
+## Synopsis
+
+`intrusive_ref_counter` is defined in
+``.
+
+```
+namespace boost {
+ struct thread_unsafe_counter;
+ struct thread_safe_counter;
+
+ template
+ class intrusive_ref_counter {
+ public:
+ intrusive_ref_counter() noexcept;
+ intrusive_ref_counter(const intrusive_ref_counter& v) noexcept;
+
+ intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
+
+ unsigned int use_count() const noexcept;
+
+ protected:
+ ~intrusive_ref_counter() = default;
+ };
+
+ template
+ void intrusive_ptr_add_ref(
+ const intrusive_ref_counter* p) noexcept;
+
+ template
+ void intrusive_ptr_release(
+ const intrusive_ref_counter* p) noexcept;
+}
+```
+
+## Members
+
+### Constructors
+
+```
+intrusive_ref_counter() noexcept;
+```
+::
+```
+intrusive_ref_counter(const intrusive_ref_counter&) noexcept;
+```
+::
+Postconditions::: `use_count() == 0`.
+
+NOTE: The pointer to the constructed object is expected to be passed to
+`intrusive_ptr` constructor, assignment operator or `reset` method, which
+would increment the reference counter.
+
+### Destructor
+
+```
+~intrusive_ref_counter();
+```
+::
+Effects::: Destroys the counter object.
+
+NOTE: The destructor is protected so that the object can only be destroyed
+through the `Derived` class.
+
+### Assignment
+
+```
+intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
+```
+::
+Effects::: Does nothing, reference counter is not modified.
+y
+### use_count
+
+```
+unsigned int use_count() const noexcept;
+```
+::
+Returns::: The current value of the reference counter.
+
+NOTE: The returned value may not be actual in multi-threaded applications.
+
+## Free Functions
+
+### intrusive_ptr_add_ref
+
+```
+template
+ void intrusive_ptr_add_ref(
+ const intrusive_ref_counter* p) noexcept;
+```
+::
+Effects::: Increments the reference counter.
+
+### intrusive_ptr_release
+
+```
+template
+ void intrusive_ptr_release(
+ const intrusive_ref_counter* p) noexcept;
+```
+::
+Effects::: Decrements the reference counter. If the reference counter reaches
+0, calls `delete static_cast(p)`.
diff --git a/doc/smart_ptr/make_shared.adoc b/doc/smart_ptr/make_shared.adoc
new file mode 100644
index 0000000..5b4366c
--- /dev/null
+++ b/doc/smart_ptr/make_shared.adoc
@@ -0,0 +1,295 @@
+////
+Copyright 2017 Peter Dimov
+Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
+
+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
+////
+
+[#make_shared]
+# make_shared: Creating shared_ptr
+:toc:
+:toc-title:
+:idprefix: make_shared_
+
+## Description
+
+The function templates `make_shared` and `allocate_shared` provide convenient,
+safe and efficient ways to create `shared_ptr` objects.
+
+## Rationale
+
+Consistent use of `shared_ptr` can eliminate the need to use an explicit
+`delete`, but alone it provides no support in avoiding explicit `new`. There
+were repeated requests from users for a factory function that creates an
+object of a given type and returns a `shared_ptr` to it. Besides convenience
+and style, such a function is also exception safe and considerably faster
+because it can use a single allocation for both the object and its
+corresponding control block, eliminating a significant portion of
+`shared_ptr` construction overhead. This eliminates one of the major
+efficiency complaints about `shared_ptr`.
+
+The family of overloaded function templates, `make_shared` and
+`allocate_shared`, were provided to address this need. `make_shared` uses the
+global `operator new` to allocate memory, whereas `allocate_shared` uses an
+user-supplied allocator, allowing finer control.
+
+The rationale for choosing the name `make_shared` is that the expression
+`make_shared()` can be read aloud and conveys the intended meaning.
+
+Originally the Boost function templates `allocate_shared` and `make_shared`
+were provided for scalar objects only. There was a need to have efficient
+allocation of array objects. One criticism of class template `shared_array`
+was always the lack of a utility like `make_shared` that uses only a single
+allocation. When `shared_ptr` was enhanced to support array types, additional
+overloads of `allocate_shared` and `make_shared` were provided for array
+types.
+
+## Synopsis
+
+`make_shared` and `allocate_shared` are defined in
+``.
+
+[subs=+quotes]
+```
+namespace boost {
+ `// only if T is not an array type`
+ template
+ shared_ptr make_shared(Args&&... args);
+ template
+ shared_ptr allocate_shared(const A& a, Args&&... args);
+
+ `// only if T is an array type of the form U[]`
+ template
+ shared_ptr make_shared(std::size_t n);
+ template
+ shared_ptr allocate_shared(const A& a, std::size_t n);
+
+ `// only if T is an array type of the form U[N]`
+ template
+ shared_ptr make_shared();
+ template
+ shared_ptr allocate_shared(const A& a);
+
+ `// only if T is an array type of the form U[]`
+ template shared_ptr
+ make_shared(std::size_t n, const remove_extent_t& v);
+ template shared_ptr
+ allocate_shared(const A& a, std::size_t n, const remove_extent_t& v);
+
+ `// only if T is an array type of the form U[N]`
+ template
+ shared_ptr make_shared(const remove_extent_t& v);
+ template
+ shared_ptr allocate_shared(const A& a, const remove_extent_t& v);
+
+ `// only if T is not an array type of the form U[]`
+ template
+ shared_ptr make_shared_noinit();
+ template
+ shared_ptr allocate_shared_noinit(const A& a);
+
+ `// only if T is an array type of the form U[N]`
+ template
+ shared_ptr make_shared_noinit(std::size_t n);
+ template
+ shared_ptr allocate_shared_noinit(const A& a, std::size_t n);
+}
+```
+
+## Common Requirements
+
+The common requirements that apply to all `make_shared` and `allocate_shared`
+overloads, unless specified otherwise, are described below.
+
+Requires:: `A` shall be an _allocator_. The copy constructor and destructor
+of `A` shall not throw exceptions.
+
+Effects:: Allocates memory for an object of type `T` or `n` objects of `U`
+(if `T` is an array type of the form `U[]` and `n` is determined by
+arguments, as specified by the concrete overload). The object is initialized
+from arguments as specified by the concrete overload. Uses a rebound copy of
+`a` (for an unspecified `value_type`) to allocate memory. If an exception is
+thrown, the functions have no effect.
+
+Returns:: A `shared_ptr` instance that stores and owns the address of the
+newly constructed object.
+
+Postconditions:: `r.get() != 0` and `r.use_count() == 1`, where `r`
+is the return value.
+
+Throws:: `std::bad_alloc`, an exception thrown from `A::allocate`, or from the
+initialization of the object.
+
+Remarks::
+* Performs no more than one memory allocation. This provides efficiency
+equivalent to an intrusive smart pointer.
+* When an object of an array type is specified to be initialized to a value of
+the same type `v`, this shall be interpreted to mean that each array element
+of the object is initialized to the corresponding element from `v`.
+* When an object of an array type is specified to be value-initialized, this
+shall be interpreted to mean that each array element of the object is
+value-initialized.
+* When a (sub)object of non-array type `U` is specified to be initialized to
+a value `v`, or constructed from `args\...`, `make_shared` shall perform
+this initialization via the expression `::new(p) U(expr)` (where
+`_expr_` is `v` or `std::forward(args)\...)` respectively) and `p`
+has type `void*` and points to storage suitable to hold an object of type
+`U`.
+* When a (sub)object of non-array type `U` is specified to be initialized to
+a value `v`, or constructed from `args\...`, `allocate_shared` shall
+perform this initialization via the expression
+`std::allocator_traits::construct(a2, p, expr)` (where
+`_expr_` is `v` or `std::forward(args)\...)` respectively), `p`
+points to storage suitable to hold an object of type `U`, and `a2` of
+type `A2` is a rebound copy `a` such that its `value_type` is `U`.
+* When a (sub)object of non-array type `U` is specified to be
+default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall
+perform this initialization via the expression `::new(p) U`, where
+`p` has type `void*` and points to storage suitable to hold an object of
+type `U`.
+* When a (sub)object of non-array type `U` is specified to be
+value-initialized, `make_shared` shall perform this initialization via the
+expression `::new(p) U()`, where `p` has type `void*` and points to
+storage suitable to hold an object of type `U`.
+* When a (sub)object of non-array type `U` is specified to be
+value-initialized, `allocate_shared` shall perform this initialization via the
+expression `std::allocator_traits::construct(a2, p)`, where
+`p` points to storage suitable to hold an object of type `U` and `a2` of
+type `A2` is a rebound copy of `a` such that its value_type is `U`.
+* Array elements are initialized in ascending order of their addresses.
+* When the lifetime of the object managed by the return value ends, or when
+the initialization of an array element throws an exception, the initialized
+elements should be destroyed in the reverse order of their construction.
+
+NOTE: These functions will typically allocate more memory than the total size
+of the element objects to allow for internal bookkeeping structures such as
+the reference counts.
+
+## Free Functions
+
+```
+template
+ shared_ptr make_shared(Args&&... args);
+```
+::
+```
+template
+ shared_ptr allocate_shared(const A& a, Args&&... args);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is not an array type.
+Returns::: A `shared_ptr` to an object of type `T`, constructed from
+`args\...`.
+Examples:::
+* `auto p = make_shared();`
+* `auto p = make_shared >(16, 1);`
+
+```
+template
+ shared_ptr make_shared(std::size_t n);
+```
+::
+```
+template
+ shared_ptr allocate_shared(const A& a, std::size_t n);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[]`.
+Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of
+type `U`.
+Examples:::
+* `auto p = make_shared(1024);`
+* `auto p = make_shared(6);`
+
+```
+template
+ shared_ptr make_shared();
+```
+::
+```
+template
+ shared_ptr allocate_shared(const A& a);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[N]`.
+Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of
+type `U`.
+Examples:::
+* `auto p = make_shared();`
+* `auto p = make_shared();`
+
+```
+template shared_ptr
+ make_shared(std::size_t n, const remove_extent_t& v);
+```
+::
+```
+template shared_ptr
+ allocate_shared(const A& a, std::size_t n, const remove_extent_t& v);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[]`.
+Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each
+initialized to `v`.
+Examples:::
+* `auto p = make_shared(1024, 1.0);`
+* `auto p = make_shared(6, {1.0, 0.0});`
+* `auto p = make_shared[]>(4, {1, 2});`
+
+```
+template
+ shared_ptr make_shared(const remove_extent_t& v);
+```
+::
+```
+template
+ shared_ptr allocate_shared(const A& a, const remove_extent_t& v);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[N]`.
+Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each
+initialized to `v`.
+Examples:::
+* `auto p = make_shared(1.0);`
+* `auto p = make_shared({1.0, 0.0});`
+* `auto p = make_shared[4]>({1, 2});`
+
+```
+template
+ shared_ptr make_shared_noinit();
+```
+::
+```
+template
+ shared_ptr allocate_shared_noinit(const A& a);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is not an array type, or an array type of the `U[N]`.
+Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a
+sequence of `N` default-initialized objects of type `U`, respectively.
+Example::: `auto p = make_shared_noinit();`
+
+```
+template
+ shared_ptr make_shared_noinit(std::size_t n);
+```
+::
+```
+template
+ shared_ptr allocate_shared_noinit(const A& a, std::size_t n);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[]`.
+Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects
+of type `U`.
+Example::: `auto p = make_shared_noinit(1024);`
diff --git a/doc/smart_ptr/make_unique.adoc b/doc/smart_ptr/make_unique.adoc
new file mode 100644
index 0000000..b4e94bf
--- /dev/null
+++ b/doc/smart_ptr/make_unique.adoc
@@ -0,0 +1,115 @@
+////
+Copyright 2017 Peter Dimov
+Copyright 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
+
+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
+////
+
+[#make_unique]
+# make_unique: Creating unique_ptr
+:toc:
+:toc-title:
+:idprefix: make_unique_
+
+## Description
+
+The `make_unique` function templates provide convenient and safe ways to
+create `std::unique_ptr` objects.
+
+## Rationale
+
+The {cpp}11 standard introduced `std::unique_ptr` but did not provide any
+`make_unique` utility like `std::make_shared` that provided the same
+exception safety and facility to avoid writing `new` expressions. Before it
+was implemented by some standard library vendors (and prior to the {cpp}14
+standard introducing `std::make_unique`), this library provided it due to
+requests from users.
+
+This library also provides additional overloads of `make_unique` for
+default-initialization, when users do not need or want to incur the expense
+of value-initialization. The {cpp} standard does not yet provide this
+feature with `std::make_unique`.
+
+## Synopsis
+
+`make_unique` is defined in ``.
+
+[subs=+quotes]
+```
+namespace boost {
+ `// only if T is not an array type`
+ template
+ std::unique_ptr make_unique(Args&&... args);
+
+ `// only if T is not an array type`
+ template
+ std::unique_ptr make_unique(remove_reference_t&& v);
+
+ `// only if T is an array type of the form U[]`
+ template
+ std::unique_ptr make_unique(std::size_t n);
+
+ `// only if T is not an array type`
+ template
+ std::unique_ptr make_unique_noinit();
+
+ `// only if T is an array type of the form U[]`
+ template
+ std::unique_ptr make_unique_noinit(std::size_t n);
+}
+```
+
+## Free Functions
+
+```
+template
+ std::unique_ptr make_unique(Args&&... args);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is not an array type.
+Returns::: `std::unique_ptr(new T(std::forward(args)\...)`.
+Example::: `auto p = make_unique();`
+
+```
+template
+ std::unique_ptr make_unique(remove_reference_t&& v);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is not an array type.
+Returns::: `std::unique_ptr(new T(std::move(v))`.
+Example::: `auto p = make_unique >({1, 2});`
+
+```
+template
+ std::unique_ptr make_unique(std::size_t n);
+```
+::
+Remarks::: These overloads shall only participate in overload resolution when
+`T` is an array type of the form `U[]`.
+Returns::: `std::unique_ptr