about summary refs log tree commit diff
path: root/third_party/immer/doc
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-07-15T07·20+0100
committerVincent Ambo <mail@tazj.in>2020-07-15T07·23+0100
commit1213b086a1015a662ab7ebd658f784534fd3116a (patch)
treed3bc8f3b7f40b8b60f0ef6fbd649cf765f4fdfb6 /third_party/immer/doc
parent1390827b9ea1e04bc9863e48930bfd16db3b716e (diff)
parent7f19d641647ac4ef313ed88d6b5c140983ce5436 (diff)
merge(3p/immer): Subtree merge at 'ad3e3556d' as 'third_party/immer' r/1299
Change-Id: I9636a41ad44b4218293833fd3e9456d9b07c731b
Diffstat (limited to 'third_party/immer/doc')
-rw-r--r--third_party/immer/doc/CMakeLists.txt23
-rw-r--r--third_party/immer/doc/Makefile226
-rw-r--r--third_party/immer/doc/_static/logo-black.svg100
-rw-r--r--third_party/immer/doc/_static/logo-front.svg99
-rw-r--r--third_party/immer/doc/_static/logo.svg99
-rw-r--r--third_party/immer/doc/_static/patreon.svg120
-rw-r--r--third_party/immer/doc/_static/sinusoidal-badge.svg166
-rw-r--r--third_party/immer/doc/algorithms.rst28
-rw-r--r--third_party/immer/doc/conf.py452
-rw-r--r--third_party/immer/doc/containers.rst50
-rw-r--r--third_party/immer/doc/design.rst268
-rw-r--r--third_party/immer/doc/doxygen.config23
l---------third_party/immer/doc/guile.rst1
-rw-r--r--third_party/immer/doc/implementation.rst6
-rw-r--r--third_party/immer/doc/index.rst31
-rw-r--r--third_party/immer/doc/introduction.rst6
-rw-r--r--third_party/immer/doc/memory.rst204
l---------third_party/immer/doc/python.rst1
-rw-r--r--third_party/immer/doc/requirements.txt3
-rwxr-xr-xthird_party/immer/doc/sphinx-html-hack.bash101
-rw-r--r--third_party/immer/doc/transients.rst51
-rw-r--r--third_party/immer/doc/utilities.rst15
22 files changed, 2073 insertions, 0 deletions
diff --git a/third_party/immer/doc/CMakeLists.txt b/third_party/immer/doc/CMakeLists.txt
new file mode 100644
index 0000000000..0b3d85c6ac
--- /dev/null
+++ b/third_party/immer/doc/CMakeLists.txt
@@ -0,0 +1,23 @@
+
+#  Targets
+#  =======
+
+add_custom_target(doxygen
+  COMMAND doxygen doxygen.config
+  WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc")
+
+add_custom_target(docs
+  COMMAND make html
+  WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc")
+add_dependencies(docs doxygen)
+
+set(immer_ssh_method
+  ssh -p 5488
+      -o StrictHostKeyChecking=no
+      -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key)
+
+add_custom_target(upload-docs
+  COMMAND
+  rsync -av -e \"${immer_ssh_method}\"
+        ${CMAKE_SOURCE_DIR}/doc/_build/html/*
+        raskolnikov@sinusoid.es:public/immer/)
diff --git a/third_party/immer/doc/Makefile b/third_party/immer/doc/Makefile
new file mode 100644
index 0000000000..101addd4ef
--- /dev/null
+++ b/third_party/immer/doc/Makefile
@@ -0,0 +1,226 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  applehelp  to make an Apple Help Book"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  epub3      to make an epub3"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  xml        to make Docutils-native XML files"
+	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+	@echo "  coverage   to run coverage check of the documentation (if enabled)"
+	@echo "  dummy      to check syntax errors of document sources"
+
+.PHONY: clean
+clean:
+	rm -rf $(BUILDDIR)/*
+
+.PHONY: html
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	bash sphinx-html-hack.bash
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+.PHONY: dirhtml
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+.PHONY: singlehtml
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+.PHONY: pickle
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+.PHONY: json
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+.PHONY: htmlhelp
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+.PHONY: qthelp
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/immer.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/immer.qhc"
+
+.PHONY: applehelp
+applehelp:
+	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+	@echo
+	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+	@echo "N.B. You won't be able to view it unless you put it in" \
+	      "~/Library/Documentation/Help or install it in your application" \
+	      "bundle."
+
+.PHONY: devhelp
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/immer"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/immer"
+	@echo "# devhelp"
+
+.PHONY: epub
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+.PHONY: epub3
+epub3:
+	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
+	@echo
+	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
+
+.PHONY: latex
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+.PHONY: latexpdf
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: latexpdfja
+latexpdfja:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through platex and dvipdfmx..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: text
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+.PHONY: man
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+.PHONY: texinfo
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+.PHONY: info
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+.PHONY: gettext
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+.PHONY: changes
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+.PHONY: linkcheck
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+.PHONY: doctest
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+
+.PHONY: coverage
+coverage:
+	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+	@echo "Testing of coverage in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/coverage/python.txt."
+
+.PHONY: xml
+xml:
+	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+	@echo
+	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+.PHONY: pseudoxml
+pseudoxml:
+	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+	@echo
+	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+
+.PHONY: dummy
+dummy:
+	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
+	@echo
+	@echo "Build finished. Dummy builder generates no files."
diff --git a/third_party/immer/doc/_static/logo-black.svg b/third_party/immer/doc/_static/logo-black.svg
new file mode 100644
index 0000000000..370e047c4b
--- /dev/null
+++ b/third_party/immer/doc/_static/logo-black.svg
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="437.76035"
+   height="141.89464"
+   viewBox="0 0 115.8241 37.542956"
+   version="1.1"
+   id="svg5447"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="logo-black.svg">
+  <defs
+     id="defs5441" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#000000"
+     bordercolor="#8b8384"
+     borderopacity="1"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35"
+     inkscape:cx="335.15011"
+     inkscape:cy="98.353481"
+     inkscape:document-units="mm"
+     inkscape:current-layer="g4502"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1152"
+     inkscape:window-height="1080"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5444">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(6.8182189,-70.341619)">
+    <g
+       id="g4502"
+       transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)">
+      <g
+         id="g5321"
+         transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)"
+         style="fill:none;stroke:#ffffff">
+        <g
+           style="fill:none;stroke:#ffffff;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none"
+           transform="translate(303.46093,-4.9296877)"
+           id="g5317">
+          <path
+             id="rect5315"
+             style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z"
+             inkscape:connector-curvature="0" />
+        </g>
+      </g>
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="43.067963"
+         y="112.13454"
+         id="text5338"><tspan
+           sodipodi:role="line"
+           id="tspan5336"
+           x="43.067963"
+           y="112.13454"
+           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';fill:#ffffff;stroke-width:0.30189785px">immer</tspan></text>
+      <rect
+         ry="0"
+         y="66.38237"
+         x="-37.756119"
+         height="7.9375"
+         width="7.9375"
+         id="rect5425"
+         style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>
diff --git a/third_party/immer/doc/_static/logo-front.svg b/third_party/immer/doc/_static/logo-front.svg
new file mode 100644
index 0000000000..b56393b9b1
--- /dev/null
+++ b/third_party/immer/doc/_static/logo-front.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1037.7604"
+   height="441.89462"
+   viewBox="0 0 274.57411 116.91795"
+   version="1.1"
+   id="svg5447"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="logo-front.svg">
+  <defs
+     id="defs5441" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35"
+     inkscape:cx="172.29297"
+     inkscape:cy="385.49612"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="150"
+     fit-margin-left="300"
+     fit-margin-right="300"
+     fit-margin-bottom="150"
+     inkscape:window-width="1440"
+     inkscape:window-height="1080"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5444">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(86.193219,-30.654119)">
+    <g
+       id="g4502"
+       transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)">
+      <g
+         id="g5321"
+         transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)">
+        <g
+           style="stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none"
+           transform="translate(303.46093,-4.9296877)"
+           id="g5317">
+          <path
+             id="rect5315"
+             style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z"
+             inkscape:connector-curvature="0" />
+        </g>
+      </g>
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="43.067963"
+         y="112.13454"
+         id="text5338"><tspan
+           sodipodi:role="line"
+           id="tspan5336"
+           x="43.067963"
+           y="112.13454"
+           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';stroke-width:0.30189785px">immer</tspan></text>
+      <rect
+         ry="0"
+         y="66.38237"
+         x="-37.756119"
+         height="7.9375"
+         width="7.9375"
+         id="rect5425"
+         style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>
diff --git a/third_party/immer/doc/_static/logo.svg b/third_party/immer/doc/_static/logo.svg
new file mode 100644
index 0000000000..64bff0dde8
--- /dev/null
+++ b/third_party/immer/doc/_static/logo.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="437.76035"
+   height="141.89464"
+   viewBox="0 0 115.8241 37.542956"
+   version="1.1"
+   id="svg5447"
+   inkscape:version="0.92.1 r15371"
+   sodipodi:docname="logo.svg">
+  <defs
+     id="defs5441" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35"
+     inkscape:cx="-127.70703"
+     inkscape:cy="235.49612"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1440"
+     inkscape:window-height="1080"
+     inkscape:window-x="1920"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     units="px" />
+  <metadata
+     id="metadata5444">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(6.8182189,-70.341619)">
+    <g
+       id="g4502"
+       transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)">
+      <g
+         id="g5321"
+         transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)">
+        <g
+           style="stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none"
+           transform="translate(303.46093,-4.9296877)"
+           id="g5317">
+          <path
+             id="rect5315"
+             style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z"
+             inkscape:connector-curvature="0" />
+        </g>
+      </g>
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="43.067963"
+         y="112.13454"
+         id="text5338"><tspan
+           sodipodi:role="line"
+           id="tspan5336"
+           x="43.067963"
+           y="112.13454"
+           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';stroke-width:0.30189785px">immer</tspan></text>
+      <rect
+         ry="0"
+         y="66.38237"
+         x="-37.756119"
+         height="7.9375"
+         width="7.9375"
+         id="rect5425"
+         style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>
diff --git a/third_party/immer/doc/_static/patreon.svg b/third_party/immer/doc/_static/patreon.svg
new file mode 100644
index 0000000000..a8cc33975b
--- /dev/null
+++ b/third_party/immer/doc/_static/patreon.svg
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 175.20599 88.309158"
+   xml:space="preserve"
+   sodipodi:docname="patreon.svg"
+   inkscape:version="0.92.2pre0 (973e216, 2017-07-25)"
+   width="175.20599"
+   height="88.309158"><metadata
+     id="metadata53"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title>support</dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs51" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1267"
+     inkscape:window-height="1054"
+     id="namedview49"
+     showgrid="false"
+     inkscape:zoom="1.672"
+     inkscape:cx="-2.5899259"
+     inkscape:cy="100.34184"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Layer_1"
+     fit-margin-left="16"
+     fit-margin-right="16"
+     fit-margin-bottom="16"
+     fit-margin-top="16"
+     showborder="true" /><style
+     type="text/css"
+     id="style2">
+	.st0{fill:#E64825;}
+	.st1{fill:#FFFFFF;}
+	.st2{enable-background:new    ;}
+</style><title
+     id="title4">support</title><g
+     id="g4591"
+     transform="matrix(1.1623322,0,0,1.1623322,4.376678,-18.86997)"><rect
+       ry="5.3968496"
+       y="30.000004"
+       x="10"
+       height="48.444977"
+       width="123.20574"
+       id="rect4576"
+       style="opacity:1;vector-effect:none;fill:#f96854;fill-opacity:1;stroke:none;stroke-width:1.95915079;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><g
+       transform="translate(9.401915,29.145936)"
+       id="g4574"><g
+         id="g4557"
+         transform="translate(-120.21531,7.9502949)"><path
+           id="path8"
+           d="m 143.8,12.9 h 0.7 c 6.4,0.2 11.5,5.6 11.3,12 -0.2,6.2 -5.1,11.1 -11.3,11.3 h -5.7 c 0,-3.9 0,-7.8 0,-11.7 0.1,-2.9 2.5,-5.3 5.4,-5.2 2.9,0.1 5.3,2.5 5.2,5.4 -0.1,2.9 -2.5,5.3 -5.4,5.2 -0.8,0 -1.7,-0.2 -2.4,-0.6 0,1.3 0,2.5 0,3.8 1.7,0.5 3.6,0.5 5.3,-0.1 4.7,-1.5 7.2,-6.6 5.6,-11.2 -1.5,-4.7 -6.6,-7.2 -11.2,-5.6 -3.6,1.2 -6,4.5 -6.1,8.3 0,3.9 0,7.8 0,11.7 h -2.8 v -12 c 0.1,-4 2.3,-7.6 5.6,-9.6 1.9,-1.1 3.8,-1.7 5.8,-1.7 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path10"
+           d="m 186.5,13.9 h 1.9 c 0,1.4 0,2.9 0,4.3 h 2.8 c 0,0.6 0,1.3 0,1.9 h -2.8 c 0,3.1 0,6.2 0,9.3 h -1.9 c 0,-3.1 0,-6.2 0,-9.3 h -1.1 c 0,-0.6 0,-1.3 0,-1.9 h 1.1 c 0,-1.4 -0.1,-2.9 0,-4.3 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path12"
+           d="m 177.5,17.8 c 3.3,-0.7 6.5,1.5 7.2,4.8 0,0.1 0,0.2 0,0.2 0.1,0.6 0.1,1.2 0.1,1.8 0,1.6 0,3.2 0,4.8 h -1.9 c 0,-0.4 0,-0.8 0,-1.2 -2.4,2.3 -6.3,2.2 -8.6,-0.2 -2.3,-2.4 -2.2,-6.3 0.2,-8.6 0.8,-0.9 1.9,-1.4 3,-1.6 z m 0.8,1.7 c -2.3,0.2 -4,2.3 -3.8,4.6 0,0.3 0.1,0.5 0.2,0.8 0.2,0.8 0.7,1.5 1.3,2 0.7,0.6 1.6,1 2.6,1 0.8,0 1.6,-0.1 2.3,-0.5 2,-1.2 2.7,-3.7 1.6,-5.8 -1,-1.4 -2.5,-2.2 -4.2,-2.1 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path14"
+           d="m 203.3,17.7 c 2,-0.3 4,0.5 5.3,1.9 l -7.9,6.6 c 1.4,1.9 4,2.3 5.9,0.9 1.3,-0.9 1.9,-2.5 1.7,-4 h 1.9 c 0.1,1.3 -0.2,2.6 -0.9,3.8 -0.5,0.9 -1.2,1.6 -2.1,2.1 -2.9,1.7 -6.6,0.8 -8.4,-2.1 -0.7,-1.1 -1,-2.4 -0.9,-3.6 0.1,-1 0.4,-2 1,-2.8 1.1,-1.5 2.6,-2.5 4.4,-2.8 z m -2.8,3.8 c -0.6,0.9 -0.8,2 -0.6,3 l 5.6,-4.7 c -0.3,-0.1 -0.7,-0.2 -1,-0.2 -1.6,-0.2 -3.1,0.6 -4,1.9 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path16"
+           d="m 216.6,17.7 c 1.3,-0.1 2.6,0.2 3.6,0.9 2.9,1.8 3.7,5.5 1.9,8.4 -1.8,2.9 -5.5,3.7 -8.4,1.9 -2.9,-1.8 -3.7,-5.5 -1.9,-8.4 0.5,-0.8 1.2,-1.5 2,-2 0.9,-0.5 1.8,-0.8 2.8,-0.8 z m 0.1,1.8 c -2.3,0.2 -4.1,2.2 -3.9,4.5 0.2,2.3 2.2,4.1 4.5,3.9 2.3,-0.2 4.1,-2.2 3.9,-4.5 -0.1,-1.2 -0.7,-2.4 -1.7,-3.1 -0.8,-0.6 -1.8,-0.8 -2.8,-0.8 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path18"
+           d="m 226,18.9 c 1.2,-1.1 2.8,-1.5 4.3,-1.1 1.2,0.3 2.2,1 2.9,1.9 0.6,0.8 1,1.8 1,2.8 0,1.5 0,3 0,4.6 v 2.2 h -1.9 c 0,-2.2 0,-4.5 0,-6.7 0,-1.1 -0.6,-2.1 -1.5,-2.6 -0.8,-0.5 -1.8,-0.6 -2.7,-0.3 -1.1,0.4 -1.9,1.5 -2.1,2.7 0,0.5 0,1 0,1.6 0,1.8 0,3.6 0,5.4 h -1.9 c 0,-3.7 0,-7.4 0,-11.1 h 1.9 c 0,0.1 0,0.3 0,0.6 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path20"
+           d="m 161.1,20 c 2.1,-2.6 5.9,-3.1 8.6,-1 2.6,2.1 3.1,5.9 1,8.6 -1.1,1.3 -2.6,2.2 -4.3,2.3 -1,0.1 -2,-0.1 -2.8,-0.6 -0.7,-0.3 -1.3,-0.8 -1.8,-1.3 0,1.9 0,3.8 0,5.7 h -1.9 c 0,-3.3 0,-6.6 0,-9.9 -0.1,-1.4 0.4,-2.7 1.2,-3.8 z m 4,-0.4 c -2.3,0.4 -3.8,2.6 -3.4,4.9 0.4,2.3 2.6,3.8 4.9,3.4 2.3,-0.4 3.8,-2.6 3.4,-4.9 -0.2,-1.2 -1,-2.3 -2,-2.9 -0.9,-0.5 -1.9,-0.7 -2.9,-0.5 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /><path
+           id="path22"
+           d="m 192,18.2 h 1.8 c 0,0.6 0,1.1 0,1.7 1.2,-1.1 2.8,-1.8 4.4,-1.7 0,0.6 0,1.3 0,1.9 -2.3,-0.1 -4.3,1.7 -4.4,4.1 0,0 0,0.1 0,0.1 0,1.7 0,3.4 0,5.1 H 192 c 0.1,-3.8 0,-7.5 0,-11.2 z"
+           class="st1"
+           inkscape:connector-curvature="0"
+           style="fill:#ffffff" /></g><text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.8520174px;line-height:4.5em;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.73991024"
+         x="114.89897"
+         y="14.870183"
+         id="text4561"><tspan
+           sodipodi:role="line"
+           id="tspan4559"
+           x="114.89897"
+           y="14.870183"
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';fill:#ffffff;stroke-width:0.73991024">support us on</tspan></text>
+</g></g></svg>
\ No newline at end of file
diff --git a/third_party/immer/doc/_static/sinusoidal-badge.svg b/third_party/immer/doc/_static/sinusoidal-badge.svg
new file mode 100644
index 0000000000..0282a2f7a4
--- /dev/null
+++ b/third_party/immer/doc/_static/sinusoidal-badge.svg
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="350"
+   height="20"
+   version="1.1"
+   id="svg28"
+   sodipodi:docname="sinusoidal-badge.svg"
+   inkscape:version="0.92.2pre0 (973e216, 2017-07-25)">
+  <metadata
+     id="metadata34">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs32">
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="Arrow1Lstart"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow1Lstart">
+      <path
+         inkscape:connector-curvature="0"
+         transform="matrix(0.8,0,0,0.8,10,0)"
+         style="fill:#444444;fill-opacity:1;fill-rule:evenodd;stroke:#444444;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="M 0,0 5,-5 -12.5,0 5,5 Z"
+         id="path10186" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1267"
+     inkscape:window-height="1054"
+     id="namedview30"
+     showgrid="false"
+     inkscape:zoom="1"
+     inkscape:cx="89.411561"
+     inkscape:cy="-177.54677"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g26" />
+  <linearGradient
+     id="b"
+     x2="0"
+     y2="1">
+    <stop
+       offset="0"
+       stop-color="#bbb"
+       stop-opacity=".1"
+       id="stop2" />
+    <stop
+       offset="1"
+       stop-opacity=".1"
+       id="stop4" />
+  </linearGradient>
+  <mask
+     id="a">
+    <rect
+       width="96"
+       height="20"
+       rx="3"
+       id="rect7"
+       x="0"
+       y="0"
+       style="fill:#ffffff" />
+  </mask>
+  <g
+     font-size="11"
+     id="g26"
+     style="font-size:11px;font-family:'DejaVu Sans', Verdana, Geneva, sans-serif;text-anchor:middle;fill:#000000">
+    <text
+       x="30"
+       y="15"
+       id="text18"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';fill:#000000;fill-opacity:0.3" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:4.5em;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
+       x="52.626465"
+       y="14.072"
+       id="text843"><tspan
+         sodipodi:role="line"
+         id="tspan841"
+         x="52.626465"
+         y="14.072"
+         style="font-size:13.33333397px"><tspan
+           style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:13.33333397px;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Light'"
+           id="tspan859">quality libre software by</tspan><tspan
+           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.33333397px;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold'"
+           id="tspan4711">  </tspan><tspan
+           style="font-weight:bold;font-size:13.33333397px"
+           id="tspan849">sinusoidal engineering</tspan></tspan></text>
+    <g
+       transform="matrix(4.4383113,0,0,4.4383113,-73.95876,-379.69787)"
+       id="layer1"
+       inkscape:label="Layer 1">
+      <g
+         id="g10518"
+         transform="matrix(0.07290361,0,0,0.07290361,90.22887,85.474692)">
+        <g
+           id="g906"
+           transform="matrix(0.8913912,0,0,0.8913912,6.4029255,3.518587)">
+          <g
+             transform="translate(2.9886077,2.3730299)"
+             style="stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none"
+             id="g10505">
+            <g
+               transform="matrix(0.28222223,0,0,0.28222223,237.85811,-1729.1481)"
+               style="stroke:#444444;stroke-width:32.14861298;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+               id="g6292">
+              <rect
+                 y="6129.2646"
+                 x="-842.80432"
+                 height="206.24994"
+                 width="206.25005"
+                 id="rect6290"
+                 style="opacity:1;fill:none;fill-opacity:1;stroke:#444444;stroke-width:32.14861298;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+            </g>
+            <path
+               id="path6294"
+               title="sin(x/2)"
+               d="m 55.5625,0.66666667 c -0.928371,0 -1.856705,0.13319437 -2.785079,0.39715343 -0.928371,0.2636873 -1.856744,0.6592201 -2.785077,1.1798418 -0.928372,0.5208916 -1.856743,1.1674139 -2.785116,1.9309205 -0.928334,0.7632369 -1.856705,1.6439988 -2.785078,2.6290465 -0.928372,0.9850477 -1.856743,2.0754629 -2.785077,3.2555751 -0.928372,1.180112 -1.856744,2.450461 -2.785115,3.793218 -0.928336,1.342755 -1.856706,2.758458 -2.785077,4.227385 -0.928374,1.469197 -1.856708,2.991617 -2.785079,4.546459 -0.928372,1.555111 -1.856744,3.142642 -2.785115,4.741252 -0.928334,1.598609 -1.856707,3.208295 -2.785078,4.806905 -0.928371,1.598608 -1.856705,3.18614 -2.785079,4.741251 -0.928371,1.555112 -1.856705,3.077263 -2.785077,4.546188 -0.928408,1.469197 -1.856743,2.88463 -2.785079,4.227655 -0.928407,1.342757 -1.856742,2.612837 -2.785115,3.793218 -0.928334,1.180113 -1.856705,2.270258 -2.785077,3.255575 -0.928372,0.985319 -1.856742,1.86554 -2.785113,2.629047 -0.928337,0.763506 -1.8567441,1.409758 -2.785079,1.93092 C 7.2876175,57.819171 6.3592466,58.214164 5.4308755,58.478121 4.5025393,58.742347 3.5742044,58.875 2.6458333,58.875"
+               style="opacity:1;fill:none;fill-opacity:1;stroke:#444444;stroke-width:9.07305336;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               inkscape:connector-curvature="0" />
+          </g>
+          <circle
+             r="7.2447839"
+             cy="2.9294415"
+             cx="61.518147"
+             id="ellipse10510"
+             style="opacity:1;fill:#f0544c;fill-opacity:1;stroke:#ffffff;stroke-width:5.44383192;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+          <circle
+             style="opacity:1;fill:#444444;fill-opacity:1;stroke:#ffffff;stroke-width:5.44383192;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             id="circle898"
+             cx="2.0896502"
+             cy="61.450638"
+             r="7.2447839" />
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/third_party/immer/doc/algorithms.rst b/third_party/immer/doc/algorithms.rst
new file mode 100644
index 0000000000..f7de519c05
--- /dev/null
+++ b/third_party/immer/doc/algorithms.rst
@@ -0,0 +1,28 @@
+
+Algorithms
+==========
+
+This module provides overloads of standard algorithms that leverage
+the internal structure of the immutable containers to provide faster
+iteration. These are drop-in replacements of the respective STL
+algorithms that can be a few times faster when applied on immutable
+sequences.
+
+For further convenience they can be passed in just a container where
+the standard library algorithms require being passed in two iterators.
+
+.. note::
+
+   They are a similar idea to `structure-aware iterators`_
+   but implemented using higher order functions in order to support
+   structures of any depth.  The downside is that this sometimes
+   causes the compiler to generate bigger executable files.
+
+.. _structure-aware iterators: https://www.youtube.com/watch?v=T3oA3zAMH9M
+
+
+-----
+
+.. doxygengroup:: algorithm
+   :project: immer
+   :content-only:
diff --git a/third_party/immer/doc/conf.py b/third_party/immer/doc/conf.py
new file mode 100644
index 0000000000..3c32cc505b
--- /dev/null
+++ b/third_party/immer/doc/conf.py
@@ -0,0 +1,452 @@
+# -*- coding: utf-8 -*-
+#
+# immer documentation build configuration file, created by
+# sphinx-quickstart on Thu Oct 27 18:10:24 2016.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.mathjax',
+    'breathe',
+]
+
+breathe_projects = { "immer": "_doxygen/xml" }
+breathe_default_project = "immer"
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+from recommonmark.parser import CommonMarkParser
+from recommonmark.transform import AutoStructify
+source_parsers = { '.md': CommonMarkParser, }
+source_suffix = ['.rst', '.md']
+
+def setup(app):
+    app.add_config_value('recommonmark_config', {
+        'enable_eval_rst': True,
+    }, True)
+    app.add_transform(AutoStructify)
+
+# The encoding of source files.
+#
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'immer'
+copyright = u'2016, 2017 Juan Pedro Bolivar Puente'
+author = u'Juan Pedro Bolivar Puente'
+
+raw_enabled = True
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = u'0.0.0'
+# The full version, including alpha/beta/rc tags.
+release = u'0.0.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#
+# today = ''
+#
+# Else, today_fmt is used as the format for a strftime call.
+#
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+
+import sys
+import os.path
+sys.path.append(os.path.join(os.path.dirname(__file__),
+                             '../tools/sinusoidal-sphinx-theme'))
+
+import sinusoidal_sphinx_theme
+html_theme_path = sinusoidal_sphinx_theme.html_theme_path()
+html_theme = 'sinusoidal_sphinx_theme'
+extensions.append("sinusoidal_sphinx_theme")
+html_theme_options = {
+    "project_nav_name": "immer",
+    "github_link" : "https://github.com/arximboldi/immer",
+}
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.
+# "<project> v<release> documentation" by default.
+#
+# html_title = u'immer v0.0.0'
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#
+html_logo = '_static/logo-black.svg'
+
+# The name of an image file (relative to this directory) to use as a favicon of
+# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#
+# html_extra_path = []
+
+# If not None, a 'Last updated on:' timestamp is inserted at every page
+# bottom, using the given strftime format.
+# The empty string is equivalent to '%b %d, %Y'.
+#
+# html_last_updated_fmt = None
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+#
+# html_domain_indices = True
+
+# If false, no index is generated.
+#
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
+#
+# html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# 'ja' uses this config value.
+# 'zh' user can custom change `jieba` dictionary path.
+#
+# html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#
+# html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'immerdoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+     # The paper size ('letterpaper' or 'a4paper').
+     #
+     # 'papersize': 'letterpaper',
+
+     # The font size ('10pt', '11pt' or '12pt').
+     #
+     # 'pointsize': '10pt',
+
+     # Additional stuff for the LaTeX preamble.
+     #
+     # 'preamble': '',
+
+     # Latex figure (float) alignment
+     #
+     # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, 'immer.tex', u'immer Documentation',
+     u'Juan Pedro Bolivar Puente', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+#
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#
+# latex_appendices = []
+
+# It false, will not define \strong, \code, 	itleref, \crossref ... but only
+# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
+# packages.
+#
+# latex_keep_old_macro_names = True
+
+# If false, no module index is generated.
+#
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    (master_doc, 'immer', u'immer Documentation',
+     [author], 1)
+]
+
+# If true, show URL addresses after external links.
+#
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (master_doc, 'immer', u'immer Documentation',
+     author, 'immer', 'One line description of project.',
+     'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+#
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#
+# texinfo_no_detailmenu = False
+
+
+# -- Options for Epub output ----------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
+epub_author = author
+epub_publisher = author
+epub_copyright = copyright
+
+# The basename for the epub file. It defaults to the project name.
+# epub_basename = project
+
+# The HTML theme for the epub output. Since the default themes are not
+# optimized for small screen space, using the same theme for HTML and epub
+# output is usually not wise. This defaults to 'epub', a theme designed to save
+# visual space.
+#
+# epub_theme = 'epub'
+
+# The language of the text. It defaults to the language option
+# or 'en' if the language is not set.
+#
+# epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+# epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#
+# epub_identifier = ''
+
+# A unique identification for the text.
+#
+# epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#
+# epub_cover = ()
+
+# A sequence of (type, uri, title) tuples for the guide element of content.opf.
+#
+# epub_guide = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#
+# epub_pre_files = []
+
+# HTML files that should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#
+# epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+# The depth of the table of contents in toc.ncx.
+#
+# epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#
+# epub_tocdup = True
+
+# Choose between 'default' and 'includehidden'.
+#
+# epub_tocscope = 'default'
+
+# Fix unsupported image types using the Pillow.
+#
+# epub_fix_images = False
+
+# Scale large images.
+#
+# epub_max_image_width = 0
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#
+# epub_show_urls = 'inline'
+
+# If false, no index is generated.
+#
+# epub_use_index = True
diff --git a/third_party/immer/doc/containers.rst b/third_party/immer/doc/containers.rst
new file mode 100644
index 0000000000..c6913ba4a5
--- /dev/null
+++ b/third_party/immer/doc/containers.rst
@@ -0,0 +1,50 @@
+.. highlight:: c++
+
+Containers
+==========
+
+This section describes all the containers provided by the library.
+Check the :ref:`design` section for a general discussion of these
+containers and how to use them.
+
+box
+---
+
+.. doxygenclass:: immer::box
+    :members:
+    :undoc-members:
+
+array
+-----
+
+.. doxygenclass:: immer::array
+    :members:
+    :undoc-members:
+
+vector
+------
+
+.. doxygenclass:: immer::vector
+    :members:
+    :undoc-members:
+
+flex_vector
+-----------
+
+.. doxygenclass:: immer::flex_vector
+    :members:
+    :undoc-members:
+
+set
+---
+
+.. doxygenclass:: immer::set
+    :members:
+    :undoc-members:
+
+map
+---
+
+.. doxygenclass:: immer::map
+    :members:
+    :undoc-members:
diff --git a/third_party/immer/doc/design.rst b/third_party/immer/doc/design.rst
new file mode 100644
index 0000000000..27d29e9e61
--- /dev/null
+++ b/third_party/immer/doc/design.rst
@@ -0,0 +1,268 @@
+.. _design:
+
+Design
+======
+
+This is a library of **immutable containers**.
+
+These containers have all their methods marked ``const``.  Instead of
+mutating them *in place*, they provide manipulation functions that
+*return a new transformed value*, leaving the original value
+unaltered.  In the context of data-structures, this property of
+preserving old values is called **persistence**.
+
+Most of these containers use data-structures in which these operations
+can be done *efficiently*.  In particular, not all data is copied when
+a new value is produced.  Instead, the new values may share,
+internally, common data with other objects.  We sometimes refer to
+this property as **structural sharing**.  This behaviour is
+transparent to the user.
+
+Assigment
+---------
+
+We are sorry, we lied. These containers provide *one mutating
+operation*: **assignment** --- i.e. ``operator=``.
+
+There is a good reason: without ``operator=`` everything becomes
+complicated in C++.  For example, one may not contain non-assignable
+types in many standard containers, assignment would also be disabled
+from your custom types holding immutable containers, and so on and so
+forth.
+
+C++ is a multi-paradigm language with an imperative core.  Thus, it is
+built on the foundation that *variables* can be mutated ---
+i.e. assigned to.  We don't want to ride against this tide.  What we
+want to prevent is in-place *object* manipulation.  Because of C++
+semantics, *variable* assignment is defined in terms of *object
+mutation*, so we have to provide *this very particular mutating
+operation*, but nothing else.  Of course, you are free to mark your
+variables ``const`` to completely forbid assignment.
+
+.. warning::
+
+   **Assignment is not thread safe**.  When a *mutable* variable is
+   shared across multiple threads, protect access using some other
+   mechanism.
+
+   For obvious reasons, all other methods, which are ``const``, are
+   thread-safe.  It is safe to share *immutable* state across multiple
+   threads.
+
+To ``const`` or not to ``const``
+--------------------------------
+
+Many C++ programmers, influenced by functional programming, are trying
+to escape the evils of mutability by using ``const`` whenever
+possible.  We also do it ourselves in many of our examples to
+reinforce the property of immutability.
+
+While in general this is a good practice backed up with very good
+intentions, it has one caveat: *it disables moveability*.  It does so
+even when ``std::move()`` is used.  This makes sense, since moving from
+an object may mutate it, and ``const``, my friends, prevents *all*
+mutations.  For example:
+
+.. literalinclude:: ../example/vector/move.cpp
+   :language: c++
+   :start-after: move-bad/start
+   :end-before:  move-bad/end
+
+One may think that the variable ``v`` is moved into the
+``push_back()`` call.  This is not the case, because the variable
+``v`` is marked ``const``.  Of course, one may enable the move by
+removing it, as in:
+
+.. literalinclude:: ../example/vector/move.cpp
+   :language: c++
+   :start-after: move-good/start
+   :end-before:  move-good/end
+
+So, is it bad style then to use ``const`` as much as possible?  I
+wouldn't say so and it is advisable when ``std::move()`` is not used.
+An alternative style is to not use ``const`` but adopt an `AAA-style
+<aaa>`_ (*Almost Always use Auto*).  This way, it is easy to look for
+mutations by looking for lines that contain ``=`` but no ``auto``.
+Remember that when using our immutable containers ``operator=`` is the
+only way to mutate a variable.
+
+.. _aaa: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/
+
+.. admonition:: Why does ``const`` prevent move semantics?
+
+   For those adventurous into the grainy details C++, here is why.
+   ``std::move()`` does not move anything, it is just *a cast* from
+   normal *l-value* references (``T&``) to *r-value* reference
+   (``T&&``).  This is, you pass it a variable, and it returns a
+   reference to its object disguised as an intermediate result.  In
+   exchange, you promise not to do anything with this variable later
+   [#f1]_. It is the role of the thing that *receives the moved-from
+   value* (in the previous example, ``push_back``) to actually do
+   anything interesting with it --- for example, steal its contents
+   😈.
+
+   So if you pass a ``T&`` to ``std::move()`` you get a ``T&&`` and,
+   unsurprisingly, if you pass a ``const T&`` you get a ``const T&&``.
+   But the receivers of the moved-from value (like constructors or our
+   ``push_back()``) maybe be moved-into because they provide an
+   overload that expects ``T&&`` --- without the ``const``!  Since a
+   ``const T&&`` can not be converted into a ``T&&``, the compiler
+   looks up for you another viable overload, and most often finds a
+   copy constructor or something alike that expects a ``const T&`` or
+   just ``T``, to which a ``const T&&`` can be converted.  The code
+   compiles and works correctly, but it is less efficient than we
+   expected.  Our call to ``std::move()`` was fruitless.
+
+   .. [#f1] For the sake of completeness: it is actually allowed to do stuff
+            with the variable *after another value is assigned to it*.
+
+.. _move-semantics:
+
+Leveraging move semantics
+-------------------------
+
+When using :ref:`reference counting<rc>` (which is the default)
+mutating operations can often be faster when operating on *r-value
+references* (temporaries and moved-from values).  Note that this
+removes *persistence*, since one can not access the moved-from value
+anymore!  However, this may be a good idea when doing a chain of
+operations where the intermediate values are not important to us.
+
+For example, let's say we want to write a function that inserts all
+integers in the range :math:`[first, last)` into an immutable vector.
+From the point of view of the caller of the function, this function is
+a *transaction*.  Whatever intermediate vectors are generated inside
+of it can be discarded since the caller can only see the initial
+vector (the one passed in as argument) and the vector with *all* the
+elements.  We may write such function like this:
+
+.. literalinclude:: ../example/vector/iota-move.cpp
+   :language: c++
+   :start-after: myiota/start
+   :end-before:  myiota/end
+
+The intermediate values are *moved* into the next ``push_back()``
+call.  They are going to be discarded anyways, this little
+``std::move`` just makes the whole thing faster, letting ``push_back``
+mutate part of the internal data structure in place when possible.
+
+If you don't like this syntax, :doc:`transients<transients>` may be
+used to obtain similar performance benefits.
+
+.. admonition:: Assigment guarantees
+
+   From the language point of view, the only requirement on moved from
+   values is that they should still be destructible.  We provide the
+   following two additional guarantees:
+
+   - **It is valid to assign to a moved-from variable**.  The variable
+     gets the assigned value and becomes usable again.  This is the
+     behaviour of standard types.
+
+   - **It is valid to assign a moved-from variable to itself**.  For
+     most standard types this is *undefined behaviour*.  However, for our
+     immutable containers types, expressions of the form ``v =
+     std::move(v)`` are well-defined.
+
+Recursive types
+---------------
+
+Most containers will fail to be instantiated with a type of unknown
+size, this is, an *incomplete type*.  This prevents using them for
+building recursive types.  The following code fails to compile:
+
+.. code-block:: c++
+
+  struct my_type
+  {
+      int data;
+      immer::vector<my_type> children;
+  };
+
+However, we can easily workaround this by using an ``immer::box`` to wrap
+the elements in the vector, as in:
+
+.. code-block:: c++
+
+  struct my_type
+  {
+      int data;
+      immer::vector<immer::box<my_type>> children;
+  };
+
+.. admonition:: Standard containers and incomplete types
+
+  While the first example might seem to compile when using some
+  implementations of ``std::vector`` instead of ``immer::vector``, such
+  use is actually forbidden by the standard:
+
+    **17.6.4.8** *Other functions (...)* 2. the effects are undefined in
+    the following cases: (...) In particular---if an incomplete type (3.9)
+    is used as a template argument when instantiating a template
+    component, unless specifically allowed for that component.
+
+.. _batch-update:
+Efficient batch manipulations
+-----------------------------
+
+Sometimes you may write a function that needs to do multiple changes
+to a container.  Like most code you write with this library, this
+function is *pure*: it takes one container value in, and produces a
+new container value out, no side-effects.
+
+Let's say we want to write a function that inserts all integers in the
+range :math:`[first, last)` into an immutable vector:
+
+.. literalinclude:: ../example/vector/iota-slow.cpp
+   :language: c++
+   :start-after: include:myiota/start
+   :end-before:  include:myiota/end
+
+This function works as expected, but it is slower than necessary.
+On every loop iteration, a new value is produced, just to be
+forgotten in the next iteration.
+
+Instead, we can grab a mutable view on the value, a :ref:`transient`.
+Then, we manipulate it *in-place*.  When we are done with it, we
+extract back an immutable value from it.  The code now looks like
+this:
+
+.. _iota-transient:
+
+.. literalinclude:: ../example/vector/iota-transient.cpp
+   :language: c++
+   :start-after: include:myiota/start
+   :end-before:  include:myiota/end
+
+Both conversions are :math:`O(1)`.  Note that calling ``transient()``
+does not break the immutability of the variable it is called on.  The
+new mutable object will adopt its contents, but when a mutation is
+performed, it will copy the data necessary using *copy on write*.
+Subsequent manipulations may hit parts that have already been copied,
+and these changes are done in-place.  Because of this, it does not
+make sense to use transients to do only one change.
+
+.. tip::
+
+   Note that :ref:`move semantics<move-semantics>` can be used instead to
+   support a similar use-case.  However, transients optimise updates
+   even when reference counting is disabled.
+
+.. _std-compat:
+Standard library compatibility
+------------------------------
+
+While the immutable containers provide an interface that follows a
+functional style, this is incompatible with what the standard library
+algorithms sometimes expect. :ref:`transients` try to provide an
+interface as similar as possible to similar standard library
+containers.  Thus, can also be used to interoperate with standard
+library components.
+
+For example the :ref:`myiota() function above<iota-transient>` may as
+well be written using standard library tools:
+
+.. literalinclude:: ../example/vector/iota-transient-std.cpp
+   :language: c++
+   :start-after: include:myiota/start
+   :end-before:  include:myiota/end
diff --git a/third_party/immer/doc/doxygen.config b/third_party/immer/doc/doxygen.config
new file mode 100644
index 0000000000..b6002b8d8f
--- /dev/null
+++ b/third_party/immer/doc/doxygen.config
@@ -0,0 +1,23 @@
+PROJECT_NAME     = "immer"
+OUTPUT_DIRECTORY = _doxygen
+GENERATE_LATEX   = NO
+GENERATE_MAN     = NO
+GENERATE_RTF     = NO
+GENERATE_HTML    = NO
+GENERATE_XML     = YES
+INPUT            = \
+                 ../immer \
+                 ../immer/heap \
+                 ../immer/refcount \
+                 ../immer/transience
+INCLUDE_PATH     = ..
+QUIET            = YES
+
+JAVADOC_AUTOBRIEF = YES
+ENABLE_PREPROCESSING = YES
+MARKDOWN_SUPPORT = YES
+MACRO_EXPANSION = YES
+
+ALIASES  = "rst=\verbatim embed:rst:leading-asterisk\n"
+ALIASES += "endrst=\n\endverbatim"
+ALIASES += "rst{1}=\rst\1\endrst"
diff --git a/third_party/immer/doc/guile.rst b/third_party/immer/doc/guile.rst
new file mode 120000
index 0000000000..dfda6df878
--- /dev/null
+++ b/third_party/immer/doc/guile.rst
@@ -0,0 +1 @@
+../extra/guile/README.rst
\ No newline at end of file
diff --git a/third_party/immer/doc/implementation.rst b/third_party/immer/doc/implementation.rst
new file mode 100644
index 0000000000..3bfdd9c2b8
--- /dev/null
+++ b/third_party/immer/doc/implementation.rst
@@ -0,0 +1,6 @@
+Implementation overview
+=======================
+
+.. image:: https://upload.wikimedia.org/wikipedia/commons/e/e6/%22Work_in_progress%22%2C_animated.gif
+   :alt: Work in Progress
+   :align: center
diff --git a/third_party/immer/doc/index.rst b/third_party/immer/doc/index.rst
new file mode 100644
index 0000000000..311549c74b
--- /dev/null
+++ b/third_party/immer/doc/index.rst
@@ -0,0 +1,31 @@
+
+.. include:: ../README.rst
+   :end-before: include:index/end
+
+Contents
+--------
+
+.. toctree::
+   :caption: User Manual
+   :maxdepth: 3
+
+   introduction
+   design
+   containers
+   transients
+   algorithms
+   utilities
+   memory
+
+.. toctree::
+   :caption: Experimental
+   :maxdepth: 3
+
+   python
+   guile
+
+----
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/third_party/immer/doc/introduction.rst b/third_party/immer/doc/introduction.rst
new file mode 100644
index 0000000000..2445cf9df8
--- /dev/null
+++ b/third_party/immer/doc/introduction.rst
@@ -0,0 +1,6 @@
+
+Introduction
+============
+
+.. include:: ../README.rst
+   :start-after: include:introduction/start
diff --git a/third_party/immer/doc/memory.rst b/third_party/immer/doc/memory.rst
new file mode 100644
index 0000000000..3138b249f3
--- /dev/null
+++ b/third_party/immer/doc/memory.rst
@@ -0,0 +1,204 @@
+Memory management
+=================
+
+Memory management is specially important for immutable data
+structures.  This is mainly due to:
+
+#. In order to preserve the old value, new memory has to be allocated
+   to store the new data whenever a container is manipulated.  Thus,
+   more allocations are performed *when changing* than with traditional
+   mutable data structures.
+
+#. In order to support *structural sharing* transparently, some kind
+   of garbage collection mechanism is required.  Passing immutable
+   data structures around is, internally, just passing references,
+   thus the system needs to figure out somehow when old values are not
+   referenced anymore and should be deallocated.
+
+Thus, most containers in this library can be customized via policies_
+in order to use different *allocation* and *garbage collection*
+strategies.
+
+.. doxygentypedef:: immer::default_memory_policy
+.. doxygentypedef:: immer::default_heap_policy
+.. doxygentypedef:: immer::default_refcount_policy
+
+.. _policies: https://en.wikipedia.org/wiki/Policy-based_design
+
+.. _memory policy:
+
+Memory policy
+-------------
+
+.. doxygenstruct:: immer::memory_policy
+    :members:
+    :undoc-members:
+
+.. _gc:
+
+Example: tracing garbage collection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is note worthy that all aspects of a
+:cpp:class:`immer::memory_policy` are not completely orthogonal.
+
+Let's say you want to use a `tracing garbage collector`_. Actually, we
+already provide :cpp:class:`a heap <immer::gc_heap>` that interfaces
+with the `Boehm's conservative garbage collector`_.  Chunks of memory
+allocated with this heap do not need to be deallocated, instead, after
+a certain number of allocations, the heap itself will scan the stack
+and all allocated memory to find references to other blocks of memory.
+The memory that is not referenced anymore is automatically *freed*.
+Thus, no reference counting mechanism is needed, and it makes no sense
+to use this heap with anything else than the
+:cpp:class:`immer::no_refcount_policy`.  Also, a big object can be
+separated in parts that contain pointers and parts that do not, which
+make scanning references faster.  So it makes most sense to use
+``prefer_fewer_bigger_objects = false``.
+
+.. note:: There are few considerations to note when using
+          :cpp:class:`gc_heap` with containers.  Please make sure to
+          read :cpp:class:`its documentation section <immer::gc_heap>`
+          before using it.
+
+.. literalinclude:: ../example/vector/gc.cpp
+   :language: c++
+   :start-after: example/start
+   :end-before:  example/end
+
+
+.. _boehm's conservative garbage collector: https://github.com/ivmai/bdwgc
+.. _tracing garbage collector: https://en.wikipedia.org/wiki/Tracing_garbage_collection
+
+Heaps
+-----
+
+A **heap policy** is a `metafunction class`_ that given the sizes of
+the objects that we want to allocate, it *returns* a heap that can
+allocate objects of those sizes.
+
+.. _metafunction class: http://www.boost.org/doc/libs/1_62_0/libs/mpl/doc/refmanual/metafunction-class.html
+
+A **heap** is a type with a methods ``void* allocate(std::size_t)``
+and ``void deallocate(void*)`` that return and release raw memory.
+For a canonical model of this concept check the
+:cpp:class:`immer::cpp_heap`.
+
+.. note:: Currently, *heaps* can only have **global state**.  Having
+          internal state poses conceptual problems for immutable data
+          structures: should a `const` method of a container modify
+          its internal allocator state?  Should every immutable
+          container object have its own internal state, or new objects
+          made from another one just keep a reference to the allocator
+          of the parent?
+
+          On the other hand, having some **scoped state** does make
+          sense for some use-cases of immutable data structures.  For
+          example, we might want to support variations of `region
+          based allocation`_.  This interface might evolve to evolve
+          to support some kind of non-global state to accommodate
+          these use cases.
+
+.. _region based allocation: https://en.wikipedia.org/wiki/Region-based_memory_management
+
+.. admonition:: Why not use the standard allocator interface?
+
+   The standard allocator API was not designed to support different
+   allocation strategies, but to abstract over the underlying memory
+   model instead.  In C++11 the situation improves, but the new API is
+   *stateful*, posing various challenges as described in the previous
+   note.  So far it was easier to provide our own allocation
+   interface.  In the future, we will provide adaptors so
+   standard-compatible allocators can also be used with ``immer``.
+
+Heap policies
+~~~~~~~~~~~~~
+
+.. doxygenstruct:: immer::heap_policy
+   :members:
+   :undoc-members:
+
+.. doxygenstruct:: immer::free_list_heap_policy
+
+Standard heap
+~~~~~~~~~~~~~
+
+.. doxygenstruct:: immer::cpp_heap
+   :members:
+
+Malloc heap
+~~~~~~~~~~~
+
+.. doxygenstruct:: immer::malloc_heap
+   :members:
+
+Garbage collected heap
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygenclass:: immer::gc_heap
+
+Heap adaptors
+~~~~~~~~~~~~~
+
+Inspired by `Andrei Alexandrescu's talk on allocators <allocation
+vexation>`_ and `Emery Berger's heap layers <heap layers>`_ we provide
+allocator adaptors that can be combined using C++ mixins.  These
+enable building more complex allocator out of simpler strategies, or
+provide application specific optimizations on top of general
+allocators.
+
+.. _allocation vexation: https://www.youtube.com/watch?v=LIb3L4vKZ7U
+.. _heap layers: https://github.com/emeryberger/Heap-Layers
+
+.. doxygenstruct:: immer::with_data
+
+.. doxygenstruct:: immer::free_list_heap
+
+.. doxygenstruct:: immer::thread_local_free_list_heap
+
+.. doxygenstruct:: immer::unsafe_free_list_heap
+
+.. doxygenstruct:: immer::identity_heap
+
+.. doxygenstruct:: immer::debug_size_heap
+
+.. doxygenstruct:: immer::split_heap
+
+.. _rc:
+
+Reference counting
+------------------
+
+`Reference counting`_ is the most commonly used garbage collection
+strategy for C++.  It can be implemented non-intrusively, in a way
+orthogonal to the allocation strategy. It is deterministic, playing
+well with RAII_.
+
+A `memory policy`_ can provide a reference counting strategy that
+containers can use to track their contents.
+
+.. _reference counting: https://en.wikipedia.org/wiki/Reference_counting
+.. _raii: https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
+
+.. doxygenstruct:: immer::refcount_policy
+
+.. doxygenstruct:: immer::unsafe_refcount_policy
+
+.. doxygenstruct:: immer::no_refcount_policy
+
+Transience
+----------
+
+In order to support `transients`, it is needed to provide a mechanism
+to track the ownership of the data allocated inside the container.
+This concept is encapsulated in *transience policies*.
+
+Note that when :ref:`reference counting <rc>` is available, no such mechanism is
+needed.  However, when :ref:`tracing garbage collection<gc>` is used instead,
+a special policy has to be provided.  Otherwise, the transient API is
+still available, but it will perform poorly, since it won't be able to
+mutate any data in place.
+
+.. doxygenstruct:: immer::no_transience_policy
+
+.. doxygenstruct:: immer::gc_transience_policy
diff --git a/third_party/immer/doc/python.rst b/third_party/immer/doc/python.rst
new file mode 120000
index 0000000000..4266420dfb
--- /dev/null
+++ b/third_party/immer/doc/python.rst
@@ -0,0 +1 @@
+../extra/python/README.rst
\ No newline at end of file
diff --git a/third_party/immer/doc/requirements.txt b/third_party/immer/doc/requirements.txt
new file mode 100644
index 0000000000..4d0744feec
--- /dev/null
+++ b/third_party/immer/doc/requirements.txt
@@ -0,0 +1,3 @@
+git+https://github.com/arximboldi/sphinx.git
+git+https://github.com/arximboldi/breathe.git
+recommonmark
diff --git a/third_party/immer/doc/sphinx-html-hack.bash b/third_party/immer/doc/sphinx-html-hack.bash
new file mode 100755
index 0000000000..1dccb9265d
--- /dev/null
+++ b/third_party/immer/doc/sphinx-html-hack.bash
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+location=`dirname $0`
+
+echo "Running $0 at $location"
+
+# Fixes issues described here among others
+# https://github.com/michaeljones/breathe/issues/284
+
+fix-missing-class-name()
+{
+    src='<span id="\([^"]*\)"></span>\(.*\)<em class="property">class </em>'
+    dst='<span id=""></span>\2<em class="property">class</em><tt class="descname">\1</tt>'
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-missing-struct-name()
+{
+    src='<span id="\([^"]*\)"></span>\(.*\)<em class="property">struct </em>'
+    dst='<span id=""></span>\2<em class="property">struct</em><tt class="descname">\1</tt>'
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-double-using-keyword()
+{
+    src='<em class="property">using</em><em class="property">using </em>'
+    dst='<em class="property">using </em>'
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-do-not-repeat-type-in-member-using-declaration()
+{
+    src='<em class="property">using </em><code class="descname">\(\([^:]*::\)*\)\([^ ]*\) = \([^<]*\)</code>'
+    dst='<em class="property">using </em><code class="descname">\3 = \4</code>'
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-do-not-repeat-type-in-member-using-declaration
+
+fix-remove-double-class-name()
+{
+    # src='<code class="descclassname">\([^&]*\)&lt;\([^&]*\)&gt;::</code>'
+    # dst='<code class="descclassname">\1::</code>'
+    src='<code class="descclassname">\([^<]*\)</code>'
+    dst=''
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-remove-straneous-typedefs()
+{
+    src='typedef '
+    dst=''
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-remove-straneous-typedefs-2()
+{
+    src='= typedef '
+    dst='= '
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-remove-straneous-typedefs-2
+
+fix-remove-straneous-using-declarations()
+{
+    src='<em class="property">using </em>template&lt;&gt;<br />'
+    dst=''
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+
+fix-remove-straneous-template-in-using-declarations-1()
+{
+    src='\(<dl class="type">\n<dt[^>]*>\)\ntemplate&lt;&gt;<br />'
+    dst='\1'
+    pre=':a;N;$!ba;'
+    sed -i "$pre;s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-remove-straneous-template-in-using-declarations-1
+
+fix-remove-straneous-template-in-using-declarations-2()
+{
+    src='></span>template&lt;&gt;<br /><span '
+    dst='></span><span '
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-remove-straneous-template-in-using-declarations-2
+
+fix-remove-countainer-css-class-in-member-definitions-causing-overflow()
+{
+    src='breathe-sectiondef\([[:alnum:] _-]*\)container'
+    dst='breathe-sectiondef'
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-remove-countainer-css-class-in-member-definitions-causing-overflow
+
+fix-remove-inherits-from()
+{
+    src='<p>Inherits from [^/]*</p>'
+    dst=''
+    sed -i "s@$src@$dst@g" $location/_build/html/*.html
+}
+fix-remove-inherits-from
diff --git a/third_party/immer/doc/transients.rst b/third_party/immer/doc/transients.rst
new file mode 100644
index 0000000000..9b385d4db5
--- /dev/null
+++ b/third_party/immer/doc/transients.rst
@@ -0,0 +1,51 @@
+.. _transient:
+
+Transients
+==========
+
+*Transients* is a concept borrowed `from Clojure
+<clojure-transients>`_, with some twists to turn make more idiomatic
+in C++.  Essentially, they are a mutable interface built on top of the
+same data structures the implements the immutable containers under the
+hood.
+
+These can be useful for :ref:`performing efficient batch
+updates<batch-update>` or :ref:`interfacing with standard
+algorithms<std-compat>`.
+
+.. _clojure-transients: https://clojure.org/reference/transients
+
+array_transient
+---------------
+
+.. doxygenclass:: immer::array_transient
+    :members:
+    :undoc-members:
+
+vector_transient
+----------------
+
+.. doxygenclass:: immer::vector_transient
+    :members:
+    :undoc-members:
+
+flex_vector_transient
+---------------------
+
+.. doxygenclass:: immer::flex_vector_transient
+    :members:
+    :undoc-members:
+
+set_transient
+-------------
+
+.. doxygenclass:: immer::set_transient
+    :members:
+    :undoc-members:
+
+map_transient
+-------------
+
+.. doxygenclass:: immer::map_transient
+    :members:
+    :undoc-members:
diff --git a/third_party/immer/doc/utilities.rst b/third_party/immer/doc/utilities.rst
new file mode 100644
index 0000000000..eaeea475c2
--- /dev/null
+++ b/third_party/immer/doc/utilities.rst
@@ -0,0 +1,15 @@
+.. highlight:: c++
+
+Utilities
+=========
+
+The library provides also some types that, while they are not exactly
+immutable data-structures, they are very useful when using immutable
+data-structures and value-oriented design in practice.
+
+atom
+----
+
+.. doxygenclass:: immer::atom
+    :members:
+    :undoc-members: