:memo: add docset
diff --git a/.gitignore b/.gitignore
index 7e5a881..bf938c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,4 @@
 doc/mkdocs/site
 doc/mkdocs/docs/__pycache__/
 doc/xml
+/doc/docset/nlohmann_json.docset/
diff --git a/Makefile b/Makefile
index 0b310e9..f506950 100644
--- a/Makefile
+++ b/Makefile
@@ -627,7 +627,7 @@
 	rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html
 	rm -fr benchmarks/files/numbers/*.json
 	rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
-	rm -fr cmake-build-coverage cmake-build-benchmarks fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake-build-clang-sanitize cmake_build
+	rm -fr cmake-build-coverage cmake-build-benchmarks cmake-build-pedantic fuzz-testing cmake-build-clang-analyze cmake-build-pvs-studio cmake-build-infer cmake-build-clang-sanitize cmake_build
 	$(MAKE) clean -Cdoc
 
 ##########################################################################
diff --git a/doc/Makefile b/doc/Makefile
index 35e8b5a..9addd34 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -44,6 +44,8 @@
 
 clean:
 	rm -fr me.nlohmann.json.docset html xml $(EXAMPLES:.cpp=)
+	$(MAKE) clean -C docset
+	$(MAKE) clean -C mkdocs
 
 
 ##########################################################################
diff --git a/doc/docset/Info.plist b/doc/docset/Info.plist
new file mode 100644
index 0000000..81bd95f
--- /dev/null
+++ b/doc/docset/Info.plist
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleIdentifier</key>
+	<string>nlohmann_json</string>
+	<key>CFBundleName</key>
+	<string>JSON for Modern C++</string>
+	<key>DocSetPlatformFamily</key>
+	<string>json</string>
+	<key>isDashDocset</key>
+	<true/>
+</dict>
+</plist>
diff --git a/doc/docset/Makefile b/doc/docset/Makefile
new file mode 100644
index 0000000..d2ebf44
--- /dev/null
+++ b/doc/docset/Makefile
@@ -0,0 +1,8 @@
+nlohmann_json.docset: Info.plist docSet.sql
+	$(MAKE) clean
+	mkdir -p nlohmann_json.docset/Contents/Resources/Documents/
+	cp info.plist nlohmann_json.docset/Contents
+	sqlite3 nlohmann_json.docset/Contents/Resources/docSet.dsidx < docSet.sql
+
+clean:
+	rm -fr nlohmann_json.docset
diff --git a/doc/docset/README.md b/doc/docset/README.md
new file mode 100644
index 0000000..b0dd7f8
--- /dev/null
+++ b/doc/docset/README.md
@@ -0,0 +1,13 @@
+# docset
+
+The folder contains the required files to create a [docset](https://kapeli.com/docsets) which can be used in
+documentation browsers like [Dash](https://kapeli.com/dash), [Velocity](https://velocity.silverlakesoftware.com), or
+[Zeal](https://zealdocs.org).
+
+The docset can be created with
+
+```sh
+make nlohmann_json.docset
+```
+
+The generated folder `nlohmann_json.docset` can then be opened in the documentation browser.
diff --git a/doc/docset/docSet.sql b/doc/docset/docSet.sql
new file mode 100644
index 0000000..d824b01
--- /dev/null
+++ b/doc/docset/docSet.sql
@@ -0,0 +1,106 @@
+DROP TABLE IF EXISTS searchIndex;
+CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);
+CREATE UNIQUE INDEX anchor ON searchIndex (name, type, path);
+
+-- API
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('accept', 'Function', 'https://nlohmann.github.io/json/api/basic_json/accept/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('array', 'Function', 'https://nlohmann.github.io/json/api/basic_json/array/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('array_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/array_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('at', 'Method', 'https://nlohmann.github.io/json/api/basic_json/at/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('back', 'Method', 'https://nlohmann.github.io/json/api/basic_json/back/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('basic_json', 'Constructor', 'https://nlohmann.github.io/json/api/basic_json/basic_json/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('begin', 'Method', 'https://nlohmann.github.io/json/api/basic_json/begin/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('binary', 'Function', 'https://nlohmann.github.io/json/api/basic_json/binary/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('boolean_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/boolean_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('cbegin', 'Method', 'https://nlohmann.github.io/json/api/basic_json/cbegin/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('cend', 'Method', 'https://nlohmann.github.io/json/api/basic_json/cend/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('clear', 'Method', 'https://nlohmann.github.io/json/api/basic_json/clear/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('contains', 'Method', 'https://nlohmann.github.io/json/api/basic_json/contains/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('count', 'Method', 'https://nlohmann.github.io/json/api/basic_json/count/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('crbegin', 'Method', 'https://nlohmann.github.io/json/api/basic_json/crbegin/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('crend', 'Method', 'https://nlohmann.github.io/json/api/basic_json/crend/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('diff', 'Function', 'https://nlohmann.github.io/json/api/basic_json/diff/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('dump', 'Method', 'https://nlohmann.github.io/json/api/basic_json/dump/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('emplace', 'Method', 'https://nlohmann.github.io/json/api/basic_json/emplace/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('emplace_back', 'Method', 'https://nlohmann.github.io/json/api/basic_json/emplace_back/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('empty', 'Method', 'https://nlohmann.github.io/json/api/basic_json/empty/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('end', 'Method', 'https://nlohmann.github.io/json/api/basic_json/end/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('erase', 'Method', 'https://nlohmann.github.io/json/api/basic_json/erase/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('error_handler_t', 'Enum', 'https://nlohmann.github.io/json/api/basic_json/error_handler_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('find', 'Method', 'https://nlohmann.github.io/json/api/basic_json/find/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('flatten', 'Method', 'https://nlohmann.github.io/json/api/basic_json/flatten/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('front', 'Method', 'https://nlohmann.github.io/json/api/basic_json/front/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('basic_json', 'Class', 'https://nlohmann.github.io/json/api/basic_json/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('insert', 'Method', 'https://nlohmann.github.io/json/api/basic_json/insert/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_array', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_array/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_binary', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_binary/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_boolean', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_boolean/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_discarded', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_discarded/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_null', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_null/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_number', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_number/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_number_float', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_number_float/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_number_integer', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_number_integer/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_number_unsigned', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_number_unsigned/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_object', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_object/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_primitive', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_primitive/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_string', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_string/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('is_structured', 'Method', 'https://nlohmann.github.io/json/api/basic_json/is_structured/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('items', 'Method', 'https://nlohmann.github.io/json/api/basic_json/items/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'https://nlohmann.github.io/json/api/json/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('max_size', 'Method', 'https://nlohmann.github.io/json/api/basic_json/max_size/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('merge_patch', 'Method', 'https://nlohmann.github.io/json/api/basic_json/merge_patch/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('meta', 'Function', 'https://nlohmann.github.io/json/api/basic_json/meta/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('number_float_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/number_float_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('number_integer_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/number_integer_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('number_unsigned_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/number_unsigned_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('object', 'Function', 'https://nlohmann.github.io/json/api/basic_json/object/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('object_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/object_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator!=', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator!=/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator+=', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator+=/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator=', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator=/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator==', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator==/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator[]', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator[]/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('operator value_t', 'Operator', 'https://nlohmann.github.io/json/api/basic_json/operator_value_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'https://nlohmann.github.io/json/api/ordered_json/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'https://nlohmann.github.io/json/api/ordered_map/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('parse', 'Function', 'https://nlohmann.github.io/json/api/basic_json/parse/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('parse_event_t', 'Enum', 'https://nlohmann.github.io/json/api/basic_json/parse_event_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('parser_callback_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/parser_callback_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('patch', 'Method', 'https://nlohmann.github.io/json/api/basic_json/patch/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('push_back', 'Method', 'https://nlohmann.github.io/json/api/basic_json/push_back/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('rbegin', 'Method', 'https://nlohmann.github.io/json/api/basic_json/rbegin/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('rend', 'Method', 'https://nlohmann.github.io/json/api/basic_json/rend/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('sax_parse', 'Function', 'https://nlohmann.github.io/json/api/basic_json/sax_parse/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('size', 'Method', 'https://nlohmann.github.io/json/api/basic_json/size/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('string_t', 'Type', 'https://nlohmann.github.io/json/api/basic_json/string_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('type', 'Method', 'https://nlohmann.github.io/json/api/basic_json/type/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('type_name', 'Method', 'https://nlohmann.github.io/json/api/basic_json/type_name/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('unflatten', 'Method', 'https://nlohmann.github.io/json/api/basic_json/unflatten/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('update', 'Method', 'https://nlohmann.github.io/json/api/basic_json/update/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('value', 'Method', 'https://nlohmann.github.io/json/api/basic_json/value/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('value_t', 'Enum', 'https://nlohmann.github.io/json/api/basic_json/value_t/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('~basic_json', 'Method', 'https://nlohmann.github.io/json/api/basic_json/~basic_json/');
+
+-- Features
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Binary Formats', 'Guide', 'https://nlohmann.github.io/json/features/binary_formats/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('BSON', 'Guide', 'https://nlohmann.github.io/json/features/binary_formats/bson/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('CBOR', 'Guide', 'https://nlohmann.github.io/json/features/binary_formats/cbor/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('MessagePack', 'Guide', 'https://nlohmann.github.io/json/features/binary_formats/messagepack/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('UBJSON', 'Guide', 'https://nlohmann.github.io/json/features/binary_formats/ubjson/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Supported Macros', 'Guide', 'https://nlohmann.github.io/json/features/macros/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Binary Values', 'Guide', 'https://nlohmann.github.io/json/features/binary_values/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Comments', 'Guide', 'https://nlohmann.github.io/json/features/comments/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'https://nlohmann.github.io/json/features/iterators/');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'https://nlohmann.github.io/json/features/types/');
+
+-- Macros
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_assertx');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_catch_userexception');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_NOEXCEPTION', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_noexception');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_SKIP_UNSUPPORTED_COMPILER_CHECK', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_skip_unsupported_compiler_check');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_THROW_USER', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_throw_userexception');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_TRY_USER', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_try_user');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('JSON_USE_IMPLICIT_CONVERSIONS', 'Macro', 'https://nlohmann.github.io/json/features/macros/#json_use_implicit_conversions');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_INTRUSIVE', 'Macro', 'https://nlohmann.github.io/json/features/macros/#nlohmann_define_type_intrusivetype-member');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE', 'Macro', 'https://nlohmann.github.io/json/features/macros/#nlohmann_define_type_non_intrusivetype-member');
+INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES ('NLOHMANN_JSON_SERIALIZE_ENUM', 'Macro', 'https://nlohmann.github.io/json/features/macros/#nlohmann_json_serialize_enumtype');
diff --git a/doc/mkdocs/docs/api/basic_json/index.md b/doc/mkdocs/docs/api/basic_json/index.md
index bcfbdb6..67448d6 100644
--- a/doc/mkdocs/docs/api/basic_json/index.md
+++ b/doc/mkdocs/docs/api/basic_json/index.md
@@ -24,8 +24,8 @@
 
 ## Specializations
 
-- json
-- ordered_json
+- [**json**](../json.md) - default specialization
+- [**ordered_json**](../ordered_json.md) - specialization that maintains the insertion order of object keys
 
 ## Template parameters
 
diff --git a/doc/mkdocs/docs/api/json.md b/doc/mkdocs/docs/api/json.md
new file mode 100644
index 0000000..0aff6d2
--- /dev/null
+++ b/doc/mkdocs/docs/api/json.md
@@ -0,0 +1,5 @@
+# json
+
+```cpp
+using json = basic_json<>;
+```
diff --git a/doc/mkdocs/docs/api/ordered_json.md b/doc/mkdocs/docs/api/ordered_json.md
new file mode 100644
index 0000000..8ce8dfe
--- /dev/null
+++ b/doc/mkdocs/docs/api/ordered_json.md
@@ -0,0 +1,5 @@
+# ordered_json
+
+```cpp
+using ordered_json = basic_json<nlohmann::ordered_map>;
+```
diff --git a/doc/mkdocs/docs/api/ordered_map.md b/doc/mkdocs/docs/api/ordered_map.md
new file mode 100644
index 0000000..1a99b63
--- /dev/null
+++ b/doc/mkdocs/docs/api/ordered_map.md
@@ -0,0 +1,7 @@
+# ordered_map
+
+```cpp
+template<class Key, class T, class IgnoredLess = std::less<Key>,
+         class Allocator = std::allocator<std::pair<const Key, T>>>
+struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;
+```
diff --git a/doc/mkdocs/mkdocs.yml b/doc/mkdocs/mkdocs.yml
index b49a663..f9fd0c3 100644
--- a/doc/mkdocs/mkdocs.yml
+++ b/doc/mkdocs/mkdocs.yml
@@ -145,6 +145,9 @@
         - api/basic_json/update.md
         - api/basic_json/value.md
         - api/basic_json/value_t.md
+      - api/json.md
+      - api/ordered_map.md
+      - api/ordered_json.md
 
 # Extras
 extra: