summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:46:17 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:46:17 +0000
commit85adc697d2ec2a379ce6d721f0419ae5df3abdb6 (patch)
tree265f329bc4544c6f11a27ac3fd6022f593a10c11 /doc
parentInitial commit. (diff)
downloadmdds-85adc697d2ec2a379ce6d721f0419ae5df3abdb6.tar.xz
mdds-85adc697d2ec2a379ce6d721f0419ae5df3abdb6.zip
Adding upstream version 2.1.1.upstream/2.1.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--doc/_static/images/fst-example1-initial.svg84
-rw-r--r--doc/_static/images/fst-example1-insert1.svg195
-rw-r--r--doc/_static/images/fst-example1-insert2.svg258
-rw-r--r--doc/_static/images/mtv-block-structure.svg265
-rw-r--r--doc/_static/images/mtv_collection_sheet.pngbin0 -> 65937 bytes
-rw-r--r--doc/_static/images/rtree_bounds2_tree.pngbin0 -> 24136 bytes
-rw-r--r--doc/_static/images/rtree_bounds2_tree_bulkload.pngbin0 -> 21290 bytes
-rw-r--r--doc/_static/images/rtree_bounds_src.pngbin0 -> 7452 bytes
-rw-r--r--doc/_static/images/rtree_bounds_tree.pngbin0 -> 11020 bytes
-rw-r--r--doc/api.rst280
-rw-r--r--doc/conf.py271
-rw-r--r--doc/doxygen.conf2276
-rw-r--r--doc/flat_segment_tree.rst268
-rw-r--r--doc/global.rst20
-rw-r--r--doc/index.rst37
-rw-r--r--doc/multi_type_matrix.rst15
-rw-r--r--doc/multi_type_vector/api-ref.rst169
-rw-r--r--doc/multi_type_vector/examples.rst929
-rw-r--r--doc/multi_type_vector/index.rst10
-rw-r--r--doc/point_quad_tree.rst10
-rw-r--r--doc/rtree.rst727
-rw-r--r--doc/segment_tree.rst11
-rw-r--r--doc/sorted_string_map.rst11
-rw-r--r--doc/trie_map.rst767
24 files changed, 6603 insertions, 0 deletions
diff --git a/doc/_static/images/fst-example1-initial.svg b/doc/_static/images/fst-example1-initial.svg
new file mode 100644
index 0000000..8b83ff5
--- /dev/null
+++ b/doc/_static/images/fst-example1-initial.svg
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="155.84mm" height="14.31mm" viewBox="2397 3240 15584 1431" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="5" horiz-adv-x="980" d="M 1053,459 C 1053,310 1009,193 921,108 832,23 710,-20 553,-20 422,-20 316,9 235,66 154,123 103,206 82,315 L 264,336 C 302,197 400,127 557,127 654,127 729,156 784,215 839,273 866,353 866,455 866,544 839,615 784,670 729,725 654,752 561,752 512,752 467,744 425,729 383,714 341,688 299,651 L 123,651 170,1409 971,1409 971,1256 334,1256 307,809 C 385,869 482,899 598,899 737,899 847,858 930,777 1012,696 1053,590 1053,459 Z"/>
+ <glyph unicode="0" horiz-adv-x="980" d="M 1059,705 C 1059,470 1018,290 935,166 852,42 729,-20 567,-20 405,-20 283,42 202,165 121,288 80,468 80,705 80,947 120,1128 199,1249 278,1370 402,1430 573,1430 739,1430 862,1369 941,1247 1020,1125 1059,944 1059,705 Z M 876,705 C 876,908 853,1056 806,1147 759,1238 681,1284 573,1284 462,1284 383,1239 335,1149 286,1059 262,911 262,705 262,505 287,359 336,266 385,173 462,127 569,127 675,127 753,174 802,269 851,364 876,509 876,705 Z"/>
+ </font>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ <g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
+ </g>
+ </defs>
+ <g class="Page">
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2770" y="4380" width="14280" height="3"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2771,4381 L 17048,4381"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2470" y="4093" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 3046,4382 C 3046,4432 3033,4482 3007,4525 2982,4569 2946,4605 2902,4630 2859,4656 2809,4669 2759,4669 2708,4669 2658,4656 2615,4630 2571,4605 2535,4569 2510,4525 2484,4482 2471,4432 2471,4382 2471,4331 2484,4281 2510,4238 2535,4194 2571,4158 2615,4133 2658,4107 2708,4094 2759,4094 2809,4094 2859,4107 2902,4133 2946,4158 2982,4194 3007,4238 3033,4281 3046,4331 3046,4382 L 3046,4382 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 3046,4382 C 3046,4432 3033,4482 3007,4525 2982,4569 2946,4605 2902,4630 2859,4656 2809,4669 2759,4669 2708,4669 2658,4656 2615,4630 2571,4605 2535,4569 2510,4525 2484,4482 2471,4432 2471,4382 2471,4331 2484,4281 2510,4238 2535,4194 2571,4158 2615,4133 2658,4107 2708,4094 2759,4094 2809,4094 2859,4107 2902,4133 2946,4158 2982,4194 3007,4238 3033,4281 3046,4331 3046,4382 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16748" y="4093" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 17324,4382 C 17324,4432 17311,4482 17285,4525 17260,4569 17224,4605 17180,4630 17137,4656 17087,4669 17037,4669 16986,4669 16936,4656 16893,4630 16849,4605 16813,4569 16788,4525 16762,4482 16749,4432 16749,4382 16749,4331 16762,4281 16788,4238 16813,4194 16849,4158 16893,4133 16936,4107 16986,4094 17037,4094 17087,4094 17137,4107 17180,4133 17224,4158 17260,4194 17285,4238 17311,4281 17324,4331 17324,4382 L 17324,4382 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 17324,4382 C 17324,4432 17311,4482 17285,4525 17260,4569 17224,4605 17180,4630 17137,4656 17087,4669 17037,4669 16986,4669 16936,4656 16893,4630 16849,4605 16813,4569 16788,4525 16762,4482 16749,4432 16749,4382 16749,4331 16762,4281 16788,4238 16813,4194 16849,4158 16893,4133 16936,4107 16986,4094 17037,4094 17087,4094 17137,4107 17180,4133 17224,4158 17260,4194 17285,4238 17311,4281 17324,4331 17324,4382 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2397" y="3351" width="854" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="2647" y="3925"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16424" y="3351" width="1557" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="16674" y="3925"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">500</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9482" y="3240" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="9733" y="4005"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/_static/images/fst-example1-insert1.svg b/doc/_static/images/fst-example1-insert1.svg
new file mode 100644
index 0000000..52efe74
--- /dev/null
+++ b/doc/_static/images/fst-example1-insert1.svg
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="155.84mm" height="15.32mm" viewBox="2397 6203 15584 1532" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="7" horiz-adv-x="954" d="M 1036,1263 C 892,1043 790,871 731,746 672,621 627,498 598,377 568,256 553,130 553,0 L 365,0 C 365,180 403,370 480,569 556,768 683,997 862,1256 L 105,1256 105,1409 1036,1409 1036,1263 Z"/>
+ <glyph unicode="5" horiz-adv-x="980" d="M 1053,459 C 1053,310 1009,193 921,108 832,23 710,-20 553,-20 422,-20 316,9 235,66 154,123 103,206 82,315 L 264,336 C 302,197 400,127 557,127 654,127 729,156 784,215 839,273 866,353 866,455 866,544 839,615 784,670 729,725 654,752 561,752 512,752 467,744 425,729 383,714 341,688 299,651 L 123,651 170,1409 971,1409 971,1256 334,1256 307,809 C 385,869 482,899 598,899 737,899 847,858 930,777 1012,696 1053,590 1053,459 Z"/>
+ <glyph unicode="2" horiz-adv-x="954" d="M 103,0 L 103,127 C 137,205 179,274 228,334 277,393 328,447 382,496 436,544 490,589 543,630 596,671 643,713 686,754 729,795 763,839 790,884 816,929 829,981 829,1038 829,1115 806,1175 761,1218 716,1261 653,1282 572,1282 495,1282 432,1261 383,1220 333,1178 304,1119 295,1044 L 111,1061 C 124,1174 172,1263 255,1330 337,1397 443,1430 572,1430 714,1430 823,1397 900,1330 976,1263 1014,1167 1014,1044 1014,989 1002,935 977,881 952,827 914,773 865,719 816,665 721,581 582,468 505,405 444,349 399,299 354,248 321,200 301,153 L 1036,153 1036,0 103,0 Z"/>
+ <glyph unicode="1" horiz-adv-x="927" d="M 156,0 L 156,153 515,153 515,1237 197,1010 197,1180 530,1409 696,1409 696,153 1039,153 1039,0 156,0 Z"/>
+ <glyph unicode="0" horiz-adv-x="980" d="M 1059,705 C 1059,470 1018,290 935,166 852,42 729,-20 567,-20 405,-20 283,42 202,165 121,288 80,468 80,705 80,947 120,1128 199,1249 278,1370 402,1430 573,1430 739,1430 862,1369 941,1247 1020,1125 1059,944 1059,705 Z M 876,705 C 876,908 853,1056 806,1147 759,1238 681,1284 573,1284 462,1284 383,1239 335,1149 286,1059 262,911 262,705 262,505 287,359 336,266 385,173 462,127 569,127 675,127 753,174 802,269 851,364 876,509 876,705 Z"/>
+ </font>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ <g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
+ </g>
+ </defs>
+ <g class="Page">
+ <g class="Group">
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2770" y="7444" width="14280" height="3"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2771,7445 L 17048,7445"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10906" y="7347" width="3532" height="205"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="203" stroke-linejoin="round" d="M 11008,7449 L 14335,7449"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4835" y="7347" width="2618" height="205"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="203" stroke-linejoin="round" d="M 4937,7449 L 7350,7449"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2470" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 3046,7446 C 3046,7496 3033,7546 3007,7589 2982,7633 2946,7669 2902,7694 2859,7720 2809,7733 2759,7733 2708,7733 2658,7720 2615,7694 2571,7669 2535,7633 2510,7589 2484,7546 2471,7496 2471,7446 2471,7395 2484,7345 2510,7302 2535,7258 2571,7222 2615,7197 2658,7171 2708,7158 2759,7158 2809,7158 2859,7171 2902,7197 2946,7222 2982,7258 3007,7302 3033,7345 3046,7395 3046,7446 L 3046,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 3046,7446 C 3046,7496 3033,7546 3007,7589 2982,7633 2946,7669 2902,7694 2859,7720 2809,7733 2759,7733 2708,7733 2658,7720 2615,7694 2571,7669 2535,7633 2510,7589 2484,7546 2471,7496 2471,7446 2471,7395 2484,7345 2510,7302 2535,7258 2571,7222 2615,7197 2658,7171 2708,7158 2759,7158 2809,7158 2859,7171 2902,7197 2946,7222 2982,7258 3007,7302 3033,7345 3046,7395 3046,7446 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16748" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 17324,7446 C 17324,7496 17311,7546 17285,7589 17260,7633 17224,7669 17180,7694 17137,7720 17087,7733 17037,7733 16986,7733 16936,7720 16893,7694 16849,7669 16813,7633 16788,7589 16762,7546 16749,7496 16749,7446 16749,7395 16762,7345 16788,7302 16813,7258 16849,7222 16893,7197 16936,7171 16986,7158 17037,7158 17087,7158 17137,7171 17180,7197 17224,7222 17260,7258 17285,7302 17311,7345 17324,7395 17324,7446 L 17324,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 17324,7446 C 17324,7496 17311,7546 17285,7589 17260,7633 17224,7669 17180,7694 17137,7720 17087,7733 17037,7733 16986,7733 16936,7720 16893,7694 16849,7669 16813,7633 16788,7589 16762,7546 16749,7496 16749,7446 16749,7395 16762,7345 16788,7302 16813,7258 16849,7222 16893,7197 16936,7171 16986,7158 17037,7158 17087,7158 17137,7171 17180,7197 17224,7222 17260,7258 17285,7302 17311,7345 17324,7395 17324,7446 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2397" y="6353" width="854" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="2647" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16424" y="6353" width="1557" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="16674" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">500</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id10">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3482" y="6406" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="3733" y="7171"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id11">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4616" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 5192,7446 C 5192,7496 5179,7546 5153,7589 5128,7633 5092,7669 5048,7694 5005,7720 4955,7733 4905,7733 4854,7733 4804,7720 4761,7694 4717,7669 4681,7633 4656,7589 4630,7546 4617,7496 4617,7446 4617,7395 4630,7345 4656,7302 4681,7258 4717,7222 4761,7197 4804,7171 4854,7158 4905,7158 4955,7158 5005,7171 5048,7197 5092,7222 5128,7258 5153,7302 5179,7345 5192,7395 5192,7446 L 5192,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 5192,7446 C 5192,7496 5179,7546 5153,7589 5128,7633 5092,7669 5048,7694 5005,7720 4955,7733 4905,7733 4854,7733 4804,7720 4761,7694 4717,7669 4681,7633 4656,7589 4630,7546 4617,7496 4617,7446 4617,7395 4630,7345 4656,7302 4681,7258 4717,7222 4761,7197 4804,7171 4854,7158 4905,7158 4955,7158 5005,7171 5048,7197 5092,7222 5128,7258 5153,7302 5179,7345 5192,7395 5192,7446 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id12">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7037" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 7613,7446 C 7613,7496 7600,7546 7574,7589 7549,7633 7513,7669 7469,7694 7426,7720 7376,7733 7326,7733 7275,7733 7225,7720 7182,7694 7138,7669 7102,7633 7077,7589 7051,7546 7038,7496 7038,7446 7038,7395 7051,7345 7077,7302 7102,7258 7138,7222 7182,7197 7225,7171 7275,7158 7326,7158 7376,7158 7426,7171 7469,7197 7513,7222 7549,7258 7574,7302 7600,7345 7613,7395 7613,7446 L 7613,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7613,7446 C 7613,7496 7600,7546 7574,7589 7549,7633 7513,7669 7469,7694 7426,7720 7376,7733 7326,7733 7275,7733 7225,7720 7182,7694 7138,7669 7102,7633 7077,7589 7051,7546 7038,7496 7038,7446 7038,7395 7051,7345 7077,7302 7102,7258 7138,7222 7182,7197 7225,7171 7275,7158 7326,7158 7376,7158 7426,7171 7469,7197 7513,7222 7549,7258 7574,7302 7600,7345 7613,7395 7613,7446 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id13">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4411" y="6353" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="4661" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">10</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id14">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6869" y="6353" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="7119" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">20</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id15">
+ <rect class="BoundingBox" stroke="none" fill="none" x="5399" y="6203" width="1652" height="1445"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="5831" y="7171"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">10</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id16">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10712" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 11288,7446 C 11288,7496 11275,7546 11249,7589 11224,7633 11188,7669 11144,7694 11101,7720 11051,7733 11001,7733 10950,7733 10900,7720 10857,7694 10813,7669 10777,7633 10752,7589 10726,7546 10713,7496 10713,7446 10713,7395 10726,7345 10752,7302 10777,7258 10813,7222 10857,7197 10900,7171 10950,7158 11001,7158 11051,7158 11101,7171 11144,7197 11188,7222 11224,7258 11249,7302 11275,7345 11288,7395 11288,7446 L 11288,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 11288,7446 C 11288,7496 11275,7546 11249,7589 11224,7633 11188,7669 11144,7694 11101,7720 11051,7733 11001,7733 10950,7733 10900,7720 10857,7694 10813,7669 10777,7633 10752,7589 10726,7546 10713,7496 10713,7446 10713,7395 10726,7345 10752,7302 10777,7258 10813,7222 10857,7197 10900,7171 10950,7158 11001,7158 11051,7158 11101,7171 11144,7197 11188,7222 11224,7258 11249,7302 11275,7345 11288,7395 11288,7446 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id17">
+ <rect class="BoundingBox" stroke="none" fill="none" x="14079" y="7157" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 14655,7446 C 14655,7496 14642,7546 14616,7589 14591,7633 14555,7669 14511,7694 14468,7720 14418,7733 14368,7733 14317,7733 14267,7720 14224,7694 14180,7669 14144,7633 14119,7589 14093,7546 14080,7496 14080,7446 14080,7395 14093,7345 14119,7302 14144,7258 14180,7222 14224,7197 14267,7171 14317,7158 14368,7158 14418,7158 14468,7171 14511,7197 14555,7222 14591,7258 14616,7302 14642,7345 14655,7395 14655,7446 L 14655,7446 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 14655,7446 C 14655,7496 14642,7546 14616,7589 14591,7633 14555,7669 14511,7694 14468,7720 14418,7733 14368,7733 14317,7733 14267,7720 14224,7694 14180,7669 14144,7633 14119,7589 14093,7546 14080,7496 14080,7446 14080,7395 14093,7345 14119,7302 14144,7258 14180,7222 14224,7197 14267,7171 14317,7158 14368,7158 14418,7158 14468,7171 14511,7197 14555,7222 14591,7258 14616,7302 14642,7345 14655,7395 14655,7446 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id18">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10444" y="6353" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="10694" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">50</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id19">
+ <rect class="BoundingBox" stroke="none" fill="none" x="13911" y="6353" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="14161" y="6927"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">70</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id20">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8740" y="6406" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="8991" y="7171"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id21">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11933" y="6203" width="1652" height="1445"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="12365" y="7171"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">15</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id22">
+ <rect class="BoundingBox" stroke="none" fill="none" x="15362" y="6406" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="15613" y="7171"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id23">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16366" y="7092" width="128" height="636"/>
+ <path fill="rgb(255,255,255)" stroke="none" d="M 16430,7727 L 16366,7727 16366,7092 16493,7092 16493,7727 16430,7727 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id24">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16360" y="7092" width="3" height="638"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 16361,7093 L 16361,7728"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id25">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16493" y="7092" width="3" height="638"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 16494,7093 L 16494,7728"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/_static/images/fst-example1-insert2.svg b/doc/_static/images/fst-example1-insert2.svg
new file mode 100644
index 0000000..21207e4
--- /dev/null
+++ b/doc/_static/images/fst-example1-insert2.svg
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="155.84mm" height="48.06mm" viewBox="2397 8366 15584 4806" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="7" horiz-adv-x="954" d="M 1036,1263 C 892,1043 790,871 731,746 672,621 627,498 598,377 568,256 553,130 553,0 L 365,0 C 365,180 403,370 480,569 556,768 683,997 862,1256 L 105,1256 105,1409 1036,1409 1036,1263 Z"/>
+ <glyph unicode="6" horiz-adv-x="980" d="M 1049,461 C 1049,312 1009,195 928,109 847,23 736,-20 594,-20 435,-20 314,39 230,157 146,275 104,447 104,672 104,916 148,1103 235,1234 322,1365 447,1430 608,1430 821,1430 955,1334 1010,1143 L 838,1112 C 803,1227 725,1284 606,1284 503,1284 424,1236 368,1141 311,1045 283,906 283,725 316,786 362,832 421,864 480,895 548,911 625,911 755,911 858,870 935,789 1011,708 1049,598 1049,461 Z M 866,453 C 866,555 841,634 791,689 741,744 671,772 582,772 498,772 430,748 379,699 327,650 301,582 301,496 301,387 328,298 382,229 435,160 504,125 588,125 675,125 743,154 792,213 841,271 866,351 866,453 Z"/>
+ <glyph unicode="5" horiz-adv-x="980" d="M 1053,459 C 1053,310 1009,193 921,108 832,23 710,-20 553,-20 422,-20 316,9 235,66 154,123 103,206 82,315 L 264,336 C 302,197 400,127 557,127 654,127 729,156 784,215 839,273 866,353 866,455 866,544 839,615 784,670 729,725 654,752 561,752 512,752 467,744 425,729 383,714 341,688 299,651 L 123,651 170,1409 971,1409 971,1256 334,1256 307,809 C 385,869 482,899 598,899 737,899 847,858 930,777 1012,696 1053,590 1053,459 Z"/>
+ <glyph unicode="2" horiz-adv-x="954" d="M 103,0 L 103,127 C 137,205 179,274 228,334 277,393 328,447 382,496 436,544 490,589 543,630 596,671 643,713 686,754 729,795 763,839 790,884 816,929 829,981 829,1038 829,1115 806,1175 761,1218 716,1261 653,1282 572,1282 495,1282 432,1261 383,1220 333,1178 304,1119 295,1044 L 111,1061 C 124,1174 172,1263 255,1330 337,1397 443,1430 572,1430 714,1430 823,1397 900,1330 976,1263 1014,1167 1014,1044 1014,989 1002,935 977,881 952,827 914,773 865,719 816,665 721,581 582,468 505,405 444,349 399,299 354,248 321,200 301,153 L 1036,153 1036,0 103,0 Z"/>
+ <glyph unicode="1" horiz-adv-x="927" d="M 156,0 L 156,153 515,153 515,1237 197,1010 197,1180 530,1409 696,1409 696,153 1039,153 1039,0 156,0 Z"/>
+ <glyph unicode="0" horiz-adv-x="980" d="M 1059,705 C 1059,470 1018,290 935,166 852,42 729,-20 567,-20 405,-20 283,42 202,165 121,288 80,468 80,705 80,947 120,1128 199,1249 278,1370 402,1430 573,1430 739,1430 862,1369 941,1247 1020,1125 1059,944 1059,705 Z M 876,705 C 876,908 853,1056 806,1147 759,1238 681,1284 573,1284 462,1284 383,1239 335,1149 286,1059 262,911 262,705 262,505 287,359 336,266 385,173 462,127 569,127 675,127 753,174 802,269 851,364 876,509 876,705 Z"/>
+ </font>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ <g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
+ </g>
+ </defs>
+ <g class="Page">
+ <g class="Group">
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2770" y="10793" width="14280" height="3"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2771,10794 L 17048,10794"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10906" y="10696" width="3532" height="205"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="203" stroke-linejoin="round" d="M 11008,10798 L 14335,10798"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12074" y="10677" width="1094" height="205"/>
+ <path fill="none" stroke="rgb(0,102,179)" stroke-width="203" stroke-linejoin="round" d="M 12176,10779 L 13065,10779"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4835" y="10696" width="2618" height="205"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="203" stroke-linejoin="round" d="M 4937,10798 L 7350,10798"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2470" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 3046,10804 C 3046,10854 3033,10904 3007,10947 2982,10991 2946,11027 2902,11052 2859,11078 2809,11091 2759,11091 2708,11091 2658,11078 2615,11052 2571,11027 2535,10991 2510,10947 2484,10904 2471,10854 2471,10804 2471,10753 2484,10703 2510,10660 2535,10616 2571,10580 2615,10555 2658,10529 2708,10516 2759,10516 2809,10516 2859,10529 2902,10555 2946,10580 2982,10616 3007,10660 3033,10703 3046,10753 3046,10804 L 3046,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 3046,10804 C 3046,10854 3033,10904 3007,10947 2982,10991 2946,11027 2902,11052 2859,11078 2809,11091 2759,11091 2708,11091 2658,11078 2615,11052 2571,11027 2535,10991 2510,10947 2484,10904 2471,10854 2471,10804 2471,10753 2484,10703 2510,10660 2535,10616 2571,10580 2615,10555 2658,10529 2708,10516 2759,10516 2809,10516 2859,10529 2902,10555 2946,10580 2982,10616 3007,10660 3033,10703 3046,10753 3046,10804 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16748" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 17324,10804 C 17324,10854 17311,10904 17285,10947 17260,10991 17224,11027 17180,11052 17137,11078 17087,11091 17037,11091 16986,11091 16936,11078 16893,11052 16849,11027 16813,10991 16788,10947 16762,10904 16749,10854 16749,10804 16749,10753 16762,10703 16788,10660 16813,10616 16849,10580 16893,10555 16936,10529 16986,10516 17037,10516 17087,10516 17137,10529 17180,10555 17224,10580 17260,10616 17285,10660 17311,10703 17324,10753 17324,10804 L 17324,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 17324,10804 C 17324,10854 17311,10904 17285,10947 17260,10991 17224,11027 17180,11052 17137,11078 17087,11091 17037,11091 16986,11091 16936,11078 16893,11052 16849,11027 16813,10991 16788,10947 16762,10904 16749,10854 16749,10804 16749,10753 16762,10703 16788,10660 16813,10616 16849,10580 16893,10555 16936,10529 16986,10516 17037,10516 17087,10516 17137,10529 17180,10555 17224,10580 17260,10616 17285,10660 17311,10703 17324,10753 17324,10804 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2397" y="9727" width="854" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="2647" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id10">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16424" y="9727" width="1557" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="16674" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">500</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id11">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3482" y="9755" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="3733" y="10520"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id12">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4616" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 5192,10804 C 5192,10854 5179,10904 5153,10947 5128,10991 5092,11027 5048,11052 5005,11078 4955,11091 4905,11091 4854,11091 4804,11078 4761,11052 4717,11027 4681,10991 4656,10947 4630,10904 4617,10854 4617,10804 4617,10753 4630,10703 4656,10660 4681,10616 4717,10580 4761,10555 4804,10529 4854,10516 4905,10516 4955,10516 5005,10529 5048,10555 5092,10580 5128,10616 5153,10660 5179,10703 5192,10753 5192,10804 L 5192,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 5192,10804 C 5192,10854 5179,10904 5153,10947 5128,10991 5092,11027 5048,11052 5005,11078 4955,11091 4905,11091 4854,11091 4804,11078 4761,11052 4717,11027 4681,10991 4656,10947 4630,10904 4617,10854 4617,10804 4617,10753 4630,10703 4656,10660 4681,10616 4717,10580 4761,10555 4804,10529 4854,10516 4905,10516 4955,10516 5005,10529 5048,10555 5092,10580 5128,10616 5153,10660 5179,10703 5192,10753 5192,10804 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id13">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7037" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 7613,10804 C 7613,10854 7600,10904 7574,10947 7549,10991 7513,11027 7469,11052 7426,11078 7376,11091 7326,11091 7275,11091 7225,11078 7182,11052 7138,11027 7102,10991 7077,10947 7051,10904 7038,10854 7038,10804 7038,10753 7051,10703 7077,10660 7102,10616 7138,10580 7182,10555 7225,10529 7275,10516 7326,10516 7376,10516 7426,10529 7469,10555 7513,10580 7549,10616 7574,10660 7600,10703 7613,10753 7613,10804 L 7613,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7613,10804 C 7613,10854 7600,10904 7574,10947 7549,10991 7513,11027 7469,11052 7426,11078 7376,11091 7326,11091 7275,11091 7225,11078 7182,11052 7138,11027 7102,10991 7077,10947 7051,10904 7038,10854 7038,10804 7038,10753 7051,10703 7077,10660 7102,10616 7138,10580 7182,10555 7225,10529 7275,10516 7326,10516 7376,10516 7426,10529 7469,10555 7513,10580 7549,10616 7574,10660 7600,10703 7613,10753 7613,10804 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id14">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4411" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="4661" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">10</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id15">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6869" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="7119" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">20</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id16">
+ <rect class="BoundingBox" stroke="none" fill="none" x="5399" y="9552" width="1652" height="1445"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="5831" y="10520"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">10</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id17">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10712" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 11288,10804 C 11288,10854 11275,10904 11249,10947 11224,10991 11188,11027 11144,11052 11101,11078 11051,11091 11001,11091 10950,11091 10900,11078 10857,11052 10813,11027 10777,10991 10752,10947 10726,10904 10713,10854 10713,10804 10713,10753 10726,10703 10752,10660 10777,10616 10813,10580 10857,10555 10900,10529 10950,10516 11001,10516 11051,10516 11101,10529 11144,10555 11188,10580 11224,10616 11249,10660 11275,10703 11288,10753 11288,10804 L 11288,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 11288,10804 C 11288,10854 11275,10904 11249,10947 11224,10991 11188,11027 11144,11052 11101,11078 11051,11091 11001,11091 10950,11091 10900,11078 10857,11052 10813,11027 10777,10991 10752,10947 10726,10904 10713,10854 10713,10804 10713,10753 10726,10703 10752,10660 10777,10616 10813,10580 10857,10555 10900,10529 10950,10516 11001,10516 11051,10516 11101,10529 11144,10555 11188,10580 11224,10616 11249,10660 11275,10703 11288,10753 11288,10804 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id18">
+ <rect class="BoundingBox" stroke="none" fill="none" x="14079" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 14655,10804 C 14655,10854 14642,10904 14616,10947 14591,10991 14555,11027 14511,11052 14468,11078 14418,11091 14368,11091 14317,11091 14267,11078 14224,11052 14180,11027 14144,10991 14119,10947 14093,10904 14080,10854 14080,10804 14080,10753 14093,10703 14119,10660 14144,10616 14180,10580 14224,10555 14267,10529 14317,10516 14368,10516 14418,10516 14468,10529 14511,10555 14555,10580 14591,10616 14616,10660 14642,10703 14655,10753 14655,10804 L 14655,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 14655,10804 C 14655,10854 14642,10904 14616,10947 14591,10991 14555,11027 14511,11052 14468,11078 14418,11091 14368,11091 14317,11091 14267,11078 14224,11052 14180,11027 14144,10991 14119,10947 14093,10904 14080,10854 14080,10804 14080,10753 14093,10703 14119,10660 14144,10616 14180,10580 14224,10555 14267,10529 14317,10516 14368,10516 14418,10516 14468,10529 14511,10555 14555,10580 14591,10616 14616,10660 14642,10703 14655,10753 14655,10804 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id19">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10444" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="10694" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">50</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id20">
+ <rect class="BoundingBox" stroke="none" fill="none" x="13911" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="14161" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">70</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id21">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8740" y="9755" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="8991" y="10520"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id22">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10536" y="11944" width="1387" height="1228"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="10835" y="12803"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">15</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id23">
+ <rect class="BoundingBox" stroke="none" fill="none" x="15362" y="9755" width="897" height="1039"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="15613" y="10520"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">0</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id24">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16366" y="10441" width="128" height="636"/>
+ <path fill="rgb(255,255,255)" stroke="none" d="M 16430,11076 L 16366,11076 16366,10441 16493,10441 16493,11076 16430,11076 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id25">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16360" y="10441" width="3" height="638"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 16361,10442 L 16361,11077"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id26">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16493" y="10441" width="3" height="638"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 16494,10442 L 16494,11077"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id27">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11921" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 12497,10804 C 12497,10854 12484,10904 12458,10947 12433,10991 12397,11027 12353,11052 12310,11078 12260,11091 12210,11091 12159,11091 12109,11078 12066,11052 12022,11027 11986,10991 11961,10947 11935,10904 11922,10854 11922,10804 11922,10753 11935,10703 11961,10660 11986,10616 12022,10580 12066,10555 12109,10529 12159,10516 12210,10516 12260,10516 12310,10529 12353,10555 12397,10580 12433,10616 12458,10660 12484,10703 12497,10753 12497,10804 L 12497,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 12497,10804 C 12497,10854 12484,10904 12458,10947 12433,10991 12397,11027 12353,11052 12310,11078 12260,11091 12210,11091 12159,11091 12109,11078 12066,11052 12022,11027 11986,10991 11961,10947 11935,10904 11922,10854 11922,10804 11922,10753 11935,10703 11961,10660 11986,10616 12022,10580 12066,10555 12109,10529 12159,10516 12210,10516 12260,10516 12310,10529 12353,10555 12397,10580 12433,10616 12458,10660 12484,10703 12497,10753 12497,10804 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id28">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12810" y="10515" width="578" height="578"/>
+ <path fill="rgb(237,28,36)" stroke="none" d="M 13386,10804 C 13386,10854 13373,10904 13347,10947 13322,10991 13286,11027 13242,11052 13199,11078 13149,11091 13099,11091 13048,11091 12998,11078 12955,11052 12911,11027 12875,10991 12850,10947 12824,10904 12811,10854 12811,10804 12811,10753 12824,10703 12850,10660 12875,10616 12911,10580 12955,10555 12998,10529 13048,10516 13099,10516 13149,10516 13199,10529 13242,10555 13286,10580 13322,10616 13347,10660 13373,10703 13386,10753 13386,10804 L 13386,10804 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 13386,10804 C 13386,10854 13373,10904 13347,10947 13322,10991 13286,11027 13242,11052 13199,11078 13149,11091 13099,11091 13048,11091 12998,11078 12955,11052 12911,11027 12875,10991 12850,10947 12824,10904 12811,10854 12811,10804 12811,10753 12824,10703 12850,10660 12875,10616 12911,10580 12955,10555 12998,10529 13048,10516 13099,10516 13149,10516 13199,10529 13242,10555 13286,10580 13322,10616 13347,10660 13373,10703 13386,10753 13386,10804 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id29">
+ <rect class="BoundingBox" stroke="none" fill="none" x="13838" y="11944" width="1387" height="1228"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="14137" y="12803"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">15</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id30">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11704" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="11954" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">60</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id31">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12684" y="9727" width="1235" height="807"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="12934" y="10301"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">65</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id32">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11246" y="10738" width="464" height="1226"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="81" stroke-linejoin="round" d="M 11287,11922 L 11668,10779"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id33">
+ <rect class="BoundingBox" stroke="none" fill="none" x="13659" y="10738" width="718" height="1353"/>
+ <path fill="none" stroke="rgb(114,191,68)" stroke-width="81" stroke-linejoin="round" d="M 14335,12049 L 13700,10779"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id34">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12314" y="8366" width="1387" height="1228"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="706px" font-weight="400"><tspan class="TextPosition" x="12810" y="9225"><tspan fill="rgb(0,108,59)" stroke="none" style="white-space: pre">5</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id35">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12643" y="9341" width="337" height="1480"/>
+ <path fill="none" stroke="rgb(0,102,179)" stroke-width="81" stroke-linejoin="round" d="M 12938,9382 L 12684,10779"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/_static/images/mtv-block-structure.svg b/doc/_static/images/mtv-block-structure.svg
new file mode 100644
index 0000000..95aa0ed
--- /dev/null
+++ b/doc/_static/images/mtv-block-structure.svg
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="166.98mm" height="46.46mm" viewBox="3924 3601 16698 4646" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="z" horiz-adv-x="848" d="M 83,0 L 83,137 688,943 117,943 117,1082 901,1082 901,945 295,139 922,139 922,0 83,0 Z"/>
+ <glyph unicode="y" horiz-adv-x="1033" d="M 191,-425 C 142,-425 100,-421 67,-414 L 67,-279 C 92,-283 120,-285 151,-285 263,-285 352,-203 417,-38 L 434,5 5,1082 197,1082 425,484 C 428,475 432,464 437,451 442,438 457,394 482,320 507,246 521,205 523,196 L 593,393 830,1082 1020,1082 604,0 C 559,-115 518,-201 479,-258 440,-314 398,-356 351,-384 304,-411 250,-425 191,-425 Z"/>
+ <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 495,-8 434,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 474,127 509,132 554,141 L 554,8 Z"/>
+ <glyph unicode="s" horiz-adv-x="901" d="M 950,299 C 950,197 912,118 835,63 758,8 650,-20 511,-20 376,-20 273,2 200,47 127,91 79,160 57,254 L 216,285 C 231,227 263,185 311,158 359,131 426,117 511,117 602,117 669,131 712,159 754,187 775,229 775,285 775,328 760,362 731,389 702,416 654,438 589,455 L 460,489 C 357,516 283,542 240,568 196,593 162,624 137,661 112,698 100,743 100,796 100,895 135,970 206,1022 276,1073 378,1099 513,1099 632,1099 727,1078 798,1036 868,994 912,927 931,834 L 769,814 C 759,862 732,899 689,925 645,950 586,963 513,963 432,963 372,951 333,926 294,901 275,864 275,814 275,783 283,758 299,738 315,718 339,701 370,687 401,673 467,654 568,629 663,605 732,583 774,563 816,542 849,520 874,495 898,470 917,442 930,410 943,377 950,340 950,299 Z"/>
+ <glyph unicode="r" horiz-adv-x="530" d="M 142,0 L 142,830 C 142,906 140,990 136,1082 L 306,1082 C 311,959 314,886 314,861 L 318,861 C 347,954 380,1017 417,1051 454,1085 507,1102 575,1102 599,1102 623,1099 648,1092 L 648,927 C 624,934 592,937 552,937 477,937 420,905 381,841 342,776 322,684 322,564 L 322,0 142,0 Z"/>
+ <glyph unicode="p" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 488,-20 376,43 319,168 L 314,168 C 317,163 318,106 318,-2 L 318,-425 138,-425 138,861 C 138,972 136,1046 132,1082 L 306,1082 C 307,1079 308,1070 309,1054 310,1037 312,1012 314,978 315,944 316,921 316,908 L 320,908 C 352,975 394,1024 447,1055 500,1086 569,1101 655,1101 788,1101 888,1056 954,967 1020,878 1053,737 1053,546 Z M 864,542 C 864,693 844,800 803,865 762,930 698,962 609,962 538,962 482,947 442,917 401,887 371,840 350,777 329,713 318,630 318,528 318,386 341,281 386,214 431,147 505,113 607,113 696,113 762,146 803,212 844,277 864,387 864,542 Z"/>
+ <glyph unicode="o" horiz-adv-x="980" d="M 1053,542 C 1053,353 1011,212 928,119 845,26 724,-20 565,-20 407,-20 288,28 207,125 126,221 86,360 86,542 86,915 248,1102 571,1102 736,1102 858,1057 936,966 1014,875 1053,733 1053,542 Z M 864,542 C 864,691 842,800 798,868 753,935 679,969 574,969 469,969 393,935 346,866 299,797 275,689 275,542 275,399 298,292 345,221 391,149 464,113 563,113 671,113 748,148 795,217 841,286 864,395 864,542 Z"/>
+ <glyph unicode="n" horiz-adv-x="874" d="M 825,0 L 825,686 C 825,757 818,813 804,852 790,891 768,920 737,937 706,954 661,963 602,963 515,963 447,933 397,874 347,815 322,732 322,627 L 322,0 142,0 142,851 C 142,977 140,1054 136,1082 L 306,1082 C 307,1079 307,1070 308,1055 309,1040 310,1024 311,1005 312,986 313,950 314,897 L 317,897 C 358,972 406,1025 461,1056 515,1087 582,1102 663,1102 782,1102 869,1073 924,1014 979,955 1006,857 1006,721 L 1006,0 825,0 Z"/>
+ <glyph unicode="m" horiz-adv-x="1457" d="M 768,0 L 768,686 C 768,791 754,863 725,903 696,943 645,963 570,963 493,963 433,934 388,875 343,816 321,734 321,627 L 321,0 142,0 142,851 C 142,977 140,1054 136,1082 L 306,1082 C 307,1079 307,1070 308,1055 309,1040 310,1024 311,1005 312,986 313,950 314,897 L 317,897 C 356,974 400,1027 450,1057 500,1087 561,1102 633,1102 715,1102 780,1086 828,1053 875,1020 908,968 927,897 L 930,897 C 967,970 1013,1022 1066,1054 1119,1086 1183,1102 1258,1102 1367,1102 1447,1072 1497,1013 1546,954 1571,856 1571,721 L 1571,0 1393,0 1393,686 C 1393,791 1379,863 1350,903 1321,943 1270,963 1195,963 1116,963 1055,934 1012,876 968,817 946,734 946,627 L 946,0 768,0 Z"/>
+ <glyph unicode="l" horiz-adv-x="187" d="M 138,0 L 138,1484 318,1484 318,0 138,0 Z"/>
+ <glyph unicode="k" horiz-adv-x="901" d="M 816,0 L 450,494 318,385 318,0 138,0 138,1484 318,1484 318,557 793,1082 1004,1082 565,617 1027,0 816,0 Z"/>
+ <glyph unicode="i" horiz-adv-x="187" d="M 137,1312 L 137,1484 317,1484 317,1312 137,1312 Z M 137,0 L 137,1082 317,1082 317,0 137,0 Z"/>
+ <glyph unicode="e" horiz-adv-x="980" d="M 276,503 C 276,379 302,283 353,216 404,149 479,115 578,115 656,115 719,131 766,162 813,193 844,233 861,281 L 1019,236 C 954,65 807,-20 578,-20 418,-20 296,28 213,123 129,218 87,360 87,548 87,727 129,864 213,959 296,1054 416,1102 571,1102 889,1102 1048,910 1048,527 L 1048,503 276,503 Z M 862,641 C 852,755 823,838 775,891 727,943 658,969 568,969 481,969 412,940 361,882 310,823 282,743 278,641 L 862,641 Z"/>
+ <glyph unicode="d" horiz-adv-x="927" d="M 821,174 C 788,105 744,55 689,25 634,-5 565,-20 484,-20 347,-20 247,26 183,118 118,210 86,349 86,536 86,913 219,1102 484,1102 566,1102 634,1087 689,1057 744,1027 788,979 821,914 L 823,914 821,1035 821,1484 1001,1484 1001,223 C 1001,110 1003,36 1007,0 L 835,0 C 833,11 831,35 829,74 826,113 825,146 825,174 L 821,174 Z M 275,542 C 275,391 295,282 335,217 375,152 440,119 530,119 632,119 706,154 752,225 798,296 821,405 821,554 821,697 798,802 752,869 706,936 633,969 532,969 441,969 376,936 336,869 295,802 275,693 275,542 Z"/>
+ <glyph unicode="c" horiz-adv-x="901" d="M 275,546 C 275,402 298,295 343,226 388,157 457,122 548,122 612,122 666,139 709,174 752,209 778,262 788,334 L 970,322 C 956,218 912,135 837,73 762,11 668,-20 553,-20 402,-20 286,28 207,124 127,219 87,359 87,542 87,724 127,863 207,959 287,1054 402,1102 551,1102 662,1102 754,1073 827,1016 900,959 945,880 964,779 L 779,765 C 770,825 746,873 708,908 670,943 616,961 546,961 451,961 382,929 339,866 296,803 275,696 275,546 Z"/>
+ <glyph unicode="b" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 573,-20 505,-5 451,25 396,54 352,102 318,168 L 316,168 C 316,147 315,116 312,74 309,31 307,7 306,0 L 132,0 C 136,36 138,110 138,223 L 138,1484 318,1484 318,1061 C 318,1018 317,967 314,908 L 318,908 C 351,977 396,1027 451,1057 506,1087 574,1102 655,1102 792,1102 892,1056 957,964 1021,872 1053,733 1053,546 Z M 864,540 C 864,691 844,800 804,865 764,930 699,963 609,963 508,963 434,928 388,859 341,790 318,680 318,529 318,387 341,282 386,215 431,147 505,113 607,113 698,113 763,147 804,214 844,281 864,389 864,540 Z"/>
+ <glyph unicode="a" horiz-adv-x="1060" d="M 414,-20 C 305,-20 224,9 169,66 114,123 87,202 87,302 87,414 124,500 198,560 271,620 390,652 554,656 L 797,660 797,719 C 797,807 778,870 741,908 704,946 645,965 565,965 484,965 426,951 389,924 352,897 330,853 323,793 L 135,810 C 166,1005 310,1102 569,1102 705,1102 807,1071 876,1009 945,946 979,856 979,738 L 979,272 C 979,219 986,179 1000,152 1014,125 1041,111 1080,111 1097,111 1117,113 1139,118 L 1139,6 C 1094,-5 1047,-10 1000,-10 933,-10 885,8 855,43 824,78 807,132 803,207 L 797,207 C 751,124 698,66 637,32 576,-3 501,-20 414,-20 Z M 455,115 C 521,115 580,130 631,160 682,190 723,231 753,284 782,336 797,390 797,445 L 797,534 600,530 C 515,529 451,520 408,504 364,488 330,463 307,430 284,397 272,353 272,299 272,240 288,195 320,163 351,131 396,115 455,115 Z"/>
+ <glyph unicode=" " horiz-adv-x="556"/>
+ </font>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ <g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/>
+ </g>
+ </defs>
+ <g class="Page">
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7448" y="4870" width="511" height="511"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 7703,5379 L 7449,5379 7449,4871 7957,4871 7957,5379 7703,5379 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7703,5379 L 7449,5379 7449,4871 7957,4871 7957,5379 7703,5379 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7448" y="5378" width="511" height="511"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 7703,5887 L 7449,5887 7449,5379 7957,5379 7957,5887 7703,5887 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7703,5887 L 7449,5887 7449,5379 7957,5379 7957,5887 7703,5887 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7448" y="5886" width="511" height="511"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 7703,6395 L 7449,6395 7449,5887 7957,5887 7957,6395 7703,6395 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7703,6395 L 7449,6395 7449,5887 7957,5887 7957,6395 7703,6395 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7448" y="6394" width="511" height="511"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 7703,6903 L 7449,6903 7449,6395 7957,6395 7957,6903 7703,6903 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7703,6903 L 7449,6903 7449,6395 7957,6395 7957,6903 7703,6903 Z"/>
+ </g>
+ </g>
+ <g class="Group">
+ <g class="TextShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11244" y="3601" width="1629" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="11494" y="4302"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">size</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11244" y="4550" width="1701" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="11494" y="5251"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">type</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11244" y="5500" width="2683" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="11494" y="6201"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">position</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id10">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11244" y="6449" width="1735" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="11494" y="7150"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">data</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id11">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7956" y="3981" width="2797" height="892"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 7957,4871 L 8008,4855"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8058,4839 L 8109,4823"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8159,4807 L 8210,4791"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8261,4774 L 8311,4758"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8362,4742 L 8412,4726"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8463,4710 L 8514,4694"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8564,4678 L 8615,4662"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8665,4646 L 8716,4630"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8766,4613 L 8817,4597"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8868,4581 L 8918,4565"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8969,4549 L 9019,4533"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9070,4517 L 9121,4501"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9171,4485 L 9222,4469"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9272,4452 L 9323,4436"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9374,4420 L 9424,4404"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9475,4388 L 9525,4372"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9576,4356 L 9627,4340"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9677,4324 L 9728,4308"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9778,4291 L 9829,4275"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9880,4259 L 9930,4243"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9981,4227 L 10031,4211"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10082,4195 L 10132,4179"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10183,4163 L 10234,4147"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10284,4131 L 10335,4114"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10385,4098 L 10436,4082"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10487,4066 L 10537,4050"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10588,4034 L 10638,4018"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10689,4002 L 10740,3986"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id12">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10877" y="3790" width="258" height="3433"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 11133,3791 C 11005,3791 10878,3933 10878,4076 L 10878,6935 C 10878,7078 11005,7221 11133,7221"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id13">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7956" y="5378" width="2797" height="1654"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 7957,5379 L 8003,5406"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8048,5433 L 8094,5460"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8140,5487 L 8186,5514"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8231,5541 L 8277,5568"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8323,5595 L 8368,5622"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8414,5649 L 8460,5676"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8505,5703 L 8551,5730"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8597,5757 L 8643,5784"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8688,5811 L 8734,5838"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8780,5865 L 8825,5892"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8871,5919 L 8917,5946"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8963,5973 L 9008,6000"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9054,6027 L 9100,6054"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9145,6081 L 9191,6108"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9237,6135 L 9283,6162"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9328,6189 L 9374,6216"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9420,6243 L 9465,6270"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9511,6297 L 9557,6324"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9602,6351 L 9648,6378"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9694,6405 L 9740,6432"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9785,6459 L 9831,6486"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9877,6513 L 9922,6540"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9968,6567 L 10014,6594"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10060,6621 L 10105,6648"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10151,6675 L 10197,6702"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10242,6729 L 10288,6756"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10334,6783 L 10380,6810"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10425,6837 L 10471,6865"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10517,6892 L 10562,6919"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10608,6946 L 10654,6973"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10699,7000 L 10745,7027"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id14">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16211" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 16466,7284 L 16212,7284 16212,6776 16720,6776 16720,7284 16466,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 16466,7284 L 16212,7284 16212,6776 16720,6776 16720,7284 16466,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id15">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16719" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 16974,7284 L 16720,7284 16720,6776 17228,6776 17228,7284 16974,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 16974,7284 L 16720,7284 16720,6776 17228,6776 17228,7284 16974,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id16">
+ <rect class="BoundingBox" stroke="none" fill="none" x="17227" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 17482,7284 L 17228,7284 17228,6776 17736,6776 17736,7284 17482,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 17482,7284 L 17228,7284 17228,6776 17736,6776 17736,7284 17482,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id17">
+ <rect class="BoundingBox" stroke="none" fill="none" x="17735" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 17990,7284 L 17736,7284 17736,6776 18244,6776 18244,7284 17990,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 17990,7284 L 17736,7284 17736,6776 18244,6776 18244,7284 17990,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id18">
+ <rect class="BoundingBox" stroke="none" fill="none" x="18243" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 18498,7284 L 18244,7284 18244,6776 18752,6776 18752,7284 18498,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 18498,7284 L 18244,7284 18244,6776 18752,6776 18752,7284 18498,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id19">
+ <rect class="BoundingBox" stroke="none" fill="none" x="18751" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 19006,7284 L 18752,7284 18752,6776 19260,6776 19260,7284 19006,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 19006,7284 L 18752,7284 18752,6776 19260,6776 19260,7284 19006,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id20">
+ <rect class="BoundingBox" stroke="none" fill="none" x="19259" y="6775" width="511" height="511"/>
+ <path fill="rgb(255,0,0)" stroke="none" d="M 19514,7284 L 19260,7284 19260,6776 19768,6776 19768,7284 19514,7284 Z"/>
+ <path fill="none" stroke="rgb(153,0,0)" d="M 19514,7284 L 19260,7284 19260,6776 19768,6776 19768,7284 19514,7284 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id21">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12977" y="6869" width="3236" height="301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 12978,7019 L 15782,7019"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 16212,7019 L 15762,6869 15762,7169 16212,7019 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id22">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16212" y="7284" width="4410" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="16462" y="7985"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">element block</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id23">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3924" y="3756" width="4237" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="4174" y="4457"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">primary array</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="TextShape">
+ <g id="id24">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8899" y="5017" width="1980" height="963"/>
+ <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="9149" y="5718"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">block</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/_static/images/mtv_collection_sheet.png b/doc/_static/images/mtv_collection_sheet.png
new file mode 100644
index 0000000..0e2afd4
--- /dev/null
+++ b/doc/_static/images/mtv_collection_sheet.png
Binary files differ
diff --git a/doc/_static/images/rtree_bounds2_tree.png b/doc/_static/images/rtree_bounds2_tree.png
new file mode 100644
index 0000000..fed50a0
--- /dev/null
+++ b/doc/_static/images/rtree_bounds2_tree.png
Binary files differ
diff --git a/doc/_static/images/rtree_bounds2_tree_bulkload.png b/doc/_static/images/rtree_bounds2_tree_bulkload.png
new file mode 100644
index 0000000..99fda1c
--- /dev/null
+++ b/doc/_static/images/rtree_bounds2_tree_bulkload.png
Binary files differ
diff --git a/doc/_static/images/rtree_bounds_src.png b/doc/_static/images/rtree_bounds_src.png
new file mode 100644
index 0000000..d20cc0f
--- /dev/null
+++ b/doc/_static/images/rtree_bounds_src.png
Binary files differ
diff --git a/doc/_static/images/rtree_bounds_tree.png b/doc/_static/images/rtree_bounds_tree.png
new file mode 100644
index 0000000..2619873
--- /dev/null
+++ b/doc/_static/images/rtree_bounds_tree.png
Binary files differ
diff --git a/doc/api.rst b/doc/api.rst
new file mode 100644
index 0000000..9944b93
--- /dev/null
+++ b/doc/api.rst
@@ -0,0 +1,280 @@
+
+API Incompatibility Notes
+=========================
+
+v2.1
+----
+
+* The following public template types have been put into ``mdds::detail`` namespace:
+
+ * ``has_value_type``
+ * ``const_or_not``
+ * ``const_t``
+ * ``get_iterator_type``
+ * ``invalid_static_int``
+
+multi_type_vector
+^^^^^^^^^^^^^^^^^
+
+* In 2.0, multi_type_vector took two template parameters: one for the element block
+ functions and one for other traits. In 2.1, multi_type_vector only takes one
+ template parameter for the traits, and the traits now must include the element
+ block functions.
+
+* The following block function helpers have been removed:
+
+ * ``mdds::mtv::custom_block_func1``
+ * ``mdds::mtv::custom_block_func2``
+ * ``mdds::mtv::custom_block_func3``
+
+ They have been replaced with ``mdds::mtv::element_block_funcs`` which uses
+ `template parameter pack <https://en.cppreference.com/w/cpp/language/parameter_pack>`_
+ to allow unspecified number of standard and custom blocks.
+
+ As a result of this change, the following headers have been removed:
+
+ * ``include/mdds/multi_type_vector/custom_func1.hpp``
+ * ``include/mdds/multi_type_vector/custom_func2.hpp``
+ * ``include/mdds/multi_type_vector/custom_func3.hpp``
+ * ``include/mdds/multi_type_vector/trait.hpp``
+ * ``include/mdds/multi_type_vector_custom_func2.hpp``
+ * ``include/mdds/multi_type_vector_custom_func3.hpp``
+ * ``include/mdds/multi_type_vector_trait.hpp``
+
+* ``mdds::mtv::default_trait`` has been renamed to ``mdds::mtv::default_traits``.
+
+* The following element block types have an additional template parameter to specify
+ the underlying storage type. This can be used to specify, for instance, whether
+ the element block uses ``std::vector``, ``std::deque`` or another custom container
+ type with API compatible with the aforementioned two.
+
+ * ``mdds::mtv::default_element_block``
+ * ``mdds::mtv::managed_element_block``
+ * ``mdds::mtv::noncopyable_managed_element_block``
+
+ With this change, the compiler macro named ``MDDS_MULTI_TYPE_VECTOR_USE_DEQUE``,
+ which was previously used to switch from ``std::vector`` to ``std::deque`` as the
+ underlying storage type for all element blocks, has been removed.
+
+multi_type_matrix
+^^^^^^^^^^^^^^^^^
+
+* ``mdds::mtm::std_string_trait`` has been renamed to ``mdds::mtm::std_string_traits``.
+
+trie_map / packed_trie_map
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The following public types have been renamed:
+
+ * ``mdds::trie::std_container_trait`` -> ``mdds::trie::std_container_traits``
+ * ``mdds::trie::std_string_trait`` -> ``mdds::trie::std_string_traits``
+
+
+v2.0
+----
+
+* baseline C++ version has been set to C++17.
+
+* deprecated ``rectangle_set`` data structure has been removed.
+
+multi_type_vector
+^^^^^^^^^^^^^^^^^
+
+* The second template parameter is now a trait type that specifies custom event
+ function type and loop-unrolling factor. Prior to 2.0 the second template
+ parameter was custom event function type.
+
+* Due to the addition of the structure-of-arrays variant, the following header
+ files have been relocated:
+
+ .. list-table:: Relocated Headers
+ :widths: 50 50
+ :header-rows: 1
+
+ * - Old header location
+ - New header location
+ * - mdds/multi_type_vector_types.hpp
+ - mdds/multi_type_vector/types.hpp
+ * - mdds/multi_type_vector_macro.hpp
+ - mdds/multi_type_vector/macro.hpp
+ * - mdds/multi_type_vector_trait.hpp
+ - mdds/multi_type_vector/trait.hpp
+ * - mdds/multi_type_vector_itr.hpp
+ - mdds/multi_type_vector/aos/iterator.hpp
+ * - mdds/multi_type_vector_custom_func1.hpp
+ - mdds/multi_type_vector/custom_func1.hpp
+ * - mdds/multi_type_vector_custom_func2.hpp
+ - mdds/multi_type_vector/custom_func2.hpp
+ * - mdds/multi_type_vector_custom_func3.hpp
+ - mdds/multi_type_vector/custom_func3.hpp
+
+ The old headers will continue to work for the time being, but consider them
+ deprecated.
+
+* Since now we have array-of-structures (AoS) and structure-of-arrays (SoA) variants
+ of multi_type_vector, there are two instances of multi_type_vector class in two
+ different headers and namespace locations. To use the AoS variant, include the header
+
+ .. code-block:: c++
+
+ #include <mdds/multi_type_vector/aos/main.hpp>
+
+ and instantiate the template class as ``mdds::mtv::aos::multi_type_vector``.
+ Likewise, to use the SoA variant, include the header
+
+ .. code-block:: c++
+
+ #include <mdds/multi_type_vector/soa/main.hpp>
+
+ and instantiate the template class as ``mdds::mtv::soa::multi_type_vector``.
+
+ If you include the original header
+
+ .. code-block:: c++
+
+ #include <mdds/multi_type_vector.hpp>
+
+ it will include a template alias ``mdds::multi_type_vector`` that simply references
+ ``mdds::mtv::soa::multi_type_vector``.
+
+
+segment_tree
+^^^^^^^^^^^^
+
+* The following public types have been renamed:
+
+ * ``search_result`` -> ``search_results``
+ * ``search_result_type`` -> ``search_results_type``
+
+v1.5
+----
+
+multi_type_vector
+^^^^^^^^^^^^^^^^^
+
+* The standard integer blocks previously used non-standard integer types,
+ namely:
+
+ * short
+ * unsigned short
+ * int
+ * unsigned int
+ * long
+ * unsigned long
+ * char
+ * unsigned char
+
+ Starting with this version, the integer blocks now use:
+
+ * (u)int8_t
+ * (u)int16_t
+ * (u)int32_t
+ * (u)int64_t
+
+* The numeric_element_block type has been renamed to `double_element_block`,
+ to make room for a new element block for float type named
+ `float_element_block`.
+
+v1.4
+----
+
+multi_type_matrix
+^^^^^^^^^^^^^^^^^
+
+* The walk() methods previously took the function object by reference,
+ but the newer versions now take the function object by value. With
+ this change, it is now possible to pass inline lambda function.
+ However, if you were dependent on the old behavior, *this change may
+ adversely affect the outcome of your code especially when your
+ function object stores data members that are expected to be altered by
+ the walk() methods*.
+
+v1.2
+----
+
+trie_map / packed_trie_map
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The find() method now returns a const_iterator instance rather than a value
+ type. It returns an end position iterator when the method fails to find a
+ match.
+
+* The prefix_search() method now returns a search_results instance that has
+ begin() and end() methods to allow iterating through the result set.
+
+* The constructor no longer takes a null value parameter.
+
+* Some nested type names have been renamed:
+
+ * string_type -> key_type
+ * char_type -> key_unit_type
+ * string_buffer_type -> key_buffer_type
+
+* Some functions expected from the key trait class have been renamed:
+
+ * init_buffer() -> to_key_buffer()
+ * to_string() -> to_key()
+
+* The kay trait class now expects the following additional static methods:
+
+ * key_buffer_type to_key_buffer(const key_type& key)
+ * key_unit_type* buffer_data(const key_buffer_type& buf)
+ * size_t buffer_size(const key_buffer_type& buf)
+
+quad_point_tree
+^^^^^^^^^^^^^^^
+
+* The search_result nested class has been renamed to search_results, to keep
+ the name consistent with that of the same name in trie_map and
+ packed_trie_map.
+
+multi_type_matrix
+^^^^^^^^^^^^^^^^^
+
+* The matrix trait structure (formerly known as the string trait structure)
+ now needs to specify the type of block that stores integer values as its
+ **integer_element_block** member.
+
+v1.0
+----
+
+* Starting with version 1.0, mdds now requires support for C++11. Stick with
+ 0.12 or earlier versions if you use a compiler that doesn't support C++11.
+
+* data_type has been renamed to value_type for segment_tree, rectangle_set,
+ and point_quad_tree.
+
+
+v0.9
+----
+
+multi_type_vector
+^^^^^^^^^^^^^^^^^
+
+* The number of template parameters in custom_block_func1,
+ custom_block_func2 and custom_block_func3 have been reduced by half,
+ by deducing the numerical block type ID from the block type
+ definition directly. If you use the older variant, simply remove
+ the template arguments that are numerical block IDs.
+
+v0.8
+----
+
+flat_segment_tree
+^^^^^^^^^^^^^^^^^
+
+* The search_tree() method in 0.8.0 returns std::pair<const_iterator,
+ bool> instead of just returning bool as of 0.7.1. If you use this
+ method and relies on the return value of the old version, use the
+ second parameter of the new return value which is equivalent of the
+ previous return value.
+
+v0.5
+----
+
+flat_segment_tree
+^^^^^^^^^^^^^^^^^
+
+* The search() method now returns ::std::pair<const_iterator, bool>.
+ This method previously returned only bool. Use the second parameter of
+ the new return value which is equivalent of the previous return value.
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..98b45fc
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,271 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# mdds documentation build configuration file, created by
+# sphinx-quickstart on Tue Sep 22 20:54:14 2015.
+#
+# 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.
+
+import sys
+import os
+import subprocess
+
+rtd_build = os.environ.get('READTHEDOCS', None) == 'True'
+
+if rtd_build:
+ subprocess.call("doxygen --version; doxygen doxygen.conf", shell=True)
+
+# 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.
+#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 = ['breathe']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'mdds'
+copyright = '2022, Kohei Yoshida'
+
+# 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 = "2.1"
+# The full version, including alpha/beta/rc tags.
+release = "2.1.1"
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#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.
+exclude_patterns = ['_build']
+
+# 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
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'sphinx_rtd_theme'
+
+# 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. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# 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 = None
+
+# The name of an image file (within the static path) to use as 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 '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# 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
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'mddsdoc'
+
+
+# -- 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': '',
+}
+
+# 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 = [
+ ('index', 'mdds.tex', 'mdds Documentation',
+ 'Kohei Yoshida', '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 = []
+
+# 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 = [
+ ('index', 'mdds', 'mdds Documentation',
+ ['Kohei Yoshida'], 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 = [
+ ('index', 'mdds', 'mdds Documentation',
+ 'Kohei Yoshida', 'mdds', '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
+
+breathe_projects = {"mdds": "./_doxygen/xml"}
+
+breathe_default_project = "mdds"
+
+breathe_default_members = ('members', 'undoc-members')
diff --git a/doc/doxygen.conf b/doc/doxygen.conf
new file mode 100644
index 0000000..76cda4d
--- /dev/null
+++ b/doc/doxygen.conf
@@ -0,0 +1,2276 @@
+# Doxyfile 1.8.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "mdds"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = _doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = ../include
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS = *.hpp
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = YES
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/doc/flat_segment_tree.rst b/doc/flat_segment_tree.rst
new file mode 100644
index 0000000..d5e7b8a
--- /dev/null
+++ b/doc/flat_segment_tree.rst
@@ -0,0 +1,268 @@
+.. highlight:: cpp
+
+Flat Segment Tree
+=================
+
+Overview
+--------
+
+Flat segment tree is a derivative of `segment tree
+<https://en.wikipedia.org/wiki/Segment_tree>`_, and is designed to store
+non-overlapping 1-dimensional range values such that *the values of the
+neighboring ranges are guaranteed to be different.* An insertion of a range
+value into this structure will always overwrite one or more existing ranges
+that overlap with the new range. If an insertion of a new range would cause
+any adjacent ranges to have the equal value, those ranges will be merged into
+one range.
+
+An instance of this structure is initialized with fixed lower and upper
+bounaries, which will not change throughout the life time of the instance.
+
+The flat segment tree structure consists of two parts: the leaf-node part
+which also forms a doubly-linked list, and the non-leaf-node part which forms
+a balanced-binary tree and is used only when performing tree-based queries.
+The range values are stored in the leaf-nodes, while the non-leaf nodes are
+used only for queries.
+
+
+Quick start
+-----------
+
+This section demonstrates a simple use case of storing non-overlapping ranged
+values and performing queries using :cpp:class:`~mdds::flat_segment_tree`.
+
+First, we need to instantiate a concrete type from the template:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: type
+ :end-before: //!code-end: type
+ :dedent: 4
+
+then create an instance of this type:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: instance
+ :end-before: //!code-end: instance
+ :dedent: 4
+
+Here, the first and second arguments specify the lower and upper boundaries of
+the whole segment. The third argument specifies the value for the empty
+segments. What this line does is to create a new instance and initializes it
+with one initial segment ranging from 0 to 500 with a value of 0:
+
+.. figure:: _static/images/fst-example1-initial.svg
+ :align: center
+
+ The new instance is initialized with an initial segment.
+
+Internally, this initial range is represented by two leaf nodes, with the
+first one storing the start key and the value for the segment both of which
+happen to be 0 in this example, and the second one storing the end key of 500.
+Note that the end key of a segment is not inclusive.
+
+The following lines insert two new segments into this structure:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: insert-1
+ :end-before: //!code-end: insert-1
+ :dedent: 4
+
+The first line inserts a segment ranging from 10 to 20 with a value of 10, and
+the second line from 50 to 70 with a value of 15:
+
+.. figure:: _static/images/fst-example1-insert1.svg
+ :align: center
+
+ Two new segments have been inserted.
+
+You can insert a new segment either via :cpp:func:`~mdds::flat_segment_tree::insert_front`
+or :cpp:func:`~mdds::flat_segment_tree::insert_back`. The end result will be
+the same regardless of which method you use; the difference is that
+:cpp:func:`~mdds::flat_segment_tree::insert_front` begins its search for
+the insertion point from the first node associated with the minimum key value,
+whereas :cpp:func:`~mdds::flat_segment_tree::insert_back` starts its search
+from the last node associated with the maximum key value.
+
+After the insertions, the tree now contains a total of six leaf nodes to
+represent all stored segments. Note that one leaf node typically represents
+both the end of a segment and the start of the adjacent segment that comes
+after it, unless it's either the first or the last node.
+
+The next line inserts another segment ranging from 60 to 65 having a value of
+5:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: insert-2
+ :end-before: //!code-end: insert-2
+ :dedent: 4
+
+As this new segment overlaps with the existing segment of 50 to 70, it will
+cut into a middle part of that segment to make room for the new segment. At
+this point, the tree contains a total of eight leaf nodes representing seven
+segments:
+
+.. figure:: _static/images/fst-example1-insert2.svg
+ :align: center
+
+ A new segment has been inserted that overlaps an existing non-empty segment.
+
+Next, we are going to query the value associated with a key of 15 via
+:cpp:func:`~mdds::flat_segment_tree::search`:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: linear-search
+ :end-before: //!code-end: linear-search
+ :dedent: 4
+
+Executing this code will yield the following output:
+
+.. code-block:: none
+
+ The value at 15 is 10, and this segment spans from 10 to 20
+
+One thing to note is that the :cpp:func:`~mdds::flat_segment_tree::search`
+method performs a linear search which involves traversing only through the
+leaf nodes in this data structure in order to find the target segment. As
+such, the worst-case lookup performance is directly proportional to the number
+of leaf nodes.
+
+There is another way to perform the query with better worse-case performance,
+that is through :cpp:func:`~mdds::flat_segment_tree::search_tree` as seen in
+the following code:
+
+.. literalinclude:: ../example/flat_segment_tree.cpp
+ :language: C++
+ :start-after: //!code-start: tree-search
+ :end-before: //!code-end: tree-search
+ :dedent: 4
+
+The signature of the :cpp:func:`~mdds::flat_segment_tree::search_tree` method
+is identical to that of the :cpp:func:`~mdds::flat_segment_tree::search` method
+except for the name. This code generates the following output:
+
+.. code-block:: none
+
+ The value at 62 is 5, and this segment spans from 60 to 65
+
+Query via :cpp:func:`~mdds::flat_segment_tree::search_tree` generally performs
+better since it traverses through the search tree to find the target segment.
+But it does require the search tree to be built ahead of time by calling
+:cpp:func:`~mdds::flat_segment_tree::build_tree`. Please be aware that if the
+segments have been modified after the tree was last built, you will have to rebuild
+the tree by calling :cpp:func:`~mdds::flat_segment_tree::build_tree`.
+
+.. warning::
+
+ You need to build the tree by calling :cpp:func:`~mdds::flat_segment_tree::build_tree`
+ before performing a tree-based search via :cpp:func:`~mdds::flat_segment_tree::search_tree`.
+ If the segments have been modified after the tree was last built, you will have to
+ rebuild the tree by calling :cpp:func:`~mdds::flat_segment_tree::build_tree` again.
+
+
+Iterate through stored segments
+-------------------------------
+
+:cpp:class:`~mdds::flat_segment_tree` supports two types of iterators to allow
+you to iterate through the segments stored in your tree. The first way is to
+iterate through the individual leaf nodes one at a time by using
+:cpp:func:`~mdds::flat_segment_tree::begin` and :cpp:func:`~mdds::flat_segment_tree::end`:
+
+.. literalinclude:: ../example/flat_segment_tree_itrs.cpp
+ :language: C++
+ :start-after: //!code-start: iterate-nodes
+ :end-before: //!code-end: iterate-nodes
+ :dedent: 4
+
+Each iterator value contains a pair of two values named ``first`` and ``second``,
+with the first one being the key of the segment that the node initiates, and the
+second one being the value associated with that segment. When executing this
+code with the tree from the example code above, you'll get the following output:
+
+.. code-block:: none
+
+ key: 0; value: 0
+ key: 10; value: 10
+ key: 20; value: 0
+ key: 50; value: 15
+ key: 60; value: 5
+ key: 65; value: 15
+ key: 70; value: 0
+ key: 500; value: 0
+
+Each node stores the start key and the value of the segment it initiates, and
+the key stored in each node is also the end key of the segment that the
+previous node initiates except for the first node. Note that the value stored
+in the last node is currently not used. It is set to be the zero value of the
+value type, but this may change in the future.
+
+One thing to keep in mind is that :cpp:class:`~mdds::flat_segment_tree` does
+not support mutable iterators that let you modify the stored keys or values.
+
+.. note::
+
+ :cpp:class:`~mdds::flat_segment_tree` does not support mutable iterators;
+ you can only traverse the values in a read-only fashion.
+
+You can also use range-based for loop to iterate through the leaf nodes in a
+similar fashion:
+
+.. literalinclude:: ../example/flat_segment_tree_itrs.cpp
+ :language: C++
+ :start-after: //!code-start: loop-nodes
+ :end-before: //!code-end: loop-nodes
+ :dedent: 4
+
+The output from this code is identical to that from the previous one.
+
+Now, one major inconvenience of navigating through the individual leaf nodes
+is that you need to manually keep track of the start and end points of each
+segment if you need to operate on the segments rather than the nodes that
+comprise the segments. The good news is that
+:cpp:class:`~mdds::flat_segment_tree` does provide a way to iterate through
+the segments directly as the following code demonstrates:
+
+.. literalinclude:: ../example/flat_segment_tree_itrs.cpp
+ :language: C++
+ :start-after: //!code-start: iterate-segments
+ :end-before: //!code-end: iterate-segments
+ :dedent: 4
+
+This code uses :cpp:func:`~mdds::flat_segment_tree::begin_segment` and
+:cpp:func:`~mdds::flat_segment_tree::end_segment` to iterate through one
+segment at a time with the value of each iterator containing ``start``,
+``end`` and ``value`` members that correspond with the start key, end key and
+the value of the segment, respectively. Running this code produces the
+following output:
+
+.. code-block:: none
+
+ start: 0; end: 10; value: 0
+ start: 10; end: 20; value: 10
+ start: 20; end: 50; value: 0
+ start: 50; end: 60; value: 15
+ start: 60; end: 65; value: 5
+ start: 65; end: 70; value: 15
+ start: 70; end: 500; value: 0
+
+It's also possible to iterate through the segments in a range-based for loop, by
+calling :cpp:func:`~mdds::flat_segment_tree::segment_range()`:
+
+.. literalinclude:: ../example/flat_segment_tree_itrs.cpp
+ :language: C++
+ :start-after: //!code-start: loop-segments
+ :end-before: //!code-end: loop-segments
+ :dedent: 4
+
+This code should generate output identical to that of the previous code.
+
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::flat_segment_tree
+ :members:
diff --git a/doc/global.rst b/doc/global.rst
new file mode 100644
index 0000000..7655b27
--- /dev/null
+++ b/doc/global.rst
@@ -0,0 +1,20 @@
+
+Globals
+=======
+
+Macros
+------
+
+.. doxygendefine:: MDDS_ASCII
+
+.. doxygendefine:: MDDS_N_ELEMENTS
+
+
+Exceptions
+----------
+
+.. doxygenclass:: mdds::general_error
+.. doxygenclass:: mdds::invalid_arg_error
+.. doxygenclass:: mdds::size_error
+.. doxygenclass:: mdds::type_error
+.. doxygenclass:: mdds::integrity_error
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..b8a8fdf
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,37 @@
+.. mdds documentation master file, created by
+ sphinx-quickstart on Tue Sep 22 20:54:14 2015.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+.. _index:
+
+mdds documentation
+==================
+
+Multi-dimensional data structure, or mdds for short, is a collection of data
+structures and indexing algorithms that are useful for storing and indexing
+multi-dimensional data for C++ projects.
+
+Contents:
+
+.. toctree::
+ :maxdepth: 1
+
+ global.rst
+ flat_segment_tree.rst
+ segment_tree.rst
+ point_quad_tree.rst
+ multi_type_vector/index.rst
+ multi_type_matrix.rst
+ sorted_string_map.rst
+ trie_map.rst
+ rtree.rst
+ api.rst
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/doc/multi_type_matrix.rst b/doc/multi_type_matrix.rst
new file mode 100644
index 0000000..7166cd4
--- /dev/null
+++ b/doc/multi_type_matrix.rst
@@ -0,0 +1,15 @@
+.. highlight:: cpp
+
+Multi Type Matrix
+=================
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::multi_type_matrix
+ :members:
+
+.. doxygenstruct:: mdds::mtm::std_string_traits
+ :members:
+
+.. doxygenenum:: mdds::mtm::element_t
diff --git a/doc/multi_type_vector/api-ref.rst b/doc/multi_type_vector/api-ref.rst
new file mode 100644
index 0000000..b060862
--- /dev/null
+++ b/doc/multi_type_vector/api-ref.rst
@@ -0,0 +1,169 @@
+.. highlight:: cpp
+
+API Reference
+=============
+
+Core
+----
+
+mdds::multi_type_vector
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygentypedef:: mdds::multi_type_vector
+
+mdds::mtv::soa::multi_type_vector
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenclass:: mdds::mtv::soa::multi_type_vector
+ :members:
+
+mdds::mtv::aos::multi_type_vector
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenclass:: mdds::mtv::aos::multi_type_vector
+ :members:
+
+mdds::mtv::empty_event_func
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenstruct:: mdds::mtv::empty_event_func
+ :members:
+
+mdds::mtv::default_traits
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenstruct:: mdds::mtv::default_traits
+ :members:
+
+Element Stores
+--------------
+
+.. doxygenclass:: mdds::mtv::delayed_delete_vector
+ :members:
+
+Element Blocks
+--------------
+
+.. doxygenclass:: mdds::mtv::base_element_block
+ :members:
+
+.. doxygenclass:: mdds::mtv::element_block
+ :members:
+
+.. doxygenstruct:: mdds::mtv::default_element_block
+ :members:
+
+.. doxygenclass:: mdds::mtv::copyable_element_block
+ :members:
+
+.. doxygenclass:: mdds::mtv::noncopyable_element_block
+ :members:
+
+.. doxygenstruct:: mdds::mtv::managed_element_block
+ :members:
+
+.. doxygenstruct:: mdds::mtv::noncopyable_managed_element_block
+ :members:
+
+.. doxygenstruct:: mdds::mtv::element_block_funcs
+ :members:
+
+
+Types
+-----
+
+mdds::mtv::element_t
+^^^^^^^^^^^^^^^^^^^^
+
+.. doxygentypedef:: mdds::mtv::element_t
+
+.. doxygenvariable:: mdds::mtv::element_type_empty
+.. doxygenvariable:: mdds::mtv::element_type_reserved_start
+.. doxygenvariable:: mdds::mtv::element_type_reserved_end
+.. doxygenvariable:: mdds::mtv::element_type_user_start
+
+mdds::mtv::lu_factor_t
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenenum:: mdds::mtv::lu_factor_t
+
+mdds::mtv::trace_method_t
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenenum:: mdds::mtv::trace_method_t
+
+mdds::mtv::trace_method_properties_t
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygenstruct:: mdds::mtv::trace_method_properties_t
+
+
+Standard Element Blocks
+-----------------------
+
+The following types are automatically defined by default when including one of
+the following headers:
+
+* ``mdds/multi_type_vector.hpp``
+* ``mdds/multi_type_vector/aos/main.hpp``
+* ``mdds/multi_type_vector/soa/main.hpp``
+
+To disable automatic definitions of these standard element block types, you must
+define the :c:macro:`MDDS_MTV_USE_STANDARD_ELEMENT_BLOCKS` macro and set its value
+to 0. Refer to the :ref:`custom-value-types-custom-store` section for more details
+on when you may want to disable these block types.
+
+Constants
+^^^^^^^^^
+
+.. doxygenvariable:: mdds::mtv::element_type_boolean
+.. doxygenvariable:: mdds::mtv::element_type_int8
+.. doxygenvariable:: mdds::mtv::element_type_uint8
+.. doxygenvariable:: mdds::mtv::element_type_int16
+.. doxygenvariable:: mdds::mtv::element_type_uint16
+.. doxygenvariable:: mdds::mtv::element_type_int32
+.. doxygenvariable:: mdds::mtv::element_type_uint32
+.. doxygenvariable:: mdds::mtv::element_type_int64
+.. doxygenvariable:: mdds::mtv::element_type_uint64
+.. doxygenvariable:: mdds::mtv::element_type_float
+.. doxygenvariable:: mdds::mtv::element_type_double
+.. doxygenvariable:: mdds::mtv::element_type_string
+
+Block Types and Traits
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. doxygentypedef:: mdds::mtv::boolean_element_block
+.. doxygentypedef:: mdds::mtv::int8_element_block
+.. doxygentypedef:: mdds::mtv::uint8_element_block
+.. doxygentypedef:: mdds::mtv::int16_element_block
+.. doxygentypedef:: mdds::mtv::uint16_element_block
+.. doxygentypedef:: mdds::mtv::int32_element_block
+.. doxygentypedef:: mdds::mtv::uint32_element_block
+.. doxygentypedef:: mdds::mtv::int64_element_block
+.. doxygentypedef:: mdds::mtv::uint64_element_block
+.. doxygentypedef:: mdds::mtv::float_element_block
+.. doxygentypedef:: mdds::mtv::double_element_block
+.. doxygentypedef:: mdds::mtv::string_element_block
+
+.. doxygenstruct:: mdds::mtv::standard_element_blocks_traits
+ :members:
+
+
+Exceptions
+----------
+
+.. doxygenclass:: mdds::mtv::element_block_error
+
+
+Macros
+------
+
+.. doxygendefine:: MDDS_MTV_DEFINE_ELEMENT_CALLBACKS
+.. doxygendefine:: MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR
+
+
+Collection
+----------
+
+.. doxygenclass:: mdds::mtv::collection
+ :members:
diff --git a/doc/multi_type_vector/examples.rst b/doc/multi_type_vector/examples.rst
new file mode 100644
index 0000000..b539eab
--- /dev/null
+++ b/doc/multi_type_vector/examples.rst
@@ -0,0 +1,929 @@
+.. highlight:: cpp
+
+Examples
+========
+
+Quick start
+-----------
+
+The following code demonstrates a simple use case of storing values of double
+and :cpp:class:`std::string` types in a single container using :cpp:type:`~mdds::multi_type_vector`.
+
+.. literalinclude:: ../../example/multi_type_vector/basic.cpp
+ :language: C++
+ :start-after: //!code-start
+ :end-before: //!code-end
+
+You'll see the following console output when you compile and execute this code:
+
+.. code-block:: none
+
+ numeric block of size 8
+ * 1.1
+ * 1.2
+ * 1.3
+ * 10.1
+ * 10.2
+ * 10.3
+ * 10.4
+ * 10.5
+ empty block of size 2
+ - no data -
+ string block of size 3
+ * Andy
+ * Bruce
+ * Charlie
+ empty block of size 7
+ - no data -
+
+.. figure:: ../_static/images/mtv-block-structure.svg
+ :align: center
+
+ Logical structure between the primary array, blocks, and element blocks.
+
+Each multi_type_vector instance maintains a logical storage structure of one
+primary array containing one or more blocks each of which consists of ``type``,
+``position``, ``size`` and ``data`` members:
+
+* ``type`` - numeric value representing the block type.
+* ``position`` - numeridc value representing the logical position of the first
+ element of the block.
+* ``size`` - number of elements present in the block a.k.a its logical size.
+* ``data`` - pointer to the secondary storage (element block) storing the element
+ values.
+
+In this example code, the ``type`` member is referenced to determine its block
+type and its logical size is determined from the ``size`` member. For the
+numeric and string blocks, their ``data`` members, which should point to the
+memory addresses of their respective element blocks, are dereferenced in order
+to print out their element values to stdout inside the ``print_block`` function.
+
+
+.. _standard-element-blocks:
+
+Standard element block types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It is worth noting that the two block types used in the previous example, namely
+:cpp:type:`~mdds::mtv::double_element_block` and :cpp:type:`~mdds::mtv::string_element_block`
+didn't come out of nowhere. By default, including the header that defines multi_type_vector
+implicitly also defines the following block types:
+
+* :cpp:type:`mdds::mtv::boolean_element_block`
+* :cpp:type:`mdds::mtv::int8_element_block`
+* :cpp:type:`mdds::mtv::uint8_element_block`
+* :cpp:type:`mdds::mtv::int16_element_block`
+* :cpp:type:`mdds::mtv::uint16_element_block`
+* :cpp:type:`mdds::mtv::int32_element_block`
+* :cpp:type:`mdds::mtv::uint32_element_block`
+* :cpp:type:`mdds::mtv::int64_element_block`
+* :cpp:type:`mdds::mtv::uint64_element_block`
+* :cpp:type:`mdds::mtv::float_element_block`
+* :cpp:type:`mdds::mtv::double_element_block`
+* :cpp:type:`mdds::mtv::string_element_block`
+
+which respectively store elements of the following value types:
+
+* ``bool``
+* ``int8_t``
+* ``uint8_t``
+* ``int16_t``
+* ``uint16_t``
+* ``int32_t``
+* ``uint32_t``
+* ``int64_t``
+* ``uint64_t``
+* ``float``
+* ``double``
+* ``std::string``
+
+The header also defines the :cpp:class:`mdds::mtv::standard_element_blocks_traits`
+struct which you can pass to the :cpp:type:`~mdds::multi_type_vector` template
+definition in order to have all of the above mentioned block types and their
+respective value types available for use.
+
+
+.. _custom-value-types:
+
+Specifying custom types in element blocks
+-----------------------------------------
+
+There are times when you need to store a set of user-defined types in :cpp:type:`~mdds::multi_type_vector`.
+That is what we are going to talk about in this section.
+
+First, let's include the header:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: header
+ :end-before: //!code-end: header
+
+then proceed to define some constant values to use as element types. We are going
+to define three custom value types, so we need three element types defined:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: element-types
+ :end-before: //!code-end: element-types
+
+Here, you need to ensure that the values used will not collide with the values
+that may be used for the standard value types. The best way to ensure that is
+to assign the values that are greater than or equal to :cpp:var:`~mdds::mtv::element_type_user_start`
+as the code above does. Values less than :cpp:var:`~mdds::mtv::element_type_user_start`
+are reserved for use either for the standard value types or any other internal uses
+in the future.
+
+Now, let's define the first two custom value types, and their respective block types:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: custom-values
+ :end-before: //!code-end: custom-values
+
+Here, we are using the :cpp:type:`~mdds::mtv::default_element_block` as the basis
+to define their block types. At minimum, you need to specify the element type constant
+and the value type as its template arguments. There is a third optional template
+argument you can specify which will become the underlying storage type. By
+default, :cpp:class:`~mdds::mtv::delayed_delete_vector` is used when the third
+argument is not given. But you can specify other types such as :cpp:type:`std::vector`
+or :cpp:type:`std::deque` instead, or any other types that have similar interfaces
+to :cpp:type:`std::vector`.
+
+Once the block types are defined, it's time to define callback functions for them.
+This should be as simple as using the :c:macro:`MDDS_MTV_DEFINE_ELEMENT_CALLBACKS` with
+all necessary parameters provided:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: custom-values-macro
+ :end-before: //!code-end: custom-values-macro
+
+Our third type is defined in a namespace ``ns``, and its associated block type is
+also defined in the same namespace. One thing to keep in mind is that, when the
+custom type is defined in a namespace, its callback functions must also be defined
+in the same namespace in order for them to be discovered per argument dependent lookup
+during overload resolution. This means that you must place the macro that defines
+the callback functions in the same namespace as the namespace that encompasses the
+original value type:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: custom-value-ns
+ :end-before: //!code-end: custom-value-ns
+
+.. warning::
+
+ If the original value type is defined inside a namespace, its associated callback
+ functions must also be defined in the same namespace, due to the way argument
+ dependent lookup works during overload resolution.
+
+The next step is to define a trait type that specifies these block types. The
+easiest way is to have your trait inherit from :cpp:struct:`mdds::mtv::default_traits`
+and overwrite the :cpp:type:`~mdds::mtv::default_traits::block_funcs` static member
+type with an instance of :cpp:type:`mdds::mtv::element_block_funcs` with one or
+more block types specified as its template arguments:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: trait
+ :end-before: //!code-end: trait
+
+Now we are ready to define the final :cpp:class:`~mdds::mtv::multi_type_vector` type
+with the trait we just defined:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: mtv-type
+ :end-before: //!code-end: mtv-type
+
+And that's it! With this in place, you can write a code like the following:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types.cpp
+ :language: C++
+ :start-after: //!code-start: main
+ :end-before: //!code-end: main
+ :dedent: 4
+
+to put some values of the custom types into your container and accessing them. This
+code should generate the following output:
+
+.. code-block:: none
+
+ is this custom_value1? 1
+ is this custom_value2? 1
+ is this ns::custom_value3? 1
+
+
+.. _custom-value-types-custom-store:
+
+Specifying different storage type
+---------------------------------
+
+By default, :cpp:class:`mdds::mtv::default_element_block` uses :cpp:class:`mdds::mtv::delayed_delete_vector`
+as its underlying storage type to store its elements starting with version 2.1. Prior to
+2.1, :cpp:class:`std::vector` was used as the only storage type of choice. If you use 2.1 or newer
+versions of the library, you can specify your own storage type as the third template argument to
+:cpp:class:`mdds::mtv::default_element_block`.
+
+Let's tweak the previous example to specify :cpp:class:`std::vector` and :cpp:class:`std::deque` as the
+storage types for ``custom_value1_block`` and ``custom_value2_block``, respectively:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: blocks-1-2
+ :end-before: //!code-end: blocks-1-2
+
+For ``custom_value3_block``, we will leave it as the default storage type, namely,
+:cpp:class:`mdds::mtv::delayed_delete_vector`:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: block-3
+ :end-before: //!code-end: block-3
+
+You can specify different storage types for different block types as you can see above. But unless you have a
+good reason to do so, you may want to stick with the same storage type for all of your blocks in order to have
+consistent performance characteristics.
+
+With this now in place, let's run the following code:
+
+.. literalinclude:: ../../example/multi_type_vector/custom_value_types_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: main
+ :end-before: //!code-end: main
+ :dedent: 4
+
+which should generate the following output:
+
+.. code-block:: none
+
+ custom_value1 stored in std::vector? 1
+ custom_value2 stored in std::deque? 1
+ ns::custom_value3 stored in delayed_delete_vector? 1
+
+One thing to note is that, in order for a class to be usable as the storage type for
+:cpp:class:`~mdds::mtv::default_element_block`, it must be a template class
+with two parameters: the first one being the value type while the second one
+is the allocator type just like how :cpp:class:`std::vector` or :cpp:class:`std::deque`
+are defined.
+
+
+Different storage types in standard element blocks
+--------------------------------------------------
+
+Now, what if you need to specify different storage types in the blocks already defined for the
+standard value types, given that, as explained in the :ref:`standard-element-blocks` section,
+those standard element blocks are automagically defined?
+
+The answer is that it is possible to do such a thing, but it will require that you follow a certain
+set of steps, as outlined below:
+
+First, manually define the element type constants, block types, and their respecitve callback functions
+for the standard value types you need to use as if they were user-defined types. When doing so, specify
+the non-default storage types you need to use for these blocks.
+
+Include the header for the multi_type_vector definition with the special macro value named
+:c:macro:`MDDS_MTV_USE_STANDARD_ELEMENT_BLOCKS` defined and its value is set to 0. This bypasses the
+automatic inclusion of the block types for the standard value types when this header is included.
+
+Lastly, define a custom trait type and overwrite the ``block_funcs`` member type to specify the block types
+defined in the first step. This is essentially the same step you would take when you define custom
+block types for user-defined value types.
+
+Let's do this step-by-step. First, include the necessary headers:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: header
+ :end-before: //!code-end: header
+
+The ``types.hpp`` header is required for the :cpp:type:`~mdds::mtv::element_t` and
+:cpp:class:`~mdds::mtv::default_element_block`, and the ``macro.hpp`` header is required
+for the :c:macro:`MDDS_MTV_DEFINE_ELEMENT_CALLBACKS` macro. The ``<deque>`` header is so
+that we can use :cpp:class:`std::deque` as storage types in our block types.
+
+Next, let's define the element and block types as well as their callback functions:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: block-defs
+ :end-before: //!code-end: block-defs
+
+This is very similar to how it is done in the :ref:`custom-value-types-custom-store` section.
+The only difference is that, this part needs to happen *before* the header for the
+multi_type_vector type gets included, in order for the multi_type_vector implementation code
+to reference the callback functions now that the callback functions for the standard value
+types will no longer be included.
+
+Let's proceed to include the multi_type_vector header:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: mtv-header
+ :end-before: //!code-end: mtv-header
+
+Here, we define the :c:macro:`MDDS_MTV_USE_STANDARD_ELEMENT_BLOCKS` macro and set its value to
+0, to skip the inclusion of the standard element blocks. It is also worth noting that we
+are including the ``mdds/multi_type_vector/soa/main.hpp`` header directly instead of
+``mdds/multi_type_vector.hpp``, which indirectly includes the first header.
+
+Lastly, let's define the trait type to specify the block types to use, and instantiate the final
+multi_type_vector type:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: mtv-def
+ :end-before: //!code-end: mtv-def
+
+Now that the concrete multi_type_vector is defined, we can use it to store some values of the
+specified types:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: main
+ :end-before: //!code-end: main
+ :dedent: 4
+
+If you inspect the storage types of the element blocks like the following:
+
+.. literalinclude:: ../../example/multi_type_vector/standard_custom_store.cpp
+ :language: C++
+ :start-after: //!code-start: main-block-type
+ :end-before: //!code-end: main-block-type
+ :dedent: 4
+
+you should see the following output:
+
+.. code-block:: none
+
+ my_double_block: is std::deque its store type? 1
+ my_int32_block: is std::deque its store type? 1
+
+which indicates that they are indeed :cpp:class:`std::deque`.
+
+Use custom event handlers
+-------------------------
+
+It is also possible to define custom event handlers that get called when
+certain events take place. To define custom event handlers, you need to
+define either a class or a struct that has the following methods:
+
+* **void element_block_acquired(mdds::mtv::base_element_block* block)**
+* **void element_block_released(mdds::mtv::base_element_block* block)**
+
+as its public methods, specify it as type named ``event_func`` in a trait struct,
+and pass it as the second template argument when instantiating your
+:cpp:type:`~mdds::multi_type_vector` type. Refer to :cpp:type:`mdds::mtv::empty_event_func`
+for the detail on when each event handler method gets triggered.
+
+The following code example demonstrates how this all works:
+
+.. literalinclude:: ../../example/multi_type_vector/event1.cpp
+ :language: C++
+ :start-after: //!code-start
+ :end-before: //!code-end
+
+You'll see the following console output when you compile and execute this code:
+
+.. code-block:: none
+
+ inserting string 'foo'...
+ * element block acquired
+ inserting string 'bah'...
+ inserting int 100...
+ * element block acquired
+ emptying the container...
+ * element block released
+ * element block released
+ exiting program...
+
+In this example, the **element_block_acquired** handler gets triggered each
+time the container creates (thus acquires) a new element block to store a value.
+It does *not* get called when a new value is appended to a pre-existing element
+block. Similarly, the **element_block_releasd** handler gets triggered each
+time an existing element block storing non-empty values gets deleted. One
+thing to keep in mind is that since these two handlers respond to events related
+to element blocks which are owned by non-empty blocks in the primary array,
+and empty blocks don't store any element block instances, creations or deletions
+of empty blocks don't trigger these event handlers.
+
+The trait also allows you to configure other behaviors of :cpp:type:`~mdds::multi_type_vector`.
+Refer to :cpp:type:`mdds::mtv::default_traits` for all available parameters.
+
+
+Get raw pointer to element block array
+--------------------------------------
+
+Sometimes you need to expose a pointer to an element block array especially
+when you need to pass such an array pointer to C API that requires one. You
+can do this by calling the ``data`` method of the element_block template
+class. This works since the element block internally just wraps
+:cpp:class:`std::vector` or one that acts like it, such as
+:cpp:class:`std::deque` or :cpp:class:`~mdds::mtv::delayed_delete_vector`, and
+its ``data`` method simply exposes the internal storage types's own ``data``
+method which returns the memory location of its internal buffer.
+
+The following code demonstrates this by exposing raw array pointers to the
+internal arrays of numeric and string element blocks, and printing their
+element values directly from these array pointers.
+
+.. literalinclude:: ../../example/multi_type_vector/element_block1.cpp
+ :language: C++
+ :start-after: //!code-start
+ :end-before: //!code-end
+
+Compiling and execute this code produces the following output:
+
+.. code-block:: none
+
+ block size: 2
+ --
+ 1.1
+ 1.2
+ 1.3
+ 1.4
+ 1.5
+ --
+ A
+ B
+ C
+ D
+ E
+
+
+Traverse multiple multi_type_vector instances "sideways"
+--------------------------------------------------------
+
+In this section we will demonstrate a way to traverse multiple instances of
+:cpp:type:`~mdds::multi_type_vector` "sideways" using the
+:cpp:class:`mdds::mtv::collection` class. What this class does is to wrap
+multiple instances of :cpp:type:`~mdds::multi_type_vector` and generate
+iterators that let you iterate the individual element values collectively in
+the direction orthogonal to the direction of the individual vector instances.
+
+The best way to explain this feature is to use a spreadsheet analogy. Let's
+say we are implementing a data store to store a 2-dimensional tabular data
+where each cell in the data set is associated with row and column indices.
+Each cell may store a value of string type, integer type, numeric type, etc.
+And let's say that the data looks like the following spreadsheet data:
+
+.. figure:: ../_static/images/mtv_collection_sheet.png
+ :align: center
+
+It consists of five columns, with each column storing 21 rows of data. The
+first row is a header row, followed by 20 rows of values. In this example, We
+will be using one :cpp:type:`~mdds::multi_type_vector` instance for each
+column thus creating five instances in total, and store them in a
+``std::vector`` container.
+
+The declaration of the data store will look like this:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: declare
+ :end-before: //!code-end: declare
+ :dedent: 4
+
+The first two lines specify the concrete :cpp:type:`~mdds::multi_type_vector`
+type used for each individual column and the collection type that wraps the
+columns. The third line instantiates the ``std::vector`` instance to store
+the columns, and we are setting its size to five to accommodate for five
+columns. We will make use of the collection_type later in this example after
+the columns have been populated.
+
+Now, we need to populate the columns with values. First, we are setting the
+header row:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: header-row
+ :end-before: //!code-end: header-row
+ :dedent: 4
+
+We are then filling each column individually from column 1 through column 5.
+First up is column 1:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: column-1
+ :end-before: //!code-end: column-1
+ :dedent: 4
+
+Hopefully this code is straight-forward. It initializes an array of values
+and push them to the column one at a time via
+:cpp:func:`~mdds::mtv::soa::multi_type_vector::push_back`. Next up is column 2:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: column-2
+ :end-before: //!code-end: column-2
+ :dedent: 4
+
+This is similar to the code for column 1, except that because we are using an
+array of string literals which implicitly becomes an initializer list of type
+``const char*``, we need to explicitly specify the type for the
+:cpp:func:`~mdds::mtv::soa::multi_type_vector::push_back` call to be ``std::string``.
+
+The code for column 3 is very similar to this:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: column-3
+ :end-before: //!code-end: column-3
+ :dedent: 4
+
+Populating column 4 needs slight pre-processing. We are inserting a string
+value of "unknown" in lieu of an integer value of -1. Therefore the following
+code will do:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: column-4
+ :end-before: //!code-end: column-4
+ :dedent: 4
+
+Finally, the last column to fill, which uses the same logic as for columns 2
+and 3:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: column-5
+ :end-before: //!code-end: column-5
+ :dedent: 4
+
+At this point, the content we've put into the ``columns`` variable roughly
+reflects the tabular data shown at the beginning of this section. Now we can
+use the collection type we've declared earlier to wrap the columns:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: wrap
+ :end-before: //!code-end: wrap
+ :dedent: 4
+
+We are naming this variable ``rows`` since what we are doing with this wrapper
+is to traverse the content of the tabular data in row-wise direction. For
+this reason, calling it ``rows`` is quite fitting.
+
+The :cpp:class:`~mdds::mtv::collection` class offers some flexibility as to
+how the instances that you are trying to traverse orthogonally are stored.
+That being said, you must meet the following prerequisites when passing the
+collection of vector instances to the constructor of the
+:cpp:class:`~mdds::mtv::collection` class:
+
+1. All :cpp:type:`~mdds::multi_type_vector` instances that comprise the
+ collection must be of the same logical length i.e. their
+ :cpp:func:`~mdds::mtv::soa::multi_type_vector::size` methods must all return the same
+ value.
+2. The instances in the collection must be stored in the source container
+ either as
+
+ * concrete instances (as in this example),
+ * as pointers, or
+ * as heap instances wrapped within smart pointer class such as
+ ``std::shared_ptr`` or ``std::unique_ptr``.
+
+Although we are storing the vector instances in a ``std::vector`` container in
+this example, you have the flexibility to pick a different type of container
+to store the individual vector instances as long as it provides STL-compatible
+standard iterator functionality.
+
+Additionally, when using the :cpp:class:`~mdds::mtv::collection` class, you
+must ensure that the content of the vector instances that it references will
+not change for the duration of its use.
+
+Finally, here is the code that does the traversing:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: traverse-row
+ :end-before: //!code-end: traverse-row
+ :dedent: 4
+
+It's a simple for-loop, and in each iteration you get a single cell node that
+contains metadata about that cell including its value. The node contains the
+following members:
+
+* ``type`` - an integer value representing the type of the value.
+* ``index`` - a 0-based index of the :cpp:type:`~mdds::multi_type_vector`
+ instance within the collection. You can think of this as column index in
+ this example.
+* ``position`` - a 0-based logical element position within each
+ :cpp:type:`~mdds::multi_type_vector` instance. You can think of this as
+ row index in this example.
+
+In the current example we are only making use of the ``type`` and ``index``
+members, but the ``position`` member will be there if you need it.
+
+The node also provides a convenient ``get()`` method to fetch the value of the
+cell. This method is a template method, and you need to explicitly specify
+the element block type in order to access the value.
+
+When executing this code, you will see the following outout:
+
+.. code-block:: none
+
+ ID | Make | Model | Year | Color
+ 1 | Nissan | Frontier | 1998 | Turquoise
+ 2 | Mercedes-Benz | W201 | 1986 | Fuscia
+ 3 | Nissan | Frontier | 2009 | Teal
+ 4 | Suzuki | Equator | unknown | Fuscia
+ 5 | Saab | 9-5 | unknown | Green
+ 6 | Subaru | Tribeca | 2008 | Khaki
+ 7 | GMC | Yukon XL 2500 | 2009 | Pink
+ 8 | Mercedes-Benz | E-Class | 2008 | Goldenrod
+ 9 | Toyota | Camry Hybrid | 2010 | Turquoise
+ 10 | Nissan | Frontier | 2001 | Yellow
+ 11 | Mazda | MX-5 | 2008 | Orange
+ 12 | Dodge | Ram Van 1500 | 2000 | Goldenrod
+ 13 | Ford | Edge | unknown | Fuscia
+ 14 | Bentley | Azure | 2009 | Goldenrod
+ 15 | GMC | Sonoma Club Coupe | 1998 | Mauv
+ 16 | Audi | S4 | 2013 | Crimson
+ 17 | GMC | 3500 Club Coupe | 1994 | Turquoise
+ 18 | Mercury | Villager | 2000 | Teal
+ 19 | Pontiac | Sunbird | 1990 | Indigo
+ 20 | BMW | 3 Series | 1993 | LKhaki
+
+which clearly shows that the code has traversed the content of the tabular
+data horizontally across columns as intended.
+
+Now, one feature that may come in handy is the ability to limit the iteration
+range within the collection. You can do that by calling either
+:cpp:func:`~mdds::mtv::collection::set_collection_range` to limit the column
+range or :cpp:func:`~mdds::mtv::collection::set_element_range` to limit the
+row range, or perhaps both.
+
+Let's see how this works in the current example. Here, we are going to limit
+the iteration range to only columns 2 and 3, and rows 2 through 11. The following
+code will set this limit:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: limit-range
+ :end-before: //!code-end: limit-range
+ :dedent: 4
+
+Then iterate through the collection once again:
+
+.. literalinclude:: ../../example/multi_type_vector/mtv_collection.cpp
+ :language: C++
+ :start-after: //!code-start: traverse-row-range
+ :end-before: //!code-end: traverse-row-range
+ :dedent: 4
+
+This code is nearly identical to the previous one except for the index values
+used to control when to insert column separators and line breaks at the top
+and bottom of each iteration. When executing this code, you'll see the
+following output:
+
+.. code-block:: none
+
+ Nissan | Frontier
+ Mercedes-Benz | W201
+ Nissan | Frontier
+ Suzuki | Equator
+ Saab | 9-5
+ Subaru | Tribeca
+ GMC | Yukon XL 2500
+ Mercedes-Benz | E-Class
+ Toyota | Camry Hybrid
+ Nissan | Frontier
+
+which clearly shows that your iteration range did indeed shrink as expected.
+
+
+Performance Considerations
+==========================
+
+Select SoA or AoS storage types
+-------------------------------
+
+If you instantiate a multi_type_vector instance via
+:cpp:type:`mdds::multi_type_vector`, which is an alias type for
+:cpp:class:`mdds::mtv::soa::multi_type_vector`, you will be using the
+structure-of-arrays (SoA) variant of its implementation which is new in 2.0.
+Prior to 2.0, multi_type_vector used the array-of-structures (AoS) layout which
+is still available post 2.0 via :cpp:class:`mdds::mtv::aos::multi_type_vector`
+in case you need it.
+
+Note, however, that the SoA variant generally yields better overall performance
+since it can make more efficient use of CPU caches. It is therefore highly
+recommended that you stick with the SoA variant unless you have a specific
+reason not to.
+
+Also note that both variants are API compatibile with each other.
+
+
+Use of position hints to avoid the cost of block position lookup
+----------------------------------------------------------------
+
+Consider the following example code:
+
+.. literalinclude:: ../../example/multi_type_vector/pos_hint.cpp
+ :language: C++
+ :start-after: //!code-start: no-pos-hint
+ :end-before: //!code-end: no-pos-hint
+ :dedent: 4
+
+which, when executed, may take quite sometime to complete especially when you
+are using an older version of mdds. This particular example exposes one
+weakness that multi_type_vector has; because it needs to first look up the
+position of the block to operate with, and that lookup *always* starts from the
+first block, the time it takes to find the correct block increases as the number
+of blocks goes up. This example demonstrates the worst case scenario of such
+lookup complexity since it always inserts the next value at the last block
+position.
+
+Fortunately, there is a simple solution to this which the following code
+demonstrates:
+
+.. literalinclude:: ../../example/multi_type_vector/pos_hint.cpp
+ :language: C++
+ :start-after: //!code-start: pos-hint
+ :end-before: //!code-end: pos-hint
+ :dedent: 4
+
+Compiling and executing this code should take only a fraction of a second.
+
+The only difference between the second example and the first one is that the
+second one uses an interator as a position hint to keep track of the position of
+the last modified block. Each
+:cpp:func:`~mdds::mtv::soa::multi_type_vector::set` method call returns an
+iterator which can then be passed to the next
+:cpp:func:`~mdds::mtv::soa::multi_type_vector::set` call as the position hint.
+Because an iterator object internally stores the location of the block the value
+was inserted to, this lets the method to start the block position lookup process
+from the last modified block, which in this example is always one block behind
+the one the new value needs to go. Using the big-O notation, the use of the
+position hint essentially turns the complexity of O(n^2) in the first example
+into O(1) in the second one if you are using an older version of mdds where the
+block position lookup had a linear complexity.
+
+This strategy should work with any methods in :cpp:type:`~mdds::multi_type_vector`
+that take a position hint as the first argument.
+
+Note that, if you are using a more recent version of mdds (1.6.0 or newer), the
+cost of block position lookup is significantly lessoned thanks to the switch to
+binary search in performing the lookup.
+
+.. note::
+
+ If you are using mdds 1.6.0 or newer, the cost of block position lookup is
+ much less significant even without the use of position hints. But the benefit
+ of using position hints may still be there. It's always a good idea to profile
+ your specific use case and decide whether the use of position hints is worth
+ it.
+
+One important thing to note is that, as a user, you must ensure that the position
+hint you pass stays valid between the calls. A position hint becomes invalid when
+the content of the container changes. A good strategy to maintain a valid position
+hint is to always receive the iterator returned from the mutator method you called
+to which you passed the previous position hint, which is what the code above does.
+Passing an invalid position hint to a method that takes one may result in invalid
+memory access or otherwise in some sort of undefined behavior.
+
+.. warning::
+
+ You must ensure that the position hint you pass stays valid. Passing an invalid
+ position hint to a method that takes one may result in invalid memory access
+ or otherwise in some sort of undefined behavior.
+
+
+Block shifting performance and loop-unrolling factor
+----------------------------------------------------
+
+The introduction of binary search in the block position lookup implementation
+in version 1.6 has significantly improved its lookup performance, but has
+also resulted in slight performance hit when shifting blocks during value
+insertion. This is because when shifting the logical positions of the blocks
+below the insertion point, their head positions need to be re-calculated to
+account for their new positions.
+
+The good news is that the switch to the structure-of-arrays (SoA) storage
+layout in 2.0 alone may bring subtle but measurable improvement in the
+block position adjustment performance due to the logical block positions now
+being stored in a separate array thereby improving its cache efficiency. In
+reality, however, this was somewhat dependent on the CPU types since some CPU's
+didn't show any noticeable improvements or even showed worse performance, while
+other CPU types showed consistent improvements with SoA over AoS.
+
+Another factor that may play a role is `loop unrolling <https://en.wikipedia.org/wiki/Loop_unrolling>`_
+factor which can be configured via the :cpp:var:`~mdds::mtv::default_traits::loop_unrolling`
+variable in your custom trait type if you use version 2.0 or newer. This variable
+is an enum class of type :cpp:type:`mdds::mtv::lu_factor_t` which enumerates
+several pre-defined loop-unrolling factors as well as some SIMD features.
+
+The hardest part is to figure out which loop unrolling factor is the best option
+in your runtime environment, since it is highly dependent on the environment.
+Luckily mdds comes with a tool called `runtime-env <https://gitlab.com/mdds/mdds/-/tree/master/tools/runtime-env>`_
+which, when run, will perform some benchmarks and give you the best loop-unrolling
+factor in your runtime environment. Be sure to build this tool with the same
+compiler and compiler flags as your target program in order for this tool to give
+you a representative answer.
+
+
+Debugging
+=========
+
+Tracing of public methods
+-------------------------
+
+When using :cpp:class:`~mdds::mtv::soa::multi_type_vector` to handle a series
+of data reads and writes in an non-trivial code base, sometimes you may find
+yourself needing to track which methods are getting called when following a
+certain code path during a debugging session. In such a situation, you can enable
+an optional trace method which gets called whenever a public method of :cpp:class:`~mdds::mtv::soa::multi_type_vector`
+is called.
+
+First, you need to define a preprocessor macro named
+``MDDS_MULTI_TYPE_VECTOR_DEBUG`` before including the header for
+:cpp:class:`~mdds::mtv::soa::multi_type_vector`:
+
+.. literalinclude:: ../../example/multi_type_vector/debug_trace.cpp
+ :language: C++
+ :start-after: //!code-start: header
+ :end-before: //!code-end: header
+
+to enable additional debug code. In this example the value of the macro is
+set to 1, but it doesn't matter what the value of the macro is, as long as it
+is defined. You can also define one as a compiler option as well.
+
+Once defined, the next step is to add a ``trace`` method as a static function to
+the trait type you pass as a template argument of multi_type_vector:
+
+.. literalinclude:: ../../example/multi_type_vector/debug_trace.cpp
+ :language: C++
+ :start-after: //!code-start: types
+ :end-before: //!code-end: types
+
+Here, we are simply inheriting our trait type from the
+:cpp:class:`~mdds::mtv::default_traits` type and simply adding a static ``trace``
+function to it, and passing this trait type to the mtv_type definition below.
+This trace function must take one argument of type
+:cpp:class:`mdds::mtv::trace_method_properties_t` which includes various
+properties of the traced call. In this example, we are simply printing the
+properties named
+:cpp:member:`~mdds::mtv::trace_method_properties_t::function_name` and
+:cpp:member:`~mdds::mtv::trace_method_properties_t::function_args` each time a
+traced method is called. Both of these properties are printable string types.
+
+Note that this ``trace`` function is entirely optional; the code will compile
+fine even when it's not defined. Also, it must be declared as static for it to
+be called.
+
+Let's instantiate an object of ``mtv_type``, call some of its methods and see
+what happens. When executing the following code:
+
+.. literalinclude:: ../../example/multi_type_vector/debug_trace.cpp
+ :language: C++
+ :start-after: //!code-start: main
+ :end-before: //!code-end: main
+ :dedent: 4
+
+You will see the following output:
+
+.. code-block:: text
+
+ function:
+ name: multi_type_vector
+ args: init_size=10
+ function:
+ name: set
+ args: pos=0; value=? (type=5)
+ function:
+ name: set
+ args: pos=2; value=? (type=1)
+ function:
+ name: set
+ args: pos=4; value=? (type=3)
+ function:
+ name: ~multi_type_vector
+ args:
+
+The :cpp:member:`~mdds::mtv::trace_method_properties_t::function_name`
+property is hopefully self-explanatory. The
+:cpp:member:`~mdds::mtv::trace_method_properties_t::function_args` property is
+a single string value containing the information about the function's
+arguments and optionally their values if their values are known to be
+printable. If the value of an argument cannot be printed, ``?`` is placed
+instead. For some argument types, an additional information is displayed e.g.
+``(type=5)`` in the above output which indicates that the type of the value
+being passed to the function is :cpp:var:`~mdds::mtv::element_type_int32`.
+
+If you want to limit your tracing to a specific function type or types, you
+can make use of the :cpp:member:`~mdds::mtv::trace_method_properties_t::type`
+property which specifies the type of the traced method. Likewise, if you want
+to only trace methods of a certain instance, use
+:cpp:member:`~mdds::mtv::trace_method_properties_t::instance` to filter the
+incoming trace calls based on the memory addresses of the instances whose
+methods are being traced.
+
+Note that this feature is available for version 2.0.2 and newer, and currently
+only available for the SoA variant of :cpp:class:`~mdds::mtv::soa::multi_type_vector`.
+
+.. note::
+
+ This feature is only available for version 2.0.2 and newer, and only for the
+ SoA variant.
+
diff --git a/doc/multi_type_vector/index.rst b/doc/multi_type_vector/index.rst
new file mode 100644
index 0000000..382c69d
--- /dev/null
+++ b/doc/multi_type_vector/index.rst
@@ -0,0 +1,10 @@
+.. highlight:: cpp
+
+Multi Type Vector
+=================
+
+.. toctree::
+ :maxdepth: 1
+
+ examples.rst
+ api-ref.rst
diff --git a/doc/point_quad_tree.rst b/doc/point_quad_tree.rst
new file mode 100644
index 0000000..058051c
--- /dev/null
+++ b/doc/point_quad_tree.rst
@@ -0,0 +1,10 @@
+.. highlight:: cpp
+
+Point Quad Tree
+===============
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::point_quad_tree
+ :members:
diff --git a/doc/rtree.rst b/doc/rtree.rst
new file mode 100644
index 0000000..4f691e2
--- /dev/null
+++ b/doc/rtree.rst
@@ -0,0 +1,727 @@
+
+.. highlight:: cpp
+
+R-tree
+======
+
+Overview
+--------
+
+`R-tree <https://en.wikipedia.org/wiki/R-tree>`_ is a tree-based data
+structure designed for optimal query performance on multi-dimensional spatial
+objects with rectangular bounding shapes. The R-tree implementation included
+in this library is a variant of R-tree known as `R*-tree
+<https://en.wikipedia.org/wiki/R*_tree>`_ which differs from the original
+R-tree in that it may re-insert an object if the insertion of that object
+would cause the original target directory to overflow. Such re-insertions
+lead to more balanced tree which in turn lead to better query performance, at
+the expense of slightly more overhead at insertion time.
+
+Our implementation of R-tree theoretically supports any number of dimensions
+although certain functionalities, especially those related to visualization,
+are only supported for 2-dimensional instances.
+
+R-tree consists of three types of nodes. Value nodes store the values
+inserted externally and always sit at the bottom of the tree. Leaf directory
+nodes sit directly above the value nodes, and store only value nodes as their
+child nodes. The rest are all non-leaf directory nodes which can either store
+leaf or non-leaf directory nodes.
+
+
+Quick start
+-----------
+
+Let's go through a very simple example to demonstrate how to use
+:cpp:class:`~mdds::rtree`. First, you need to specify a concrete type by
+specifying the key type and value type to use::
+
+ #include <mdds/rtree.hpp>
+
+ #include <string>
+ #include <iostream>
+
+ // key values are of type double, and we are storing std::string as a
+ // value for each spatial object. By default, tree becomes 2-dimensional
+ // object store unless otherwise specified.
+ using rt_type = mdds::rtree<double, std::string>;
+
+You'll only need to specify the types of key and value here unless you want to
+customize other properties of :cpp:class:`~mdds::rtree` including the number
+of dimensions. By default, :cpp:class:`~mdds::rtree` sets the number of
+dimensions to 2.
+
+::
+
+ rt_type tree;
+
+Instantiating an rtree instance should be no brainer as it requires no input
+parameters. Now, let's insert some data::
+
+ tree.insert({{0.0, 0.0}, {15.0, 20.0}}, "first rectangle data");
+
+This inserts a string value associated with a bounding rectangle of (0, 0) -
+(15, 20). Note that in the above code we are passing the bounding rectangle
+parameter to rtree's :cpp:func:`~mdds::rtree::insert` method as a nested
+initializer list, which implicitly gets converted to
+:cpp:class:`~mdds::rtree::extent_type`. You can also use the underlying type
+directly as follows::
+
+ rt_type::extent_type bounds({-2.0, -1.0}, {1.0, 2.0});
+ std::cout << "inserting value for " << bounds.to_string() << std::endl;
+ tree.insert(bounds, "second rectangle data");
+
+which inserts a string value associated with a bounding rectangle of (-2, -1)
+to (1, 2). You may have noticed that this code also uses extent_type's
+:cpp:func:`~mdds::rtree::extent_type::to_string` method which returns a string
+representation of the bounding rectangle. This may come in handy when
+debugging your code. This method should work as long as the key type used in
+your rtree class overloads ``std::ostream``'s ``<<`` operator function.
+
+Running this code will generate the following output:
+
+.. code-block:: none
+
+ inserting value for (-2, -1) - (1, 2)
+
+As :cpp:class:`~mdds::rtree::extent_type` consists of two members called
+``start`` and ``end`` both of which are of type
+:cpp:class:`~mdds::rtree::point_type`, which in turn contains an array of keys
+called ``d`` whose size equals the number of dimensions, you can modify the
+extent directly::
+
+ bounds.start.d[0] = -1.0; // Change the first dimension value of the start rectangle point.
+ bounds.end.d[1] += 1.0; // Increment the second dimension value of the end rectangle point.
+ std::cout << "inserting value for " << bounds.to_string() << std::endl;
+ tree.insert(bounds, "third rectangle data");
+
+This code will insert a string value associated with a rectangle of (-1, -1)
+to (1, 3), and will generate the following output:
+
+.. code-block:: none
+
+ inserting value for (-1, -1) - (1, 3)
+
+So far we have only inserted data associated with rectangle shapes, but
+:cpp:class:`~mdds::rtree` also allows data associated with points to co-exist
+in the same tree. The following code inserts a string value associated with a
+point (5, 6)::
+
+ tree.insert({5.0, 6.0}, "first point data");
+
+Like the verfy first rectangle data we've inserted, we are passing the point
+data as an initializer list of two elements (for 2-dimensional data storage),
+which will implicitly get converted to :cpp:class:`~mdds::rtree::point_type`
+before it enters into the call.
+
+Now that some data have been inserted, it's time to run some queries. Let's
+query all objects that overlap with a certain rectangular region either
+partially or fully. The following code will do just that::
+
+ // Search for all objects that overlap with a (4, 4) - (7, 7) rectangle.
+ auto results = tree.search({{4.0, 4.0}, {7.0, 7.0}}, rt_type::search_type::overlap);
+
+ for (const std::string& v : results)
+ std::cout << "value: " << v << std::endl;
+
+In this query, we are specifying the search region to be (4, 4) to (7, 7)
+which should overlap with the first rectangle data and the first point data.
+Indeed, when you execute this code, you will see the following output:
+
+.. code-block:: none
+
+ value: first rectangle data
+ value: first point data
+
+indicating that the query region does overlap with two of the stored values
+
+Note that the :cpp:func:`~mdds::rtree::search` method takes exactly two
+arguments; the first one specifies the search region while the second two
+specifies the type of search to be performed. In the above call we passed
+:cpp:type:`~mdds::detail::rtree::search_type`'s ``overlap`` enum value which
+picks up all values whose bounding rectangles overlap with the search region
+either partially or fully.
+
+Sometimes, however, you may need to find a value whose bounding rectangle
+matches exactly the search region you specify in your query. You can achieve
+that by setting the search type to ``match``.
+
+Here is an example::
+
+ // Search for all objects whose bounding rectangles are exactly (4, 4) - (7, 7).
+ auto results = tree.search({{4.0, 4.0}, {7.0, 7.0}}, rt_type::search_type::match);
+ std::cout << "number of results: " << std::distance(results.begin(), results.end()) << std::endl;
+
+The search region is identical to that of the previous example, but the search
+type is set to ``match`` instead. Then the next line will count the number of
+results and print it out. The output you will see is as follows:
+
+.. code-block:: none
+
+ number of results: 0
+
+indicating that the results are empty. That is expected since none of the
+objects stored in the tree have an exact bounding rectangle of (4, 4) - (7,
+7). When you change the search region to (0, 0) - (15, 20), however, you'll
+get one object back. Here is the actual code::
+
+ // Search for all objects whose bounding rectangles are exactly (0, 0) - (15, 20).
+ auto results = tree.search({{0.0, 0.0}, {15.0, 20.0}}, rt_type::search_type::match);
+ std::cout << "number of results: " << std::distance(results.begin(), results.end()) << std::endl;
+
+which is identical to the previous one except for the search resion. This is
+its output:
+
+.. code-block:: none
+
+ number of results: 1
+
+indicating that it has found exactly one object whose bounding rectangle
+exactly matches the search region.
+
+It's worth mentioning that :cpp:class:`~mdds::rtree` supports storage of
+multiple objects with identical bounding rectangle. As such, searching with
+the search type of ``match`` can return more than one result.
+
+As you may have noticed in these example codes, the
+:cpp:class:`~mdds::rtree::search_results` object does provide
+:cpp:func:`~mdds::rtree::search_results::begin` and
+:cpp:func:`~mdds::rtree::search_results::end` methods that return standard
+iterators which you can plug into various iterator algorithms from the STL.
+Dereferencing the iterator will return a reference to the stored value i.e.
+this line::
+
+ std::cout << "value: " << *results.begin() << std::endl;
+
+which immediately comes after the previous search will output:
+
+.. code-block:: none
+
+ value: first rectangle data
+
+In addition to accessing the value that the iterator references, you can also
+query from the same iterator object the bounding rectangle associated with the
+value as well as its depth in the tree by calling its
+:cpp:func:`~mdds::rtree::iterator_base::extent` and
+:cpp:func:`~mdds::rtree::iterator_base::depth` methods, respectively, as in
+the following code::
+
+ auto it = results.begin();
+ std::cout << "value: " << *it << std::endl;
+ std::cout << "extent: " << it.extent().to_string() << std::endl;
+ std::cout << "depth: " << it.depth() << std::endl;
+
+Running this code will produce the following output:
+
+.. code-block:: none
+
+ value: first rectangle data
+ extent: (0, 0) - (15, 20)
+ depth: 1
+
+A depth value represents the distance of the node where the value is stored
+from the root node of the tree, and is technically 0-based. However, you will
+never see a depth of 0 in the search results since the root node of a R-tree
+is always a directory node, and a directory node only stores other child nodes
+and never a value (hence never appears in the search results).
+
+
+Removing a value from tree
+--------------------------
+
+Removing an existing value from the tree first requires you to perform the
+search to obtian search results, then from the search results get the iterator
+and advance it to the position of the value you wish to remove. Once you have
+your iterator set to the right position, pass it to the
+:cpp:func:`~mdds::rtree::erase` method to remove that value.
+
+Note that you can only remove one value at a time, and the iterator becomes
+invalid each time you call the :cpp:func:`~mdds::rtree::erase` method to
+remove a value.
+
+Here is a contrived example to demonstrate how erasing a value works::
+
+ #include <mdds/rtree.hpp>
+
+ #include <string>
+ #include <iostream>
+
+ int main()
+ {
+ using rt_type = mdds::rtree<int, std::string>;
+
+ rt_type tree;
+
+ // Insert multiple values at the same point.
+ tree.insert({1, 1}, "A");
+ tree.insert({1, 1}, "B");
+ tree.insert({1, 1}, "C");
+ tree.insert({1, 1}, "D");
+ tree.insert({1, 1}, "E");
+
+ // This should return all five values.
+ auto results = tree.search({1, 1}, rt_type::search_type::match);
+
+ for (const std::string& v : results)
+ std::cout << v << std::endl;
+
+ // Erase "C".
+ for (auto it = results.begin(); it != results.end(); ++it)
+ {
+ if (*it == "C")
+ {
+ tree.erase(it);
+ break; // This invalidates the iterator. Bail out.
+ }
+ }
+
+ std::cout << "'C' has been erased." << std::endl;
+
+ // Now this should only return A, B, D and E.
+ results = tree.search({1, 1}, rt_type::search_type::match);
+
+ for (const std::string& v : results)
+ std::cout << v << std::endl;
+
+ return EXIT_SUCCESS;
+ }
+
+In this code, we are intentionally putting 5 values to the same 2-dimensional
+point (1, 1), then removing one of them based on matching criteria (of being
+equal to "C").
+
+Compiling and running this code will generate the following output:
+
+.. code-block:: none
+
+ A
+ B
+ C
+ D
+ E
+ 'C' has been erased.
+ A
+ B
+ D
+ E
+
+which clearly shows that the 'C' has been successfully erased.
+
+
+Visualize R-tree structure
+--------------------------
+
+In this section we will illustrate a way to visualize an R-tree structure via
+:cpp:func:`~mdds::rtree::export_tree` method, which can be useful when you
+need to visually inspect the tree structure to see how well balanced it is (or
+not).
+
+We will be using the following set of 2-dimensional rectangles as the bounding
+rectangles for input values.
+
+.. figure:: _static/images/rtree_bounds_src.png
+ :align: center
+
+For input values, we'll simply use linearly increasing series of integer
+values, but the values themselves are not the focus of this section, and we'll
+not talk much about that. We will also intentionally make the capacity of
+directory nodes smaller so that the tree will split more frequently during
+insertion even for smaller number of inputs.
+
+Now, let's take a look at the code::
+
+ #include <mdds/rtree.hpp>
+
+ #include <iostream>
+ #include <fstream>
+
+ // Make the node capacity intentionally small.
+ struct tiny_trait_2d
+ {
+ constexpr static size_t dimensions = 2;
+ constexpr static size_t min_node_size = 2;
+ constexpr static size_t max_node_size = 5;
+ constexpr static size_t max_tree_depth = 100;
+
+ constexpr static bool enable_forced_reinsertion = true;
+ constexpr static size_t reinsertion_size = 2;
+ };
+
+ using rt_type = mdds::rtree<int, int, tiny_trait_2d>;
+
+ int main()
+ {
+ // 2D rectangle with the top-left position (x, y), width and height.
+ struct rect
+ {
+ int x;
+ int y;
+ int w;
+ int h;
+ };
+
+ std::vector<rect> rects =
+ {
+ { 3731, 2433, 1356, 937 },
+ { 6003, 3172, 1066, 743 },
+ { 4119, 6403, 825, 1949 },
+ { 10305, 2315, 776, 548 },
+ { 13930, 5468, 1742, 626 },
+ { 8614, 4107, 2709, 1793 },
+ { 14606, 1887, 5368, 1326 },
+ { 17990, 5196, 1163, 1911 },
+ { 6728, 7881, 3676, 1210 },
+ { 14704, 9789, 5271, 1092 },
+ { 4071, 10723, 4739, 898 },
+ { 11755, 9010, 1357, 2806 },
+ { 13978, 4068, 776, 509 },
+ { 17507, 3717, 777, 471 },
+ { 20358, 6092, 824, 1093 },
+ { 6390, 4535, 1066, 1715 },
+ { 13978, 7182, 2516, 1365 },
+ { 17942, 11580, 2854, 665 },
+ { 9919, 10450, 873, 1716 },
+ { 5568, 13215, 7446, 509 },
+ { 7357, 15277, 3145, 3234 },
+ { 3539, 12592, 631, 509 },
+ { 4747, 14498, 825, 626 },
+ { 4554, 16913, 969, 1443 },
+ { 12771, 14693, 2323, 548 },
+ { 18714, 8193, 2372, 586 },
+ { 22292, 2743, 487, 1638 },
+ { 20987, 17535, 1163, 1249 },
+ { 19536, 18859, 632, 431 },
+ { 19778, 15394, 1356, 626 },
+ { 22969, 15394, 631, 2066 },
+ };
+
+ rt_type tree;
+
+ // Insert the rectangle objects into the tree.
+ int value = 0;
+ for (const auto& rect : rects)
+ tree.insert({{rect.x, rect.y}, {rect.x + rect.w, rect.y + rect.h}}, value++);
+
+ // Export the tree structure as a SVG for visualization.
+ std::string tree_svg = tree.export_tree(rt_type::export_tree_type::extent_as_svg);
+ std::ofstream fout("bounds.svg");
+ fout << tree_svg;
+
+ return EXIT_SUCCESS;
+ }
+
+First, we need to talk about how the concrete rtree type is instantiated::
+
+ // Make the node capacity intentionally small.
+ struct tiny_trait_2d
+ {
+ constexpr static size_t dimensions = 2;
+ constexpr static size_t min_node_size = 2;
+ constexpr static size_t max_node_size = 5;
+ constexpr static size_t max_tree_depth = 100;
+
+ constexpr static bool enable_forced_reinsertion = true;
+ constexpr static size_t reinsertion_size = 2;
+ };
+
+ using rt_type = mdds::rtree<int, int, tiny_trait_2d>;
+
+The first and second template arguments specify the key and value types to be
+both ``int``. This time around, however, we are passing a third template
+argument which is a struct containing several static constant values. These
+constant values define certain characteristics of your R-tree, and there are
+some restrictions you need to be aware of in case you need to use your own
+custom trait for your R-tree. Refer to
+:cpp:class:`~mdds::detail::rtree::default_rtree_traits`, which is the default
+trait used when you don't specify your own, for the descriptions of the
+individual constants that your trait struct is expected to have as well as
+restrictions that you must be aware of.
+
+Also be aware that these constants must all be constant expressions with
+``constexpr`` specifiers, as some of them are used within ``static_assert``
+declarations, and even those that are currently not used within
+``static_assert`` may be used in ``static_assert`` in the future.
+
+As far as our current example goes, the only part of the custom trait we need
+to highlight is that we are setting the directory node size to 2-to-5 instead
+of the default size of 40-to-100, to trigger more node splits and make the
+tree artificially deeper.
+
+Let's move on to the next part of the code::
+
+ // 2D rectangle with the top-left position (x, y), width and height.
+ struct rect
+ {
+ int x;
+ int y;
+ int w;
+ int h;
+ };
+
+ std::vector<rect> rects =
+ {
+ { 3731, 2433, 1356, 937 },
+ { 6003, 3172, 1066, 743 },
+ { 4119, 6403, 825, 1949 },
+ { 10305, 2315, 776, 548 },
+ { 13930, 5468, 1742, 626 },
+ { 8614, 4107, 2709, 1793 },
+ { 14606, 1887, 5368, 1326 },
+ { 17990, 5196, 1163, 1911 },
+ { 6728, 7881, 3676, 1210 },
+ { 14704, 9789, 5271, 1092 },
+ { 4071, 10723, 4739, 898 },
+ { 11755, 9010, 1357, 2806 },
+ { 13978, 4068, 776, 509 },
+ { 17507, 3717, 777, 471 },
+ { 20358, 6092, 824, 1093 },
+ { 6390, 4535, 1066, 1715 },
+ { 13978, 7182, 2516, 1365 },
+ { 17942, 11580, 2854, 665 },
+ { 9919, 10450, 873, 1716 },
+ { 5568, 13215, 7446, 509 },
+ { 7357, 15277, 3145, 3234 },
+ { 3539, 12592, 631, 509 },
+ { 4747, 14498, 825, 626 },
+ { 4554, 16913, 969, 1443 },
+ { 12771, 14693, 2323, 548 },
+ { 18714, 8193, 2372, 586 },
+ { 22292, 2743, 487, 1638 },
+ { 20987, 17535, 1163, 1249 },
+ { 19536, 18859, 632, 431 },
+ { 19778, 15394, 1356, 626 },
+ { 22969, 15394, 631, 2066 },
+ };
+
+This ``rects`` variable holds an array of 2-dimensional rectangle data that
+represent the positions and sizes of rectangles shown earlier in this section.
+This will be used as bounding rectangles for the input values in the next part
+of the code::
+
+ rt_type tree;
+
+ // Insert the rectangle objects into the tree.
+ int value = 0;
+ for (const auto& rect : rects)
+ tree.insert({{rect.x, rect.y}, {rect.x + rect.w, rect.y + rect.h}}, value++);
+
+Here, the tree is instantiated, and the rectangles are inserted with their
+associated values one at a time. Once the tree is populated, the code that
+follows will export the structure of the tree as an SVG string, which will
+then be saved to a file on disk::
+
+ // Export the tree structure as a SVG for visualization.
+ std::string tree_svg = tree.export_tree(rt_type::export_tree_type::extent_as_svg);
+ std::ofstream fout("bounds.svg");
+ fout << tree_svg;
+
+When you open the exported SVG file named **bounds.svg** in a SVG viewer,
+you'll see something similar to this:
+
+.. figure:: _static/images/rtree_bounds_tree.png
+ :align: center
+
+which depicts not only the bounding rectangles of the inserted values
+(the red rectangles), but also the bounding rectangles of the directory
+nodes as well (the light green rectangles).
+
+
+Bulk-loading data
+-----------------
+
+In this section we will explore on how to bulk-load data into an
+:cpp:class:`~mdds::rtree` instance via rtree's own
+:cpp:class:`~mdds::rtree::bulk_loader` class. In this example, we'll be using
+the same custom trait we've used in the previous section in order to
+artificially promote the rate of node splits. The first part of the code::
+
+ #include <mdds/rtree.hpp>
+
+ #include <iostream>
+ #include <fstream>
+
+ // Make the node capacity intentionally small.
+ struct tiny_trait_2d
+ {
+ constexpr static size_t dimensions = 2;
+ constexpr static size_t min_node_size = 2;
+ constexpr static size_t max_node_size = 5;
+ constexpr static size_t max_tree_depth = 100;
+
+ constexpr static bool enable_forced_reinsertion = true;
+ constexpr static size_t reinsertion_size = 2;
+ };
+
+ using rt_type = mdds::rtree<int, int, tiny_trait_2d>;
+
+is pretty much identical to the example in the last section. The next part of
+the code defines what bounding rectangles to be inserted. Here, we are using
+a different set of rectangles than the previous example to illustrate the
+difference between a series of normal insertions and bulk-loading::
+
+ // 2D rectangle with the top-left position (x, y), width and height.
+ struct rect
+ {
+ int x;
+ int y;
+ int w;
+ int h;
+ };
+
+ std::vector<rect> rects =
+ {
+ { 3538, 9126, 1908, 1908 },
+ { 34272, 52053, 2416, 2543 },
+ { 32113, 9761, 2416, 638 },
+ { 16493, 16747, 7369, 2289 },
+ { 29192, 23732, 3432, 2035 },
+ { 35797, 17000, 1781, 892 },
+ { 15857, 29319, 2162, 1654 },
+ { 5825, 24239, 3559, 8512 },
+ { 9127, 46846, 2543, 1019 },
+ { 7094, 54338, 5210, 892 },
+ { 18779, 39734, 3813, 10417 },
+ { 32749, 35923, 2289, 2924 },
+ { 26018, 31098, 257, 2797 },
+ { 6713, 37066, 2924, 1146 },
+ { 19541, 3157, 3305, 1146 },
+ { 21953, 10904, 4448, 892 },
+ { 15984, 24240, 5210, 1273 },
+ { 8237, 15350, 2670, 2797 },
+ { 17001, 13826, 4067, 1273 },
+ { 30970, 13826, 3940, 765 },
+ { 9634, 6587, 1654, 1781 },
+ { 38464, 47099, 511, 1400 },
+ { 20556, 54085, 1400, 1527 },
+ { 37575, 24113, 1019, 765 },
+ { 20429, 21064, 1146, 1400 },
+ { 31733, 4427, 2543, 638 },
+ { 2142, 27161, 1273, 7369 },
+ { 3920, 43289, 8131, 1146 },
+ { 14714, 34272, 1400, 4956 },
+ { 38464, 41258, 1273, 1273 },
+ { 35542, 45703, 892, 1273 },
+ { 25891, 50783, 1273, 5083 },
+ { 35415, 28431, 2924, 1781 },
+ { 15476, 7349, 1908, 765 },
+ { 12555, 11159, 1654, 2035 },
+ { 11158, 21445, 1908, 2416 },
+ { 23350, 28049, 3432, 892 },
+ { 28684, 15985, 2416, 4321 },
+ { 24620, 21953, 1654, 638 },
+ { 30208, 30716, 2670, 2162 },
+ { 26907, 44179, 2797, 4067 },
+ { 21191, 35416, 2162, 1019 },
+ { 27668, 38717, 638, 3178 },
+ { 3666, 50528, 2035, 1400 },
+ { 15349, 48750, 2670, 1654 },
+ { 28430, 7221, 2162, 892 },
+ { 4808, 3158, 2416, 1273 },
+ { 38464, 3666, 1527, 1781 },
+ { 2777, 20937, 2289, 1146 },
+ { 38209, 9254, 1908, 1781 },
+ { 2269, 56497, 2289, 892 },
+ };
+
+As with the previous example, each line contains the top-left position as well
+as the size of a rectangle. We are now going to insert these rectangles in
+two different ways.
+
+First, we insert them via normal :cpp:func:`~mdds::rtree::insert` method::
+
+ void load_tree()
+ {
+ rt_type tree;
+
+ // Insert the rectangle objects into the tree.
+ int value = 0;
+ for (const auto& rect : rects)
+ tree.insert({{rect.x, rect.y}, {rect.x + rect.w, rect.y + rect.h}}, value++);
+
+ // Export the tree structure as a SVG for visualization.
+ std::string tree_svg = tree.export_tree(rt_type::export_tree_type::extent_as_svg);
+ std::ofstream fout("bounds2.svg");
+ fout << tree_svg;
+ }
+
+This code should look familiar since it's nearly identical to the code in the
+previous section. After the insertion is done, we export the tree as an SVG
+to visualize its structure.
+
+Next, we insert the same set of rectangles via
+:cpp:class:`~mdds::rtree::bulk_loader`::
+
+ void bulkload_tree()
+ {
+ rt_type::bulk_loader loader;
+
+ // Insert the rectangle objects into the tree.
+ int value = 0;
+ for (const auto& rect : rects)
+ loader.insert({{rect.x, rect.y}, {rect.x + rect.w, rect.y + rect.h}}, value++);
+
+ // Start bulk-loading the tree.
+ rt_type tree = loader.pack();
+
+ // Export the tree structure as a SVG for visualization.
+ std::string tree_svg = tree.export_tree(rt_type::export_tree_type::extent_as_svg);
+ std::ofstream fout("bounds2-bulkload.svg");
+ fout << tree_svg;
+ }
+
+Inserting via :cpp:class:`~mdds::rtree::bulk_loader` shouldn't be too
+different than inserting via rtree's own insert methods. The only
+difference is that you instantiate a
+:cpp:class:`~mdds::rtree::bulk_loader` instance to insert all your data
+to it, then call its :cpp:func:`~mdds::rtree::bulk_loader::pack` method
+at the end to construct the final :cpp:class:`~mdds::rtree` instance.
+
+When the insertion is done and the tree instance created, we are once again
+exporting its structure to an SVG file for visualization.
+
+There are primarily two advantages to using
+:cpp:class:`~mdds::rtree::bulk_loader` to load data. First, unlike the
+normal insertion, bulk-loading does not trigger re-insertion nor node
+splits on the fly. Second, a tree created from bulk loader is typically
+well balanced than if you insert the same data through normal insertion.
+That is because the bulk loader sorts the data with respect to their
+bounding rectangles ahead of time and partition them evenly. The tree
+is then built from the bottom-up. You can visually see the effect of
+this when comparing the two trees built in our current example.
+
+The first one is from the tree built via normal insertion:
+
+.. figure:: _static/images/rtree_bounds2_tree.png
+ :align: center
+
+The top part of the picture looks very "busy" indicated by a darker
+green area representative of more directory nodes overlaping with each
+other. In general, the rectangles look bigger and show higher degree of
+overlaps.
+
+This one, on the other hand, is from the tree built with the same data
+set but through bulk-loading:
+
+.. figure:: _static/images/rtree_bounds2_tree_bulkload.png
+ :align: center
+
+The rectangles generally look smaller and show much less overlaps than the
+previous picture, which is considered to be a more balanced R-tree structure.
+
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::rtree
+ :members:
+
+.. doxygenstruct:: mdds::detail::rtree::default_rtree_traits
+ :members:
+
+.. doxygenstruct:: mdds::detail::rtree::integrity_check_properties
+ :members:
+
+.. doxygenenum:: mdds::detail::rtree::export_tree_type
+ :project: mdds
+
+.. doxygenenum:: mdds::detail::rtree::search_type
+ :project: mdds
diff --git a/doc/segment_tree.rst b/doc/segment_tree.rst
new file mode 100644
index 0000000..c877010
--- /dev/null
+++ b/doc/segment_tree.rst
@@ -0,0 +1,11 @@
+.. highlight:: cpp
+
+Segment Tree
+============
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::segment_tree
+ :members:
+
diff --git a/doc/sorted_string_map.rst b/doc/sorted_string_map.rst
new file mode 100644
index 0000000..d308e14
--- /dev/null
+++ b/doc/sorted_string_map.rst
@@ -0,0 +1,11 @@
+.. highlight:: cpp
+
+Sorted String Map
+=================
+
+API Reference
+-------------
+
+.. doxygenclass:: mdds::sorted_string_map
+ :members:
+
diff --git a/doc/trie_map.rst b/doc/trie_map.rst
new file mode 100644
index 0000000..8266771
--- /dev/null
+++ b/doc/trie_map.rst
@@ -0,0 +1,767 @@
+.. highlight:: cpp
+
+
+Trie Maps
+=========
+
+Examples
+--------
+
+Populating Trie Map
+^^^^^^^^^^^^^^^^^^^
+
+This section illustrates how to use :cpp:class:`~mdds::trie_map` to build a
+database of city populations and perform prefix searches. In this example,
+we will use the 2013 populations of cities in North Carolina, and use the city
+names as keys.
+
+Let's define the type first::
+
+ using trie_map_type = mdds::trie_map<mdds::trie::std_string_traits, int>;
+
+The first template argument specifies the trait of the key. In this example,
+we are using a pre-defined trait for std::string, which is defined in
+:cpp:type:`~mdds::trie::std_string_traits`. The second template argument
+specifies the value type, which in this example is simply an ``int``.
+
+Once the type is defined, the next step is instantiation::
+
+ trie_map_type nc_cities;
+
+It's pretty simple as you don't need to pass any arguments to the constructor.
+Now, let's populate this data structure with some population data::
+
+ // Insert key-value pairs.
+ nc_cities.insert("Charlotte", 792862);
+ nc_cities.insert("Raleigh", 431746);
+ nc_cities.insert("Greensboro", 279639);
+ nc_cities.insert("Durham", 245475);
+ nc_cities.insert("Winston-Salem", 236441);
+ nc_cities.insert("Fayetteville", 204408);
+ nc_cities.insert("Cary", 151088);
+ nc_cities.insert("Wilmington", 112067);
+ nc_cities.insert("High Point", 107741);
+ nc_cities.insert("Greenville", 89130);
+ nc_cities.insert("Asheville", 87236);
+ nc_cities.insert("Concord", 83506);
+ nc_cities.insert("Gastonia", 73209);
+ nc_cities.insert("Jacksonville", 69079);
+ nc_cities.insert("Chapel Hill", 59635);
+ nc_cities.insert("Rocky Mount", 56954);
+ nc_cities.insert("Burlington", 51510);
+ nc_cities.insert("Huntersville", 50458);
+ nc_cities.insert("Wilson", 49628);
+ nc_cities.insert("Kannapolis", 44359);
+ nc_cities.insert("Apex", 42214);
+ nc_cities.insert("Hickory", 40361);
+ nc_cities.insert("Goldsboro", 36306);
+
+It's pretty straight-forward. Each :cpp:func:`~mdds::trie_map::insert` call
+expects a pair of string key and an integer value. You can insert your data
+in any order regardless of key's sort order.
+
+Now that the data is in, let's perform prefix search to query all cities whose
+name begins with "Cha"::
+
+ cout << "Cities that start with 'Cha' and their populations:" << endl;
+ auto results = nc_cities.prefix_search("Cha");
+ for (const auto& kv : results)
+ {
+ cout << " " << kv.first << ": " << kv.second << endl;
+ }
+
+You can perform prefix search via :cpp:func:`~mdds::trie_map::prefix_search`
+method, which returns a results object that can be iterated over using a range-based
+for loop. Running this code will produce the following output:
+
+.. code-block:: none
+
+ Cities that start with 'Cha' and their populations:
+ Chapel Hill: 59635
+ Charlotte: 792862
+
+Let's perform another prefix search, this time with a prefix of "W"::
+
+ cout << "Cities that start with 'W' and their populations:" << endl;
+ results = nc_cities.prefix_search("W");
+ for (const auto& kv : results)
+ {
+ cout << " " << kv.first << ": " << kv.second << endl;
+ }
+
+You'll see the following output when running this code:
+
+.. code-block:: none
+
+ Cities that start with 'W' and their populations:
+ Wilmington: 112067
+ Wilson: 49628
+ Winston-Salem: 236441
+
+Note that the results are sorted in key's ascending order.
+
+.. note::
+
+ Results from the prefix search are sorted in key's ascending order.
+
+
+Creating Packed Trie Map from Trie Map
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There is also another variant of trie called :cpp:class:`~mdds::packed_trie_map`
+which is designed to store all its data in contiguous memory region. Unlike
+:cpp:class:`~mdds::trie_map` which is mutable, :cpp:class:`~mdds::packed_trie_map`
+is immutable; once populated, you can only perform queries and it is no longer
+possible to add new entries into the container.
+
+One way to create an instance of :cpp:class:`~mdds::packed_trie_map` is from
+:cpp:class:`~mdds::trie_map` by calling its :cpp:func:`~mdds::trie_map::pack`
+method::
+
+ auto packed = nc_cities.pack();
+
+The query methods of :cpp:class:`~mdds::packed_trie_map` are identical to those
+of :cpp:class:`~mdds::trie_map`. For instance, performing prefix search to find
+all entries whose key begins with "C" can be done as follows::
+
+ cout << "Cities that start with 'C' and their populations:" << endl;
+ auto packed_results = packed.prefix_search("C");
+ for (const auto& kv : packed_results)
+ {
+ cout << " " << kv.first << ": " << kv.second << endl;
+ }
+
+Running this code will generate the following output:
+
+.. code-block:: none
+
+ Cities that start with 'C' and their populations:
+ Cary: 151088
+ Chapel Hill: 59635
+ Charlotte: 792862
+ Concord: 83506
+
+You can also perform an exact-match query via :cpp:func:`~mdds::packed_trie_map::find`
+method which returns an iterator associated with the key-value pair entry::
+
+ // Individual search.
+ auto it = packed.find("Wilmington");
+ cout << "Population of Wilmington: " << it->second << endl;
+
+You'll see the following output with this code:
+
+.. code-block:: none
+
+ Population of Wilmington: 112067
+
+What if you performed an exact-match query with a key that doesn't exist in the
+container? You will basically get the end iterator position as its return value.
+Thus, running this code::
+
+ // You get an end position iterator when the container doesn't have the
+ // specified key.
+ it = packed.find("Asheboro");
+
+ cout << "Population of Asheboro: ";
+
+ if (it == packed.end())
+ cout << "not found";
+ else
+ cout << it->second;
+
+ cout << endl;
+
+will generate the following output:
+
+.. code-block:: none
+
+ Population of Asheboro: not found
+
+The complete source code for the examples in these two sections is available
+`here <https://gitlab.com/mdds/mdds/-/blob/master/example/trie_map.cpp>`__.
+
+
+Using Packed Trie Map directly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the previous example, we showed a way to create an instance of :cpp:class:`~mdds::packed_trie_map`
+from a populated instance of :cpp:class:`~mdds::trie_map`. There is also a way
+to instantiate and populate an instance of :cpp:class:`~mdds::packed_trie_map`
+directly, and that is what we will cover in this section.
+
+First, declare the type::
+
+ using trie_map_type = mdds::packed_trie_map<mdds::trie::std_string_traits, int>;
+
+Once again, we are using the pre-defined trait for std::string as its key, and int
+as its value type. The next step is to prepare its entries ahead of time::
+
+ trie_map_type::entry entries[] =
+ {
+ { MDDS_ASCII("Apex"), 42214 },
+ { MDDS_ASCII("Asheville"), 87236 },
+ { MDDS_ASCII("Burlington"), 51510 },
+ { MDDS_ASCII("Cary"), 151088 },
+ { MDDS_ASCII("Chapel Hill"), 59635 },
+ { MDDS_ASCII("Charlotte"), 792862 },
+ { MDDS_ASCII("Concord"), 83506 },
+ { MDDS_ASCII("Durham"), 245475 },
+ { MDDS_ASCII("Fayetteville"), 204408 },
+ { MDDS_ASCII("Gastonia"), 73209 },
+ { MDDS_ASCII("Goldsboro"), 36306 },
+ { MDDS_ASCII("Greensboro"), 279639 },
+ { MDDS_ASCII("Greenville"), 89130 },
+ { MDDS_ASCII("Hickory"), 40361 },
+ { MDDS_ASCII("High Point"), 107741 },
+ { MDDS_ASCII("Huntersville"), 50458 },
+ { MDDS_ASCII("Jacksonville"), 69079 },
+ { MDDS_ASCII("Kannapolis"), 44359 },
+ { MDDS_ASCII("Raleigh"), 431746 },
+ { MDDS_ASCII("Rocky Mount"), 56954 },
+ { MDDS_ASCII("Wilmington"), 112067 },
+ { MDDS_ASCII("Wilson"), 49628 },
+ { MDDS_ASCII("Winston-Salem"), 236441 },
+ };
+
+We need to do this since :cpp:class:`~mdds::packed_trie_map` is immutable, and
+the only time we can populate its content is at instantiation time. Here, we
+are using the :c:macro:`MDDS_ASCII` macro to expand a string literal to its
+pointer value and size. Note that you need to ensure that the entries are sorted
+by the key in ascending order.
+
+.. warning::
+
+ When instantiating :cpp:class:`~mdds::packed_trie_map` directly with a static
+ set of entries, the entries must be sorted by the key in ascending order.
+
+You can then pass this list of entries to construct the instance::
+
+ trie_map_type nc_cities(entries, MDDS_N_ELEMENTS(entries));
+
+The :c:macro:`MDDS_N_ELEMENTS` macro will infer the size of a fixed-size array
+from its static definition. Once it's instantiated, the rest of the example
+for performing searches will be the same as in the previous section, which we
+will not repeat here.
+
+The complete source code for the example in this section is available
+`here <https://gitlab.com/mdds/mdds/-/blob/master/example/packed_trie_map.cpp>`__.
+
+
+Saving and loading Packed Trie Map instances
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are times when you need to save the state of a :cpp:class:`~mdds::packed_trie_map`
+instance to a file, or an in-memory buffer, and load it back later. Doing that
+is now possible by using the :cpp:func:`~mdds::packed_trie_map::save_state` and
+:cpp:func:`~mdds::packed_trie_map::load_state` member methods of the
+:cpp:class:`~mdds::packed_trie_map` class.
+
+First, let's define the type of use::
+
+ using map_type = mdds::packed_trie_map<mdds::trie::std_string_traits, int>;
+
+As with the previous examples, we will use ``std::string`` as the key type and
+``int`` as the value type. In this example, we are going to use `the world's
+largest cities and their 2018 populations
+<https://en.wikipedia.org/wiki/List_of_largest_cities>`__ as the data to store
+in the container.
+
+The following code defines the entries::
+
+ std::vector<map_type::entry> entries =
+ {
+ { MDDS_ASCII("Ahmedabad"), 7681000 },
+ { MDDS_ASCII("Alexandria"), 5086000 },
+ { MDDS_ASCII("Atlanta"), 5572000 },
+ { MDDS_ASCII("Baghdad"), 6812000 },
+ { MDDS_ASCII("Bangalore"), 11440000 },
+ { MDDS_ASCII("Bangkok"), 10156000 },
+ { MDDS_ASCII("Barcelona"), 5494000 },
+ { MDDS_ASCII("Beijing"), 19618000 },
+ { MDDS_ASCII("Belo Horizonte"), 5972000 },
+ { MDDS_ASCII("Bogota"), 10574000 },
+ { MDDS_ASCII("Buenos Aires"), 14967000 },
+ { MDDS_ASCII("Cairo"), 20076000 },
+ { MDDS_ASCII("Chengdu"), 8813000 },
+ { MDDS_ASCII("Chennai"), 10456000 },
+ { MDDS_ASCII("Chicago"), 8864000 },
+ { MDDS_ASCII("Chongqing"), 14838000 },
+ { MDDS_ASCII("Dalian"), 5300000 },
+ { MDDS_ASCII("Dallas"), 6099000 },
+ { MDDS_ASCII("Dar es Salaam"), 6048000 },
+ { MDDS_ASCII("Delhi"), 28514000 },
+ { MDDS_ASCII("Dhaka"), 19578000 },
+ { MDDS_ASCII("Dongguan"), 7360000 },
+ { MDDS_ASCII("Foshan"), 7236000 },
+ { MDDS_ASCII("Fukuoka"), 5551000 },
+ { MDDS_ASCII("Guadalajara"), 5023000 },
+ { MDDS_ASCII("Guangzhou"), 12638000 },
+ { MDDS_ASCII("Hangzhou"), 7236000 },
+ { MDDS_ASCII("Harbin"), 6115000 },
+ { MDDS_ASCII("Ho Chi Minh City"), 8145000 },
+ { MDDS_ASCII("Hong Kong"), 7429000 },
+ { MDDS_ASCII("Houston"), 6115000 },
+ { MDDS_ASCII("Hyderabad"), 9482000 },
+ { MDDS_ASCII("Istanbul"), 14751000 },
+ { MDDS_ASCII("Jakarta"), 10517000 },
+ { MDDS_ASCII("Jinan"), 5052000 },
+ { MDDS_ASCII("Johannesburg"), 5486000 },
+ { MDDS_ASCII("Karachi"), 15400000 },
+ { MDDS_ASCII("Khartoum"), 5534000 },
+ { MDDS_ASCII("Kinshasa"), 13171000 },
+ { MDDS_ASCII("Kolkata"), 14681000 },
+ { MDDS_ASCII("Kuala Lumpur"), 7564000 },
+ { MDDS_ASCII("Lagos"), 13463000 },
+ { MDDS_ASCII("Lahore"), 11738000 },
+ { MDDS_ASCII("Lima"), 10391000 },
+ { MDDS_ASCII("London"), 9046000 },
+ { MDDS_ASCII("Los Angeles"), 12458000 },
+ { MDDS_ASCII("Luanda"), 7774000 },
+ { MDDS_ASCII("Madrid"), 6497000 },
+ { MDDS_ASCII("Manila"), 13482000 },
+ { MDDS_ASCII("Mexico City"), 21581000 },
+ { MDDS_ASCII("Miami"), 6036000 },
+ { MDDS_ASCII("Moscow"), 12410000 },
+ { MDDS_ASCII("Mumbai"), 19980000 },
+ { MDDS_ASCII("Nagoya"), 9507000 },
+ { MDDS_ASCII("Nanjing"), 8245000 },
+ { MDDS_ASCII("New York City"), 18819000 },
+ { MDDS_ASCII("Osaka"), 19281000 },
+ { MDDS_ASCII("Paris"), 10901000 },
+ { MDDS_ASCII("Philadelphia"), 5695000 },
+ { MDDS_ASCII("Pune"), 6276000 },
+ { MDDS_ASCII("Qingdao"), 5381000 },
+ { MDDS_ASCII("Rio de Janeiro"), 13293000 },
+ { MDDS_ASCII("Riyadh"), 6907000 },
+ { MDDS_ASCII("Saint Petersburg"), 5383000 },
+ { MDDS_ASCII("Santiago"), 6680000 },
+ { MDDS_ASCII("Sao Paulo"), 21650000 },
+ { MDDS_ASCII("Seoul"), 9963000 },
+ { MDDS_ASCII("Shanghai"), 25582000 },
+ { MDDS_ASCII("Shenyang"), 6921000 },
+ { MDDS_ASCII("Shenzhen"), 11908000 },
+ { MDDS_ASCII("Singapore"), 5792000 },
+ { MDDS_ASCII("Surat"), 6564000 },
+ { MDDS_ASCII("Suzhou"), 6339000 },
+ { MDDS_ASCII("Tehran"), 8896000 },
+ { MDDS_ASCII("Tianjin"), 13215000 },
+ { MDDS_ASCII("Tokyo"), 37400068 },
+ { MDDS_ASCII("Toronto"), 6082000 },
+ { MDDS_ASCII("Washington, D.C."), 5207000 },
+ { MDDS_ASCII("Wuhan"), 8176000 },
+ { MDDS_ASCII("Xi'an"), 7444000 },
+ { MDDS_ASCII("Yangon"), 5157000 },
+ };
+
+It's a bit long as it contains entries for 81 cities. We are then going to
+create an instance of the :cpp:class:`~mdds::packed_trie_map` class directly::
+
+ map_type cities(entries.data(), entries.size());
+
+Let's print the size of the container to make sure the container has been
+successfully populated::
+
+ cout << "Number of cities: " << cities.size() << endl;
+
+You will see the following output:
+
+.. code-block:: none
+
+ Number of cities: 81
+
+if the container has been successfully populated. Now, let's run a prefix
+search on names beginning with an 'S'::
+
+ cout << "Cities that begin with 'S':" << endl;
+ auto results = cities.prefix_search("S");
+ for (const auto& city : results)
+ cout << " * " << city.first << ": " << city.second << endl;
+
+to make sure you get the following ten cities and their populations as the
+output:
+
+.. code-block:: none
+
+ Cities that begin with 'S':
+ * Saint Petersburg: 5383000
+ * Santiago: 6680000
+ * Sao Paulo: 21650000
+ * Seoul: 9963000
+ * Shanghai: 25582000
+ * Shenyang: 6921000
+ * Shenzhen: 11908000
+ * Singapore: 5792000
+ * Surat: 6564000
+ * Suzhou: 6339000
+
+So far so good. Next, we will use the :cpp:func:`~mdds::packed_trie_map::save_state`
+method to dump the internal state of this container to a file named **cities.bin**::
+
+ std::ofstream outfile("cities.bin", std::ios::binary);
+ cities.save_state(outfile);
+
+This will create a file named **cities.bin** which contains a binary blob
+representing the content of this container in the current working directory.
+Run the ``ls -l cities.bin`` command to make sure the file has been created:
+
+.. code-block:: none
+
+ -rw-r--r-- 1 kohei kohei 17713 Jun 20 12:49 cities.bin
+
+Now that the state of the container has been fully serialized to a file, let's
+work on restoring its content in another, brand-new instance of
+:cpp:class:`~mdds::packed_trie_map`.
+
+::
+
+ map_type cities_loaded;
+
+ std::ifstream infile("cities.bin", std::ios::binary);
+ cities_loaded.load_state(infile);
+
+Here, we used the :cpp:func:`~mdds::packed_trie_map::load_state` method to
+restore the state from the file we have previously created. Let's make sure
+that this new instance has content equivalent to that of the original::
+
+ cout << "Equal to the original? " << std::boolalpha << (cities == cities_loaded) << endl;
+
+If you see the following output:
+
+.. code-block:: none
+
+ Equal to the original? true
+
+then this new instance has equivalent contant as the original one. Let's also
+make sure that it contains the same number of entries as the original::
+
+ cout << "Number of cities: " << cities_loaded.size() << endl;
+
+Hopefully you will see the following output:
+
+.. code-block:: none
+
+ Number of cities: 81
+
+Lastly, let's run on this new instance the same prefix search we did on the
+original instance, to make sure we still get the same results::
+
+ cout << "Cities that begin with 'S':" << endl;
+ auto results = cities_loaded.prefix_search("S");
+ for (const auto& city : results)
+ cout << " * " << city.first << ": " << city.second << endl;
+
+You should see the following output:
+
+.. code-block:: none
+
+ Cities that begin with 'S':
+ * Saint Petersburg: 5383000
+ * Santiago: 6680000
+ * Sao Paulo: 21650000
+ * Seoul: 9963000
+ * Shanghai: 25582000
+ * Shenyang: 6921000
+ * Shenzhen: 11908000
+ * Singapore: 5792000
+ * Surat: 6564000
+ * Suzhou: 6339000
+
+which is the same output we saw in the first prefix search.
+
+The complete source code for this example is found
+`here <https://gitlab.com/mdds/mdds/-/blob/master/example/packed_trie_state_int.cpp>`__.
+
+
+Saving Packed Trie Map with custom value type
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the previos example, you didn't have to explicitly specify the serializer type
+to the :cpp:func:`~mdds::packed_trie_map::save_state` and
+:cpp:func:`~mdds::packed_trie_map::load_state` methods, even though these two
+methods require the serializer type as their template arguments. That's because
+the library provides default serializer types for
+
+* numeric value types i.e. integers, float and double,
+* ``std::string``, and
+* the standard sequence types, such as ``std::vector``, whose elements are of
+ numeric value types,
+
+and the previous example used ``int`` as the value type.
+
+In this section, we are going to illustrate how you can write your own custom
+serializer to allow serialization of your own custom value type. In this example,
+we are going to use `the list of presidents of the United States
+<https://en.wikipedia.org/wiki/List_of_presidents_of_the_United_States>`__,
+with the names of the presidents as the keys, and their years of inauguration
+and political affiliations as the values.
+
+We will use the following structure to store the values::
+
+ enum affiliated_party_t : uint8_t
+ {
+ unaffiliated = 0,
+ federalist,
+ democratic_republican,
+ democratic,
+ whig,
+ republican,
+ national_union,
+ republican_national_union,
+ };
+
+ struct us_president
+ {
+ uint16_t year;
+ affiliated_party_t party;
+ };
+
+Each entry stores the year as a 16-bit integer and the affiliated party as an enum
+value of 8-bit width.
+
+Next, let's define the container type::
+
+ using map_type = mdds::packed_trie_map<mdds::trie::std_string_traits, us_president>;
+
+As with the previous example, the first step is to define the entries that are
+sorted by the keys, which in this case are the president's names::
+
+ std::vector<map_type::entry> entries =
+ {
+ { MDDS_ASCII("Abraham Lincoln"), { 1861, republican_national_union } },
+ { MDDS_ASCII("Andrew Jackson"), { 1829, democratic } },
+ { MDDS_ASCII("Andrew Johnson"), { 1865, national_union } },
+ { MDDS_ASCII("Barack Obama"), { 2009, democratic } },
+ { MDDS_ASCII("Benjamin Harrison"), { 1889, republican } },
+ { MDDS_ASCII("Bill Clinton"), { 1993, democratic } },
+ { MDDS_ASCII("Calvin Coolidge"), { 1923, republican } },
+ { MDDS_ASCII("Chester A. Arthur"), { 1881, republican } },
+ { MDDS_ASCII("Donald Trump"), { 2017, republican } },
+ { MDDS_ASCII("Dwight D. Eisenhower"), { 1953, republican } },
+ { MDDS_ASCII("Franklin D. Roosevelt"), { 1933, democratic } },
+ { MDDS_ASCII("Franklin Pierce"), { 1853, democratic } },
+ { MDDS_ASCII("George H. W. Bush"), { 1989, republican } },
+ { MDDS_ASCII("George W. Bush"), { 2001, republican } },
+ { MDDS_ASCII("George Washington"), { 1789, unaffiliated } },
+ { MDDS_ASCII("Gerald Ford"), { 1974, republican } },
+ { MDDS_ASCII("Grover Cleveland 1"), { 1885, democratic } },
+ { MDDS_ASCII("Grover Cleveland 2"), { 1893, democratic } },
+ { MDDS_ASCII("Harry S. Truman"), { 1945, democratic } },
+ { MDDS_ASCII("Herbert Hoover"), { 1929, republican } },
+ { MDDS_ASCII("James A. Garfield"), { 1881, republican } },
+ { MDDS_ASCII("James Buchanan"), { 1857, democratic } },
+ { MDDS_ASCII("James K. Polk"), { 1845, democratic } },
+ { MDDS_ASCII("James Madison"), { 1809, democratic_republican } },
+ { MDDS_ASCII("James Monroe"), { 1817, democratic_republican } },
+ { MDDS_ASCII("Jimmy Carter"), { 1977, democratic } },
+ { MDDS_ASCII("John Adams"), { 1797, federalist } },
+ { MDDS_ASCII("John F. Kennedy"), { 1961, democratic } },
+ { MDDS_ASCII("John Quincy Adams"), { 1825, democratic_republican } },
+ { MDDS_ASCII("John Tyler"), { 1841, whig } },
+ { MDDS_ASCII("Lyndon B. Johnson"), { 1963, democratic } },
+ { MDDS_ASCII("Martin Van Buren"), { 1837, democratic } },
+ { MDDS_ASCII("Millard Fillmore"), { 1850, whig } },
+ { MDDS_ASCII("Richard Nixon"), { 1969, republican } },
+ { MDDS_ASCII("Ronald Reagan"), { 1981, republican } },
+ { MDDS_ASCII("Rutherford B. Hayes"), { 1877, republican } },
+ { MDDS_ASCII("Theodore Roosevelt"), { 1901, republican } },
+ { MDDS_ASCII("Thomas Jefferson"), { 1801, democratic_republican } },
+ { MDDS_ASCII("Ulysses S. Grant"), { 1869, republican } },
+ { MDDS_ASCII("Warren G. Harding"), { 1921, republican } },
+ { MDDS_ASCII("William Henry Harrison"), { 1841, whig } },
+ { MDDS_ASCII("William Howard Taft"), { 1909, republican } },
+ { MDDS_ASCII("William McKinley"), { 1897, republican } },
+ { MDDS_ASCII("Woodrow Wilson"), { 1913, democratic } },
+ { MDDS_ASCII("Zachary Taylor"), { 1849, whig } },
+ };
+
+Note that we need to add numeric suffixes to the entries for Grover Cleveland,
+who became president twice in two separate periods, in order to make the keys
+for his entries unique.
+
+Now, proceed to create an instance of :cpp:class:`~mdds::packed_trie_map`::
+
+ map_type us_presidents(entries.data(), entries.size());
+
+and inspect its size to make sure it is instantiated properly::
+
+ cout << "Number of entries: " << us_presidents.size() << endl;
+
+You should see the following output:
+
+.. code-block:: none
+
+ Number of entries: 45
+
+Before we proceed to save the state of this instance, let's define the custom
+serializer type first::
+
+ struct us_president_serializer
+ {
+ union bin_buffer
+ {
+ char buffer[2];
+ uint16_t i16;
+ affiliated_party_t party;
+ };
+
+ static constexpr bool variable_size = false;
+ static constexpr size_t value_size = 3;
+
+ static void write(std::ostream& os, const us_president& v)
+ {
+ bin_buffer buf;
+
+ // Write the year value first.
+ buf.i16 = v.year;
+ os.write(buf.buffer, 2);
+
+ // Write the affiliated party value.
+ buf.party = v.party;
+ os.write(buf.buffer, 1);
+ }
+
+ static void read(std::istream& is, size_t n, us_president& v)
+ {
+ // For a fixed-size value type, this should equal the defined value size.
+ assert(n == 3);
+
+ bin_buffer buf;
+
+ // Read the year value.
+ is.read(buf.buffer, 2);
+ v.year = buf.i16;
+
+ // Read the affiliated party value.
+ is.read(buf.buffer, 1);
+ v.party = buf.party;
+ }
+ };
+
+A custom value type can be either variable-size or fixed-size. For a variable-size
+value type, each value segment is preceded by the byte length of that segment.
+For a fixed-size value type, the byte length of all of the value segments
+is written only once up-front, followed by one or more value segments of equal
+byte length.
+
+Since the value type in this example is fixed-size, we set the value of the
+``variable_size`` static constant to false, and define the size of the value to 3 (bytes)
+as the ``value_size`` static constant. Keep in mind that you need to define
+the ``value_size`` constant *only* for fixed-size value types; if your value
+type is variable-size, you can leave it out.
+
+Additionally, you need to define two static methods - one for writing to the
+output stream, and one for reading from the input stream. The write method
+must have the following signature::
+
+ static void write(std::ostream& os, const T& v);
+
+where the ``T`` is the value type. In the body of this method you write to the
+output stream the bytes that represent the value. The length of the bytes you
+write must match the size specified by the ``value_size`` constant.
+
+The read method must have the following signature::
+
+ static void read(std::istream& is, size_t n, T& v);
+
+where the ``T`` is the value type, and the ``n`` specifies the length of the
+bytes you need to read for the value. For a fixed-size value type, the value
+of ``n`` should equal the ``value_size`` constant. Your job is to read the
+bytes off of the input stream for the length specified by the ``n``, and
+populate the value instance passed to the method as the third argument.
+
+Now that we have defined the custom serializer type, let's proceed to save the
+state to a file::
+
+ std::ofstream outfile("us-presidents.bin", std::ios::binary);
+ us_presidents.save_state<us_president_serializer>(outfile);
+
+This time around, we are specifying the serializer type explicitly as the template
+argument to the :cpp:func:`~mdds::packed_trie_map::save_state` method. Otherwise
+it is no different than what we did in the previous example.
+
+Let's create another instance of :cpp:class:`~mdds::packed_trie_map` and restore
+the state back from the file we just created::
+
+ map_type us_presidents_loaded;
+
+ std::ifstream infile("us-presidents.bin", std::ios::binary);
+ us_presidents_loaded.load_state<us_president_serializer>(infile);
+
+Once again, aside from explicitly specifying the serializer type as the template
+argument to the :cpp:func:`~mdds::packed_trie_map::load_state` method, it is
+identical to the way we did in the previous example.
+
+Let's compare the new instance with the old one to see if the two are equal::
+
+ cout << "Equal to the original? " << std::boolalpha << (us_presidents == us_presidents_loaded) << endl;
+
+The output says:
+
+.. code-block:: none
+
+ Equal to the original? true
+
+They are. While we are at it, let's run a simple prefix search to find out
+all the US presidents whose first name is 'John'::
+
+ cout << "Presidents whose first name is 'John':" << endl;
+ auto results = us_presidents_loaded.prefix_search("John");
+ for (const auto& entry : results)
+ cout << " * " << entry.first << " (" << entry.second.year << "; " << entry.second.party << ")" << endl;
+
+Here is the output:
+
+.. code-block:: none
+
+ Presidents whose first name is 'John':
+ * John Adams (1797; Federalist)
+ * John F. Kennedy (1961; Democratic)
+ * John Quincy Adams (1825; Democratic Republican)
+ * John Tyler (1841; Whig)
+
+This looks like the correct results!
+
+You can find the complete source code for this example `here
+<https://gitlab.com/mdds/mdds/-/blob/master/example/packed_trie_state_custom.cpp>`__.
+
+
+API Reference
+-------------
+
+Trie Map
+^^^^^^^^
+
+.. doxygenclass:: mdds::trie_map
+ :members:
+
+
+Packed Trie Map
+^^^^^^^^^^^^^^^
+
+.. doxygenclass:: mdds::packed_trie_map
+ :members:
+
+
+Traits
+^^^^^^
+
+.. doxygenstruct:: mdds::trie::std_container_traits
+ :members:
+
+.. doxygentypedef:: mdds::trie::std_string_traits
+
+
+Value Serializers
+^^^^^^^^^^^^^^^^^
+
+.. doxygenstruct:: mdds::trie::value_serializer
+ :members:
+
+.. doxygenstruct:: mdds::trie::numeric_value_serializer
+ :members:
+
+.. doxygenstruct:: mdds::trie::variable_value_serializer
+ :members:
+
+.. doxygenstruct:: mdds::trie::numeric_sequence_value_serializer
+ :members: