[
  {
    "path": ".gitignore",
    "content": "bin\nbuild\nnode_modules\ntypes\n\n# ignore all js files under lib except explicit ones specified here\nlib/**/*.js\n!lib/core/*.js\n!lib/zone/zone-main.js\n!lib/binding.js\n\n# ignore all js files under test\ntest/**/*.js\ntest/module/test-dir\ntest/module/test-file\n!test/module/node_modules\n!test/module/**/*.js\n\n!unittest/module/test-files/node_modules\n\n# ignore all js files under benchmark\nbenchmark/**/*.js\n\npackage-lock.json\n\n!tsconfig.json\n\n# ignore all VSCode files\n.vscode\n\n# ignore npm related files\nnpm-debug.log\n"
  },
  {
    "path": ".npmignore",
    "content": "bin\nbuild\nexamples\n\n# Exclude TypeScript source files.\nbenchmark/**/*.ts\nbenchmark/tsconfig.json\nlib/**/*.ts\nlib/tsconfig.json\ntest/**/*.ts\ntest/module/test-dir\ntest/module/test-file\ntest/tsconfig.json\n\n.vscode\n.npmrc\n.npmignore\n.taskkey\n.travis.yml\nappveyor.yml\nnpm-debug.log\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\ncompiler: default\nmatrix:\n  exclude:\n  # Disable the default build and use customized matrix only.\n  - compiler: default\n  include:\n  # Node 6.x                 Linux (Precise)          G++5.4.1\n  - os: linux\n    dist: precise\n    node_js: '6'\n    compiler: g++-5\n    addons:\n      apt:\n        # The apt source 'ubuntu-toolchain-r-test' is for GCC 5+\n        # The apt source 'george-edison55-precise-backports' is for CMake 3.2+\n        sources:\n        - ubuntu-toolchain-r-test\n        - george-edison55-precise-backports\n        packages:\n        - g++-5\n        - cmake-data\n        - cmake\n    env:\n    - COMPILER_OVERRIDE=\"CXX=g++-5 CC=gcc-5\"\n  # Node 6.x                 OS X (Yosemite)          AppleClang 6.1\n  - os: osx\n    node_js: '6'\n    osx_image: xcode6.4\n  # Node LTS (8.x)           Linux (Trusty)           G++6.4.0\n  - os: linux\n    dist: trusty\n    node_js: '8'\n    compiler: g++-6\n    addons:\n      apt:\n        sources:\n        - ubuntu-toolchain-r-test\n        packages:\n        - g++-6\n    env:\n    - COMPILER_OVERRIDE=\"CXX=g++-6 CC=gcc-6\"\n  # Node LTS (8.x)           OS X (El Capitan)        AppleClang 7.3\n  - os: osx\n    node_js: '8'\n    osx_image: xcode7.3\n  # Node (9.x)               Linux (Trusty)           G++6.4.0\n  - os: linux\n    dist: trusty\n    node_js: '9'\n    compiler: g++-6\n    addons:\n      apt:\n        sources:\n        - ubuntu-toolchain-r-test\n        packages:\n        - g++-6\n    env:\n    - COMPILER_OVERRIDE=\"CXX=g++-6 CC=gcc-6\"\n  # Node (9.x)               macOS (Sierra)           AppleClang 8.1\n  - os: osx\n    node_js: '9'\n    osx_image: xcode8.3\n  # Node Current (10.x)       Linux (Trusty)          G++7.3.0\n  - os: linux\n    dist: trusty\n    node_js: '10'\n    compiler: g++-7\n    addons:\n      apt:\n        sources:\n        - ubuntu-toolchain-r-test\n        packages:\n        - g++-7\n    env:\n    - COMPILER_OVERRIDE=\"CXX=g++-7 CC=gcc-7\"\n  # Node Current (10.x)       macOS (High Sierra)     AppleClang 9.1\n  - os: osx\n    node_js: '10'\n    osx_image: xcode9.3\n\nbefore_install:\n- |\n  if [ $TRAVIS_OS_NAME == linux ]; then\n    export ${COMPILER_OVERRIDE}\n  fi\ninstall:\n- npm install cmake-js -g\n- npm install --no-fetch\nscript:\n- npm test\n- npm run unittest\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"napa\")\n\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nif (NOT WIN32 AND NOT APPLE)\n    # Set symbol visibility to hidden by default.\n    # Napa shared library shares a few classes with napa-binding.node with different compile definition,\n    # exposing the same symbols from both shared libraries may cause improper behaviors under gcc.\n    set(CMAKE_CXX_VISIBILITY_PRESET hidden)\n    set(CMAKE_VISIBILITY_INLINES_HIDDEN)\n\n    # Prevent symbol relocations internal to our wrapper library to be overwritten by the application.\n    set (CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic -Wl,-Bsymbolic-functions\")\n    set (CMAKE_MODULE_LINKER_FLAGS \"${CMAKE_MODULE_LINKER_FLAGS} -Wl,-Bsymbolic -Wl,-Bsymbolic-functions\")\n\n    # Mark object non-lazy runtime binding.\n    set (CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,now\")\n    set (CMAKE_MODULE_LINKER_FLAGS \"${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,now\")\nendif ()\n\n# Build napa shared library.\nadd_subdirectory(src)\n\nif (CMAKE_JS_VERSION)\n    # Build napa addon for node.\n    add_subdirectory(node)\n    add_subdirectory(test/module/addon)\nendif()\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Napa.JS\n\nCopyright (c) Microsoft Corporation. All rights reserved. \n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"\"Software\"\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![Build Status for Linux/MacOS](https://travis-ci.org/Microsoft/napajs.svg?branch=master)](https://travis-ci.org/Microsoft/napajs)\n[![Build Status for Windows](https://ci.appveyor.com/api/projects/status/github/Microsoft/napajs?branch=master&svg=true)](https://ci.appveyor.com/project/napajs/napajs)\n[![npm version](https://badge.fury.io/js/napajs.svg)](https://www.npmjs.com/package/napajs)\n[![Downloads](https://img.shields.io/npm/dm/napajs.svg)](https://www.npmjs.com/package/napajs)\n\n# Napa.js\nNapa.js is a multi-threaded JavaScript runtime built on [V8](https://github.com/v8/v8), which was originally designed to develop highly iterative services with non-compromised performance in Bing. As it evolves, we find it useful to complement [Node.js](https://nodejs.org) in CPU-bound tasks, with the capability of executing JavaScript in multiple V8 isolates and communicating between them. Napa.js is exposed as a Node.js module, while it can also be embedded in a host process without Node.js dependency.\n\n## Installation\nInstall the latest stable version:\n```\nnpm install napajs\n```\nOther options can be found in [Build Napa.js](https://github.com/Microsoft/napajs/wiki/build-napa.js).\n\n## Quick Start\n```js\nconst napa = require('napajs');\nconst zone1 = napa.zone.create('zone1', { workers: 4 });\n\n// Broadcast code to all 4 workers in 'zone1'.\nzone1.broadcast('console.log(\"hello world\");');\n\n// Execute an anonymous function in any worker thread in 'zone1'.\nzone1.execute(\n    (text) => text, \n    ['hello napa'])\n    .then((result) => {\n        console.log(result.value);\n    });\n```\nMore examples:\n* [Estimate PI in parallel](./examples/tutorial/estimate-pi-in-parallel)\n* [Max sub-matrix of 1s with layered parallelism](./examples/tutorial/max-square-sub-matrix)\n* [Parallel Quick Sort](./examples/tutorial/parallel-quick-sort)\n* [Recursive Fibonacci with multiple JavaScript threads](./examples/tutorial/recursive-fibonacci)\n* [Synchronized loading](./examples/tutorial/synchronized-loading)\n\n## Features\n- Multi-threaded JavaScript runtime.\n- Node.js compatible module architecture with NPM support.\n- API for object transportation, object sharing and synchronization across JavaScript threads.\n- API for pluggable logging, metric and memory allocator.\n- Distributed as a Node.js module, as well as supporting embed scenarios.\n\n## Documentation\n- [Napa.js Home](https://github.com/Microsoft/napajs/wiki)\n- [API Reference](./docs/api/index.md)\n- [FAQ](https://github.com/Microsoft/napajs/wiki/FAQ)\n\n# Contribute\nYou can contribute to Napa.js in following ways:\n\n* [Report issues](https://github.com/Microsoft/napajs/issues) and help us verify fixes as they are checked in.\n* Review the [source code changes](https://github.com/Microsoft/napajs/pulls).\n* Contribute to core module compatibility with Node.\n* Contribute bug fixes.\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).<br> For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact opencode@microsoft.com with any additional questions or comments.\n\n# License\nCopyright (c) Microsoft Corporation. All rights reserved.\n\nLicensed under the [MIT](https://github.com/Microsoft/napajs/blob/master/LICENSE.txt) License.\n"
  },
  {
    "path": "appveyor.yml",
    "content": "environment:\n  matrix:\n    # Windows Server 2012 R2       Visual C++ Build Tools 2015\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      nodejs_version: 6\n    # Windows Server 2012 R2       Visual C++ Build Tools 2015\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015\n      nodejs_version: 8\n    # Windows Server 2016          Visual C++ Build Tools 2017\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017\n      nodejs_version: 9\n    # Windows Server 2016          Visual C++ Build Tools 2017\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017\n      nodejs_version: 10\n\nplatform:\n- x64\n\ninstall:\n- ps: Install-Product node $env:nodejs_version $env:platform\n- npm install cmake-js -g\n- npm install --no-fetch\n\n# Skip MSBuild stage\nbuild: off\n\ntest_script:\n- npm test\n- npm run unittest\n"
  },
  {
    "path": "benchmark/README.md",
    "content": "# Benchmark\n\n## Summary\n- JavaScript execution in napajs is on par with node, using the same version of V8, which is expected.\n- `zone.execute` scales linearly on number of workers, which is expected.\n- The overhead of calling `zone.execute` from node is around 0.1ms after warm-up. The cost of using anonymous function is neglectable.\n- `transport.marshall` cost on small plain JavaScript values is about 3x of JSON.stringify.\n- The overhead of `store.set` and `store.get` is around 0.06ms plus transport overhead on the objects.\n\nWe got this report on environment below:\n\n| Name              | Value                                                                                 |\n|-------------------|---------------------------------------------------------------------------------------|\n|**Processor**      |Intel(R) Xeon(R) CPU L5640 @ 2.27GHz, 8 virtual processors                             |\n|**System Type**    |x64-based PC                                                                           |\n|**Physical Memory**|16.0 GB                                                                                |\n|**OS version**     |Microsoft Windows Server 2012 R2                                                       |\n\n\n## Napa vs. Node on JavaScript execution \nPlease refer to [node-napa-perf-comparison.ts](node-napa-perf-comparison.ts).\n\n| node time | napa time |\n| --------- | --------- |\n| 3026.76   | 3025.81   |\n\n## Linear scalability\n`zone.execute` scales linearly on number of workers. We performed 1M CRC32 calls on a 1024-length string on each worker, here are the numbers. We still need to understand why the time of more workers running parallel would beat less workers.\n\n|         | node        | napa - 1 worker | napa - 2 workers | napa - 4 workers | napa - 8 workers |\n| ------- | ----------- | --------------- | ---------------- | ---------------- | ---------------- |\n| time    | 8,649521600 | 6146.98         | 4912.57          | 4563.48          | 6168.41          |\n| cpu%    | ~15%        | ~15%            | ~27%             | ~55%             | ~99%             |\n\nPlease refer to [execute-scalability.ts](./execute-scalability.ts) for test details.\n\n## Execute overhead\nThe overhead of `zone.execute` includes\n1. Marshalling cost of arguments in caller thread.\n2. Queuing time before a worker can execute.\n3. Unmarshalling cost of arguments in target worker.\n4. Marshalling cost of return value from target worker.\n5. Queuing time before caller callback is notified. \n6. Unmarshalling cost of return value in caller thread.\n\nIn this section we will examine #2 and #5. So we use empty function with no arguments and no return value.\n\nTransport overhead (#1, #3, #4, #6) varies by size and complexity of payload, will be benchmarked separately in [Transport Overhead](#transport-overhead) section.\n\nPlease refer to [execute-overhead.ts](./execute-overhead.ts) for test details.\n\n### Overhead after warm-up\nAverage overhead is around 0.06ms to 0.12ms for `zone.execute`.\n\n| repeat   | zone.execute (ms) |\n|----------|-------------------|\n| 200      | 24.932            |\n| 5000     | 456.893           |\n| 10000    | 810.687           |\n| 50000    | 3387.361          |\n\n*10000 times of zone.execute on anonymous function is 807.241ms. The gap is within range of bench noise.\n\n### Overhead during warm-up:\n\n| Sequence of call | Time (ms) |\n|------------------|-----------|\n| 1                |  6.040    |\n| 2                |  4.065    |\n| 3                |  5.250    |\n| 4                |  4.652    |\n| 5                |  1.572    |\n| 6                |  1.366    |\n| 7                |  1.403    |\n| 8                |  1.213    |\n| 9                |  0.450    |\n| 10               |  0.324    |\n| 11               |  0.193    |\n| 12               |  0.238    |\n| 13               |  0.191    |\n| 14               |  0.230    |\n| 15               |  0.203    |\n| 16               |  0.188    |\n| 17               |  0.188    |\n| 18               |  0.181    |\n| 19               |  0.185    |\n| 20               |  0.182    |\n\n\n## Transport overhead\n\nThe overhead of `transport.marshall` includes\n1. overhead of needing replacer callback during JSON.stringify. (even an empty callback will slow down JSON.stringify significantly)\n2. traverse every value during JSON.stringify, to check value type and get `cid` to put into payload.\n    - a. If value doesn't need special care.\n    - b. If value is a transportable object that needs special care.\n\n2.b is related to individual transportable classes, which may vary per individual class. Thus we examine #1 and #2.a in this test.\n\nThe overhead of `transport.unmarshall` includes\n1. overhead of needing reviver callback during JSON.parse.\n2. traverse every value during JSON.parse, to check if object has `_cid` property.\n    - a. If value doesn't have property `_cid`.\n    - b. Otherwise, find constructor and call the [`Transportable.marshall`](../docs/api/transport.md#transportable-marshall).\n\nWe also evaluate only #1, #2.a in this test.\n\nPlease refer to [transport-overhead.ts](./transport-overhead.ts) for test details.\n\n\\*All operations are repeated for 1000 times.\n\n| payload type                       | size  | JSON.stringify (ms) | transport.marshall (ms) | JSON.parse (ms) | transport.unmarshall (ms) |\n| ---------------------------------- | ----- | ------------------- | ----------------------- | --------------- | ------------------------- |\n| 1 level - 10 integers              | 91    | 4.90                | 18.05 (3.68x)           | 3.50            | 17.98 (5.14x)             |\n| 1 level - 100 integers             | 1081  | 65.45               | 92.78 (1.42x)           | 20.45           | 122.25 (5.98x)            |\n| 10 level - 2 integers              | 18415 | 654.40              | 2453.37 (3.75x)         | 995.02          | 2675.72 (2.69x)           |\n| 2 level - 10 integers              | 991   | 19.74               | 66.82 (3.39x)           | 27.85           | 138.45 (4.97x)            |\n| 3 level - 5 integers               | 1396  | 33.66               | 146.33 (4.35x)          | 51.54           | 189.07 (3.67x)            |\n| 1 level - 10 strings - length 10   | 201   | 3.81                | 10.17 (2.67x)           | 9.46            | 20.81 (2.20x)             |\n| 1 level - 100 strings - length 10  | 2191  | 76.53               | 115.74 (1.51x)          | 77.71           | 181.24 (2.33x)            |\n| 2 level - 10 strings - length 10   | 2091  | 30.15               | 97.65 (3.24x)           | 95.51           | 213.20 (2.23x)            |\n| 3 level - 5 strings - length 10    | 2646  | 41.95               | 155.42 (3.71x)          | 123.82          | 227.90 (1.84x)            |\n| 1 level - 10 strings - length 100  | 1101  | 7.74                | 12.19 (1.57x)           | 17.34           | 29.83 (1.72x)             |\n| 1 level - 100 strings - length 100 | 11191 | 66.17               | 112.83 (1.71x)          | 197.67          | 282.63 (1.43x)            |\n| 2 level - 10 strings - length 100  | 11091 | 68.46               | 149.99 (2.19x)          | 202.85          | 298.19 (1.47x)            |\n| 3 level - 5 integers               | 13896 | 89.46               | 208.21 (2.33x)          | 265.25          | 418.42 (1.58x)            |\n| 1 level - 10 booleans              | 126   | 2.84                | 8.14 (2.87x)            | 3.06            | 14.20 (4.65x)             |\n| 1 level - 100 booleans             | 1341  | 20.28               | 59.36 (2.93x)           | 21.59           | 121.15 (5.61x)            |\n| 2 level - 10 booleans              | 1341  | 23.92               | 89.62 (3.75x)           | 31.84           | 137.92 (4.33x)            |\n| 3 level - 5 booleans               | 1821  | 36.15               | 138.24 (3.82x)          | 55.71           | 195.50 (3.51x)            |\n\n## Store access overhead\n\nThe overhead of `store.set` includes\n1. Overhead of calling `transport.marshall` on value.\n2. Overhead of put marshalled data and transport context into C++ map (with exclusive_lock).\n\nThe overhead of `store.get` includes\n1. Overhead of getting marshalled data and transport context from C++ map (with shared_lock).\n2. Overhead of calling `transport.unmarshall` on marshalled data.\n\nFor `store.set`, numbers below indicates the cost beyond marshall is around 0.07~0.4ms varies per payload size. (10B to 18KB). `store.get` takes a bit more: 0.06~0.9ms with the same payload size variance. If the value in store is not updated frequently, it's always good to cache it in JavaScript world.\n\nPlease refer to [store-overhead.ts](./store-overhead.ts) for test details.\n\n\\*All operations are repeated for 1000 times.\n\n| payload type                       | size  | transport.marshall (ms) | store.save (ms) | transport.unmarshall (ms) | store.get (ms) |\n| ---------------------------------- | ----- | ----------------------- | --------------- | ------------------------- | -------------- |\n| 1 level - 1 integers               | 10    | 2.54                    | 73.85           | 3.98                      | 65.57          |\n| 1 level - 10 integers              | 91    | 8.27                    | 98.55           | 17.23                     | 90.89          |\n| 1 level - 100 integers             | 1081  | 97.10                   | 185.31          | 144.75                    | 274.39         |\n| 10 level - 2 integers              | 18415 | 2525.18                 | 2973.17         | 3093.06                   | 3927.80        |\n| 2 level - 10 integers              | 991   | 71.22                   | 174.01          | 154.76                    | 276.04         |\n| 3 level - 5 integers               | 1396  | 127.06                  | 219.73          | 182.27                    | 337.59         |\n| 1 level - 10 strings - length 10   | 201   | 14.43                   | 79.68           | 31.28                     | 84.71          |\n| 1 level - 100 strings - length 10  | 2191  | 104.40                  | 212.44          | 173.32                    | 239.09         |\n| 2 level - 10 strings - length 10   | 2091  | 79.54                   | 188.72          | 189.29                    | 252.83         |\n| 3 level - 5 strings - length 10    | 2646  | 155.14                  | 257.78          | 276.22                    | 342.95         |\n| 1 level - 10 strings - length 100  | 1101  | 15.22                   | 89.84           | 30.87                     | 88.18          |\n| 1 level - 100 strings - length 100 | 11191 | 119.89                  | 284.05          | 287.17                    | 403.77         |\n| 2 level - 10 strings - length 100  | 11091 | 137.10                  | 299.32          | 244.13                    | 297.12         |\n| 3 level - 5 integers               | 13896 | 183.84                  | 310.89          | 285.80                    | 363.50         |\n| 1 level - 10 booleans              | 126   | 5.74                    | 49.89           | 22.69                     | 97.27          |\n| 1 level - 100 booleans             | 1341  | 57.41                   | 157.80          | 106.30                    | 218.05         |\n| 2 level - 10 booleans              | 1341  | 76.93                   | 150.25          | 104.02                    | 185.82         |\n| 3 level - 5 booleans               | 1821  | 102.47                  | 171.44          | 150.42                    | 207.27         |\n"
  },
  {
    "path": "benchmark/bench-utils.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/// <summary> Utility function to generate object for testing. </summary>\n\nexport function generateString(length: number): string {\n    return Array(length).join('x');\n}\n\nexport function generateObject(keys: number, depth: number, valueType: string = \"string\", valueLength = 7) {\n    let object: any = {};\n    for (let i = 0; i < keys; ++i) {\n        let key = `key${i}`;\n        let value: any = null;\n        if (depth > 1) {\n            value = generateObject(keys, depth - 1, valueType, valueLength);\n        }\n        else if (valueType === 'string') {\n            // We try to make each string different.\n            value = generateString(valueLength - 1) + (depth * keys + i);\n        }\n        else if (valueType === 'number') {\n            value = i;\n        }\n        else if (valueType === 'boolean') {\n            value = i % 2 == 0;\n        }\n        object[key] = value;\n    }\n    return object;\n}\n\nexport function timeDiffInMs(diff: [number, number]): number {\n    return (diff[0] * 1e9 + diff[1]) / 1e6;\n}\n\nexport function formatTimeDiff(diff: number | [number, number], printUnit: boolean = false): string {\n    if (Array.isArray(diff)) {\n        diff = timeDiffInMs(diff);\n    }\n    let message = diff.toFixed(2);\n    if (printUnit) {\n        message += \"ms\"\n    }\n    return message;\n}\n\nexport function formatRatio(dividend: number, divider: number): string {\n    return \"(\" + (dividend / divider).toFixed(2) + \"x)\";\n}"
  },
  {
    "path": "benchmark/bench.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as nodeNapaPerfComp from './node-napa-perf-comparison';\nimport * as executeOverhead from './execute-overhead';\nimport * as executeScalability from './execute-scalability';\nimport * as transportOverhead from './transport-overhead';\nimport * as storeOverhead from './store-overhead';\n\nexport function bench(): Promise<void> {\n    // Non-zone related benchmarks.\n    transportOverhead.bench();\n    storeOverhead.bench();\n\n    // Create zones for execute related benchmark.\n    let singleWorkerZone = napa.zone.create('single-worker-zone', { workers: 1});\n    let multiWorkerZone = napa.zone.create('multi-worker-zone', { workers: 8 });\n\n    return nodeNapaPerfComp.bench(singleWorkerZone)\n        .then(() => { return executeOverhead.bench(singleWorkerZone); })\n        .then(() => { return executeScalability.bench(multiWorkerZone);});\n}\n\nbench();"
  },
  {
    "path": "benchmark/execute-overhead.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as mdTable from 'markdown-table';\nimport { formatTimeDiff } from './bench-utils';\n\nfunction batchExecuteOnNamedFunction(\n    zone: napa.zone.Zone, \n    repeat: number,\n    args: any[]): Promise<void> {\n    \n    return new Promise<void>((resolve, reject) => {\n        let finished = 0;\n        let start = process.hrtime();\n        for (let i = 0; i < repeat; ++i) {\n            zone.execute(\"\", \"test\", args).then(() => {\n                ++finished;\n                if (finished === repeat) {\n                    resolve();\n                }\n            });\n        }\n    });\n}\n\nfunction batchExecuteOnAnonymousFunction(\n    zone: napa.zone.Zone, \n    repeat: number,\n    args: any[]): Promise<void> {\n    \n    return new Promise<void>((resolve, reject) => {\n        let finished = 0;\n        let start = process.hrtime();\n        for (let i = 0; i < repeat; ++i) {\n            zone.execute(() => {}, args).then(() => {\n                ++finished;\n                if (finished === repeat) {\n                    resolve();\n                }\n            });\n        }\n    });\n}\n\nexport async function bench(zone: napa.zone.Zone): Promise<void> {\n    console.log(\"Benchmarking execute overhead...\");\n\n    // Prepare a empty function.\n    await zone.broadcast(\"function test() {}\");\n    const ARGS = [1, \"hello\", {a: 1, b: true}];\n\n    // Warm-up.\n    const WARMUP_REPEAT: number = 20;\n\n    console.log(\"## Execute overhead during warmup\\n\")\n    let warmupTable = [];\n    warmupTable.push([\"call #\", \"time (ms)\"]);\n    for (let i = 0; i < WARMUP_REPEAT; ++i) {\n        let start = process.hrtime();\n        await zone.execute(\"\", \"test\", ARGS);\n        warmupTable.push([i.toString(), formatTimeDiff(process.hrtime(start))]);\n    }\n    console.log(mdTable(warmupTable));\n\n    // execute after warm-up\n    const REPEAT: number = 10000;\n    console.log(\"## `zone.execute` overhead (use function name)\\n\");\n    let start = process.hrtime();\n    await batchExecuteOnNamedFunction(zone, REPEAT, ARGS);\n    console.log(`Elapse of running empty function by name for ${REPEAT} times: ${formatTimeDiff(process.hrtime(start), true)}\\n`);\n\n    console.log(\"## `zone.execute` overhead (use anonymous function)\\n\");\n    start = process.hrtime();\n    await batchExecuteOnAnonymousFunction(zone, REPEAT, ARGS);\n    console.log(`Elapse of running empty anonymous function for ${REPEAT} times: ${formatTimeDiff(process.hrtime(start), true)}\\n`);\n\n    return;\n}"
  },
  {
    "path": "benchmark/execute-scalability.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as assert from 'assert';\nimport * as mdTable from 'markdown-table';\nimport { formatTimeDiff } from './bench-utils';\n\nfunction makeCRCTable(){\n    var c;\n    var crcTable = [];\n    for(var n =0; n < 256; n++){\n        c = n;\n        for(var k =0; k < 8; k++){\n            c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n        }\n        crcTable[n] = c;\n    }\n    return crcTable;\n}\n\nlet crcTable = makeCRCTable();\nfunction crc32(str: string) {\n    let crc = 0 ^ (-1);\n    for (var i = 0; i < str.length; i++ ) {\n        crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];\n    }\n\n    return (crc ^ (-1)) >>> 0;\n};\n\nfunction testCrc() {\n    const REPEAT: number = 1000000;\n    let result = 0;\n    let key = Array(1024).join('x');\n    for (let i = 0; i < REPEAT; ++i) {\n        let hash = crc32(key);\n        result = result ^ hash;\n    }\n    return result;\n}\n\nexport async function bench(zone: napa.zone.Zone): Promise<void> {\n    console.log(\"Benchmarking execute scalability...\");\n\n    // Prepare a empty function.\n    await zone.broadcast(makeCRCTable.toString());\n    await zone.broadcast(\"var crcTable = makeCRCTable();\");\n    await zone.broadcast(crc32.toString());\n    await zone.broadcast(testCrc.toString());\n\n    // Warm-up.\n    let crcResult = testCrc();\n    await zone.broadcast(\"testCrc()\");\n\n    // Execute in Node with 1 thread.\n    let start = process.hrtime();\n    assert(testCrc() === crcResult);\n    let nodeTime = formatTimeDiff(process.hrtime(start));\n\n    let executeTime = {};\n    let scalabilityTest = function(workers: number): Promise<void> {\n        let finished = 0;\n        let start = process.hrtime();\n\n        return new Promise<void>((resolve, reject) => {\n            for (let i = 0; i < workers; ++i) {\n                zone.execute(\"\", \"testCrc\", []).then((result: napa.zone.Result) => {\n                    assert(crcResult === result.value);\n                    ++finished;\n                    if (finished === workers) {\n                        executeTime[workers] = formatTimeDiff(process.hrtime(start))\n                        resolve();\n                    }\n                });\n            }\n        })\n    };\n\n    // Execute from 1 worker to 8 workers.\n    await scalabilityTest(1);\n    await scalabilityTest(2);\n    await scalabilityTest(4);\n    await scalabilityTest(8);\n    console.log(\"## Execute scalability\\n\")\n    console.log(mdTable([\n        [\"node\", \"napa - 1 worker\", \"napa - 2 workers\", \"napa - 4 workers\", \"napa - 8 workers\"],\n        [nodeTime, executeTime[1], executeTime[2], executeTime[4], executeTime[8]]\n    ]));\n    console.log('');\n}"
  },
  {
    "path": "benchmark/node-napa-perf-comparison.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as mdTable from 'markdown-table';\nimport { formatTimeDiff } from './bench-utils';\n\nexport function timeIt(func: () => void): [number, number] {\n    let start = process.hrtime();\n    func();\n    return process.hrtime(start);\n}\n\nexport function test1(): [number, number] {\n    return timeIt(() => {\n        const REPEAT = 1000000000;\n        let sum = 0;\n        for (let i = 0; i < REPEAT; ++i) {\n            sum += i;\n        }\n    });\n}\n\nexport async function bench(zone: napa.zone.Zone): Promise<void> {\n    zone.broadcast(timeIt.toString());\n    zone.broadcast(test1.toString());\n\n    // Warm up.\n    test1();\n    await zone.execute('', 'test1', []);\n\n    // Actual test.\n    let table = [];\n    table.push([\"node time\", \"napa time\"]);\n    let nodeTime = formatTimeDiff(test1());\n    let napaTime = formatTimeDiff((await zone.execute('', 'test1', [])).value);\n    table.push([nodeTime, napaTime]);\n        \n    console.log(\"## Node vs Napa JavaScript execution performance\\n\");\n    console.log(mdTable(table));\n    console.log('');\n}"
  },
  {
    "path": "benchmark/store-overhead.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as assert from 'assert';\nimport * as mdTable from 'markdown-table';\nimport { generateObject, formatTimeDiff } from './bench-utils';\n\ntype BenchmarkSettings = [\n    string,     // label\n    number,     // # of keys per level\n    number,     // # of levels\n    string,     // value type\n    number      // value length for string.\n];\n\nexport function bench() {\n    console.log(\"Benchmarking store overhead...\");\n    let settings: BenchmarkSettings[] = [\n        // Number\n        [\"1 level - 1 integers\", 1, 1, \"number\", 0],\n        [\"1 level - 10 integers\", 10, 1, \"number\", 0],\n        [\"1 level - 100 integers\", 100, 1, \"number\", 0],\n        [\"10 level - 2 integers\", 2, 10, \"number\", 0],\n        [\"2 level - 10 integers\", 10, 2, \"number\", 0],\n        [\"3 level - 5 integers\", 5, 3, \"number\", 0],\n\n        // String\n        [\"1 level - 10 strings - length 10\", 10, 1, \"string\", 10],\n        [\"1 level - 100 strings - length 10\", 100, 1, \"string\", 10],\n        [\"2 level - 10 strings - length 10\", 10, 2, \"string\", 10],\n        [\"3 level - 5 strings - length 10\", 5, 3, \"string\", 10],\n\n        [\"1 level - 10 strings - length 100\", 10, 1, \"string\", 100],\n        [\"1 level - 100 strings - length 100\", 100, 1, \"string\", 100],\n        [\"2 level - 10 strings - length 100\", 10, 2, \"string\", 100],\n        [\"3 level - 5 integers\", 5, 3, \"string\", 100],\n\n        // Boolean\n        [\"1 level - 10 booleans\", 10, 1, \"boolean\", 0],\n        [\"1 level - 100 booleans\", 100, 1, \"boolean\", 0],\n        [\"2 level - 10 booleans\", 10, 2, \"boolean\", 0],\n        [\"3 level - 5 booleans\", 5, 3, \"boolean\", 0],\n    ];\n\n    let store = napa.store.create('store');\n    let table = [];\n    table.push([\"payload type\", \"size\", \"transport.marshall (ms)\", \"store.save (ms)\", \"transport.unmarshall (ms)\", \"store.get (ms)\"]);\n\n    for (let s of settings) {\n        const REPEAT = 1000;\n        let object = generateObject(s[1], s[2], s[3], s[4])\n        let payload = JSON.stringify(object);\n        let size = payload.length;\n\n        // transport.marshall\n        let start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            napa.transport.marshall(object, null);\n        }\n        let marshallTime = formatTimeDiff(process.hrtime(start));\n\n        // store.set\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            store.set('key', object);\n        }\n        let storeSetTime = formatTimeDiff(process.hrtime(start));\n\n        assert.deepEqual(object, store.get('key'));\n\n        // transport.unmarshall\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            napa.transport.unmarshall(payload, null);\n        }\n        let unmarshallTime = formatTimeDiff(process.hrtime(start));\n\n        // store.get\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            store.get('key');\n        }\n        let storeGetTime = formatTimeDiff(process.hrtime(start));\n\n        table.push([s[0], size, marshallTime, storeSetTime, unmarshallTime, storeGetTime]);\n    }\n    console.log(\"## Store access overhead\\n\");\n    console.log(mdTable(table));\n    console.log('');\n}"
  },
  {
    "path": "benchmark/transport-overhead.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../lib/index';\nimport * as assert from 'assert';\nimport * as mdTable from 'markdown-table';\nimport { generateObject, timeDiffInMs, formatTimeDiff, formatRatio } from './bench-utils';\n\ntype BenchmarkSettings = [\n    string,     // label\n    number,     // # of keys per level\n    number,     // # of levels\n    string,     // value type\n    number      // value length for string.\n];\n\nexport function bench() {\n    console.log(\"Benchmarking transport overhead...\");\n    let settings: BenchmarkSettings[] = [\n        // Number\n        [\"1 level - 10 integers\", 10, 1, \"number\", 0],\n        [\"1 level - 100 integers\", 100, 1, \"number\", 0],\n        [\"10 level - 2 integers\", 2, 10, \"number\", 0],\n        [\"2 level - 10 integers\", 10, 2, \"number\", 0],\n        [\"3 level - 5 integers\", 5, 3, \"number\", 0],\n\n        // String\n        [\"1 level - 10 strings - length 10\", 10, 1, \"string\", 10],\n        [\"1 level - 100 strings - length 10\", 100, 1, \"string\", 10],\n        [\"2 level - 10 strings - length 10\", 10, 2, \"string\", 10],\n        [\"3 level - 5 strings - length 10\", 5, 3, \"string\", 10],\n\n        [\"1 level - 10 strings - length 100\", 10, 1, \"string\", 100],\n        [\"1 level - 100 strings - length 100\", 100, 1, \"string\", 100],\n        [\"2 level - 10 strings - length 100\", 10, 2, \"string\", 100],\n        [\"3 level - 5 integers\", 5, 3, \"string\", 100],\n\n        // Boolean\n        [\"1 level - 10 booleans\", 10, 1, \"boolean\", 0],\n        [\"1 level - 100 booleans\", 100, 1, \"boolean\", 0],\n        [\"2 level - 10 booleans\", 10, 2, \"boolean\", 0],\n        [\"3 level - 5 booleans\", 5, 3, \"boolean\", 0],\n    ];\n\n    let table = [];\n    table.push([\"payload type\", \"size\", \"JSON.stringify (ms)\", \"transport.marshall (ms)\", \"JSON.parse (ms)\", \"transport.unmarshall (ms)\"]);\n    for (let s of settings) {\n        const REPEAT = 1000;\n        let object = generateObject(s[1], s[2], s[3], s[4])\n        let payload = JSON.stringify(object);\n        let size = payload.length;\n\n        // JSON.stringify\n        let start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            JSON.stringify(object);\n        }\n        let stringifyTime = timeDiffInMs(process.hrtime(start));\n        let stringifyTimeText = formatTimeDiff(stringifyTime);\n\n        // transport.marshall\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            napa.transport.marshall(object, null);\n        }\n        let marshallTime = timeDiffInMs(process.hrtime(start));\n        let marshallTimeText = formatTimeDiff(marshallTime) + \" \" + formatRatio(marshallTime, stringifyTime);\n\n        let marshalled = napa.transport.marshall(object, null);\n        assert.deepEqual(payload, marshalled);\n\n        // JSON.parse\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            JSON.parse(payload);\n        }\n        let parseTime = timeDiffInMs(process.hrtime(start));\n        let parseTimeText = formatTimeDiff(parseTime);\n\n        start = process.hrtime();\n        for (let i = 0; i < REPEAT; ++i) {\n            napa.transport.unmarshall(payload, null);\n        }\n        let unmarshallTime = timeDiffInMs(process.hrtime(start));\n        let unmarshallTimeText = formatTimeDiff(unmarshallTime) + \" \" + formatRatio(unmarshallTime, parseTime);\n\n        table.push([s[0], size, stringifyTimeText, marshallTimeText, parseTimeText, unmarshallTimeText]);\n    }\n    console.log(\"## Transport overhead\\n\");\n    console.log(mdTable(table));\n    console.log('');\n}"
  },
  {
    "path": "benchmark/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": false,\n        \"declaration\": false,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"]\n    }\n}"
  },
  {
    "path": "build.bat",
    "content": ":: Copyright (c) Microsoft Corporation. All rights reserved.\n:: Licensed under the MIT license.\n@echo off\n\nset NODE_EXE=%~dp0\\node.exe\nif not exist \"%NODE_EXE%\" (\n  set NODE_EXE=node\n)\n\n%NODE_EXE% %~dp0\\build.js %*\n"
  },
  {
    "path": "build.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// Distinguish between running this file as a script or loading it as a module.\nif (module.parent) {\n    // Loaded as a module - 'require('./build.js')\n    exports.paths = require('./scripts/paths');\n}\nelse {\n    // Loaded as a script - 'node build.js'\n\n    // Remove first two parameters which are node executable and this javascript file.\n    // Transform all parameters to lowercase for easier handling.\n    let params = process.argv.slice(2).map((item) => item.toLowerCase());\n\n    // Specify wheater cleanup is needed.\n    if (params.indexOf('clean') != -1) {\n        require('./scripts/clean').clean();\n    }\n    \n    // Only build if embed was specified as a parameter.\n    if (params.indexOf('embed') != -1) {\n        let embedded = require('./scripts/embedded');\n\n        if (params.indexOf('debug') != -1) {\n            embedded.build('debug');\n        }\n        else {\n            embedded.build('release');\n        }\n    }\n}\n"
  },
  {
    "path": "docs/api/index.md",
    "content": "# API References\n\n## Core modules\n- Napa.js specific [`global`](./napa-globals.md) variables\n- Namespace [`zone`](./zone.md): Multi-thread JavaScript runtime\n- Namespace [`transport`](./transport.md): Passing JavaScript values across threads\n- Namespace [`store`](./store.md): Sharing JavaScript values by global storage\n- Namespace [`sync`](./sync.md): Handling synchronization between threads\n- Namespace [`memory`](./memory.md): Handling native objects and memory\n- Namespace [`metric`](./metric.md): Pluggable metrics.\n- Function [`log`](./log.md): Pluggable logging.\n\n## Node compatibility\n- [List of supported Node APIs](./node-api.md)\n\n## API for creating modules\n- [Writing Napa.js modules](./module.md)\n"
  },
  {
    "path": "docs/api/log.md",
    "content": "# Function `log`\n\n## Table of Contents\n- [Introduction](#intro)\n- [C++ API](#cpp-api)\n- [JavaScript API](#js-api)\n    - [`log(message: string): void`](#log)\n    - [`log(section: string, message: string): void`](#log-with-section)\n    - [`log(section: string, traceId: string, message: string): void`](#log-with-traceid)\n    - [`log.err(...)`](#log-err)\n    - [`log.warn(...)`](#log-warn)\n    - [`log.info(...)`](#log-info)\n    - [`log.debug(...)`](#log-debug)\n- [Using custom logging providers](#use-custom-providers)\n- [Developing custom logging providers](#develop-custom-providers)\n\n## <a name=\"intro\"></a> Introduction\nLogging is a basic requirement for building services. `napajs` logging API enables developers to integrate their own logging capabilities in both JavaScript and C++ (addon) world.\n\nA log row may contain the following information:\n- (Optional) Section: Useful field to filter log rows. Treatment is defined by logging providers.\n- (Optional) Trace ID: Useful field to join logs in the same transaction or request.\n- (Required) Message: Log message.\n- (Required) Logging level: \n    - Error: for application error.\n    - Warn: for warning information.\n    - Info: for notification. \n    - Debug: for debugging purpose.\n\n## <a name=\"cpp-api\"></a> C++ API\nInclude header: `<napa.h>`\n\nMacros:\n- LOG_ERROR(section, format, ...)\n- LOG_ERROR_WITH_TRACEID(section, traceId, format, ...)\n- LOG_WARNING(section, format, ...)\n- LOG_WARNING_WITH_TRACEID(section, traceId, format, ...)\n- LOG_INFO(section, format, ...)\n- LOG_INFO_WITH_TRACEID(section, traceId, format, ...)\n- LOG_DEBUG(section, format, ...)\n- LOG_DEBUG_WITH_TRACEID(section, traceId, format, ...)\n\n```cpp\n#include <napa.h>\n\nvoid MyFunction() {\n    // ...\n    LOG_ERROR(\"init\", \"error: %s\", errorMessage.c_str());\n}\n```\n\n## <a name=\"js-api\"></a> JavaScript API\n\n### <a name=\"log\"></a> log(message: string): void\nIt logs a message. Using info level. \n\n* A `log` is a shortcut for `log.info`.*\n\nExample:\n```js\nvar napa = require('napajs');\nnapa.log('program started');\n```\n\n### <a name=\"log-with-section\"></a> log(section: string, message: string): void\nIt logs a message with a section. Using info level. \n\nExample:\n```js\nnapa.log('init', 'program started');\n```\n\n### <a name=\"log-with-traceid\"></a> log(section: string, traceId: string, message: string): void\nIt logs a message with a section, associating it with a traceId. Using info level.\n\nExample:\n```js\nnapa.log('request', 'A1B2C3D4', 'request received');\n```\n### <a name=\"log-err\"></a> log.err(...)\nIt logs an error message. Three variations of arguments are the same with the `log`.\n\n### <a name=\"log-warn\"></a> log.warn(...)\nIt logs a warning message. Three variations of arguments are the same with the `log`.\n\n### <a name=\"log-info\"></a>log.info(...)\nIt logs an info message. Three variations of arguments are the same with the `log`.\n\n### <a name=\"log-debug\"></a> log.debug(...)\nIt logs a debug message. Three combinations of arguments are the same with the `log`.\n\n## <a name=\"use-custom-providers\"></a> Using custom logging providers\nDevelopers can hook up custom logging provider by calling the following before creation of any zones:\n```js\nnapa.runtime.setPlatformSettings({\n    \"loggingProvider\": \"<custom-logging-provider-module-name>\"\n}\n```\n## <a name=\"develop-custom-providers\"></a> Developing custom logging providers\nTBD\n"
  },
  {
    "path": "docs/api/memory.md",
    "content": "# Namespace `memory`\n\n## Table of Contents\n- [API](#api)\n    - Type [`Handle`](#handle)\n    - Interface [`Shareable`](#shareable)\n    - Interface [`Allocator`](#allocator)\n        - [`allocator.allocate(size: number): Handle`](#allocator-allocate)\n        - [`allocator.deallocate(handle: Handle, sizeHint: number): void`](#allocator-deallocate)\n        - [`allocator.type: string`](#allocator-type)\n    - Interface [`AllocatorDebugger`](#allocatordebugger)\n        - [`allocatorDebugger.getDebugInfo(): string`](#allocatordebugger-getdebuginfo)\n    - Function [`debugAllocator(allocator: Allocator): AllocatorDebugger`](#debugallocator)\n    - Object [`crtAllocator`](#crtallocator)\n    - Object [`defaultAllocator`](#defaultallocator)\n    - [Memory allocation in C++ addon](#memory-allocation-in-cpp-addon)\n\n## <a name=\"api\"></a> API\n## <a name=\"handle\"></a> Type `Handle`\nHandle is defined in TypeScript as below:\n```ts\ntype Handle = [number, number]\n``` \nIt is a standard way to represent a 64-bit pointer in Napa.\n\n## <a name=\"shareable\"></a> Interface `Shareable`\nInterface for native object wrap that can be shared across multiple JavaScript threads.\n\n## <a name=\"allocator\"></a> Interface `Allocator`\nInterface for memory allocator that allocates memory for native objects. \n\n### <a name=\"allocator-allocate\"></a> allocator.allocate(size: number): Handle\nIt allocates memory of requested size.\n\n```js\nvar handle = allocator.allocate(10);\n```\n### <a name=\"allocator-deallocate\"></a> allocator.deallocate(handle: Handle, sizeHint: number): void\nIt deallocates memory from a input handle, with a size hint which is helpful for some C++ allocator implementations for deallocating memory.\n```js\nallocator.deallocate(handle, 10);\n```\n### <a name=\"allocator-type\"></a> allocator.type: string\nIt gets a string type identifier for the allocator, which will be useful during debugging purpose.\n\n## <a name=\"allocatordebugger\"></a> Interface `AllocatorDebugger`\n`AllocatorDebugger` extends interface `Allocator`, with a member function `getDebugInfo` to expose debug information. Basically an allocator debugger will use a pass-in allocator for memory allocation, meanwhile intercepting it to keep track of allocation count and size. \n\n### <a name=\"allocatordebugger-getdebuginfo\"></a> allocatorDebugger.getDebugInfo(): string\nIt gets the debug information for allocation. Implementations of interface `AllocatorDebugger` can have different schema on debug info.\n\n## <a name=\"debugallocator\"></a> debugAllocator(allocator: Allocator): AllocatorDebugger\nIt returns a simple allocator debugger, which returns debug information like below:\n```json\n{\n    \"allocate\": 10,\n    \"allocateSize\": 1024,\n    \"deallocate\": 8,\n    \"deallocateSize\": 912\n}\n```\n## <a name=\"crtallocator\"></a> Object `crtAllocator`\nIt returns a C-runtime allocator from Napa.js shared library. Its corresponding C++ part is `napa::memory::GetCrtAllocator()`.\n\n## <a name=\"defaultallocator\"></a> Object `defaultAllocator`\nIt returns the default allocator from Napa.js shared library. Its corresponding C++ part is `napa::memory::GetDefaultAllocator()`. \n\nUsers can set default allocation/deallocation callback in `napa_allocator_set` API.\n\n## <a name=\"memory-allocation-in-cpp-addon\"></a> Memory allocation in C++ addon\nMemory allocation in C++ addon is tricky. A common pitfall is to allocate memory in one dll, but deallocate in another. This can cause issue if C-runtime in these 2 dlls are not compiled the same way. \n\nThere are also advanced scenarios that user want to customize memory allocation. Napa.js provides APIs for customizing memory allocator as well.\n\n### Recommended way of allocate memory\nTBD\n\n### Customize memory allocation\nTBD\n\n"
  },
  {
    "path": "docs/api/metric.md",
    "content": "# Namespace `metric`\n\n## Table of Contents\n- [Introduction](#intro)\n- [C++ API](#cpp-api)\n    - Interface [`Metric`](#cpp-metric)\n    - Interface [`MetricProvider`](#cpp-metricprovider)\n    - Function [`MetricProvider& GetMetricProvider()`](#cpp-getmetricprovider)\n- [JavaScript API](#js-api)\n    - Enum [`MetricType`](#metrictype)\n    - Class [`Metric`](#metric)\n        - [`set(value: number, dimensions?: string[]): void`](#metric-set)\n        - [`increment(dimensions?: string[]): void`](#metric-increment);\n        - [`decrement(dimensions?: string[]): void`](#metric-decrement);\n    - Function [`get(section: string, name: string, type: MetricType, dimensionNames: string[])`](#get)\n- [Using custom metric providers](#use-custom-providers)\n- [Developing custom metric providers](#develop-custom-providers)\n\n## <a name=\"intro\"></a> Introduction\nSimilar as logging, metric is a basic requirement for creating monitorable services. Metric API enables developers to use their own metric system in both JavaScript and C++ (addon) world.\n\nA metric has its identity containing following information:\n- **Section**: The group or category of the metric.\n- **Name**: Name of the metric. Section/Name combination should be unique in the system.\n- **Type**: Type of the metric, which can be\n    - *Number*: An absolute number, e.g: PrivateBytes.\n    - *Rate*: A flowing volume in number, e.g: QueryPerSecond.\n    - *Percentile*: An absolute number that needs to be sampled by percentiles, e.g: SuccessLatency.\n- **Dimensions**: A metric can have multiple dimensions, each dimension can bind with a string value at runtime. e.g: IncomingRequestRate can have 2 dimensions: ['client-id', 'request-type'].\n\nMetrics are process-wise objects, which can be used across [zones](./zone.md#intro).\n\n## <a name=\"cpp-api\"></a> C++ API\n### <a name=\"cpp-metric\"></a> Interface Metric\n```cpp\n /// <summary> Enumeration of metric type. </summary>\n    enum class MetricType {\n        Number = 0,\n        Rate,\n        Percentile,\n    };\n\n    /// <summary> Interface to represent a multi-dimensional metric with a maximum dimensionality of 64. </summary>\n    class Metric {\n    public:\n\n        /// <summary> Sets a metric value with variadic dimension arguments. </summary>\n        /// <param name=\"value\"> Int64 value. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions provided when\n        ///     creating this metric.\n        /// </remarks>\n        virtual bool Set(int64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary>\n        ///     Increments a metric value with variadic dimension arguments.\n        ///     Use mainly to simplify rate counters.\n        /// </summary>\n        /// <param name=\"value\"> UInt64 value to increment. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions\n        ///     provided when creating this metric.\n        /// </remarks>\n        virtual bool Increment(uint64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary>\n        ///     Decrements metric value with variadic dimension arguments.\n        ///     Use mainly to simplify rate counters.\n        /// </summary>\n        /// <param name=\"value\"> UInt64 value to decrement. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions\n        ///     provided when creating this metric.\n        /// </remarks>\n        virtual bool Decrement(uint64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary> Explicitly destroys the Metric. </summary>\n        /// <remarks>\n        ///     Consumers are not required to call this.\n        ///     The MetricProvider owns this class and will automatically perform cleanup on shutdown.\n        /// </remarks>\n        virtual void Destroy() = 0;\n\n    protected:\n\n        ///<summary> Prevent calling delete on the interface. Must use Destroy! </summary>\n        virtual ~Metric() = default;\n    };\n```\n### <a name=\"cpp-metricprovider\"></a> Interface MetricProvider\n```cpp\n\n    /// <summary> Interface for a generic metric provider. </summary>\n    /// <remarks> \n    ///     Ownership of this metric provider belongs to the shared library which created it. Hence the explicit\n    ///     Destroy method in this class. To simplify memory management across multiple shared libraries, this class\n    ///     can only be created via a factory method provided by the shared library. When it is no longer needed,\n    ///     the caller may call Destroy() which will tell the shared library which created it to dispose of the object.\n    /// </remarks>\n    class MetricProvider {\n    public:\n\n        /// <summary>\n        ///     Gets or creates a N-dimensional metric. Metric objects are owned and cached by this class.\n        ///     Up to 64 dimensions may be used.</summary>\n        /// <param name=\"section\"> Section of the metric.</param>\n        /// <param name=\"name\"> Name of the metric.</param>\n        /// <param name=\"type\"> Type of the metric.</param>\n        /// <param name=\"dimensions\">\n        ///     Number of dimensions requested for this metric.\n        ///     Represents the size of the array passed in for p_dimensionNames.\n        /// </param>\n        /// <param name=\"dimensionNames\"> Array of dimension names being requested for this metric.</param>\n        /// <remarks>\n        ///     The IMetric class returned is owned and cached by this class.\n        ///     Callers are not required to call destroy() on the Metric.\n        /// </remarks>\n        virtual Metric* GetMetric(\n            const char* section,\n            const char* name,\n            MetricType type,\n            size_t dimensions,\n            const char* dimensionNames[]) = 0;\n\n        ///<summary> Explicitly destroys the metric provider. </summary>\n        virtual void Destroy() = 0;\n\n    protected:\n\n        ///<summary> Prevent calling delete on the interface. Must use Destroy! </summary>\n        virtual ~MetricProvider() = default;\n    };\n```\n### <a name=\"cpp-getmetricprovider\"></a> function `MetricProvider& GetMetricProvider()`\n```cpp\n/// <summary> Exports a getter function for retrieves the configured metric provider. </summary>\nNAPA_API MetricProvider& GetMetricProvider();\n```\n## <a name=\"js-api\"></a> JavaScript API\n\n### <a name=\"metrictype\"></a> enum `MetricType`\n```ts\nexport enum MetricType {\n    Number = 0,\n    Rate,\n    Percentile,\n}\n```\n### <a name=\"metric\"></a> Class `Metric`\n\nClass to manipulate metrics in JavaScript.\n\n### <a name=\"metric-set\"></a> `set(value: number, dimensions?: string[]): void`\n\nSet absolute value on an instance of the metric constrained by dimension values.\nExample:\n```js\n// Create a percentile metric to measure end-to-end latency, with 1 dimension of client-id.\nlatency = napa.metric.get(\n    'app1',\n    'end-to-end-latency',\n    napa.metric.MetricType.Percentile, \n    ['client-id']);\n\n// Set end-to-end latency of current request to 100, with client-id 'client1'.\nlatency.set(100, ['client1']);\n```\n\n#### <a name=\"metric-increment\"></a> `increment(dimensions?: string[]): void`\n\nIncrement the value of an instance of the metric constrained by dimension values.\n\nExample:\n```js\n// Create a percentile metric to measure end-to-end latency, with 1 dimension of client-id.\nlatency = napa.metric.get(\n    'app1',\n    'qps',\n    napa.metric.MetricType.Rate, \n    ['client-id']);\n\n// Increment QPS of client-id 'client1'.\nlatency.increment(['client1']);\n```\n#### <a name=\"metric-decrement\"></a> `decrement(dimensions?: string[]): void`\nDecrement the value of an instance of the metric constrained by dimension values.\n\n### <a name=\"get\"></a> function `get(section: string, name: string, type: MetricType, dimensions: string[] = []): Metric`\nCreate a metric with an identity consisting of section, name, type and dimensions. If a metric already exists with given parameters, returns existing one.\n\nExample:\n```ts\nimport * as napa from 'napajs';\nlet metric = napa.metric.get(\n    'app1', \n    'counter1', \n    napa.metric.MetricType.Number, \n    []);\nmetric.increment([]);\n```\n## <a name=\"use-custom-providers\"></a> Using custom metric providers\nDevelopers can hook up custom metric provider by calling the following before creation of any zones:\n```ts\nnapa.runtime.setPlatformSettings({\n    \"metricProvider\": \"<custom-metric-provider-module-name>\"\n}\n```\n## <a name=\"develop-custom-providers\"></a> Developing custom metric providers\nTBD\n"
  },
  {
    "path": "docs/api/module.md",
    "content": "# Napa.js Module\n\n## Table of Contents\n- [Introduction](#intro)\n- [Developing modules](#develop-modules)\n  - [Module: JavaScript vs C++](#js-vs-cpp)\n- [Quick reference](#quick-ref)\n  - [JavaScript module](#ref-js-module)\n  - [C++ module](#ref-cpp-module)\n- [API](#api)\n  - [JavaScript API](#js-api)\n  - [C++ API](#cpp-api)\n    - [Exporting JavaScript class from C++ modules](#export-class)\n    - [V8 helpers](#v8helpers)\n    - [Using STL with custom allocators](#stl-with-allocator)\n- [Special topics](#topics)\n  - [Topic #1: Make objects shareable across multiple JavaScript threads](#topic-shareable-objects)\n  - [Topic #2: Asynchronous functions](#topic-async-functions)\n  - [Topic #3: Memory management in C++ modules](#topic-memory-management)\n\n## <a name=\"intro\"></a> Introduction\nNapa.js follows [Node.js' convention](https://nodejs.org/api/modules.html) to support modules, that means:\n\n1) Both JavaScript modules and C++ modules are supported.\n2) Module resolution follows the [same algorithm](https://nodejs.org/api/modules.html#modules_all_together), except instead of searching file extension `.node` for addons, Napa.JS searches `.napa`.\n3) Supports NPM, with the [same way](https://docs.npmjs.com/getting-started/creating-node-modules) to create and publish modules.\n4) API of creating C++ modules (addons) are similar. Napa.JS introduced macros that the same source code can be compiled to produce both Napa.js addon and Node.js addon.\n\nBut there are also differences:\n1) C++ module that is designed/implemented for Napa.js can run on Node.JS (need different compile flags to produce '.napa' and '.node'). But not vice versa.\n2) Napa.js doesn't support all Node.js API. Node API are supported [incrementally](./node-api.md) on the motivation of adding Node.js built-ins and core modules that are needed for computation heavy tasks. You can access full capabilities of Node exposed via [Node zone](./zone.md#node-zone).\n3) Napa.js doesn't provide `uv` functionalities, thus built-ins and core modules have its own implementation. To write async function in addon, methods `DoAsyncWork`/`PostAsyncWork` are introduced to work for both Napa.js and Node.js.\n4) Napa.js supports embed mode. C++ modules need separate compilation between Node mode and embed mode.\n\n\n## <a name=\"develop-modules\"></a> Developing modules\n### <a name=\"js-vs-cpp\"></a> Module: JavaScript vs. C++\nA quick glance at NPM will reveal that most modules are pure JavaScript. These are only a few reasons that you may want to create a C++ module.\n- You want to expose JavaScript API for existing C/C++ functionalities.\n- Code includes considerably amount of computation that is performance critical.\n- Objects need to be shared across multiple JavaScript threads, marshalling/unmarshalling cost on these objects is not trivial (big payload size, complex structure, etc.), but it's reasonable cheap to expose JavaScript APIs from underlying native objects.\n- In embed mode, you want to communicate with host process with native objects.\n\n[This post](https://docs.npmjs.com/getting-started/creating-node-modules) gives a good introduction on creating a JavaScript module. For creating a Napa.JS C++ module, please refer to the [API](#api) section or checkout examples in the [quick reference](#quick-reference) section.\n\n## <a name=\"quick-ref\"></a> Quick reference\n\n### <a name=\"ref-js-module\"></a> JavaScript module\n\n| Description                                                  | Transportable | Example code |\n| ------------------------------------------------------------ | ------------- | ------------ |\n| Standard JavaScript module                                   |               | [Blog post](https://www.hacksparrow.com/how-to-write-node-js-modules.html)           |\n| Share JavaScript object across isolates                      |      X        |              |\n\n### <a name=\"ref-cpp-module\"></a> C++ module\n\n| Description                                                  | ObjectWrap | Transportable | Async function | Example code |\n| ------------------------------------------------------------ | ---------- | ------------- | -------------- | ------------ |\n| Export JavaScript function only                              |            |               |                |  hello-world [[.md](../../examples/modules/hello-world/README.md) [.cpp](../../examples/modules/hello-world/node/addon.cpp) [test](../../examples/modules/hello-world/test/test.ts)]                           |\n| Export JavaScript object (ObjectWrap)                        |      X     |               |                |  plus-number [[.md](../../examples/modules/plus-number/README.md) [.cpp](../../examples/modules/plus-number/node/addon.cpp) [test](../../examples/modules/plus-number/test/module-test/test.ts)]            |\n| Share C++ object across isolates                             |      X     |      X        |                |  allocator-wrap [[.h](../../src/module/core-modules/napa/allocator-wrap.h) [.cpp](../../src/module/core-modules/napa/allocator-wrap.cpp)]            |\n| Export asynchronous JavaScript function                      |      X     |               |      X         |  async-number [[.md](../../examples/modules/async-number/README.md) [.cpp](../../examples/modules/async-number/node/addon.cpp) [test](../../examples/modules/async-number/test/test.ts)]            |\n\n## <a name=\"api\"></a> API\n### <a name=\"js-api\"></a> JavaScript\nSee [API reference](./index.md).\n\n### <a name=\"cpp-api\"></a> C++\n#### <a name=\"export-class\"></a> Exporting JavaScript classes from C++ modules\nTBD\n#### <a name=\"v8helpers\"></a> V8 helpers\nTBD\n#### <a name=\"stl-with-allocator\"></a> Using STL with custom allocators\nTBD\n\n## <a name=\"topics\"></a> Special topics\n### <a name=\"topic-shareable-objects\"></a> Topic #1: Make objects shareable across multiple JavaScript threads\nTBD\n\n### <a name=\"topic-async-functions\"></a> Topic #2: Asynchronous functions\nTBD\n\n### <a name=\"topic-memory-management\"></a> Topic #3: Memory management in C++ modules\nTBD\n"
  },
  {
    "path": "docs/api/napa-globals.md",
    "content": "# Napa.js specific global variables\n\nThis file describes Napa.js specific globals, please refer to [this documentation](./node-api.md#globals) for Node.js globals.\n\n## `global.napa`\nShortcut to access `napajs` module in all Napa enabled isolates. This is helpful to avoid extra `require` when using `napajs` module in anonymous function during `broadcast` or `execute`.\n\nExample:\n```js\nvar napa = require('napajs');\n\nvar zone = napa.zone.create('zone1');\n\nfunction test() {\n    global.napa.log('hi');\n}\n\nzone.execute(test);\n\n```"
  },
  {
    "path": "docs/api/node-api.md",
    "content": "# Node.js Compatibility\n\nNapa.js doesn't support full compatibility with node.js and necessary core modules will be added incrementally. Here are the list of what Napa.js currently supports. Please refer to https://nodejs.org/api/all.html for details.\n\n## Assert\n\nSince Napa doesn't support *Buffer* yet, assert is not working on *Buffer*.\n\n* assert(value[, message])\n* assert.deepEqual(actual, expected[, message])\n* assert.doesNotThrow(block[, error][, message])\n* assert.equal(actual, expected[, message])\n* assert.fail(actual, expected, message, operator)\n* assert.ifError(value)\n* assert.notDeepEqual(actual, expected[, message])\n* assert.notEqual(actual, expected[, message])\n* assert.notStrictEqual(actual, expected[, message])\n* assert.ok(value[, message])\n* assert.strictEqual(actual, expected[, message])\n* assert.throws(block[, error][, message])\n\n## Console\n\n* console.log([data][, ...args])\n\n## Events\n\n* Event: 'newListener'\n* Event: 'removeListener'\n* EventEmitter.listenerCount(emitter, eventName)\n* EventEmitter.defaultMaxListeners\n* emitter.addListener(eventName, listener)\n* emitter.emit(eventName[, ...args])\n* emitter.eventNames()\n* emitter.getMaxListeners()\n* emitter.listenerCount(eventName)\n* emitter.listeners(eventName)\n* emitter.on(eventName, listener)\n* emitter.once(eventName, listener)\n* emitter.prependListener(eventName, listener)\n* emitter.prependOnceListener(eventName, listener)\n* emitter.removeAllListeners([eventName])\n* emitter.removeListener(eventName, listener)\n* emitter.setMaxListeners(n)\n\n## File system\n\n* fs.readFileSync(path)\n* fs.writeFileSync(file, data)\n* fs.mkdirSync(path)\n* fs.existsSync(path)\n* fs.readdirSync(path)\n\n## Globals\n\n* __dirname\n* __filename\n* console\n* exports\n* global\n* module\n    * module.exports\n    * module.id\n* process\n* require\n\n## OS\n\n* os.type\n\n## Path\n\n* path.basename(path[, ext])\n* path.dirname(path)\n* path.extname(path)\n* path.format(pathObject)\n* path.isAbsolute(path)\n* path.join([...paths])\n* path.normalize(path)\n* path.relative(from, to)\n* path.resolve([...paths])\n* path.sep\n\n## Process\n\n* process.argv\n* process.cwd()\n* process.chdir(directory)\n* process.env\n* process.execPath\n* process.exit(code)\n* process.hrtime([time])\n* process.pid\n* process.platform\n* process.umask([mask])\n\n## TTY\n\n* tty.isatty(fd)\n\n## Util\n\n* util.debuglog(section)\n* util.format(format[, ...args])\n* util.inherits(constructor, superConstructor)\n* util.inspect(object[, options])\n* util._extend(target, source)\n"
  },
  {
    "path": "docs/api/store.md",
    "content": "# Namespace `store`\n\n## Table of Contents\n- [Introduction](#intro)\n- [API](#api)\n    - [`create(id: string): Store`](#create)\n    - [`get(id: string): Store`](#get)\n    - [`getOrCreate(id: string): Store`](#getorcreate)\n    - [`count: number`](#count)\n    - Interface [`Store`](#store)\n        - [`store.id: string`](#store-id)\n        - [`store.set(key: string, value: any): void`](#store-set)\n        - [`store.get(key: string): any`](#store-get)\n        - [`store.has(key: string): boolean`](#store-has)\n        - [`store.size: number`](#store-size)\n\n## <a name=\"intro\"></a> Introduction\nStore API is a necessary complement of sharing [transportable](transport.md#transportable-types) objects across JavaScript threads, on top of passing objects via arguments. During [`store.set`](#store-set), values marshalled into JSON and stored in process heap, so all threads can access it, and unmarshalled while users retrieve them via [`store.get`](#store-get).\n\nThough very convenient, it's not recommended to use store to pass values within a transaction or request, since its overhead is more than passing objects by arguments (there are extra locking, etc.). Besides, developers have the obligation to delete the key after usage, while it's automatically managed by reference counting in passing arguments.\n\n## <a name=\"api\"></a> API\nFollowing APIs are exposed to create, get and operate upon stores.\n\n### <a name=\"create\"></a> create(id: string): Store\nIt creates a store by a string identifier that can be used to get the store later. When all references to the store from all JavaScript VMs are cleared, the store will be destroyed. Thus always keep a reference at global or module scope is usually a good practice using `Store`. Error will be thrown if the id already exists.\n\nExample:\n```js\nvar store = napa.store.create('store1');\n```\n### <a name=\"get\"></a> get(id: string): Store\nIt gets a reference of store by a string identifier. `undefined` will be returned if the id doesn't exist. \n\nExample:\n```js\nvar store = napa.store.get('store1');\n```\n\n### <a name=\"getorcreate\"></a> getOrCreate(id: string): Store\nIt gets a reference of store by a string identifier, or creates it if the id doesn't exist. This API is handy when you want to create a store in code that is executed by every worker of a zone, since it doesn't break symmetry.\n\nExample:\n```js\nvar store = napa.store.getOrCreate('store1');\n```\n### <a name=\"count\"></a> count: number\nIt returns count of living stores.\n\n### <a name=\"store\"></a> Interface `Store`\nInterface that let user to put and get objects across multiple JavaScript VMs.\n\n### <a name=\"store-id\"></a> store.id: string\nIt gets the string identifier for the store.\n\n### <a name=\"store-set\"></a> store.set(key: string, value: any): void\nIt puts a [transportable](transport.md#transportable-types) value into store with a string key. If key already exists, new value will override existing value.\n\nExample:\n```js\nstore.set('status', 1);\n```\n### <a name=\"store-get\"></a> store.get(key: string): any\nIt gets a [transportable](transportable.md#transportable-types) value from the store by a string key. If key doesn't exist, `undefined` will be returned.\n\nExample:\n```js\nvar value = store.get('status');\nassert(value === 1);\n```\n### <a name=\"store-has\"></a> store.has(key: string): boolean\nIt tells if a key exists in current store.\n\nExample:\n```js\nassert(store.has('status'))\n```\n\n### <a name=\"store-size\"></a> store.size: number\nIt tells how many keys are stored in current store.\n"
  },
  {
    "path": "docs/api/sync.md",
    "content": "# Namespace `sync`\n## Table of Contents\n- class [`Lock`](#interface-lock)\n    - [`lock.guardSync(func: (...params: any[]) => any, params?: any[]): any`](#lock-guard-sync-func-any-any)\n<!--\n    // Preserve this interface for async lock.\n    - [`lock.guard(func: () => Promise<any>): Promise<any>`](#lock-guard-func-promise-any-promise-any)\n-->\n<!--\n- class [`ReadWriteLock`](#class-readwritelock)\n    - [`rwlock.guardRead(func: () => any): any`](#rwlock-guardread-func-any-any)\n    - [`rwlock.guardWrite(func: () => any): any`](#rwlock-guardwrite-func-any-any)\n-->\n\n## APIs\nNamespace `sync` deal with synchronization between threads in Napa. `Lock` <!-- and `ReadWriteLock` are --> is provided for exclusive and shared mutex scenarios.\n## <a name=\"interface-lock\"></a> Interface `Lock`\nExclusive Lock, which is [transportable](transport.md#transportable) across JavaScript threads.\n\nUse `napa.sync.createLock()` to create a lock.\n```ts\nvar lock = napa.sync.createLock();\n```\n### <a name=\"lock-guard-sync-func-any-any\"></a> lock.guardSync(func: (...params: any[]) => any, params?: any[]): any\nRun input function synchronously and obtain the lock during its execution, returns what the function returns, or throws error if input function throws. Lock will be released once execution finishes.\n```ts\ntry {\n    var value = lock.guardSync(() => {\n        // DoSomething may throw.\n        return DoSomething();\n    });\n    console.log(value);\n}\ncatch(error) {\n    console.log(error);\n}\n```\n\nAn example [Synchronized Loading](./../../examples/tutorial/synchronized-loading) demonstrated how to implement a shared, lazy-loading phone book.\n\n<!--\n### <a name=\"lock-guard-func-promise-any-promise-any\"></a> lock.guard(func: () => Promise\\<any>): Promise\\<any>\n\n// TBD: this is a non-blocking guard function.\n//      It tries to obtain the lock and run the func.\n//      It will return regardless of whether it obtained the lock successfully.\n\n-->\n<!--\n## Class `ReadWriteLock`\nRead-write lock, which is [transportable](transport.md#transportable) across JavaScript threads.\n\n// TBD: RWLock APIs may be redesign in future.\n\nExample: Creating a read-write lock with operator `new`.\n```ts\nlet lock = new napa.sync.ReadWriteLock();\n```\n\n### rwlock.guardRead(func: () => any): any\nRun input function synchronously and obtain the read (shared) lock during its execution, returns what the function returns, or throws error if input function throws. Read lock will be released once execution finishes. Multiple guardRead across threads can enter simultaneously while no pending guardWrite.\n\n```ts\ntry {\n    let value = lock.guardRead(() => {\n        // DoRead may throw.\n        return DoRead();\n    });\n    console.log(value);\n}\ncatch(error) {\n    console.log(error);\n}\n```\n\n### rwlock.guardWrite(func: () => any): any\n\nRun input function synchronously and obtain the write (exclusive) lock during its execution, returns what the function returns, or throws error if input function throws. Write lock will be released once execution finishes. Multiple guardWrite across threads cannot entered simultaneously, and will always wait if there is any pending guardRead.\n\n```ts\ntry {\n    let value = lock.guardWrite(() => {\n        // DoWrite may throw.\n        return DoWrite();\n    });\n    console.log(value);\n}\ncatch(error) {\n    console.log(error);\n}\n-->\n"
  },
  {
    "path": "docs/api/transport.md",
    "content": "# Namespace `transport`\n\n## Table of Contents\n- [Introduction](#intro)\n    - [Transportable types](#transportable-types)\n    - [Constructor ID](#constructor-id)\n    - [Transport context](#transport-context)\n    - [Transporting functions](#transporting-functions)\n    - [Transporting JavaScript built-in objects](#transporting-built-in)\n- API\n    - [`isTransportable(jsValue: any): boolean`](#istransportable)\n    - [`register(transportableClass: new(...args: any[]) => any): void`](#register)\n    - [`marshall(jsValue: any, context: TransportContext): string`](#marshall)\n    - [`unmarshall(json: string, context: TransporteContext): any`](#unmarshall)\n    - class [`TransportContext`](#transportcontext)\n        - [`context.saveShared(object: memory.Shareable): void`](transportcontext-saveshared)\n        - [`context.loadShared(handle: memory.Handle): memory.Shareable`](transportcontext-loadshared)\n        - [`context.sharedCount: number`](transportcontext-sharedcount)\n    - interface [`Transportable`](#transportable)\n        - [`transportable.cid: string`](#transportable-cid)\n        - [`transportable.marshall(context: TransportContext): object`](#transportable-marshall)\n        - [`transportable.unmarshall(payload: object, context: TransportContext): void`](#transportable-unmarshall)\n    - abstract class [`TransportableObject`](#transportableobject)\n        - [`transportableObject.cid: string`](#transportableobject-cid)\n        - [`transportableObject.marshall(context: TransportContext): object`](#transportableobject-marshall)\n        - [`transportableObject.unmarshall(payload: object, context: TransportContext): void`](#transportableobject-unmarshall)\n        - abstract [`transportableObject.save(payload: object, context: TransportContext): void`](#transportableobject-save)\n        - abstract [`transportableObject.load(payload: object, context: TransportContext): void`](#transportableobject-load)\n    - decorator [`cid`](#decorator-cid)\n\n## <a name=\"intro\"></a> Introduction\nExisting JavaScript engines are not designed for running JavaScript across multiple VMs, which means every VM manages their own heap. Passing values from one VM to another has to be marshalled/unmarshalled. The size of payload and complexity of object will greatly impact communication efficiency. In Napa, we try to work out a design pattern for efficient object sharing, based on the fact that all JavaScript VMs (exposed as workers) reside in the same process, and native objects can be wrapped and exposed as JavaScripts objects.\n\nFollowing concepts are introduced to implement this pattern:\n\n### <a name=\"transportable-types\"></a>  Transportable types\nTransportable types are JavaScript types that can be passed or shared transparently across Napa workers. They are used as value types for passing arguments in [`zone.broadcast`](zone.md#broadcast-function) / [`zone.execute`](zone.md#execute-anonymous-function), and sharing objects in  key/value pairs via [`store.set`](store.md#store-set) / [`store.get`](store.md#store-get).\n\nTransportable types are:\n- JavaScript primitive types: undefined, null, boolean, number, string\n- Object (TypeScript class) that implement [`Transportable`](#transportable) interface\n- Function without referencing closures.\n- <a name=\"built-in-whitelist\"></a> JavaScript standard built-in objects in this whitelist.\n    * ArrayBuffer\n    * Float32Array\n    * Float64Array\n    * Int16Array\n    * Int32Array\n    * Int8Array\n    * SharedArrayBuffer\n    * Uint16Array\n    * Uint32Array\n    * Uint8Array\n- Array or plain JavaScript object that is composite pattern of above.\n\n### <a name=\"constructor-id\"></a> Constructor ID (cid)\nFor user classes that implement the [`Transportable`](#transportable) interface, Napa uses Constructor ID (`cid`) to lookup constructors for creating a right object from a string payload. `cid` is marshalled as a part of the payload. During unmarshalling, the transport layer will extract the `cid`, create an object instance using the constructor associated with it, and then call unmarshall on the object. \n\nIt's the class developer's responsibility to choose the right `cid` for your class. To avoid conflict, we suggest to use the combination of module.id and class name as `cid`. Developer can use class decorator [`cid`](#decorator-cid) to register a user Transportable class automatically, when using TypeScript with decorator feature enabled. Or call [`transport.register`](#register) manually during module initialization.\n\n### <a name=\"transport-context\"></a> Transport context\nThere are states that cannot be saved or loaded in serialized form (like std::shared_ptr), or it's very inefficient to serialize (like JavaScript function). Transport context is introduced to help in these scenarios. TransportContext objects can be passed from one JavaScript VM to another, or stored in the native world, so lifecycle of shared native objects extended by using TransportContext. An example of the `Transportable` implementation using TransportContext is [`ShareableWrap`](./../../inc/napa/module/shareable-wrap.h).\n\n### <a name=\"transporting-functions\"></a> Transporting functions\nJavaScript function is a special transportable type, through marshalling its definition into a [store](./store.md#intro), and generate a new function from its definition on target thread. \n\nHighlights on transporting functions are:\n- For the same function, marshall/unmarshall is an one-time cost on each JavaScript thread. Once a function is transported for the first time, later transportation of the same function to previous JavaScript thread can be regarded as free.\n- Closure cannot be transported, but you won't get an error when transporting a function. Instead, you will get runtime error complaining a variable (from closure) is undefined when you can the function later.\n- `__dirname` / `__filename` can be accessed in transported function, which is determined by `origin` property of the function. By default, `origin` property is set to the current working directory.\n\n### <a name=\"transporting-built-in\"></a> Transporting JavaScript built-in objects\nJavaScript standard built-in objects in [the whitelist](#built-in-whitelist) can be transported among napa workers transparently. JavaScript Objects with properties in these types are also able to be transported. Please refer to [unit tests](./../../test/transport-test.ts) for detail.\n\nAn example [Parallel Quick Sort](./../../examples/tutorial/parallel-quick-sort) demonstrated transporting TypedArray (created from SharedArrayBuffer) among multiple Napa workers for efficient data sharing.\n\n## <a name=\"api\"></a> API\n\n### <a name=\"istransportable\"></a> isTransportable(jsValue: any): boolean\nIt tells whether a JavaScript value is transportable or not.\n```ts\n// JS primitives\nassert(transport.isTransportable(undefined));\nassert(transport.isTransportable(null));\nassert(transport.isTransportable(1));\nassert(transport.isTransportable('string'));\nassert(transport.isTransportable(true));\n\n// Transportable addon\nassert(transport.isTransportable(napa.memory.crtAllocator));\n\n// Composite of transportable types.\nassert(transport.isTransportable([\n    1, \n    \"string\", \n    { a: napa.memory.crtAllocator }\n    ]));\n\nclass B {\n    field1: number;\n    field2: string;\n}\n\n// Not transportable JS class. (not registered with @cid).\nassert(!transport.isTransportable(new B()));\n```\n### <a name=\"register\"></a> register(transportableClass: new(...args: any[]) => any): void\nRegister a `Transportable` class before the transport layer can marshall/unmarshall its instances.\nUser can also use class decorator [`@cid`](#cid-decorator) for class registration.\n\nExample:\n```ts\nclass A extends transport.AutoTransportable {\n    field1: string,\n    method1(): string {\n        return this.field1;\n    }\n}\n\n// Explicitly register class A in transport.\ntransport.register(A);\n```\n### <a name=\"marshall\"></a> marshall(jsValue: any, context: TransportContext): string\nMarshall a [transportable](#transportable-types) JavaScript value into a JSON payload with a [`TransportContext`](#transport-context).An Error will be thrown if the value is not transportable. \n\nExample:\n```js\nvar context = transport.createTransportContext();\nvar jsonPayload = transport.marshall(\n    [1, 'string', napa.memory.crtAllocator], \n    context);\nconsole.log(jsonPayload);\n```\n### <a name=\"unmarshall\"></a> unmarshall(json: string, context: TransportContext): any\nUnmarshall a [transportable](#transportable-types) JavaScript value from a JSON payload with a [`TransportContext`](#transport-context).An Error will be thrown if `cid` property is found and not registered with the transport layer.\n\nExample:\n```js\nvar value = transport.unmarshall(jsonPayload, context);\n```\n\n## <a name=\"transportcontext\"></a> Class `TransportContext`\nClass for [Transport Context](#transport-context), that stores shared pointers and functions during marshall/unmarshall.\n### <a name=\"transportcontext-saveshared\"></a> context.saveShared(object: memory.Shareable): void\nSave a shareable object in context.\n\n### <a name=\"transportcontext-loadshared\"></a> context.loadShared(handle: memory.Handle): memory.Shareable\nLoad a shareable object from handle.\n\n### <a name=\"transportcontext-sharedcount\"></a> context.sharedCount: number\nCount of shareable objects saved in the current context.\n\n## <a name=\"transportable\"></a> Interface `Transportable`\nInterface for the Transportable object.\n### <a name=\"transportable-cid\"></a> transportable.cid: string\nGet accessor for [Constructor ID](#constructor-id). It is used to lookup constructor for the payload of the current class.\n\n### <a name=\"transportable-marshall\"></a> transportable.marshall(context: TransportContext): object\nMarshall transforms this object into a plain JavaScript object with the help of [TransportContext](#transport-context).\n\n### <a name=\"transportable.unmarshall\"></a> transportable.unmarshall(payload: object, context: TransportContext): void\nUnmarshall transforms marshalled payload into current object.\n\n## <a name=\"transportableobject\"></a> Abstract class `TransportableObject`\nTBD\n### <a name=\"decorator-cid\"></a> Decorator `cid`\nTBD\n"
  },
  {
    "path": "docs/api/zone.md",
    "content": "# Namespace `zone`\n\n## Table of Contents\n- [Introduction](#intro)\n    - [Multiple workers vs Multiple zones](#worker-vs-zone)\n    - [Zone types](#zone-types)\n    - [Zone operations](#zone-operations)\n- [API](#api)\n    - [`create(id: string, settings: ZoneSettings = DEFAULT_SETTINGS): Zone`](#create)\n    - [`get(id: string): Zone`](#get)\n    - [`current: Zone`](#current)\n    - [`node: Zone`](#node-zone)\n    - Interface [`ZoneSettings`](#zone-settings)\n        - [`settings.workers: number`](#zone-settings-workers)\n    - Object [`DEFAULT_SETTINGS: ZoneSettings`](#default-settings)\n    - Interface [`Zone`](#zone)\n        - [`zone.id: string`](#zone-id)\n        - [`zone.broadcast(code: string): Promise<void>`](#broadcast-code)\n        - [`zone.broadcast(function: (...args: any[]) => void, args?: any[]): Promise<void>`](#broadcast-function)\n        - [`zone.execute(moduleName: string, functionName: string, args?: any[], options?: CallOptions): Promise<Result>`](#execute-by-name)\n        - [`zone.execute(function: (...args[]) => any, args?: any[], options?: CallOptions): Promise<Result>`](#execute-anonymous-function)\n    - Interface [`CallOptions`](#call-options)\n        - [`options.timeout: number`](#call-options-timeout)\n    - Interface [`Result`](#result)\n        - [`result.value: any`](#result-value)\n        - [`result.payload: string`](#result-payload)\n        - [`result.transportContext: transport.TransportContext`](#result-transportcontext)\n\n## <a name=\"intro\"></a> Introduction\nZone is a key concept of napajs that exposes multi-thread capabilities in JavaScript world, which is a logical group of symmetric workers for specific tasks. \n\nPlease note that it's not the same `zone` concept of a context object for async calls in [Dart](https://www.dartlang.org/articles/libraries/zones), or [Angular](https://github.com/angular/zone.js), or a proposal in [TC39](https://github.com/domenic/zones).\n\n### <a name=\"worker-vs-zone\"></a> Multiple workers vs. Multiple zones\nZone consists of one or multiple JavaScript threads, we name each thread `worker`. Workers within a zone are symmetric, which means code executed on any worker from the zone should return the same result, and the internal state of every worker should be the same from a long-running point of view. \n \nMultiple zones can co-exist in the same process, with each loading different code, bearing different states or applying different policies, like heap size, etc. The purpose of having multiple zone is to allow multiple roles for complex work, each role loads the minimum resources for its own usage.\n \n### <a name=\"zone-types\"></a> Zone types\nThere are two types of zone:\n- **Napa zone** - zone consists of Napa.js managed JavaScript workers (V8 isolates). Can be multiple, each may contain multiple workers. Workers in Napa zone support partial Node.JS APIs.\n- **Node zone** - a 'virtual' zone which exposes Node.js eventloop, has access to full Node.js capabilities.\n\n### <a name=\"zone-operations\"><a> Zone operations \nThere are two operations, designed to reinforce the symmetry of workers within a zone:\n 1) **Broadcast** - run code that changes worker state on all workers, returning a promise for the pending operation. Through the promise, we can only know if the operation succeeded or failed. Usually we use `broadcast` to bootstrap the application, pre-cache objects, or change application settings. Function `broadcastSync` is also offered as a synchronized version of broadcast operations.\n 2) **Execute** - run code that doesn't change worker state on an arbitrary worker, returning a promise of getting the result. Execute is designed for doing the real work.\n\n Zone operations are on a basis of first-come-first-serve, while `broadcast` takes higher priority over `execute`.\n\n## <a name=\"api\"></a>API\n### <a name=\"create\"></a> create(id: string, settings: ZoneSettings): Zone\n\nIt creates a Napa zone with a string id. If a zone with the id is already created, an error will be thrown. [`ZoneSettings`](#zone-settings) can be specified for creating zones.\n\nExample 1: Create a zone with id 'zone1', using default ZoneSettings. \n```js\nvar napa = require('napajs');\nvar zone1 = napa.zone.create('zone1');\n```\nExample 2: Create a zone with id 'zone2', with 1 worker.\n```js\nvar zone2 = napa.zone.create('zone2', {\n    workers: 1\n});\n```\n### <a name=\"get\"></a> get(id: string): Zone\nIt gets a reference of zone by an id. Error will be thrown if the zone doesn't exist.\n\nExample:\n```js\nvar zone = napa.zone.get('zone1');\n```\n### <a name=\"current\"></a>current: Zone\nIt returns a reference of the zone of the currently running isolate. If it's under node, it returns the [node zone](#node-zone).\n\nExample: Get current zone.\n```js\nvar zone = napa.zone.current;\n```\n### <a name=\"node-zone\"></a>node: Zone\nIt returns a reference to the node zone. It is equivalent to `napa.zone.get('node')`;\n\nExample:\n```js\nvar zone = napa.zone.node;\n```\n## <a name=\"zone-settings\"></a> Interface `ZoneSettings`\nSettings for zones, which will be specified during the creation of zones. If not specified, [DEFAULT_SETTINGS](#default-settings) will be used.\n\n### <a name=\"zone-settings-workers\"></a>settings.workers: number\nNumber of workers in the zone.\n\n## <a name=\"default-settings\"></a> Object `DEFAULT_SETTINGS`\nDefault settings for creating zones.\n```js\n{\n    workers: 2\n}\n```\n## <a name=\"zone\"></a> Interface `Zone`\nZone is the basic concept to execute JavaScript and apply policies in Napa. You can find its definition in [Introduction](#intro). Through the Zone API, developers can broadcast JavaScript code on all workers, or execute a function on one of them. When you program against a zone, it is the best practice to ensure all workers within a zone are symmetrical to each other, that is, you should not assume a worker may maintain its own states.\n\nThe two major sets of APIs are [`broadcast`](#broadcast-code) and [`execute`](#execute-by-name), which are asynchronous operations with a few variations on their inputs.\n### <a name=\"zone-id\"></a> zone.id: string\nIt gets the id of the zone.\n\n### <a name=\"broadcast-code\"></a> zone.broadcast(code: string): Promise\\<void\\>\nIt asynchronously broadcasts a snippet of JavaScript code in a string to all workers, which returns a Promise of void. If any of the workers failed to execute the code, the promise will be rejected with an error message.\n\nExample:\n\n```js\nvar napa = require('napajs');\nvar zone = napa.zone.get('zone1');\nzone.broadcast('var state = 0;')\n    .then(() => {\n        console.log('broadcast succeeded.');\n    })\n    .catch((error) => {\n        console.log('broadcast failed.')\n    });\n```\n\n### <a name=\"broadcast-code-sync\"></a> zone.broadcastSync(code: string): void\nIt synchronously broadcasts a snippet of JavaScript code in a string to all workers. If any of the workers failed to execute the code, an exception will be thrown with an error message.\n\nRemarks:\n\n- It's not allowed to call `broadcastSync` on current zone. It will cause a deadlock\n\nExample:\n\n```js\nvar napa = require('napajs');\nvar zone = napa.zone.get('zone1');\ntry {\n    zone.broadcastSync('var state = 0;');\n    console.log('broadcast succeeded.');\n} catch (error) {\n    console.log('broadcast failed.')\n}\n```\n\n### <a name=\"broadcast-function\"></a> zone.broadcast(function: (...args: any[]) => void | Promise\\<void\\>, args?: any[]): Promise\\<void\\>\nIt asynchronously broadcasts an anonymous function with its arguments to all workers, which returns a Promise of void. If any of the workers failed to execute the code, the promise will be rejected with an error message.\n\nRemarks:\n\n- If the function returns a Promise object, its state will be adopted to `broadcast`'s return value\n- The function object cannot access variables from closure\n- Unless the function object has an `origin` property, it will use the current file as `origin`, which will be used to set `__filename` and `__dirname`. (See [transporting functions](./transport.md#transporting-functions))\n- Transport context is not available in broadcast. All types that depend on [TransportContext](./transport.md#transport-context) (eg. [ShareableWrap](https://github.com/Microsoft/napajs/blob/master/inc/napa/module/shareable-wrap.h), [Transportable](./transport.md#-interface-transportable)) cannot be passed in arguments list.\n\nExample:\n\n```js\nzone.broadcast((state) => {\n        require('some-module').setModuleState(state)\n    }, [{field1: 1}])\n    .then(() => {\n        console.log('broadcast succeeded.');\n    })\n    .catch((error) => {\n        console.log('broadcast failed:', error)\n    });\n```\n\n### <a name=\"broadcast-function-sync\"></a> zone.broadcastSync(function: (...args: any[]) => void | Promise\\<void\\>, args?: any[]): void\nIt synchronously broadcasts an anonymous function with its arguments to all workers. If any of the workers failed to execute the code, an exception will be thrown with an error message.\n\nRemarks:\n\n- It's not allowed to call `broadcastSync` on current zone. It will cause a deadlock\n- If the function returns a Promise object, its state will be adopted. Function `broadcastSync` will not return until that Promise resolved or rejected.\n- The function object cannot access variables from closure\n- Unless the function object has an `origin` property, it will use the current file as `origin`, which will be used to set `__filename` and `__dirname`. (See [transporting functions](./transport.md#transporting-functions))\n- Transport context is not available in broadcast. All types that depend on [TransportContext](./transport.md#transport-context) (eg. [ShareableWrap](https://github.com/Microsoft/napajs/blob/master/inc/napa/module/shareable-wrap.h), [Transportable](./transport.md#-interface-transportable)) cannot be passed in arguments list.\n\nExample:\n\n```js\ntry {\n    zone.broadcastSync((state) => {\n            require('some-module').setModuleState(state)\n        }, [{field1: 1}]);\n    console.log('broadcast succeeded.');\n} catch (error) {\n    console.log('broadcast failed:', error)\n}\n```\n\n### <a name=\"execute-by-name\"></a> zone.execute(moduleName: string, functionName: string, args?: any[], options?: CallOptions): Promise\\<any\\>\nExecute a function asynchronously on an arbitrary worker via module name and function name. Arguments can be of any JavaScript type that is [transportable](transport.md#transportable-types). It returns a Promise of [`Result`](#result). If an error happens, either bad code, user exception, or timeout is reached, the promise will be rejected.\n\nExample: Execute function `bar` in module `foo`, with arguments [1, 'hello', { field1: 1 }]. 300ms timeout is applied.\n```js\nzone.execute(\n    'foo', \n    'bar', \n    [1, \"hello\", {field1: 1}], \n    { timeout: 300 })\n    .then((result) => {\n        console.log('execute succeeded:', result.value);\n    })\n    .catch((error) => {\n        console.log('execute failed:', error);\n    });\n\n```\n\n### <a name=\"execute-anonymous-function\"></a> zone.execute(function: (...args: any[]) => any, args?: any[], options?: CallOptions): Promise\\<any\\>\n\nExecute a function object asynchronously on an arbitrary worker. Arguments can be of any JavaScript type that is [transportable](transport.md#transportable-types). It returns a Promise of [`Result`](#result). If an error happens, either bad code, user exception, or timeout is reached, promise will be rejected.\n\nRemarks:\n\n- If the function returns a Promise object, it will be adopted\n- The function object cannot access variables from closure\n- Unless the function object has an `origin` property, it will use the current file as `origin`, which will be used to set `__filename` and `__dirname`. (See [transporting functions](./transport.md#transporting-functions))\n\nExample:\n```js\nzone.execute((a: number, b: string, c: object) => {\n        return a + b + JSON.stringify(c);\n    }, [1, \"hello\", {field1: 1}])\n    .then((result) => {\n        console.log('execute succeeded:', result.value);\n    })\n    .catch((error) => {\n        console.log('execute failed:', error);\n    });\n\n```\nOutput:\n```\nexecute succeeded: 1hello{\"field1\":1}\n\n```\nAnother example demonstrates accessing `__filename` when executing an anonymous function:\n```js\n// File: /usr/file1.js\nzone.execute(() => { console.log(__filename);});\n```\nOutput:\n```\n/usr/file1.js\n```\n## <a name=\"call-options\"></a> Interface `CallOptions`\nInterface for options to call functions in `zone.execute`.\n\n### <a name=\"call-options-timeout\"></a> options.timeout: number\nTimeout in milliseconds. Default value 0 indicates no timeout.\n\n## <a name=\"result\"></a> Interface `Result`\nInterface to access the return value of [`execute`](#execute-by-name).\n\n### <a name=\"result-value\"></a>result.value: any\nJavaScript value returned from the function which is invoked from zone.execute/executeSync. Napa marshalls/unmarshalls [transportable values](transport.md#transportable-types) between different workers (V8 isolates). Unmarshalling will happen when the first `result.value` is queried.\n\nExample:\n```js\nvar value = result.value;\n```\n\n### <a name=\"result-payload\"></a> result.payload: string\nMarshalled payload (in JSON) from the returned value. This field is for users that want to pass results through to its caller, where the unmarshalled value is not required.  \n\nExample:\n```js\nvar payload = result.payload;\n```\n\n### <a name=\"result-transportcontext\"></a> result.transportContext: transport.TransportContext\n[TransportContext](transport.md#transport-context) that is required to unmarshall [`result.payload`](#result-payload) into [`result.value`](#result-value).\n\nExample:\n```js\nvar napa = require('napajs');\nvar zone = napa.zone.create('zone1');\nzone.execute(() => { return 0; }, [])\n    .then((result) => {\n        // Manually marshall.\n        var transportContext = result.transportContext;\n        var value = napa.transport.unmarshall(result.payload, result.transportContext);\n\n        // result.value and manual unmarshall from payload are the same.\n        assert.equal(value, result.value);\n    });\n```\n"
  },
  {
    "path": "docs/design/transport-js-builtins.md",
    "content": "# Transport JavaScript standard built-in objects\n\n## Incentives\nThe abstraction of 'Transportable' lies in the center of Napa.js to efficiently share objects between JavaScript VMs (Napa workers). Except JavaScript primitive types, an object needs to implement 'Transportable' interface to make it transportable. It means [JavaScript standard built-in objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects) are not transportable unless wrappers or equivalent implementations for them are implemented by extending 'Transportable' interface. The development cost for these objects is not trivial, and new abstraction layer (wrappers or equivalent implementations) will create barriers for users to learn and adopt these new things. Moreover, developers also need to deal with the interaction between JavaScript standards objects and those wrappers or equivalent implementations.\n\nThe incentive of this design is to provide a solution to make JavaScript standard built-in objects transportable with requirements listed in the Goals section.\n\nAt the first stage, we will focus on an efficient solution to share data between Napa workers. Basically, it is about making *SharedArrayBuffer / TypedArray / DataView* transportable.\n\n## Goals\nMake Javascript standard built-in objects transportable with\n- An efficient way to share structured data, like *SharedArrayBuffer*, among Napa workers\n- Consistent APIs with ECMA standards\n- No new abstraction layers for the simplest usage\n- The least new concepts for advanced usage\n- A scalable solution to make all JavaScript standard built-in objects transportable, avoiding to make them transportable one by one.\n\n## Example\nThe below example shows how *SharedArrayBuffer* object is transported across multiple Napa workers. It will print the TypedArray 'ta' created from a *SharedArrayBuffer*, with all its elements set to 100 from different Napa workers. \n```js\nvar napa = require(\"napajs\");\nvar zone = napa.zone.create('zone', { workers: 4 });\n\nfunction foo(sab, i) {\n    var ta = new Uint8Array(sab);\n    ta[i] = 100;\n    return i;\n}\n\nfunction run() {\n    var promises = [];\n    var sab = new SharedArrayBuffer(4);\n    for (var i = 0; i < 4; i++) {\n        promises[i] = zone.execute(foo, [sab, i]);\n    }\n\n    return Promise.all(promises).then(values => {\n        var ta = new Uint8Array(sab);\n        console.log(ta);\n    });\n}\n\nrun();\n\n```\n\n## Solution\nHere we just give a high-level description of the solution. Its API will go to [docs/api/transport](https://github.com/Microsoft/napajs/blob/master/docs/api/transport.md).\n- V8 provides its value-serialization mechanism by ValueSerializer and ValueDeserializer, which is compatible with the HTML structured clone algorithm. It is a horizontal solution to serialize / deserialize JavaScript objects. ValueSerializer::Delegate and ValueDeserializer::Delegate are their inner class. They work as base classes from which developers can deprive to customize some special handling of external / shared resources, like memory used by a SharedArrayBuffer object.\n\n- **napa::v8_extensions::ExternalizedContents**\n  - It holds the externalized contents (memory) of a SharedArrayBuffer instance once it is serialized via   *napa::v8_extensions::Utils::SerializeValue()*.\n  - Only 1 instance of ExternalizedContents will be generated for each SharedArrayBuffer. If a SharedArrayBuffer had been externalized, it will reuse the ExternalizedContents instance created before in *napa::v8_extensions::Utils::SerializeValue()*.\n\n- **napa::v8_extensions::SerializedData**\n  - It is generated by *napa::v8_extensions::Utils::SerializeValue()*. It holds the serialized data of a JavaScript object, which is required during its deserialization.\n\n- **BuiltInObjectTransporter**\n  - **napa::v8_extensions::Serializer, derived from v8::ValueSerializer::Delegate**\n  - **napa::v8_extensions::Deserializer, derived from v8::ValueDeserializer::Delegate**\n  - **static std::shared_ptr\\<SerializedData> v8_extensions::Utils::SerializeValue(Isolate\\* isolate, Local\\<Value> value);**\n    - Generate the *SerializedData* instance given an input value.\n    - If any *SharedArrayBuffer* instances exist in the input value, their *ExternalizedContents* instances will be generated and attached to the *ShareArrayBuffer* instances respectively.\n  - **static MaybeLocal\\<Value> v8_extensions::Utils::DeserializeValue(Isolate\\* isolate, std::shared_ptr\\<SerializedData> data);**\n    - Restore a JavaScript value from its SerializedData instance generated by *v8_extensions::Utils::SerializeValue()* before.\n\n- Currently, Napa relies on Transportable API and a registered constructor to make an object transportable. In [marshallTransform](https://github.com/Microsoft/napajs/blob/master/lib/transport/transport.ts), when a JavaScript object is detected to have a registered constructor, it will go with Napa way to marshall this object with the help of a **TransportContext** object, otherwise a non-transportable error is thrown.\n\n- Instead of throwing an error when no registered constructor is detected, the **BuiltInObjectTransporter** can help handle this object. We can use a whitelist of object types to restrict this solution to those verified types at first.\n```js\nexport function marshallTransform(jsValue: any, context: transportable.TransportContext): any {\n     if (jsValue != null && typeof jsValue === 'object' && !Array.isArray(jsValue)) {\n        let constructorName = Object.getPrototypeOf(jsValue).constructor.name;\n        if (constructorName !== 'Object') {\n            if (typeof jsValue['cid'] === 'function') {\n                return <transportable.Transportable>(jsValue).marshall(context);\n            } else if (_builtInTypeWhitelist.has(constructorName)) {\n                let serializedData = builtinObjectTransporter.serializeValue(jsValue);\n                if (serializedData) {\n                    return { _serialized : serializedData };\n                } else {\n                    throw new Error(`Failed to serialize object with type of \\\"${constructorName}\\\".`);\n                }\n            } else {\n                throw new Error(`Object type \\\"${constructorName}\\\" is not transportable.`);\n            }\n        }\n    }\n    return jsValue;\n}\n```\n- The reverse process will be invoked in [unmarshallTransform](https://github.com/Microsoft/napajs/edit/master/lib/transport/transport.ts) if the payload is detected to have '_serialized' property.\n```js\nfunction unmarshallTransform(payload: any, context: transportable.TransportContext): any {\n    if (payload != null && payload._cid !== undefined) {\n        let cid = payload._cid;\n        if (cid === 'function') {\n            return functionTransporter.load(payload.hash);\n        }\n        let subClass = _registry.get(cid);\n        if (subClass == null) {\n            throw new Error(`Unrecognized Constructor ID (cid) \"${cid}\". Please ensure @cid is applied on the class or transport.register is called on the class.`);\n        }\n        let object = new subClass();\n        object.unmarshall(payload, context);\n        return object;\n    } else if (payload.hasOwnProperty('_serialized')) {\n        return builtinObjectTransporter.deserializeValue(payload['_serialized']);\n    }\n    return payload;\n}\n```\n\n#### Lifecycle of SharedArrayBuffer (SAB)\n- When a SAB participates transportation among Napa workers, its life cycle will be extended till the last reference this SAB. The reference of a SAB could be:\n  - SAB object in its original isolate.\n  - Received SAB transported from another Napa workers, including node zone of Napa.\n  - TypedArray or DataView created from the original SAB or a received SAB.\n\n- The life cycle extension during transportation is achieved through the *ExternalizedContents* *SharedPtrWrap* of the SAB.\n  - When a SAB is transported for the first time, it will be externalized and its ExternalizedContents will be stored in its *SerializedData*. At the same time, the *SharedPtrWrap* of the *ExternalizedContents* will be set to the '_externalized' property of the original SAB.\n\n  - When a SAB is transported for the second time or later, it will skip externalization and find its *ExternalizedContents* from its '_externalized' property, and store it to its *SerializedData*.\n\n  - When a Napa worker tries to restore a transported SAB, it will find the pre-stored *ExternalizedContents*, and create a *SharedPtrWrap* for it, then set it to the to-be-restored SAB.\n\n  - The life cycle of the *SharedArrayBuffer* is extended by the *SharedPtrWrap* of its *ExternalizedContents*.\n\n\n## Constraints\nThe above solution is based on the serialization / deserialization mechanism of V8. It may have the following constraints.\n- Not all [JavaScripts standard built-in objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects) are supported by Node (as a dependency of Napa in node mode) or V8 of a given version. We only provide transporting solution for those mature object types.\n- Presently, Node does not explicitly support multiple V8 isolates. There may be inconsistencies in transporting objects between Node zones and Napa zones. Extra effort might be required to make it consistent.\n"
  },
  {
    "path": "examples/modules/README.md",
    "content": "## Napa module source tree\n\nThe source codes can be organized as the structure below.\n```\n+-- napa-module-example\n    +-- inc\n    |   +-- example.h\n    +-- lib\n    |   +-- example.ts\n    |   +-- tsconfig.json\n    +-- napa\n    |   +-- addon.cpp\n    |   +-- CMakeLists.txt (cmake specific)\n    |   +-- example-wrap.cpp\n    |   +-- example-wrap.h\n    +-- src\n    |   +-- CMakeLists.txt (cmake specific)\n    |   +-- example.cpp\n    +-- test\n    |   +-- test.ts\n    |   +-- tsconfig.json\n    +-- binding.gyp (gyp specific)\n    +-- CMakeLists.txt (cmake specific)\n    +-- package.json\n    +-- README.md\n```\n ## How to build and test ?\n For the module examples, node-gyp or cmake-js build solution is provided for your reference.\n\nPlease make sure [node-gyp](https://github.com/nodejs/node-gyp#installation) or [cmake-js](https://github.com/cmake-js/cmake-js#installation) has been set up correctly at your client, then you could follow the steps below to build and test the module examples.\n ```\n 1. go to the directory of a module example\n 2. run \"npm install\" to build the module\n 3. run \"npm test\" to build and run the module test, as well as its unittest if any\n ```\n"
  },
  {
    "path": "examples/modules/async-number/.gitignore",
    "content": "bin\nbuild\nnode_modules\ntypes\n\n# ignore all js files under lib\nlib/*.js\n\n# ignore all js files under test\ntest/*.js\n\npackage-lock.json\n"
  },
  {
    "path": "examples/modules/async-number/.npmignore",
    "content": "bin\nbuild\n\n# Exclude TypeScript source files.\nlib/*.ts\nlib/tsconfig.json\ntest/*.ts\ntest/tsconfig.json\n"
  },
  {
    "path": "examples/modules/async-number/README.md",
    "content": "# Asynchronous numbering\n\n## APIs\n\nNapa provides two functions to support asynchronous call and they work for both node.js and Napa.\n\n```cpp\nvoid napa::module::PostAsyncWork(v8::Local<v8::Function> jsCallback,\n                                 std::function<void*()> asyncWork,\n                                 std::function<void(v8::Local<v8::Function>, void*)> asyncCompleteCallback);\n```\n\nIt fires asynchronous work onto separate thread.\n\n* *jsCallback*: Javascript callback given at Javascript land.\n* *asyncWork*: C++ function to run at separate thread asynchronously.\n* *asyncCompleteCallback*: C++ callback function, which has isolate instance and *jsCallback* as arguments. It's called at the same isolate with caller's one after *asyncWork* completes.\n\n```cpp\nvoid napa::module::DoAsyncWork(v8::Local<v8::Function> jsCallback,\n                               const std::function<void(std::function<void(void*)>)>& asyncWork,\n                               std::function<void(v8::Local<v8::Function>, void*)> asyncCompleteCallback);\n```\n\nIf you have a function already supporting async, use this API.\n\n* *jsCallback*: Javascript callback given at Javascript land.\n* *asyncWork*: Function to wrap C++ function supporting async, which callback must call Napa completion callback given as argument.\n* *asyncCompleteCallback*: C++ callback function, which has isolate instance and *jsCallback* as arguments. It's called at the same isolate with caller's one after *asyncWork* completes.\n\n### Diagram\n\nThis diagram shows how asynchronous call is working corresponding to the below example,\n\n```diagram\n                |-------------------------|     |------------------------|                   |------------------------------------|     |-------------------|\n(V8 thread)-----| Call *increase()* at JS |-----| Run the next statement |-------------------| Run *asyncCompleteCallback* at C++ |-----| Call *jsCallback* |\n                |-------------------------|     |------------------------|                   |------------------------------------|     |-------------------|\n                            |                                                                                +\n                            |                                                                                |\n                            |----------|                                                                     |\n                                       |                                                                     |\n                                       +                                                                     |\n                             |------------------|     |--------------------------------------------|         |\n                (thread)-----| Run  *asyncWork* |-----| Post a task to run *asyncCompleteCallback* |---------|\n                             |------------------|     |--------------------------------------------|\n```\n\n## C++ module\n\nThis example shows how to create async module. It keeps one number and three APIs operating on it as follows,\n\n* *Increase*: It increases a number by a given parameter in separate thread and post a completion to run Javascript callback at the next execution loop.\n* *IncreaseSync*: It increases a number by a given parameter in the same thread and post a completion to run Javascript callback at the next execution loop.\n* *Now*: It returns the current value of a number.\n\n```cpp\n#include <napa/module.h>\n\n#include <atomic>\n#include <functional>\n\nnamespace napa {\nnamespace demo {\n\nusing namespace v8;\n\nnamespace {\n    std::atomic<uint32_t> _now(0);\n}\n\n/// <summary> It increases a number by a given parameter asynchronously and runs a callback at the next execution loop. </summary>\nvoid Increase(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n\n    CHECK_ARG(isolate,\n        args.Length() == 2 && args[0]->IsUint32() && args[1]->IsFunction(),\n        \"It requires unsigned integer and callback as arguments\");\n\n    auto value = args[0]->Uint32Value();\n\n    napa::module::PostAsyncWork(Local<Function>::Cast(args[1]),\n        [value]() {\n            // This runs in a separate thread.\n            _now += value;\n            return reinterpret_cast<void*>(static_cast<uintptr_t>(_now.load()));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs in the same thread as the one Increase() is called in.\n            auto isolate = Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            Local<Value> argv[] =\n                { Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result))) };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n\n/// <summary> It increases a number by a given parameter synchronously and runs a callback at the next execution loop. </summary>\nvoid IncreaseSync(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n\n    CHECK_ARG(isolate,\n        args.Length() == 2 && args[0]->IsUint32() && args[1]->IsFunction(),\n        \"It requires unsigned integer and callback as arguments\");\n\n    auto value = args[0]->Uint32Value();\n\n    napa::module::DoAsyncWork(Local<Function>::Cast(args[1]),\n        [value](auto complete) {\n            // This runs in the same thread.\n            _now += value;\n            complete(reinterpret_cast<void*>(static_cast<uintptr_t>(_now.load())));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs in the same thread as the one IncreaseSync() is called in.\n            auto isolate = Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            Local<Value> argv[] =\n                { Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result))) };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n\n/// <summary> It returns the current value of a number. </summary>\nvoid Now(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(Integer::NewFromUnsigned(isolate, _now));\n}\n\nvoid Init(Local<Object> exports) {\n    NAPA_SET_METHOD(exports, \"increase\", Increase);\n    NAPA_SET_METHOD(exports, \"increaseSync\", IncreaseSync);\n    NAPA_SET_METHOD(exports, \"now\", Now);\n}\n\nNAPA_MODULE(addon, Init)\n\n}  // namespace demo\n}  // namespace napa\n```\n\n## Typescript\n\n### async-number.ts\n```ts\nvar addon = require('../bin/addon');\n\nexport function increase(value: number, callback: (now: number) => void) {\n    return addon.increase(value, callback);\n}\n\nexport function increaseSync(value: number, callback: (now: number) => void) {\n    return addon.increaseSync(value, callback);\n}\n\nexport function now(): string {\n    return addon.now();\n}\n```\n\n### async-number.d.ts\n```d.ts\nexport declare function increase(extra: number, callback: (now: number) => void): any;\nexport declare function increaseSync(extra: number, callback: (now: number) => void): any;\nexport declare function now(): string;\n```\n\n## Test\n\n```ts\nvar assert = require('assert');\nvar asyncNumber = require('async-number');\n\ndescribe('Test suite for async-number', function() {\n    it('change number asynchronously on separate thread', function(done) {\n        let now = asyncNumber.now();\n        assert.equal(now, 0);\n\n        asyncNumber.increase(3, (value: number) => {\n            // This must be called after the last statement of *it* block is executed.\n            assert(value == 3 || value == 6);\n\n            now = asyncNumber.now();\n            assert.equal(now, 6);\n\n            done();\n        });\n\n        asyncNumber.increaseSync(3, (value) => {} );\n    });\n\n    it('change number synchronously on current thread', function(done) {\n        let now = asyncNumber.now();\n        assert.equal(now, 0);\n\n        asyncNumber.increaseSync(3, (value: number) => {\n            // This must be called after the last statement of *it* block is executed.\n            assert.equal(value, 3);\n\n            now = asyncNumber.now();\n            assert.equal(now, 6);\n\n            done();\n        });\n\n        now = asyncNumber.now();\n        // 'now' should be 3.\n        assert.equal(now, 3);\n\n        asyncNumber.increaseSync(3, (value) => {} );\n    });\n})\n```"
  },
  {
    "path": "examples/modules/async-number/binding.gyp",
    "content": "{\n  \"variables\": {\n    \"napajs_lib\": \"<!(node -e \\\"require('napajs/build').paths.lib\\\")\",\n    \"napajs_inc\": \"<!(node -e \\\"require('napajs/build').paths.inc\\\")\"\n  },\n  \"targets\": [\n    {\n      \"target_name\": \"addon.node\",\n      \"type\": \"<(library)\",\n      \"product_name\": \"addon\",\n      \"product_extension\": \"node\",\n      \"product_dir\": \"<(PRODUCT_DIR)/../../bin\",\n      \"sources\": [ \"napa/addon.cpp\"],\n      \"defines\": [\n        \"BUILDING_NODE_EXTENSION\"\n      ],\n      \"include_dirs\": [\"<(napajs_inc)\"]\n    },\n    {\n      \"target_name\": \"addon.napa\",\n      \"type\": \"<(library)\",\n      \"product_name\": \"addon\",\n      \"product_extension\": \"napa\",\n      \"product_dir\": \"<(PRODUCT_DIR)/../../bin\",\n      \"sources\": [ \"napa/addon.cpp\" ],\n      \"defines\": [\n        \"BUILDING_NAPA_EXTENSION\"\n      ],\n      \"include_dirs\": [\"<(napajs_inc)\"],\n      \"link_settings\": {\n        \"libraries\": [\"<(napajs_lib)\"]\n      }\n    }\n  ]\n\n}\n"
  },
  {
    "path": "examples/modules/async-number/lib/async-number.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet addon = require('../bin/addon');\n\nexport function increase(value: number, callback: (now: number) => void) {\n    return addon.increase(value, callback);\n}\n\nexport function increaseSync(value: number, callback: (now: number) => void) {\n    return addon.increaseSync(value, callback);\n}\n\nexport function now(): string {\n    return addon.now();\n}\n"
  },
  {
    "path": "examples/modules/async-number/lib/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": true,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"],\n        \"declarationDir\": \"../types\"\n    }\n}\n"
  },
  {
    "path": "examples/modules/async-number/napa/addon.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/module.h>\n#include <napa/async.h>\n\n#include <atomic>\n#include <functional>\n\nnamespace napa {\nnamespace demo {\n\nusing namespace v8;\n\nnamespace {\n    std::atomic<uint32_t> _now(0);\n}\n\n/// <summary> It increases a number by a given parameter asynchronously and runs a callback at the next execution loop. </summary>\nvoid Increase(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n\n    CHECK_ARG(isolate,\n        args.Length() == 2 && args[0]->IsUint32() && args[1]->IsFunction(),\n        \"It requires unsigned integer and callback as arguments\");\n\n    auto value = args[0]->Uint32Value();\n\n    napa::zone::PostAsyncWork(Local<Function>::Cast(args[1]),\n        [value]() {\n            // This runs in a separate thread.\n            _now += value;\n            return reinterpret_cast<void*>(static_cast<uintptr_t>(_now.load()));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs in the same thread as the one Increase() is called in.\n            auto isolate = Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            Local<Value> argv[] =\n                { Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result))) };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n\n/// <summary> It increases a number by a given parameter synchronously and runs a callback at the next execution loop. </summary>\nvoid IncreaseSync(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n\n    CHECK_ARG(isolate,\n        args.Length() == 2 && args[0]->IsUint32() && args[1]->IsFunction(),\n        \"It requires unsigned integer and callback as arguments\");\n\n    auto value = args[0]->Uint32Value();\n\n    napa::zone::DoAsyncWork(Local<Function>::Cast(args[1]),\n        [value](auto complete) {\n            // This runs in the same thread.\n            _now += value;\n            complete(reinterpret_cast<void*>(static_cast<uintptr_t>(_now.load())));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs in the same thread as the one IncreaseSync() is called in.\n            auto isolate = Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            Local<Value> argv[] =\n                { Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result))) };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n\n/// <summary> It returns the current value of a number. </summary>\nvoid Now(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(Integer::NewFromUnsigned(isolate, _now));\n}\n\nvoid Init(Local<Object> exports) {\n    NAPA_SET_METHOD(exports, \"increase\", Increase);\n    NAPA_SET_METHOD(exports, \"increaseSync\", IncreaseSync);\n    NAPA_SET_METHOD(exports, \"now\", Now);\n}\n\nNAPA_MODULE(addon, Init)\n\n}  // namespace demo\n}  // namespace napa\n"
  },
  {
    "path": "examples/modules/async-number/package.json",
    "content": "{\n  \"name\": \"async-number\",\n  \"version\": \"0.1.0\",\n  \"author\": \"napajs\",\n  \"description\": \"Example of an async napa module.\",\n  \"main\": \"./lib/async-number.js\",\n  \"types\": \"./types/async-number.d.ts\",\n  \"gypfile\": true,\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"mocha\": \">= 3.4.2\",\n    \"typescript\": \">= 2.2.1\",\n    \"@types/node\": \">= 7.0.8\",\n    \"@types/mocha\": \">= 2.2.0\",\n    \"markdown-table\": \"1.1.0\"\n  },\n  \"dependencies\": {\n    \"napajs\": \">= 0.1.2\"\n  },\n  \"scripts\": {\n    \"install\": \"node-gyp configure && node-gyp build\",\n    \"prepare\": \"tsc -p lib\",\n    \"pretest\": \"tsc -p test\",\n    \"test\": \"mocha test --recursive\"\n  }\n}\n"
  },
  {
    "path": "examples/modules/async-number/test/test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet assert = require('assert');\nlet asyncNumber = require('..');\nlet napa = require('napajs');\nlet zone = napa.zone.create('zone');\n\ndescribe('Test suite for async-number', function() {\n    this.timeout(0);\n\n    it('change number asynchronously on separate thread', () => {\n        let now = asyncNumber.now();\n        assert.equal(now, 0);\n\n        asyncNumber.increase(3, (value: number) => {\n            // This must be called after the last statement of *it* block is executed.\n            assert(value == 3 || value == 6);\n\n            now = asyncNumber.now();\n            assert.equal(now, 6);\n        });\n\n        asyncNumber.increaseSync(3, (value: number) => {} );\n    });\n\n    it('change number synchronously on current thread', () => {\n        let now = asyncNumber.now();\n        assert.equal(now, 6);\n\n        asyncNumber.increaseSync(3, (value: number) => {\n            // This must be called after the last statement of *it* block is executed.\n            assert.equal(value, 9);\n\n            now = asyncNumber.now();\n            assert.equal(now, 12);\n        });\n\n        now = asyncNumber.now();\n        // 'now' should be 9.\n        assert.equal(now, 9);\n\n        asyncNumber.increaseSync(3, (value: number) => {} );\n    });\n\n    it('change number asynchronously on separate thread in napa zone', () => {\n        return zone.execute(() => {\n            let assert = require('assert');\n            let asyncNumber = require('..');\n            let now = asyncNumber.now();\n            assert.equal(now, 0);\n\n            asyncNumber.increase(3, (value: number) => {\n                // This must be called after the last statement of *it* block is executed.\n                assert(value == 3 || value == 6);\n\n                now = asyncNumber.now();\n                assert.equal(now, 6);\n            });\n\n            asyncNumber.increaseSync(3, (value: number) => {} );\n        });\n    });\n\n    it('change number synchronously on current thread in napa zone', () => {\n        return zone.execute(() => {\n            let assert = require('assert');\n            let asyncNumber = require('..');\n            let now = asyncNumber.now();\n            assert.equal(now, 6);\n\n            asyncNumber.increaseSync(3, (value: number) => {\n                // This must be called after the last statement of *it* block is executed.\n                assert.equal(value, 9);\n\n                now = asyncNumber.now();\n                assert.equal(now, 12);\n            });\n\n            now = asyncNumber.now();\n            // 'now' should be 9.\n            assert.equal(now, 9);\n            asyncNumber.increaseSync(3, (value: number) => {} );\n            return 1;\n        });\n    });\n})\n"
  },
  {
    "path": "examples/modules/async-number/test/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": false,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"]\n    }\n}\n"
  },
  {
    "path": "examples/modules/hello-world/.gitignore",
    "content": "bin\nbuild\nnode_modules\ntypes\n\n# ignore all js files under lib\nlib/*.js\n\n# ignore all js files under test\ntest/*.js\n\npackage-lock.json\n"
  },
  {
    "path": "examples/modules/hello-world/.npmignore",
    "content": "bin\nbuild\n\n# Exclude TypeScript source files.\nlib/*.ts\nlib/tsconfig.json\ntest/*.ts\ntest/tsconfig.json\n"
  },
  {
    "path": "examples/modules/hello-world/README.md",
    "content": "# Hello World\n\nThis example shows the simple napa module, which shows the basic difference between node.js module and napa module.\n\n```cpp\n#include <napa/module.h>\n\nnamespace napa {\nnamespace demo {\n\nusing namespace v8;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    args.GetReturnValue().Set(String::NewFromUtf8(isolate, \"world\"));\n}\n\nvoid Init(Local<Object> exports) {\n    NAPA_SET_METHOD(exports, \"hello\", Method);\n}\n\nNAPA_MODULE(addon, Init)\n\n}  // namespace demo\n}  // namespace napa\n```\n\n## Transition from node.js module\n* *napa/module.h* is used instead of *node.h*. Depending on preprocessor definition, *NAPA_MODULE_EXTENSION* or\n *BUILDING_NODE_EXTENSION* preprocessor definition, *napa/module.h* includes necessary napa or node header files\n  accordingly and build system creates either node.js module or napa module.\n* *NAPA_SET_METHOD* is equivalent to *NODE_SET_METHOD*. This module will have *hello()* function.\n* *NAPA_MODULE* is equivalent to *NODE_MODULE*, which exports an initialization function.\n\n## Typescript\nIt's recommended that typescript or typescript definition is provided to let the user know the APIs without\n the source codes and develop Typescript project easily.\n### hello-world.ts\n```ts\nvar addon = require('../bin/addon');\n\nexport function hello(): string {\n    return addon.hello();\n}\n```\n### hello-world.d.ts\n```d.ts\nexport declare function hello(): string;\n```\n\n## Mocha test\n```js\nvar assert = require('assert');\nvar helloWorld = require('hello-world');\n\ndescribe('Test suite for hello-word', function() {\n    it('prints the string \"world\"', function() {\n        var result = helloWorld.hello();\n        assert.equal(result, 'world');\n    });\n})\n```"
  },
  {
    "path": "examples/modules/hello-world/binding.gyp",
    "content": "{\n  \"variables\": {\n    \"napajs_lib\": \"<!(node -e \\\"require('napajs/build').paths.lib\\\")\",\n    \"napajs_inc\": \"<!(node -e \\\"require('napajs/build').paths.inc\\\")\"\n  },\n  \"targets\": [\n    {\n      \"target_name\": \"addon.node\",\n      \"type\": \"<(library)\",\n      \"product_name\": \"addon\",\n      \"product_extension\": \"node\",\n      \"product_dir\": \"<(PRODUCT_DIR)/../../bin\",\n      \"sources\": [ \"napa/addon.cpp\"],\n      \"defines\": [\n        \"BUILDING_NODE_EXTENSION\"\n      ],\n      \"include_dirs\": [\"<(napajs_inc)\"]\n    },\n    {\n      \"target_name\": \"addon.napa\",\n      \"type\": \"<(library)\",\n      \"product_name\": \"addon\",\n      \"product_extension\": \"napa\",\n      \"product_dir\": \"<(PRODUCT_DIR)/../../bin\",\n      \"sources\": [ \"napa/addon.cpp\" ],\n      \"defines\": [\n        \"BUILDING_NAPA_EXTENSION\"\n      ],\n      \"include_dirs\": [\"<(napajs_inc)\"],\n      \"link_settings\": {\n        \"libraries\": [\"<(napajs_lib)\"]\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "examples/modules/hello-world/lib/hello-world.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet addon = require('../bin/addon');\n\nexport function hello(): string {\n    return addon.hello();\n}\n"
  },
  {
    "path": "examples/modules/hello-world/lib/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": true,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"],\n        \"declarationDir\": \"../types\"\n    }\n}\n"
  },
  {
    "path": "examples/modules/hello-world/napa/addon.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/module.h>\n\nnamespace napa {\nnamespace demo {\n\nusing namespace v8;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    args.GetReturnValue().Set(String::NewFromUtf8(isolate, \"world\"));\n}\n\nvoid Init(Local<Object> exports) {\n    NAPA_SET_METHOD(exports, \"hello\", Method);\n}\n\nNAPA_MODULE(addon, Init)\n\n}  // namespace demo\n}  // namespace napa\n"
  },
  {
    "path": "examples/modules/hello-world/package.json",
    "content": "{\n  \"name\": \"hello-world\",\n  \"version\": \"0.1.0\",\n  \"author\": \"napajs\",\n  \"description\": \"Example of a simple napa module.\",\n  \"main\": \"./lib/hello-world.js\",\n  \"types\": \"./types/hello-world.d.ts\",\n  \"gypfile\": true,\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"mocha\": \">= 3.4.2\",\n    \"typescript\": \">= 2.2.1\",\n    \"@types/node\": \">= 7.0.8\",\n    \"@types/mocha\": \">= 2.2.0\",\n    \"markdown-table\": \"1.1.0\"\n  },\n  \"dependencies\": {\n    \"napajs\": \">= 0.1.2\"\n  },\n  \"scripts\": {\n    \"install\": \"node-gyp configure && node-gyp build\",\n    \"prepare\": \"tsc -p lib\",\n    \"pretest\": \"tsc -p test\",\n    \"test\": \"mocha test --recursive\"\n  }\n}\n"
  },
  {
    "path": "examples/modules/hello-world/test/test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet assert = require('assert');\nlet helloWorld = require('..');\nlet napa = require('napajs');\nlet zone = napa.zone.create('zone');\n\ndescribe('Test suite for hello-word', function() {\n    this.timeout(0);\n\n    it('prints the string \"world\"', function() {\n        let result: string = helloWorld.hello();\n        assert.equal(result, 'world');\n    });\n\n    it('prints the string \"world\" in napa zone', function() {\n        return zone.execute(() => {\n            let helloWorld = require('..');\n            let result: string = helloWorld.hello();\n            return result;\n        }).then((result : any) => {\n            assert.equal(result.value, 'world');\n        });\n    });\n})\n"
  },
  {
    "path": "examples/modules/hello-world/test/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": false,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"]\n    }\n}\n"
  },
  {
    "path": "examples/modules/plus-number/.gitignore",
    "content": "bin\nbuild\nnode_modules\ntypes\n\n# ignore all js files under lib\nlib/*.js\n\n# ignore all js files under test\ntest/*.js\n\npackage-lock.json\n"
  },
  {
    "path": "examples/modules/plus-number/.npmignore",
    "content": "bin\nbuild\nunittest\n\n# Exclude TypeScript source files.\nlib/*.ts\nlib/tsconfig.json\ntest/*.ts\ntest/tsconfig.json\n"
  },
  {
    "path": "examples/modules/plus-number/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"addon\")\n\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Build plus-number library\nadd_subdirectory(src)\n\n# Build napa addon\nadd_subdirectory(napa)\n"
  },
  {
    "path": "examples/modules/plus-number/README.md",
    "content": "# Plus Number\n\nThis example shows the napa module, which wraps C++ objects/classes. Instead of using Javascript *new* operator,\n it uses a factory pattern. i.e.\n\n```\nvar obj = addon.createPlusNumber();\n// instead of\n// var obj = new addon.PlusNumber();\n``` \n\n## Wrapped class\n\n*plus-number.h* declares the class with one constructor and one method, *Add()*.\n\n```h\nnamespace napa {\nnamespace demo {\n\n    /// <summary> Example class to show how to create Napa module using a wrapped C++ class. </summary>\n    class PlusNumber {\n    public:\n\n        /// <summary> Constructor with initial value. </summary>\n        explicit PlusNumber(double value = 0.0);\n\n        /// <summary> Add the given value and return the result. </summary>\n        double Add(double value);\n\n    private:\n\n        double _value;\n    };\n\n}  // namespace demo\n}  // namespace napa\n```\n\n## Wrapper class\n\n*plus-number-wrap.h* declares the wrapper class inherited from *NAPA_OBJECTWRAP* as follows,\n\n```h\n#include <napa/module.h>\n#include <plus-number.h>\n\nnamespace napa {\nnamespace demo {\n\n    /// <summary> Napa example module wrapping PlusNumber class. </summary>\n    class PlusNumberWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> Register this class into V8. </summary>\n        static void Init();\n\n        /// <summary> Enable to create an instance by createPlusNumber() Javascript API. </summary>\n        /// <param name=\"args\"> Addend as PlusNumber constructor parameter. </param>\n        static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    private:\n\n        /// <summary> Exported class name. </summary>\n        static const char* _exportName;\n\n        /// <summary> Constructor with initial value. </summary>\n        explicit PlusNumberWrap(double value = 0.0);\n\n        /// <summary> Create PlusNumber instance at V8. </summary>\n        /// <param name=\"args\"> Addend as PlusNumber constructor parameter. </param>\n        static void NewCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Add value. </summary>\n        /// <param name=\"args\"> Addend. </param>\n        static void Add(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Declare persistent constructor to create PlusNumber instance. </summary>\n        /// <remarks> Napa creates persistent constructor at each isolate while node.js creates the static instance. </remarks>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        PlusNumber _plusNumber;\n    };\n\n}  // namespace demo\n}  // namespace napa\n```\n\n*plus-number-wrap.cpp* implements each functions as follows,\n\n```cpp\n#include \"plus-number-wrap.h\"\n\nusing namespace napa::demo;\nusing namespace v8;\n\nconst char* PlusNumberWrap::_exportName = \"PlusNumberWrap\";\n\n// Define persistent constructor.\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(PlusNumberWrap);\n\nPlusNumberWrap::PlusNumberWrap(double value)\n    : _plusNumber(value) {\n}\n\nvoid PlusNumberWrap::Init() {\n    auto isolate = Isolate::GetCurrent();\n\n    // Prepare constructor template.\n    auto functionTemplate = FunctionTemplate::New(isolate, NewCallback);\n    functionTemplate->SetClassName(String::NewFromUtf8(isolate, _exportName));\n    functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    // Set prototype method.\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"add\", Add);\n\n    // Set persistent constructor into V8.\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(_exportName, functionTemplate->GetFunction());\n}\n\nvoid PlusNumberWrap::NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n\n    auto constructor = NAPA_GET_PERSISTENT_CONSTRUCTOR(_exportName, PlusNumberWrap);\n    auto context = isolate->GetCurrentContext();\n    auto instance = constructor->NewInstance(context, argc, argv).ToLocalChecked();\n\n    args.GetReturnValue().Set(instance);\n}\n\nvoid PlusNumberWrap::NewCallback(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate,\n        args.IsConstructCall(),\n        \"PlusNumberWrap instance must be created by the factory.\");\n\n    CHECK_ARG(isolate,\n        args.Length() == 0 || args.Length() == 1,\n        \"Only one or no argument is allowed.\");\n\n    if (args.Length() == 1) {\n        CHECK_ARG(isolate,\n            args[0]->IsNumber(),\n            \"The first argument must be a number.\");\n    }\n\n    double value = args[0]->IsUndefined() ? 0.0 : args[0]->NumberValue();\n\n    auto wrap = new PlusNumberWrap(value);\n    wrap->Wrap(args.This());\n\n    args.GetReturnValue().Set(args.This());\n}\n\nvoid PlusNumberWrap::Add(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate,\n        args.Length() == 1 && args[0]->IsNumber(),\n        \"Number must be given as argument.\");\n\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<PlusNumberWrap>(args.Holder());\n    auto value = wrap->_plusNumber.Add(args[0]->NumberValue());\n\n    args.GetReturnValue().Set(Number::New(isolate, value));\n}\n```\n\n*addon.cpp* implements the addon as below,\n\n```cpp\n#include \"plus-number-wrap.h\"\n\nusing namespace napa::demo;\nusing namespace v8;\n\nvoid CreatePlusNumber(const FunctionCallbackInfo<Value>& args) {\n    PlusNumberWrap::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports) {\n    PlusNumberWrap::Init();\n\n    NAPA_SET_METHOD(exports, \"createPlusNumber\", CreatePlusNumber);\n}\n\nNAPA_MODULE(addon, InitAll);\n```\n\n## Transition from node.js module\n* *NAPA_OBJECTWRAP* is equivalent to *node::ObjectWrap*, so object's lifetime works as Javascript object.\n* One big difference is how to handle the persistent constructor. While Node.js has only one thread for Javascript and\n static constructor instance is fine, Napa should support one constructor instance per V8 isolate. These macros help\n constructor instance creation.\n  * *NAPA_DECLARE_PERSISTENT_CONSTRUCTOR* declares constructor instance.\n  * *NAPA_DEFINE_PERSISTENT_CONSTRUCTOR* defines constructor instance.\n  * *NAPA_SET_PERSISTENT_CONSTRUCTOR* makes a local constructor as persistent. Napa stores it into thread local storage\n   to allow one instance per V8 isolate.\n  * *NAPA_GET_PERSISTENT_CONSTRUCTOR* return stored constructor instance.\n* *NAPA_SET_PROTOTYPE_METHOD* is equivalent to *NODE_SET_PROTOTYPE_METHOD*, which add a prototype method to Javascript\n object.\n\n## Typescript\n*plus-number.ts* doesn't need to fully implement *PlusNumber.add()* since the signature of *PlusNumber* instance returned by\n *addon.createPlusNumber()* is the same.\n### plus-number.ts\n```ts\nvar addon = require('../bin/addon');\n\nexport declare class PlusNumber {\n    public add(value: number): number;\n}\n\nexport function createPlusNumber(value: number = 0): PlusNumber {\n    return addon.createPlusNumber(value);\n}\n```\n### plus-number.d.ts\n```d.ts\nexport declare class PlusNumber {\n    add(value: number): number;\n}\nexport declare function createPlusNumber(value?: number): PlusNumber;\n```\n\n## NPM Package\nNPM package contains the additional binary *plus-number.dll*, which is the shared library for *PlusNumber* class. It's placed\n at *bin* directory, so either Node.js or Napa can resolve the shared object path in the same way as it does for a module.\n\n## Mocha test\n```js\nvar assert = require('assert');\nvar plusNumber = require('plus-number');\ndescribe('Test suite for plus-number', function () {\n    it('adds a given value', function () {\n        var po = plusNumber.createPlusNumber(3);\n        var result = po.add(4);\n        assert.equal(result, 7);\n    });\n    it('fails with constructor call', function () {\n        var failed = false;\n        try {\n            var po = new plusNumber.PlusNumber();\n        }\n        catch (error) {\n            failed = true;\n        }\n        assert.equal(failed, true);\n    });\n});\n```\n"
  },
  {
    "path": "examples/modules/plus-number/inc/plus-number.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#if defined(_WIN32) || defined(__WIN32__)\n    #ifdef NAPA_EXAMPLE_API\n        #define NAPA_EXAMPLE_EXPORT __declspec(dllexport)\n    #else\n        #define NAPA_EXAMPLE_EXPORT __declspec(dllimport)\n    #endif\n#else\n    #define NAPA_EXAMPLE_EXPORT\n#endif\n\nnamespace napa {\nnamespace demo {\n\n    /// <summary> Example class to show how to create Napa module using a wrapped C++ class. </summary>\n    class NAPA_EXAMPLE_EXPORT PlusNumber {\n    public:\n\n        /// <summary> Constructor with initial value. </summary>\n        explicit PlusNumber(double value = 0.0);\n\n        /// <summary> Add the given value and return the result. </summary>\n        double Add(double value);\n\n    private:\n\n        double _value;\n    };\n\n}  // napespace demo\n}  // namespace napa\n"
  },
  {
    "path": "examples/modules/plus-number/lib/plus-number.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet addon = require('../bin/addon');\n\nexport declare class PlusNumber {\n    public add(value: number): number;\n}\n\nexport function createPlusNumber(value: number = 0.0): PlusNumber {\n    return addon.createPlusNumber(value);\n}\n"
  },
  {
    "path": "examples/modules/plus-number/lib/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": true,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"],\n        \"declarationDir\": \"../types\"\n    }\n}\n"
  },
  {
    "path": "examples/modules/plus-number/napa/CMakeLists.txt",
    "content": "execute_process(COMMAND node -e \"require('napajs/build').paths.inc\" RESULT_VARIABLE ERR OUTPUT_VARIABLE NAPAJS_INC)\nif(ERR)\n    message(FATAL_ERROR \"Failed to resolve napa include directory\")\nendif(ERR)\n\nexecute_process(COMMAND node -e \"require('napajs/build').paths.lib\" RESULT_VARIABLE ERR OUTPUT_VARIABLE NAPAJS_LIB)\nif(ERR)\n    message(FATAL_ERROR \"Failed to resolve napa library path\")\nendif(ERR)\n\n#######################################################################################\n# Build napa addon.\nset(NAPA_ADDON_TARGET_NAME \"${PROJECT_NAME}.napa\")\n\n# The generated library\nadd_library(${NAPA_ADDON_TARGET_NAME} SHARED \"addon.cpp\" \"plus-number-wrap.cpp\")\n\nset_target_properties(${NAPA_ADDON_TARGET_NAME} PROPERTIES PREFIX \"\" SUFFIX \"\")\n\n# Include directories\ntarget_include_directories(${NAPA_ADDON_TARGET_NAME} PRIVATE\n    ../inc\n    ${CMAKE_JS_INC}\n    ${NAPAJS_INC})\n\n# Compiler definitions\ntarget_compile_definitions(${NAPA_ADDON_TARGET_NAME} PRIVATE\n    BUILDING_NAPA_EXTENSION)\n\n# Link libraries\ntarget_link_libraries(${NAPA_ADDON_TARGET_NAME} PRIVATE\n    plus-number\n    ${CMAKE_JS_LIB}\n    ${NAPAJS_LIB})\n\n#######################################################################################\n# Build napa addon for node.\nset(NODE_ADDON_TARGET_NAME \"${PROJECT_NAME}.node\")\n\n# The generated library\nadd_library(${NODE_ADDON_TARGET_NAME} SHARED \"addon.cpp\" \"plus-number-wrap.cpp\")\n\nset_target_properties(${NODE_ADDON_TARGET_NAME} PROPERTIES PREFIX \"\" SUFFIX \"\")\n\n# Include directories\ntarget_include_directories(${NODE_ADDON_TARGET_NAME} PRIVATE\n    ../inc\n    ${CMAKE_JS_INC}\n    ${NAPAJS_INC})\n\n# Compiler definitions\ntarget_compile_definitions(${NODE_ADDON_TARGET_NAME} PRIVATE\n    BUILDING_NODE_EXTENSION)\n\n# Link libraries\ntarget_link_libraries(${NODE_ADDON_TARGET_NAME} PRIVATE\n    plus-number\n    ${CMAKE_JS_LIB})\n"
  },
  {
    "path": "examples/modules/plus-number/napa/addon.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"plus-number-wrap.h\"\n\nusing namespace napa::demo;\nusing namespace v8;\n\nvoid CreatePlusNumber(const FunctionCallbackInfo<Value>& args) {\n    PlusNumberWrap::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports) {\n    PlusNumberWrap::Init();\n\n    NAPA_SET_METHOD(exports, \"createPlusNumber\", CreatePlusNumber);\n}\n\nNAPA_MODULE(addon, InitAll);\n"
  },
  {
    "path": "examples/modules/plus-number/napa/plus-number-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"plus-number-wrap.h\"\n\nusing namespace napa::demo;\nusing namespace v8;\n\nconst char* PlusNumberWrap::_exportName = \"PlusNumberWrap\";\n\n// Define persistent constructor.\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(PlusNumberWrap);\n\nPlusNumberWrap::PlusNumberWrap(double value)\n    : _plusNumber(value) {\n}\n\nvoid PlusNumberWrap::Init() {\n    auto isolate = Isolate::GetCurrent();\n\n    // Prepare constructor template.\n    auto functionTemplate = FunctionTemplate::New(isolate, NewCallback);\n    functionTemplate->SetClassName(String::NewFromUtf8(isolate, _exportName));\n    functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    // Set prototype method.\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"add\", Add);\n\n    // Set persistent constructor into V8.\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(_exportName, functionTemplate->GetFunction());\n}\n\nvoid PlusNumberWrap::NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n\n    auto constructor = NAPA_GET_PERSISTENT_CONSTRUCTOR(_exportName, PlusNumberWrap);\n    auto context = isolate->GetCurrentContext();\n    auto instance = constructor->NewInstance(context, argc, argv).ToLocalChecked();\n\n    args.GetReturnValue().Set(instance);\n}\n\nvoid PlusNumberWrap::NewCallback(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate,\n        args.IsConstructCall(),\n        \"PlusNumberWrap instance must be created by the factory.\");\n\n    CHECK_ARG(isolate,\n        args.Length() == 0 || args.Length() == 1,\n        \"Only one or no argument is allowed.\");\n\n    if (args.Length() == 1) {\n        CHECK_ARG(isolate,\n            args[0]->IsNumber(),\n            \"The first argument must be a number.\");\n    }\n\n    double value = args[0]->IsUndefined() ? 0.0 : args[0]->NumberValue();\n\n    auto wrap = new PlusNumberWrap(value);\n    wrap->Wrap(args.This());\n\n    args.GetReturnValue().Set(args.This());\n}\n\nvoid PlusNumberWrap::Add(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = args.GetIsolate();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate,\n        args.Length() == 1 && args[0]->IsNumber(),\n        \"Number must be given as argument.\");\n\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<PlusNumberWrap>(args.Holder());\n    auto value = wrap->_plusNumber.Add(args[0]->NumberValue());\n\n    args.GetReturnValue().Set(Number::New(isolate, value));\n}\n"
  },
  {
    "path": "examples/modules/plus-number/napa/plus-number-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <plus-number.h>\n\nnamespace napa {\nnamespace demo {\n\n    /// <summary> Napa example module wrapping PlusNumber class. </summary>\n    class PlusNumberWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> Register this class into V8. </summary>\n        static void Init();\n\n        /// <summary> Enable to create an instance by createPlusNumber() Javascript API. </summary>\n        /// <param name=\"args\"> Addend as PlusNumber constructor parameter. </param>\n        static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    private:\n\n        /// <summary> Exported class name. </summary>\n        static const char* _exportName;\n\n        /// <summary> Constructor with initial value. </summary>\n        explicit PlusNumberWrap(double value = 0.0);\n\n        /// <summary> Create PlusNumber instance at V8. </summary>\n        /// <param name=\"args\"> Addend as PlusNumber constructor parameter. </param>\n        static void NewCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Add value. </summary>\n        /// <param name=\"args\"> Addend. </param>\n        static void Add(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Declare persistent constructor to create PlusNumber instance. </summary>\n        /// <remarks> Napa creates persistent constructor at each isolate while node.js creates the static instance. </remarks>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        PlusNumber _plusNumber;\n    };\n\n}  // namespace demo\n}  // namespace napa\n"
  },
  {
    "path": "examples/modules/plus-number/package.json",
    "content": "{\n  \"name\": \"plus-number\",\n  \"version\": \"0.1.0\",\n  \"author\": \"napajs\",\n  \"description\": \"Example of a napa module wrapping a class.\",\n  \"main\": \"./lib/plus-number.js\",\n  \"types\": \"./types/plus-number.d.ts\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"mocha\": \">= 3.4.2\",\n    \"typescript\": \">= 2.2.1\",\n    \"@types/node\": \">= 7.0.8\",\n    \"@types/mocha\": \">= 2.2.0\",\n    \"markdown-table\": \"1.1.0\"\n  },\n  \"dependencies\": {\n    \"napajs\": \">= 0.1.2\"\n  },\n  \"scripts\": {\n    \"install\": \"cmake-js compile\",\n    \"pretest\": \"tsc -p lib && cmake-js compile -d unittest && tsc -p test\",\n    \"test\": \"node unittest/run.js && mocha test --recursive\"\n  }\n}\n"
  },
  {
    "path": "examples/modules/plus-number/src/CMakeLists.txt",
    "content": "# Build plus-number library.\nset(TARGET_NAME \"plus-number\")\n\n# The generated library\nadd_library(${TARGET_NAME} SHARED \"plus-number.cpp\")\n\n# Include directories\ntarget_include_directories(${TARGET_NAME} PRIVATE ../inc)\n\n# Compiler definitions\ntarget_compile_definitions(${TARGET_NAME} PRIVATE NAPA_EXAMPLE_API)\n"
  },
  {
    "path": "examples/modules/plus-number/src/plus-number.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"plus-number.h\"\n\nusing namespace napa::demo;\n\nPlusNumber::PlusNumber(double value)\n    : _value(value) {\n}\n\ndouble PlusNumber::Add(double value) {\n    return _value + value;\n}\n"
  },
  {
    "path": "examples/modules/plus-number/test/test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet assert = require('assert');\nlet plusNumber = require('..');\nlet napa = require('napajs');\nlet zone = napa.zone.create('zone');\n\ndescribe('Test suite for plus-number', function() {\n    this.timeout(0);\n\n    it('adds a given value', function() {\n        let po = plusNumber.createPlusNumber(3);\n        let result: number = po.add(4);\n        assert.equal(result, 7);\n    });\n\n    it('fails with constructor call', function() {\n        let failed: boolean = false;\n        try {\n            let po = new plusNumber.PlusNumber();\n        } catch (error) {\n            failed = true;\n        }\n        assert.equal(failed, true);\n    });\n\n    it('adds a given value in napa zone', function() {\n        return zone.execute(() => {\n            let plusNumber = require('..');\n            let po = plusNumber.createPlusNumber(3);\n            let result: number = po.add(4);\n            return result;\n        })\n        .then((result: any) => {\n            assert.equal(result.value, 7);\n        });\n    });\n\n    it('adds a given value in node zone', function() {\n        return napa.zone.node.execute(() => {\n            let plusNumber = require('..');\n            let po = plusNumber.createPlusNumber(3);\n            let result: number = po.add(4);\n            return result;\n        })\n        .then((result: any) => {\n            assert.equal(result.value, 7);\n        });\n    });\n})\n"
  },
  {
    "path": "examples/modules/plus-number/test/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": false,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"]\n    }\n}\n"
  },
  {
    "path": "examples/modules/plus-number/unittest/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"library-test\")\n\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Set symbol visibility to hidden by default.\n# Napa shared library shares a few classes with napa-binding.node with different compile definition,\n# exposing the same symbols from both shared libraries may cause improper behaviors under gcc.\nset(CMAKE_CXX_VISIBILITY_PRESET hidden)\nset(CMAKE_VISIBILITY_INLINES_HIDDEN)\n\nfile(GLOB LIBRARY-FILES \"../bin/*plus-number.*\")\nfile(COPY ${LIBRARY-FILES} DESTINATION ${PROJECT_SOURCE_DIR}/bin/)\n\n# Files to compile\nfile(GLOB SOURCE_FILES \"main.cpp\")\n\n# The executable name\nset(TARGET_NAME \"library-test\")\n\n# The generated library\nadd_executable(${TARGET_NAME} ${SOURCE_FILES})\n\n# Include directories\ntarget_include_directories(${TARGET_NAME} PRIVATE ../inc)\n\nfind_library(PLUS_NUMBER_LIBRARY NAMES plus-number PATHS ${PROJECT_SOURCE_DIR}/bin)\n\n# Link libraries\ntarget_link_libraries(${TARGET_NAME} PRIVATE ${PLUS_NUMBER_LIBRARY})\n"
  },
  {
    "path": "examples/modules/plus-number/unittest/catch/LICENSE.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "examples/modules/plus-number/unittest/catch/catch.hpp",
    "content": "/*\n *  Catch v1.6.1\n *  Generated: 2017-01-20 12:33:53.497767\n *  ----------------------------------------------------------\n *  This file has been merged from multiple headers. Please don't edit it directly\n *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n *\n *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\n#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n#define TWOBLUECUBES_CATCH_HPP_INCLUDED\n\n#ifdef __clang__\n#    pragma clang system_header\n#elif defined __GNUC__\n#    pragma GCC system_header\n#endif\n\n// #included from: internal/catch_suppress_warnings.h\n\n#ifdef __clang__\n#   ifdef __ICC // icpc defines the __clang__ macro\n#       pragma warning(push)\n#       pragma warning(disable: 161 1682)\n#   else // __ICC\n#       pragma clang diagnostic ignored \"-Wglobal-constructors\"\n#       pragma clang diagnostic ignored \"-Wvariadic-macros\"\n#       pragma clang diagnostic ignored \"-Wc99-extensions\"\n#       pragma clang diagnostic ignored \"-Wunused-variable\"\n#       pragma clang diagnostic push\n#       pragma clang diagnostic ignored \"-Wpadded\"\n#       pragma clang diagnostic ignored \"-Wc++98-compat\"\n#       pragma clang diagnostic ignored \"-Wc++98-compat-pedantic\"\n#       pragma clang diagnostic ignored \"-Wswitch-enum\"\n#       pragma clang diagnostic ignored \"-Wcovered-switch-default\"\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic ignored \"-Wvariadic-macros\"\n#    pragma GCC diagnostic ignored \"-Wunused-variable\"\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wpadded\"\n#endif\n#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)\n#  define CATCH_IMPL\n#endif\n\n#ifdef CATCH_IMPL\n#  ifndef CLARA_CONFIG_MAIN\n#    define CLARA_CONFIG_MAIN_NOT_DEFINED\n#    define CLARA_CONFIG_MAIN\n#  endif\n#endif\n\n// #included from: internal/catch_notimplemented_exception.h\n#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED\n\n// #included from: catch_common.h\n#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED\n\n// #included from: catch_compiler_capabilities.h\n#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED\n\n// Detect a number of compiler features - mostly C++11/14 conformance - by compiler\n// The following features are defined:\n//\n// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?\n// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?\n// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods\n// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?\n// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported\n// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?\n// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?\n// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)\n\n// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?\n\n// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?\n// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?\n// ****************\n// Note to maintainers: if new toggles are added please document them\n// in configuration.md, too\n// ****************\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11\n\n#ifdef __cplusplus\n\n#  if __cplusplus >= 201103L\n#    define CATCH_CPP11_OR_GREATER\n#  endif\n\n#  if __cplusplus >= 201402L\n#    define CATCH_CPP14_OR_GREATER\n#  endif\n\n#endif\n\n#ifdef __clang__\n\n#  if __has_feature(cxx_nullptr)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#  endif\n\n#  if __has_feature(cxx_noexcept)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#  endif\n\n#   if defined(CATCH_CPP11_OR_GREATER)\n#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( \"clang diagnostic ignored \\\"-Wparentheses\\\"\" )\n#   endif\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// Borland\n#ifdef __BORLANDC__\n\n#endif // __BORLANDC__\n\n////////////////////////////////////////////////////////////////////////////////\n// EDG\n#ifdef __EDG_VERSION__\n\n#endif // __EDG_VERSION__\n\n////////////////////////////////////////////////////////////////////////////////\n// Digital Mars\n#ifdef __DMC__\n\n#endif // __DMC__\n\n////////////////////////////////////////////////////////////////////////////////\n// GCC\n#ifdef __GNUC__\n\n#   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)\n#       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#   endif\n\n#   if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)\n#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( \"GCC diagnostic ignored \\\"-Wparentheses\\\"\" )\n#   endif\n\n// - otherwise more recent versions define __cplusplus >= 201103L\n// and will get picked up below\n\n#endif // __GNUC__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#ifdef _MSC_VER\n\n#if (_MSC_VER >= 1600)\n#   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))\n#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE\n#endif\n\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Use variadic macros if the compiler supports them\n#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \\\n    ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \\\n    ( defined __GNUC__ && __GNUC__ >= 3 ) || \\\n    ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )\n\n#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n\n#endif\n\n// Use __COUNTER__ if the compiler supports it\n#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \\\n    ( defined __GNUC__  && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \\\n    ( defined __clang__ && __clang_major__ >= 3 )\n\n#define CATCH_INTERNAL_CONFIG_COUNTER\n\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// C++ language feature support\n\n// catch all support for C++11\n#if defined(CATCH_CPP11_OR_GREATER)\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM\n#    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE\n#    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n#    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n#  endif\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)\n#    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG\n#  endif\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)\n#    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE\n#  endif\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)\n#    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#  endif\n# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)\n#   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE\n#  endif\n\n#endif // __cplusplus >= 201103L\n\n// Now set the actual defines based on the above + anything the user has configured\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_NULLPTR\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_NOEXCEPT\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_GENERATED_METHODS\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_IS_ENUM\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_TUPLE\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)\n#   define CATCH_CONFIG_VARIADIC_MACROS\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_LONG_LONG\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_OVERRIDE\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_UNIQUE_PTR\n#endif\n// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for\n// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.\n// This does not affect compilation\n#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)\n#   define CATCH_CONFIG_COUNTER\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_SHUFFLE\n#endif\n\n#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS\n#endif\n\n// noexcept support:\n#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)\n#  define CATCH_NOEXCEPT noexcept\n#  define CATCH_NOEXCEPT_IS(x) noexcept(x)\n#else\n#  define CATCH_NOEXCEPT throw()\n#  define CATCH_NOEXCEPT_IS(x)\n#endif\n\n// nullptr support\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n#   define CATCH_NULL nullptr\n#else\n#   define CATCH_NULL NULL\n#endif\n\n// override support\n#ifdef CATCH_CONFIG_CPP11_OVERRIDE\n#   define CATCH_OVERRIDE override\n#else\n#   define CATCH_OVERRIDE\n#endif\n\n// unique_ptr support\n#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR\n#   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>\n#else\n#   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>\n#endif\n\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )\n#ifdef CATCH_CONFIG_COUNTER\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )\n#else\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )\n#endif\n\n#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr\n#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )\n\n#include <sstream>\n#include <stdexcept>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct IConfig;\n\n    struct CaseSensitive { enum Choice {\n        Yes,\n        No\n    }; };\n\n    class NonCopyable {\n#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        NonCopyable( NonCopyable const& )              = delete;\n        NonCopyable( NonCopyable && )                  = delete;\n        NonCopyable& operator = ( NonCopyable const& ) = delete;\n        NonCopyable& operator = ( NonCopyable && )     = delete;\n#else\n        NonCopyable( NonCopyable const& info );\n        NonCopyable& operator = ( NonCopyable const& );\n#endif\n\n    protected:\n        NonCopyable() {}\n        virtual ~NonCopyable();\n    };\n\n    class SafeBool {\n    public:\n        typedef void (SafeBool::*type)() const;\n\n        static type makeSafe( bool value ) {\n            return value ? &SafeBool::trueValue : 0;\n        }\n    private:\n        void trueValue() const {}\n    };\n\n    template<typename ContainerT>\n    inline void deleteAll( ContainerT& container ) {\n        typename ContainerT::const_iterator it = container.begin();\n        typename ContainerT::const_iterator itEnd = container.end();\n        for(; it != itEnd; ++it )\n            delete *it;\n    }\n    template<typename AssociativeContainerT>\n    inline void deleteAllValues( AssociativeContainerT& container ) {\n        typename AssociativeContainerT::const_iterator it = container.begin();\n        typename AssociativeContainerT::const_iterator itEnd = container.end();\n        for(; it != itEnd; ++it )\n            delete it->second;\n    }\n\n    bool startsWith( std::string const& s, std::string const& prefix );\n    bool endsWith( std::string const& s, std::string const& suffix );\n    bool contains( std::string const& s, std::string const& infix );\n    void toLowerInPlace( std::string& s );\n    std::string toLower( std::string const& s );\n    std::string trim( std::string const& str );\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );\n\n    struct pluralise {\n        pluralise( std::size_t count, std::string const& label );\n\n        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );\n\n        std::size_t m_count;\n        std::string m_label;\n    };\n\n    struct SourceLineInfo {\n\n        SourceLineInfo();\n        SourceLineInfo( char const* _file, std::size_t _line );\n        SourceLineInfo( SourceLineInfo const& other );\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        SourceLineInfo( SourceLineInfo && )                  = default;\n        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;\n        SourceLineInfo& operator = ( SourceLineInfo && )     = default;\n#  endif\n        bool empty() const;\n        bool operator == ( SourceLineInfo const& other ) const;\n        bool operator < ( SourceLineInfo const& other ) const;\n\n        std::string file;\n        std::size_t line;\n    };\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );\n\n    // This is just here to avoid compiler warnings with macro constants and boolean literals\n    inline bool alwaysTrue( std::size_t = 0 ) { return true; }\n    inline bool alwaysFalse( std::size_t = 0 ) { return false; }\n\n    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );\n\n    void seedRng( IConfig const& config );\n    unsigned int rngSeed();\n\n    // Use this in variadic streaming macros to allow\n    //    >> +StreamEndStop\n    // as well as\n    //    >> stuff +StreamEndStop\n    struct StreamEndStop {\n        std::string operator+() {\n            return std::string();\n        }\n    };\n    template<typename T>\n    T const& operator + ( T const& value, StreamEndStop ) {\n        return value;\n    }\n}\n\n#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )\n#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );\n\n#include <ostream>\n\nnamespace Catch {\n\n    class NotImplementedException : public std::exception\n    {\n    public:\n        NotImplementedException( SourceLineInfo const& lineInfo );\n        NotImplementedException( NotImplementedException const& ) {}\n\n        virtual ~NotImplementedException() CATCH_NOEXCEPT {}\n\n        virtual const char* what() const CATCH_NOEXCEPT;\n\n    private:\n        std::string m_what;\n        SourceLineInfo m_lineInfo;\n    };\n\n} // end namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )\n\n// #included from: internal/catch_context.h\n#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED\n\n// #included from: catch_interfaces_generators.h\n#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct IGeneratorInfo {\n        virtual ~IGeneratorInfo();\n        virtual bool moveNext() = 0;\n        virtual std::size_t getCurrentIndex() const = 0;\n    };\n\n    struct IGeneratorsForTest {\n        virtual ~IGeneratorsForTest();\n\n        virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;\n        virtual bool moveNext() = 0;\n    };\n\n    IGeneratorsForTest* createGeneratorsForTest();\n\n} // end namespace Catch\n\n// #included from: catch_ptr.hpp\n#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    // An intrusive reference counting smart pointer.\n    // T must implement addRef() and release() methods\n    // typically implementing the IShared interface\n    template<typename T>\n    class Ptr {\n    public:\n        Ptr() : m_p( CATCH_NULL ){}\n        Ptr( T* p ) : m_p( p ){\n            if( m_p )\n                m_p->addRef();\n        }\n        Ptr( Ptr const& other ) : m_p( other.m_p ){\n            if( m_p )\n                m_p->addRef();\n        }\n        ~Ptr(){\n            if( m_p )\n                m_p->release();\n        }\n        void reset() {\n            if( m_p )\n                m_p->release();\n            m_p = CATCH_NULL;\n        }\n        Ptr& operator = ( T* p ){\n            Ptr temp( p );\n            swap( temp );\n            return *this;\n        }\n        Ptr& operator = ( Ptr const& other ){\n            Ptr temp( other );\n            swap( temp );\n            return *this;\n        }\n        void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }\n        T* get() const{ return m_p; }\n        T& operator*() const { return *m_p; }\n        T* operator->() const { return m_p; }\n        bool operator !() const { return m_p == CATCH_NULL; }\n        operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }\n\n    private:\n        T* m_p;\n    };\n\n    struct IShared : NonCopyable {\n        virtual ~IShared();\n        virtual void addRef() const = 0;\n        virtual void release() const = 0;\n    };\n\n    template<typename T = IShared>\n    struct SharedImpl : T {\n\n        SharedImpl() : m_rc( 0 ){}\n\n        virtual void addRef() const {\n            ++m_rc;\n        }\n        virtual void release() const {\n            if( --m_rc == 0 )\n                delete this;\n        }\n\n        mutable unsigned int m_rc;\n    };\n\n} // end namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#include <memory>\n#include <vector>\n#include <stdlib.h>\n\nnamespace Catch {\n\n    class TestCase;\n    class Stream;\n    struct IResultCapture;\n    struct IRunner;\n    struct IGeneratorsForTest;\n    struct IConfig;\n\n    struct IContext\n    {\n        virtual ~IContext();\n\n        virtual IResultCapture* getResultCapture() = 0;\n        virtual IRunner* getRunner() = 0;\n        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;\n        virtual bool advanceGeneratorsForCurrentTest() = 0;\n        virtual Ptr<IConfig const> getConfig() const = 0;\n    };\n\n    struct IMutableContext : IContext\n    {\n        virtual ~IMutableContext();\n        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;\n        virtual void setRunner( IRunner* runner ) = 0;\n        virtual void setConfig( Ptr<IConfig const> const& config ) = 0;\n    };\n\n    IContext& getCurrentContext();\n    IMutableContext& getCurrentMutableContext();\n    void cleanUpContext();\n    Stream createStream( std::string const& streamName );\n\n}\n\n// #included from: internal/catch_test_registry.hpp\n#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED\n\n// #included from: catch_interfaces_testcase.h\n#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED\n\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec;\n\n    struct ITestCase : IShared {\n        virtual void invoke () const = 0;\n    protected:\n        virtual ~ITestCase();\n    };\n\n    class TestCase;\n    struct IConfig;\n\n    struct ITestCaseRegistry {\n        virtual ~ITestCaseRegistry();\n        virtual std::vector<TestCase> const& getAllTests() const = 0;\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;\n    };\n\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n}\n\nnamespace Catch {\n\ntemplate<typename C>\nclass MethodTestCase : public SharedImpl<ITestCase> {\n\npublic:\n    MethodTestCase( void (C::*method)() ) : m_method( method ) {}\n\n    virtual void invoke() const {\n        C obj;\n        (obj.*m_method)();\n    }\n\nprivate:\n    virtual ~MethodTestCase() {}\n\n    void (C::*m_method)();\n};\n\ntypedef void(*TestFunction)();\n\nstruct NameAndDesc {\n    NameAndDesc( const char* _name = \"\", const char* _description= \"\" )\n    : name( _name ), description( _description )\n    {}\n\n    const char* name;\n    const char* description;\n};\n\nvoid registerTestCase\n    (   ITestCase* testCase,\n        char const* className,\n        NameAndDesc const& nameAndDesc,\n        SourceLineInfo const& lineInfo );\n\nstruct AutoReg {\n\n    AutoReg\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc );\n\n    template<typename C>\n    AutoReg\n        (   void (C::*method)(),\n            char const* className,\n            NameAndDesc const& nameAndDesc,\n            SourceLineInfo const& lineInfo ) {\n\n        registerTestCase\n            (   new MethodTestCase<C>( method ),\n                className,\n                nameAndDesc,\n                lineInfo );\n    }\n\n    ~AutoReg();\n\nprivate:\n    AutoReg( AutoReg const& );\n    void operator= ( AutoReg const& );\n};\n\nvoid registerTestCaseFunction\n    (   TestFunction function,\n        SourceLineInfo const& lineInfo,\n        NameAndDesc const& nameAndDesc );\n\n} // end namespace Catch\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \\\n        static void TestName(); \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( ... ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, \"&\" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\\\n        namespace{ \\\n            struct TestName : ClassName{ \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \\\n        } \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \\\n        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );\n\n#else\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \\\n        static void TestName(); \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, \"&\" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\\\n        namespace{ \\\n            struct TestCaseName : ClassName{ \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \\\n        } \\\n        void TestCaseName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \\\n        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );\n#endif\n\n// #included from: internal/catch_capture.hpp\n#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED\n\n// #included from: catch_result_builder.h\n#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED\n\n// #included from: catch_result_type.h\n#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED\n\nnamespace Catch {\n\n    // ResultWas::OfType enum\n    struct ResultWas { enum OfType {\n        Unknown = -1,\n        Ok = 0,\n        Info = 1,\n        Warning = 2,\n\n        FailureBit = 0x10,\n\n        ExpressionFailed = FailureBit | 1,\n        ExplicitFailure = FailureBit | 2,\n\n        Exception = 0x100 | FailureBit,\n\n        ThrewException = Exception | 1,\n        DidntThrowException = Exception | 2,\n\n        FatalErrorCondition = 0x200 | FailureBit\n\n    }; };\n\n    inline bool isOk( ResultWas::OfType resultType ) {\n        return ( resultType & ResultWas::FailureBit ) == 0;\n    }\n    inline bool isJustInfo( int flags ) {\n        return flags == ResultWas::Info;\n    }\n\n    // ResultDisposition::Flags enum\n    struct ResultDisposition { enum Flags {\n        Normal = 0x01,\n\n        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues\n        FalseTest = 0x04,           // Prefix expression with !\n        SuppressFail = 0x08         // Failures are reported but do not fail the test\n    }; };\n\n    inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {\n        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );\n    }\n\n    inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }\n    inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }\n    inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }\n\n} // end namespace Catch\n\n// #included from: catch_assertionresult.h\n#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct AssertionInfo\n    {\n        AssertionInfo() {}\n        AssertionInfo(  std::string const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        std::string const& _capturedExpression,\n                        ResultDisposition::Flags _resultDisposition );\n\n        std::string macroName;\n        SourceLineInfo lineInfo;\n        std::string capturedExpression;\n        ResultDisposition::Flags resultDisposition;\n    };\n\n    struct AssertionResultData\n    {\n        AssertionResultData() : resultType( ResultWas::Unknown ) {}\n\n        std::string reconstructedExpression;\n        std::string message;\n        ResultWas::OfType resultType;\n    };\n\n    class AssertionResult {\n    public:\n        AssertionResult();\n        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );\n        ~AssertionResult();\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n         AssertionResult( AssertionResult const& )              = default;\n         AssertionResult( AssertionResult && )                  = default;\n         AssertionResult& operator = ( AssertionResult const& ) = default;\n         AssertionResult& operator = ( AssertionResult && )     = default;\n#  endif\n\n        bool isOk() const;\n        bool succeeded() const;\n        ResultWas::OfType getResultType() const;\n        bool hasExpression() const;\n        bool hasMessage() const;\n        std::string getExpression() const;\n        std::string getExpressionInMacro() const;\n        bool hasExpandedExpression() const;\n        std::string getExpandedExpression() const;\n        std::string getMessage() const;\n        SourceLineInfo getSourceInfo() const;\n        std::string getTestMacroName() const;\n\n    protected:\n        AssertionInfo m_info;\n        AssertionResultData m_resultData;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_matchers.hpp\n#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n    namespace Generic {\n        template<typename ExpressionT> class AllOf;\n        template<typename ExpressionT> class AnyOf;\n        template<typename ExpressionT> class Not;\n    }\n\n    template<typename ExpressionT>\n    struct Matcher : SharedImpl<IShared>\n    {\n        typedef ExpressionT ExpressionType;\n\n        virtual ~Matcher() {}\n        virtual Ptr<Matcher> clone() const = 0;\n        virtual bool match( ExpressionT const& expr ) const = 0;\n        virtual std::string toString() const = 0;\n\n        Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;\n        Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;\n        Generic::Not<ExpressionT> operator ! () const;\n    };\n\n    template<typename DerivedT, typename ExpressionT>\n    struct MatcherImpl : Matcher<ExpressionT> {\n\n        virtual Ptr<Matcher<ExpressionT> > clone() const {\n            return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );\n        }\n    };\n\n    namespace Generic {\n        template<typename ExpressionT>\n        class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {\n        public:\n            explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}\n            Not( Not const& other ) : m_matcher( other.m_matcher ) {}\n\n            virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {\n                return !m_matcher->match( expr );\n            }\n\n            virtual std::string toString() const CATCH_OVERRIDE {\n                return \"not \" + m_matcher->toString();\n            }\n        private:\n            Ptr< Matcher<ExpressionT> > m_matcher;\n        };\n\n        template<typename ExpressionT>\n        class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {\n        public:\n\n            AllOf() {}\n            AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}\n\n            AllOf& add( Matcher<ExpressionT> const& matcher ) {\n                m_matchers.push_back( matcher.clone() );\n                return *this;\n            }\n            virtual bool match( ExpressionT const& expr ) const\n            {\n                for( std::size_t i = 0; i < m_matchers.size(); ++i )\n                    if( !m_matchers[i]->match( expr ) )\n                        return false;\n                return true;\n            }\n            virtual std::string toString() const {\n                std::ostringstream oss;\n                oss << \"( \";\n                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {\n                    if( i != 0 )\n                        oss << \" and \";\n                    oss << m_matchers[i]->toString();\n                }\n                oss << \" )\";\n                return oss.str();\n            }\n\n            AllOf operator && ( Matcher<ExpressionT> const& other ) const {\n                AllOf allOfExpr( *this );\n                allOfExpr.add( other );\n                return allOfExpr;\n            }\n\n        private:\n            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;\n        };\n\n        template<typename ExpressionT>\n        class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {\n        public:\n\n            AnyOf() {}\n            AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}\n\n            AnyOf& add( Matcher<ExpressionT> const& matcher ) {\n                m_matchers.push_back( matcher.clone() );\n                return *this;\n            }\n            virtual bool match( ExpressionT const& expr ) const\n            {\n                for( std::size_t i = 0; i < m_matchers.size(); ++i )\n                    if( m_matchers[i]->match( expr ) )\n                        return true;\n                return false;\n            }\n            virtual std::string toString() const {\n                std::ostringstream oss;\n                oss << \"( \";\n                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {\n                    if( i != 0 )\n                        oss << \" or \";\n                    oss << m_matchers[i]->toString();\n                }\n                oss << \" )\";\n                return oss.str();\n            }\n\n            AnyOf operator || ( Matcher<ExpressionT> const& other ) const {\n                AnyOf anyOfExpr( *this );\n                anyOfExpr.add( other );\n                return anyOfExpr;\n            }\n\n        private:\n            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;\n        };\n\n    } // namespace Generic\n\n    template<typename ExpressionT>\n    Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {\n        Generic::AllOf<ExpressionT> allOfExpr;\n        allOfExpr.add( *this );\n        allOfExpr.add( other );\n        return allOfExpr;\n    }\n\n    template<typename ExpressionT>\n    Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {\n        Generic::AnyOf<ExpressionT> anyOfExpr;\n        anyOfExpr.add( *this );\n        anyOfExpr.add( other );\n        return anyOfExpr;\n    }\n\n    template<typename ExpressionT>\n    Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {\n        return Generic::Not<ExpressionT>( *this );\n    }\n\n    namespace StdString {\n\n        inline std::string makeString( std::string const& str ) { return str; }\n        inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }\n\n        struct CasedString\n        {\n            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )\n            :   m_caseSensitivity( caseSensitivity ),\n                m_str( adjustString( str ) )\n            {}\n            std::string adjustString( std::string const& str ) const {\n                return m_caseSensitivity == CaseSensitive::No\n                    ? toLower( str )\n                    : str;\n\n            }\n            std::string toStringSuffix() const\n            {\n                return m_caseSensitivity == CaseSensitive::No\n                    ? \" (case insensitive)\"\n                    : \"\";\n            }\n            CaseSensitive::Choice m_caseSensitivity;\n            std::string m_str;\n        };\n\n        struct Equals : MatcherImpl<Equals, std::string> {\n            Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            :   m_data( str, caseSensitivity )\n            {}\n            Equals( Equals const& other ) : m_data( other.m_data ){}\n\n            virtual ~Equals();\n\n            virtual bool match( std::string const& expr ) const {\n                return m_data.m_str == m_data.adjustString( expr );;\n            }\n            virtual std::string toString() const {\n                return \"equals: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct Contains : MatcherImpl<Contains, std::string> {\n            Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n            Contains( Contains const& other ) : m_data( other.m_data ){}\n\n            virtual ~Contains();\n\n            virtual bool match( std::string const& expr ) const {\n                return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;\n            }\n            virtual std::string toString() const {\n                return \"contains: \\\"\" + m_data.m_str  + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct StartsWith : MatcherImpl<StartsWith, std::string> {\n            StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n\n            StartsWith( StartsWith const& other ) : m_data( other.m_data ){}\n\n            virtual ~StartsWith();\n\n            virtual bool match( std::string const& expr ) const {\n                return startsWith( m_data.adjustString( expr ), m_data.m_str );\n            }\n            virtual std::string toString() const {\n                return \"starts with: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct EndsWith : MatcherImpl<EndsWith, std::string> {\n            EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n            EndsWith( EndsWith const& other ) : m_data( other.m_data ){}\n\n            virtual ~EndsWith();\n\n            virtual bool match( std::string const& expr ) const {\n                return endsWith( m_data.adjustString( expr ), m_data.m_str );\n            }\n            virtual std::string toString() const {\n                return \"ends with: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n    } // namespace StdString\n    } // namespace Impl\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n    template<typename ExpressionT>\n    inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {\n        return Impl::Generic::Not<ExpressionT>( m );\n    }\n\n    template<typename ExpressionT>\n    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2 ) {\n        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2,\n                                                    Impl::Matcher<ExpressionT> const& m3 ) {\n        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2 ) {\n        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2,\n                                                    Impl::Matcher<ExpressionT> const& m3 ) {\n        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );\n    }\n\n    inline Impl::StdString::Equals      Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Equals( str, caseSensitivity );\n    }\n    inline Impl::StdString::Equals      Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );\n    }\n    inline Impl::StdString::Contains    Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Contains( substr, caseSensitivity );\n    }\n    inline Impl::StdString::Contains    Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );\n    }\n    inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {\n        return Impl::StdString::StartsWith( substr );\n    }\n    inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {\n        return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );\n    }\n    inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {\n        return Impl::StdString::EndsWith( substr );\n    }\n    inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {\n        return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );\n    }\n\n} // namespace Matchers\n\nusing namespace Matchers;\n\n} // namespace Catch\n\nnamespace Catch {\n\n    struct TestFailureException{};\n\n    template<typename T> class ExpressionLhs;\n\n    struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;\n\n    struct CopyableStream {\n        CopyableStream() {}\n        CopyableStream( CopyableStream const& other ) {\n            oss << other.oss.str();\n        }\n        CopyableStream& operator=( CopyableStream const& other ) {\n            oss.str(\"\");\n            oss << other.oss.str();\n            return *this;\n        }\n        std::ostringstream oss;\n    };\n\n    class ResultBuilder {\n    public:\n        ResultBuilder(  char const* macroName,\n                        SourceLineInfo const& lineInfo,\n                        char const* capturedExpression,\n                        ResultDisposition::Flags resultDisposition,\n                        char const* secondArg = \"\" );\n\n        template<typename T>\n        ExpressionLhs<T const&> operator <= ( T const& operand );\n        ExpressionLhs<bool> operator <= ( bool value );\n\n        template<typename T>\n        ResultBuilder& operator << ( T const& value ) {\n            m_stream.oss << value;\n            return *this;\n        }\n\n        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );\n        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );\n\n        ResultBuilder& setResultType( ResultWas::OfType result );\n        ResultBuilder& setResultType( bool result );\n        ResultBuilder& setLhs( std::string const& lhs );\n        ResultBuilder& setRhs( std::string const& rhs );\n        ResultBuilder& setOp( std::string const& op );\n\n        void endExpression();\n\n        std::string reconstructExpression() const;\n        AssertionResult build() const;\n\n        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );\n        void captureResult( ResultWas::OfType resultType );\n        void captureExpression();\n        void captureExpectedException( std::string const& expectedMessage );\n        void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );\n        void handleResult( AssertionResult const& result );\n        void react();\n        bool shouldDebugBreak() const;\n        bool allowThrows() const;\n\n    private:\n        AssertionInfo m_assertionInfo;\n        AssertionResultData m_data;\n        struct ExprComponents {\n            ExprComponents() : testFalse( false ) {}\n            bool testFalse;\n            std::string lhs, rhs, op;\n        } m_exprComponents;\n        CopyableStream m_stream;\n\n        bool m_shouldDebugBreak;\n        bool m_shouldThrow;\n    };\n\n} // namespace Catch\n\n// Include after due to circular dependency:\n// #included from: catch_expression_lhs.hpp\n#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED\n\n// #included from: catch_evaluate.hpp\n#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4389) // '==' : signed/unsigned mismatch\n#endif\n\n#include <cstddef>\n\nnamespace Catch {\nnamespace Internal {\n\n    enum Operator {\n        IsEqualTo,\n        IsNotEqualTo,\n        IsLessThan,\n        IsGreaterThan,\n        IsLessThanOrEqualTo,\n        IsGreaterThanOrEqualTo\n    };\n\n    template<Operator Op> struct OperatorTraits             { static const char* getName(){ return \"*error*\"; } };\n    template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return \"==\"; } };\n    template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return \"!=\"; } };\n    template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return \"<\"; } };\n    template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return \">\"; } };\n    template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return \"<=\"; } };\n    template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return \">=\"; } };\n\n    template<typename T>\n    inline T& opCast(T const& t) { return const_cast<T&>(t); }\n\n// nullptr_t support based on pull request #154 from Konstantin Baumann\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }\n#endif // CATCH_CONFIG_CPP11_NULLPTR\n\n    // So the compare overloads can be operator agnostic we convey the operator as a template\n    // enum, which is used to specialise an Evaluator for doing the comparison.\n    template<typename T1, typename T2, Operator Op>\n    class Evaluator{};\n\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs) {\n            return bool( opCast( lhs ) ==  opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsNotEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) != opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsLessThan> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) < opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsGreaterThan> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) > opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) >= opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsLessThanOrEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) <= opCast( rhs ) );\n        }\n    };\n\n    template<Operator Op, typename T1, typename T2>\n    bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {\n        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );\n    }\n\n    // This level of indirection allows us to specialise for integer types\n    // to avoid signed/ unsigned warnings\n\n    // \"base\" overload\n    template<Operator Op, typename T1, typename T2>\n    bool compare( T1 const& lhs, T2 const& rhs ) {\n        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );\n    }\n\n    // unsigned X to int\n    template<Operator Op> bool compare( unsigned int lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned long lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned char lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n\n    // unsigned X to long\n    template<Operator Op> bool compare( unsigned int lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned long lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned char lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n\n    // int to unsigned X\n    template<Operator Op> bool compare( int lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( int lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( int lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n\n    // long to unsigned X\n    template<Operator Op> bool compare( long lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n\n    // pointer to long (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n\n    // pointer to int (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\n    // long long to unsigned X\n    template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n\n    // unsigned long long to X\n    template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n\n    // pointer to long long (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n#endif // CATCH_CONFIG_CPP11_LONG_LONG\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n    // pointer to nullptr_t (when comparing against nullptr)\n    template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );\n    }\n#endif // CATCH_CONFIG_CPP11_NULLPTR\n\n} // end of namespace Internal\n} // end of namespace Catch\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// #included from: catch_tostring.h\n#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED\n\n#include <sstream>\n#include <iomanip>\n#include <limits>\n#include <vector>\n#include <cstddef>\n\n#ifdef __OBJC__\n// #included from: catch_objc_arc.hpp\n#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED\n\n#import <Foundation/Foundation.h>\n\n#ifdef __has_feature\n#define CATCH_ARC_ENABLED __has_feature(objc_arc)\n#else\n#define CATCH_ARC_ENABLED 0\n#endif\n\nvoid arcSafeRelease( NSObject* obj );\nid performOptionalSelector( id obj, SEL sel );\n\n#if !CATCH_ARC_ENABLED\ninline void arcSafeRelease( NSObject* obj ) {\n    [obj release];\n}\ninline id performOptionalSelector( id obj, SEL sel ) {\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED\n#define CATCH_ARC_STRONG\n#else\ninline void arcSafeRelease( NSObject* ){}\ninline id performOptionalSelector( id obj, SEL sel ) {\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#endif\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained\n#define CATCH_ARC_STRONG __strong\n#endif\n\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_TUPLE\n#include <tuple>\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_IS_ENUM\n#include <type_traits>\n#endif\n\nnamespace Catch {\n\n// Why we're here.\ntemplate<typename T>\nstd::string toString( T const& value );\n\n// Built in overloads\n\nstd::string toString( std::string const& value );\nstd::string toString( std::wstring const& value );\nstd::string toString( const char* const value );\nstd::string toString( char* const value );\nstd::string toString( const wchar_t* const value );\nstd::string toString( wchar_t* const value );\nstd::string toString( int value );\nstd::string toString( unsigned long value );\nstd::string toString( unsigned int value );\nstd::string toString( const double value );\nstd::string toString( const float value );\nstd::string toString( bool value );\nstd::string toString( char value );\nstd::string toString( signed char value );\nstd::string toString( unsigned char value );\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\nstd::string toString( long long value );\nstd::string toString( unsigned long long value );\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\nstd::string toString( std::nullptr_t );\n#endif\n\n#ifdef __OBJC__\n    std::string toString( NSString const * const& nsstring );\n    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );\n    std::string toString( NSObject* const& nsObject );\n#endif\n\nnamespace Detail {\n\n    extern const std::string unprintableString;\n\n    struct BorgType {\n        template<typename T> BorgType( T const& );\n    };\n\n    struct TrueType { char sizer[1]; };\n    struct FalseType { char sizer[2]; };\n\n    TrueType& testStreamable( std::ostream& );\n    FalseType testStreamable( FalseType );\n\n    FalseType operator<<( std::ostream const&, BorgType const& );\n\n    template<typename T>\n    struct IsStreamInsertable {\n        static std::ostream &s;\n        static T  const&t;\n        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };\n    };\n\n#if defined(CATCH_CONFIG_CPP11_IS_ENUM)\n    template<typename T,\n             bool IsEnum = std::is_enum<T>::value\n             >\n    struct EnumStringMaker\n    {\n        static std::string convert( T const& ) { return unprintableString; }\n    };\n\n    template<typename T>\n    struct EnumStringMaker<T,true>\n    {\n        static std::string convert( T const& v )\n        {\n            return ::Catch::toString(\n                static_cast<typename std::underlying_type<T>::type>(v)\n                );\n        }\n    };\n#endif\n    template<bool C>\n    struct StringMakerBase {\n#if defined(CATCH_CONFIG_CPP11_IS_ENUM)\n        template<typename T>\n        static std::string convert( T const& v )\n        {\n            return EnumStringMaker<T>::convert( v );\n        }\n#else\n        template<typename T>\n        static std::string convert( T const& ) { return unprintableString; }\n#endif\n    };\n\n    template<>\n    struct StringMakerBase<true> {\n        template<typename T>\n        static std::string convert( T const& _value ) {\n            std::ostringstream oss;\n            oss << _value;\n            return oss.str();\n        }\n    };\n\n    std::string rawMemoryToString( const void *object, std::size_t size );\n\n    template<typename T>\n    inline std::string rawMemoryToString( const T& object ) {\n      return rawMemoryToString( &object, sizeof(object) );\n    }\n\n} // end namespace Detail\n\ntemplate<typename T>\nstruct StringMaker :\n    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};\n\ntemplate<typename T>\nstruct StringMaker<T*> {\n    template<typename U>\n    static std::string convert( U* p ) {\n        if( !p )\n            return \"NULL\";\n        else\n            return Detail::rawMemoryToString( p );\n    }\n};\n\ntemplate<typename R, typename C>\nstruct StringMaker<R C::*> {\n    static std::string convert( R C::* p ) {\n        if( !p )\n            return \"NULL\";\n        else\n            return Detail::rawMemoryToString( p );\n    }\n};\n\nnamespace Detail {\n    template<typename InputIterator>\n    std::string rangeToString( InputIterator first, InputIterator last );\n}\n\n//template<typename T, typename Allocator>\n//struct StringMaker<std::vector<T, Allocator> > {\n//    static std::string convert( std::vector<T,Allocator> const& v ) {\n//        return Detail::rangeToString( v.begin(), v.end() );\n//    }\n//};\n\ntemplate<typename T, typename Allocator>\nstd::string toString( std::vector<T,Allocator> const& v ) {\n    return Detail::rangeToString( v.begin(), v.end() );\n}\n\n#ifdef CATCH_CONFIG_CPP11_TUPLE\n\n// toString for tuples\nnamespace TupleDetail {\n  template<\n      typename Tuple,\n      std::size_t N = 0,\n      bool = (N < std::tuple_size<Tuple>::value)\n      >\n  struct ElementPrinter {\n      static void print( const Tuple& tuple, std::ostream& os )\n      {\n          os << ( N ? \", \" : \" \" )\n             << Catch::toString(std::get<N>(tuple));\n          ElementPrinter<Tuple,N+1>::print(tuple,os);\n      }\n  };\n\n  template<\n      typename Tuple,\n      std::size_t N\n      >\n  struct ElementPrinter<Tuple,N,false> {\n      static void print( const Tuple&, std::ostream& ) {}\n  };\n\n}\n\ntemplate<typename ...Types>\nstruct StringMaker<std::tuple<Types...>> {\n\n    static std::string convert( const std::tuple<Types...>& tuple )\n    {\n        std::ostringstream os;\n        os << '{';\n        TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );\n        os << \" }\";\n        return os.str();\n    }\n};\n#endif // CATCH_CONFIG_CPP11_TUPLE\n\nnamespace Detail {\n    template<typename T>\n    std::string makeString( T const& value ) {\n        return StringMaker<T>::convert( value );\n    }\n} // end namespace Detail\n\n/// \\brief converts any type to a string\n///\n/// The default template forwards on to ostringstream - except when an\n/// ostringstream overload does not exist - in which case it attempts to detect\n/// that and writes {?}.\n/// Overload (not specialise) this template for custom typs that you don't want\n/// to provide an ostream overload for.\ntemplate<typename T>\nstd::string toString( T const& value ) {\n    return StringMaker<T>::convert( value );\n}\n\n    namespace Detail {\n    template<typename InputIterator>\n    std::string rangeToString( InputIterator first, InputIterator last ) {\n        std::ostringstream oss;\n        oss << \"{ \";\n        if( first != last ) {\n            oss << Catch::toString( *first );\n            for( ++first ; first != last ; ++first )\n                oss << \", \" << Catch::toString( *first );\n        }\n        oss << \" }\";\n        return oss.str();\n    }\n}\n\n} // end namespace Catch\n\nnamespace Catch {\n\n// Wraps the LHS of an expression and captures the operator and RHS (if any) -\n// wrapping them all in a ResultBuilder object\ntemplate<typename T>\nclass ExpressionLhs {\n    ExpressionLhs& operator = ( ExpressionLhs const& );\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n    ExpressionLhs& operator = ( ExpressionLhs && ) = delete;\n#  endif\n\npublic:\n    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n    ExpressionLhs( ExpressionLhs const& ) = default;\n    ExpressionLhs( ExpressionLhs && )     = default;\n#  endif\n\n    template<typename RhsT>\n    ResultBuilder& operator == ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator != ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsNotEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator < ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsLessThan>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator > ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsGreaterThan>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator <= ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator >= ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );\n    }\n\n    ResultBuilder& operator == ( bool rhs ) {\n        return captureExpression<Internal::IsEqualTo>( rhs );\n    }\n\n    ResultBuilder& operator != ( bool rhs ) {\n        return captureExpression<Internal::IsNotEqualTo>( rhs );\n    }\n\n    void endExpression() {\n        bool value = m_lhs ? true : false;\n        m_rb\n            .setLhs( Catch::toString( value ) )\n            .setResultType( value )\n            .endExpression();\n    }\n\n    // Only simple binary expressions are allowed on the LHS.\n    // If more complex compositions are required then place the sub expression in parentheses\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );\n\nprivate:\n    template<Internal::Operator Op, typename RhsT>\n    ResultBuilder& captureExpression( RhsT const& rhs ) {\n        return m_rb\n            .setResultType( Internal::compare<Op>( m_lhs, rhs ) )\n            .setLhs( Catch::toString( m_lhs ) )\n            .setRhs( Catch::toString( rhs ) )\n            .setOp( Internal::OperatorTraits<Op>::getName() );\n    }\n\nprivate:\n    ResultBuilder& m_rb;\n    T m_lhs;\n};\n\n} // end namespace Catch\n\n\nnamespace Catch {\n\n    template<typename T>\n    inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {\n        return ExpressionLhs<T const&>( *this, operand );\n    }\n\n    inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {\n        return ExpressionLhs<bool>( *this, value );\n    }\n\n} // namespace Catch\n\n// #included from: catch_message.h\n#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct MessageInfo {\n        MessageInfo(    std::string const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        ResultWas::OfType _type );\n\n        std::string macroName;\n        SourceLineInfo lineInfo;\n        ResultWas::OfType type;\n        std::string message;\n        unsigned int sequence;\n\n        bool operator == ( MessageInfo const& other ) const {\n            return sequence == other.sequence;\n        }\n        bool operator < ( MessageInfo const& other ) const {\n            return sequence < other.sequence;\n        }\n    private:\n        static unsigned int globalCount;\n    };\n\n    struct MessageBuilder {\n        MessageBuilder( std::string const& macroName,\n                        SourceLineInfo const& lineInfo,\n                        ResultWas::OfType type )\n        : m_info( macroName, lineInfo, type )\n        {}\n\n        template<typename T>\n        MessageBuilder& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        MessageInfo m_info;\n        std::ostringstream m_stream;\n    };\n\n    class ScopedMessage {\n    public:\n        ScopedMessage( MessageBuilder const& builder );\n        ScopedMessage( ScopedMessage const& other );\n        ~ScopedMessage();\n\n        MessageInfo m_info;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_interfaces_capture.h\n#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    class TestCase;\n    class AssertionResult;\n    struct AssertionInfo;\n    struct SectionInfo;\n    struct SectionEndInfo;\n    struct MessageInfo;\n    class ScopedMessageBuilder;\n    struct Counts;\n\n    struct IResultCapture {\n\n        virtual ~IResultCapture();\n\n        virtual void assertionEnded( AssertionResult const& result ) = 0;\n        virtual bool sectionStarted(    SectionInfo const& sectionInfo,\n                                        Counts& assertions ) = 0;\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;\n        virtual void pushScopedMessage( MessageInfo const& message ) = 0;\n        virtual void popScopedMessage( MessageInfo const& message ) = 0;\n\n        virtual std::string getCurrentTestName() const = 0;\n        virtual const AssertionResult* getLastResult() const = 0;\n\n        virtual void handleFatalErrorCondition( std::string const& message ) = 0;\n    };\n\n    IResultCapture& getResultCapture();\n}\n\n// #included from: catch_debugger.h\n#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED\n\n// #included from: catch_platform.h\n#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED\n\n#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)\n#  define CATCH_PLATFORM_MAC\n#elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)\n#  define CATCH_PLATFORM_IPHONE\n#elif defined(linux) || defined(__linux) || defined(__linux__)\n#  define CATCH_PLATFORM_LINUX\n#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)\n#  define CATCH_PLATFORM_WINDOWS\n#  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)\n#    define CATCH_DEFINES_NOMINMAX\n#  endif\n#  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)\n#    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  endif\n#endif\n\n#include <string>\n\nnamespace Catch{\n\n    bool isDebuggerActive();\n    void writeToDebugConsole( std::string const& text );\n}\n\n#ifdef CATCH_PLATFORM_MAC\n\n    // The following code snippet based on:\n    // http://cocoawithlove.com/2008/03/break-into-debugger.html\n    #ifdef DEBUG\n        #if defined(__ppc64__) || defined(__ppc__)\n            #define CATCH_TRAP() \\\n                    __asm__(\"li r0, 20\\nsc\\nnop\\nli r0, 37\\nli r4, 2\\nsc\\nnop\\n\" \\\n                    : : : \"memory\",\"r0\",\"r3\",\"r4\" )\n        #else\n            #define CATCH_TRAP() _asm__(\"int $3\\n\" : : )\n        #endif\n    #endif\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    // If we can use inline assembler, do it because this allows us to break\n    // directly at the location of the failing check instead of breaking inside\n    // raise() called from it, i.e. one stack frame below.\n    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n        #define CATCH_TRAP() asm volatile (\"int $3\")\n    #else // Fall back to the generic way.\n        #include <signal.h>\n\n        #define CATCH_TRAP() raise(SIGTRAP)\n    #endif\n#elif defined(_MSC_VER)\n    #define CATCH_TRAP() __debugbreak()\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\n    #define CATCH_TRAP() DebugBreak()\n#endif\n\n#ifdef CATCH_TRAP\n    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }\n#else\n    #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();\n#endif\n\n// #included from: catch_interfaces_runner.h\n#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED\n\nnamespace Catch {\n    class TestCase;\n\n    struct IRunner {\n        virtual ~IRunner();\n        virtual bool aborting() const = 0;\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// In the event of a failure works out if the debugger needs to be invoked\n// and/or an exception thrown and takes appropriate action.\n// This needs to be done as a macro so the debugger will stop in the user\n// source code rather than in Catch library code\n#define INTERNAL_CATCH_REACT( resultBuilder ) \\\n    if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \\\n    resultBuilder.react();\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        try { \\\n            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n            ( __catchResult <= expr ).endExpression(); \\\n        } \\\n        catch( ... ) { \\\n            __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \\\n    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \\\n    if( Catch::getResultCapture().getLastResult()->succeeded() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \\\n    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \\\n    if( !Catch::getResultCapture().getLastResult()->succeeded() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        try { \\\n            expr; \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        } \\\n        catch( ... ) { \\\n            __catchResult.useActiveException( resultDisposition ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \\\n        if( __catchResult.allowThrows() ) \\\n            try { \\\n                expr; \\\n                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \\\n            } \\\n            catch( ... ) { \\\n                __catchResult.captureExpectedException( matcher ); \\\n            } \\\n        else \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        if( __catchResult.allowThrows() ) \\\n            try { \\\n                expr; \\\n                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \\\n            } \\\n            catch( exceptionType ) { \\\n                __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n            } \\\n            catch( ... ) { \\\n                __catchResult.useActiveException( resultDisposition ); \\\n            } \\\n        else \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \\\n        do { \\\n            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, \"\", resultDisposition ); \\\n            __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \\\n            __catchResult.captureResult( messageType ); \\\n            INTERNAL_CATCH_REACT( __catchResult ) \\\n        } while( Catch::alwaysFalse() )\n#else\n    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \\\n        do { \\\n            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, \"\", resultDisposition ); \\\n            __catchResult << log + ::Catch::StreamEndStop(); \\\n            __catchResult.captureResult( messageType ); \\\n            INTERNAL_CATCH_REACT( __catchResult ) \\\n        } while( Catch::alwaysFalse() )\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_INFO( log, macroName ) \\\n    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg \", \" #matcher, resultDisposition ); \\\n        try { \\\n            std::string matcherAsString = (matcher).toString(); \\\n            __catchResult \\\n                .setLhs( Catch::toString( arg ) ) \\\n                .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \\\n                .setOp( \"matches\" ) \\\n                .setResultType( (matcher).match( arg ) ); \\\n            __catchResult.captureExpression(); \\\n        } catch( ... ) { \\\n            __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n// #included from: internal/catch_section.h\n#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED\n\n// #included from: catch_section_info.h\n#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED\n\n// #included from: catch_totals.hpp\n#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED\n\n#include <cstddef>\n\nnamespace Catch {\n\n    struct Counts {\n        Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}\n\n        Counts operator - ( Counts const& other ) const {\n            Counts diff;\n            diff.passed = passed - other.passed;\n            diff.failed = failed - other.failed;\n            diff.failedButOk = failedButOk - other.failedButOk;\n            return diff;\n        }\n        Counts& operator += ( Counts const& other ) {\n            passed += other.passed;\n            failed += other.failed;\n            failedButOk += other.failedButOk;\n            return *this;\n        }\n\n        std::size_t total() const {\n            return passed + failed + failedButOk;\n        }\n        bool allPassed() const {\n            return failed == 0 && failedButOk == 0;\n        }\n        bool allOk() const {\n            return failed == 0;\n        }\n\n        std::size_t passed;\n        std::size_t failed;\n        std::size_t failedButOk;\n    };\n\n    struct Totals {\n\n        Totals operator - ( Totals const& other ) const {\n            Totals diff;\n            diff.assertions = assertions - other.assertions;\n            diff.testCases = testCases - other.testCases;\n            return diff;\n        }\n\n        Totals delta( Totals const& prevTotals ) const {\n            Totals diff = *this - prevTotals;\n            if( diff.assertions.failed > 0 )\n                ++diff.testCases.failed;\n            else if( diff.assertions.failedButOk > 0 )\n                ++diff.testCases.failedButOk;\n            else\n                ++diff.testCases.passed;\n            return diff;\n        }\n\n        Totals& operator += ( Totals const& other ) {\n            assertions += other.assertions;\n            testCases += other.testCases;\n            return *this;\n        }\n\n        Counts assertions;\n        Counts testCases;\n    };\n}\n\nnamespace Catch {\n\n    struct SectionInfo {\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name,\n                std::string const& _description = std::string() );\n\n        std::string name;\n        std::string description;\n        SourceLineInfo lineInfo;\n    };\n\n    struct SectionEndInfo {\n        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )\n        : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )\n        {}\n\n        SectionInfo sectionInfo;\n        Counts prevAssertions;\n        double durationInSeconds;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_timer.h\n#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED\n\n#ifdef CATCH_PLATFORM_WINDOWS\ntypedef unsigned long long uint64_t;\n#else\n#include <stdint.h>\n#endif\n\nnamespace Catch {\n\n    class Timer {\n    public:\n        Timer() : m_ticks( 0 ) {}\n        void start();\n        unsigned int getElapsedMicroseconds() const;\n        unsigned int getElapsedMilliseconds() const;\n        double getElapsedSeconds() const;\n\n    private:\n        uint64_t m_ticks;\n    };\n\n} // namespace Catch\n\n#include <string>\n\nnamespace Catch {\n\n    class Section : NonCopyable {\n    public:\n        Section( SectionInfo const& info );\n        ~Section();\n\n        // This indicates whether the section should be executed or not\n        operator bool() const;\n\n    private:\n        SectionInfo m_info;\n\n        std::string m_name;\n        Counts m_assertions;\n        bool m_sectionIncluded;\n        Timer m_timer;\n    };\n\n} // end namespace Catch\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define INTERNAL_CATCH_SECTION( ... ) \\\n        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )\n#else\n    #define INTERNAL_CATCH_SECTION( name, desc ) \\\n        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )\n#endif\n\n// #included from: internal/catch_generators.hpp\n#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED\n\n#include <iterator>\n#include <vector>\n#include <string>\n#include <stdlib.h>\n\nnamespace Catch {\n\ntemplate<typename T>\nstruct IGenerator {\n    virtual ~IGenerator() {}\n    virtual T getValue( std::size_t index ) const = 0;\n    virtual std::size_t size () const = 0;\n};\n\ntemplate<typename T>\nclass BetweenGenerator : public IGenerator<T> {\npublic:\n    BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}\n\n    virtual T getValue( std::size_t index ) const {\n        return m_from+static_cast<int>( index );\n    }\n\n    virtual std::size_t size() const {\n        return static_cast<std::size_t>( 1+m_to-m_from );\n    }\n\nprivate:\n\n    T m_from;\n    T m_to;\n};\n\ntemplate<typename T>\nclass ValuesGenerator : public IGenerator<T> {\npublic:\n    ValuesGenerator(){}\n\n    void add( T value ) {\n        m_values.push_back( value );\n    }\n\n    virtual T getValue( std::size_t index ) const {\n        return m_values[index];\n    }\n\n    virtual std::size_t size() const {\n        return m_values.size();\n    }\n\nprivate:\n    std::vector<T> m_values;\n};\n\ntemplate<typename T>\nclass CompositeGenerator {\npublic:\n    CompositeGenerator() : m_totalSize( 0 ) {}\n\n    // *** Move semantics, similar to auto_ptr ***\n    CompositeGenerator( CompositeGenerator& other )\n    :   m_fileInfo( other.m_fileInfo ),\n        m_totalSize( 0 )\n    {\n        move( other );\n    }\n\n    CompositeGenerator& setFileInfo( const char* fileInfo ) {\n        m_fileInfo = fileInfo;\n        return *this;\n    }\n\n    ~CompositeGenerator() {\n        deleteAll( m_composed );\n    }\n\n    operator T () const {\n        size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );\n\n        typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();\n        typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();\n        for( size_t index = 0; it != itEnd; ++it )\n        {\n            const IGenerator<T>* generator = *it;\n            if( overallIndex >= index && overallIndex < index + generator->size() )\n            {\n                return generator->getValue( overallIndex-index );\n            }\n            index += generator->size();\n        }\n        CATCH_INTERNAL_ERROR( \"Indexed past end of generated range\" );\n        return T(); // Suppress spurious \"not all control paths return a value\" warning in Visual Studio - if you know how to fix this please do so\n    }\n\n    void add( const IGenerator<T>* generator ) {\n        m_totalSize += generator->size();\n        m_composed.push_back( generator );\n    }\n\n    CompositeGenerator& then( CompositeGenerator& other ) {\n        move( other );\n        return *this;\n    }\n\n    CompositeGenerator& then( T value ) {\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( value );\n        add( valuesGen );\n        return *this;\n    }\n\nprivate:\n\n    void move( CompositeGenerator& other ) {\n        std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );\n        m_totalSize += other.m_totalSize;\n        other.m_composed.clear();\n    }\n\n    std::vector<const IGenerator<T>*> m_composed;\n    std::string m_fileInfo;\n    size_t m_totalSize;\n};\n\nnamespace Generators\n{\n    template<typename T>\n    CompositeGenerator<T> between( T from, T to ) {\n        CompositeGenerator<T> generators;\n        generators.add( new BetweenGenerator<T>( from, to ) );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2 ) {\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2, T val3 ){\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        valuesGen->add( val3 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        valuesGen->add( val3 );\n        valuesGen->add( val4 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n} // end namespace Generators\n\nusing namespace Generators;\n\n} // end namespace Catch\n\n#define INTERNAL_CATCH_LINESTR2( line ) #line\n#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )\n\n#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ \"(\" INTERNAL_CATCH_LINESTR( __LINE__ ) \")\" )\n\n// #included from: internal/catch_interfaces_exception.h\n#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED\n\n#include <string>\n#include <vector>\n\n// #included from: catch_interfaces_registry_hub.h\n#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    class TestCase;\n    struct ITestCaseRegistry;\n    struct IExceptionTranslatorRegistry;\n    struct IExceptionTranslator;\n    struct IReporterRegistry;\n    struct IReporterFactory;\n\n    struct IRegistryHub {\n        virtual ~IRegistryHub();\n\n        virtual IReporterRegistry const& getReporterRegistry() const = 0;\n        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;\n        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;\n    };\n\n    struct IMutableRegistryHub {\n        virtual ~IMutableRegistryHub();\n        virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;\n        virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;\n        virtual void registerTest( TestCase const& testInfo ) = 0;\n        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;\n    };\n\n    IRegistryHub& getRegistryHub();\n    IMutableRegistryHub& getMutableRegistryHub();\n    void cleanUp();\n    std::string translateActiveException();\n\n}\n\nnamespace Catch {\n\n    typedef std::string(*exceptionTranslateFunction)();\n\n    struct IExceptionTranslator;\n    typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;\n\n    struct IExceptionTranslator {\n        virtual ~IExceptionTranslator();\n        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;\n    };\n\n    struct IExceptionTranslatorRegistry {\n        virtual ~IExceptionTranslatorRegistry();\n\n        virtual std::string translateActiveException() const = 0;\n    };\n\n    class ExceptionTranslatorRegistrar {\n        template<typename T>\n        class ExceptionTranslator : public IExceptionTranslator {\n        public:\n\n            ExceptionTranslator( std::string(*translateFunction)( T& ) )\n            : m_translateFunction( translateFunction )\n            {}\n\n            virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {\n                try {\n                    if( it == itEnd )\n                        throw;\n                    else\n                        return (*it)->translate( it+1, itEnd );\n                }\n                catch( T& ex ) {\n                    return m_translateFunction( ex );\n                }\n            }\n\n        protected:\n            std::string(*m_translateFunction)( T& );\n        };\n\n    public:\n        template<typename T>\n        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {\n            getMutableRegistryHub().registerTranslator\n                ( new ExceptionTranslator<T>( translateFunction ) );\n        }\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \\\n    static std::string translatorName( signature ); \\\n    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\\\n    static std::string translatorName( signature )\n\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// #included from: internal/catch_approx.hpp\n#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED\n\n#include <cmath>\n#include <limits>\n\nnamespace Catch {\nnamespace Detail {\n\n    class Approx {\n    public:\n        explicit Approx ( double value )\n        :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),\n            m_scale( 1.0 ),\n            m_value( value )\n        {}\n\n        Approx( Approx const& other )\n        :   m_epsilon( other.m_epsilon ),\n            m_scale( other.m_scale ),\n            m_value( other.m_value )\n        {}\n\n        static Approx custom() {\n            return Approx( 0 );\n        }\n\n        Approx operator()( double value ) {\n            Approx approx( value );\n            approx.epsilon( m_epsilon );\n            approx.scale( m_scale );\n            return approx;\n        }\n\n        friend bool operator == ( double lhs, Approx const& rhs ) {\n            // Thanks to Richard Harris for his help refining this formula\n            return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );\n        }\n\n        friend bool operator == ( Approx const& lhs, double rhs ) {\n            return operator==( rhs, lhs );\n        }\n\n        friend bool operator != ( double lhs, Approx const& rhs ) {\n            return !operator==( lhs, rhs );\n        }\n\n        friend bool operator != ( Approx const& lhs, double rhs ) {\n            return !operator==( rhs, lhs );\n        }\n\n        friend bool operator <= ( double lhs, Approx const& rhs )\n        {\n          return lhs < rhs.m_value || lhs == rhs;\n        }\n\n        friend bool operator <= ( Approx const& lhs, double rhs )\n        {\n          return lhs.m_value < rhs || lhs == rhs;\n        }\n\n        friend bool operator >= ( double lhs, Approx const& rhs )\n        {\n          return lhs > rhs.m_value || lhs == rhs;\n        }\n\n        friend bool operator >= ( Approx const& lhs, double rhs )\n        {\n          return lhs.m_value > rhs || lhs == rhs;\n        }\n\n        Approx& epsilon( double newEpsilon ) {\n            m_epsilon = newEpsilon;\n            return *this;\n        }\n\n        Approx& scale( double newScale ) {\n            m_scale = newScale;\n            return *this;\n        }\n\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << \"Approx( \" << Catch::toString( m_value ) << \" )\";\n            return oss.str();\n        }\n\n    private:\n        double m_epsilon;\n        double m_scale;\n        double m_value;\n    };\n}\n\ntemplate<>\ninline std::string toString<Detail::Approx>( Detail::Approx const& value ) {\n    return value.toString();\n}\n\n} // end namespace Catch\n\n// #included from: internal/catch_interfaces_tag_alias_registry.h\n#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED\n\n// #included from: catch_tag_alias.h\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias {\n        TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}\n\n        std::string tag;\n        SourceLineInfo lineInfo;\n    };\n\n    struct RegistrarForTagAliases {\n        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n    };\n\n} // end namespace Catch\n\n#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }\n// #included from: catch_option.hpp\n#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED\n\nnamespace Catch {\n\n    // An optional type\n    template<typename T>\n    class Option {\n    public:\n        Option() : nullableValue( CATCH_NULL ) {}\n        Option( T const& _value )\n        : nullableValue( new( storage ) T( _value ) )\n        {}\n        Option( Option const& _other )\n        : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )\n        {}\n\n        ~Option() {\n            reset();\n        }\n\n        Option& operator= ( Option const& _other ) {\n            if( &_other != this ) {\n                reset();\n                if( _other )\n                    nullableValue = new( storage ) T( *_other );\n            }\n            return *this;\n        }\n        Option& operator = ( T const& _value ) {\n            reset();\n            nullableValue = new( storage ) T( _value );\n            return *this;\n        }\n\n        void reset() {\n            if( nullableValue )\n                nullableValue->~T();\n            nullableValue = CATCH_NULL;\n        }\n\n        T& operator*() { return *nullableValue; }\n        T const& operator*() const { return *nullableValue; }\n        T* operator->() { return nullableValue; }\n        const T* operator->() const { return nullableValue; }\n\n        T valueOr( T const& defaultValue ) const {\n            return nullableValue ? *nullableValue : defaultValue;\n        }\n\n        bool some() const { return nullableValue != CATCH_NULL; }\n        bool none() const { return nullableValue == CATCH_NULL; }\n\n        bool operator !() const { return nullableValue == CATCH_NULL; }\n        operator SafeBool::type() const {\n            return SafeBool::makeSafe( some() );\n        }\n\n    private:\n        T* nullableValue;\n        char storage[sizeof(T)];\n    };\n\n} // end namespace Catch\n\nnamespace Catch {\n\n    struct ITagAliasRegistry {\n        virtual ~ITagAliasRegistry();\n        virtual Option<TagAlias> find( std::string const& alias ) const = 0;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;\n\n        static ITagAliasRegistry const& get();\n    };\n\n} // end namespace Catch\n\n// These files are included here so the single_include script doesn't put them\n// in the conditionally compiled sections\n// #included from: internal/catch_test_case_info.h\n#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED\n\n#include <string>\n#include <set>\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    struct ITestCase;\n\n    struct TestCaseInfo {\n        enum SpecialProperties{\n            None = 0,\n            IsHidden = 1 << 1,\n            ShouldFail = 1 << 2,\n            MayFail = 1 << 3,\n            Throws = 1 << 4\n        };\n\n        TestCaseInfo(   std::string const& _name,\n                        std::string const& _className,\n                        std::string const& _description,\n                        std::set<std::string> const& _tags,\n                        SourceLineInfo const& _lineInfo );\n\n        TestCaseInfo( TestCaseInfo const& other );\n\n        friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );\n\n        bool isHidden() const;\n        bool throws() const;\n        bool okToFail() const;\n        bool expectedToFail() const;\n\n        std::string name;\n        std::string className;\n        std::string description;\n        std::set<std::string> tags;\n        std::set<std::string> lcaseTags;\n        std::string tagsAsString;\n        SourceLineInfo lineInfo;\n        SpecialProperties properties;\n    };\n\n    class TestCase : public TestCaseInfo {\n    public:\n\n        TestCase( ITestCase* testCase, TestCaseInfo const& info );\n        TestCase( TestCase const& other );\n\n        TestCase withName( std::string const& _newName ) const;\n\n        void invoke() const;\n\n        TestCaseInfo const& getTestCaseInfo() const;\n\n        void swap( TestCase& other );\n        bool operator == ( TestCase const& other ) const;\n        bool operator < ( TestCase const& other ) const;\n        TestCase& operator = ( TestCase const& other );\n\n    private:\n        Ptr<ITestCase> test;\n    };\n\n    TestCase makeTestCase(  ITestCase* testCase,\n                            std::string const& className,\n                            std::string const& name,\n                            std::string const& description,\n                            SourceLineInfo const& lineInfo );\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n\n#ifdef __OBJC__\n// #included from: internal/catch_objc.hpp\n#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED\n\n#import <objc/runtime.h>\n\n#include <string>\n\n// NB. Any general catch headers included here must be included\n// in catch.hpp first to make sure they are included by the single\n// header for non obj-usage\n\n///////////////////////////////////////////////////////////////////////////////\n// This protocol is really only here for (self) documenting purposes, since\n// all its methods are optional.\n@protocol OcFixture\n\n@optional\n\n-(void) setUp;\n-(void) tearDown;\n\n@end\n\nnamespace Catch {\n\n    class OcMethod : public SharedImpl<ITestCase> {\n\n    public:\n        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}\n\n        virtual void invoke() const {\n            id obj = [[m_cls alloc] init];\n\n            performOptionalSelector( obj, @selector(setUp)  );\n            performOptionalSelector( obj, m_sel );\n            performOptionalSelector( obj, @selector(tearDown)  );\n\n            arcSafeRelease( obj );\n        }\n    private:\n        virtual ~OcMethod() {}\n\n        Class m_cls;\n        SEL m_sel;\n    };\n\n    namespace Detail{\n\n        inline std::string getAnnotation(   Class cls,\n                                            std::string const& annotationName,\n                                            std::string const& testCaseName ) {\n            NSString* selStr = [[NSString alloc] initWithFormat:@\"Catch_%s_%s\", annotationName.c_str(), testCaseName.c_str()];\n            SEL sel = NSSelectorFromString( selStr );\n            arcSafeRelease( selStr );\n            id value = performOptionalSelector( cls, sel );\n            if( value )\n                return [(NSString*)value UTF8String];\n            return \"\";\n        }\n    }\n\n    inline size_t registerTestMethods() {\n        size_t noTestMethods = 0;\n        int noClasses = objc_getClassList( CATCH_NULL, 0 );\n\n        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);\n        objc_getClassList( classes, noClasses );\n\n        for( int c = 0; c < noClasses; c++ ) {\n            Class cls = classes[c];\n            {\n                u_int count;\n                Method* methods = class_copyMethodList( cls, &count );\n                for( u_int m = 0; m < count ; m++ ) {\n                    SEL selector = method_getName(methods[m]);\n                    std::string methodName = sel_getName(selector);\n                    if( startsWith( methodName, \"Catch_TestCase_\" ) ) {\n                        std::string testCaseName = methodName.substr( 15 );\n                        std::string name = Detail::getAnnotation( cls, \"Name\", testCaseName );\n                        std::string desc = Detail::getAnnotation( cls, \"Description\", testCaseName );\n                        const char* className = class_getName( cls );\n\n                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );\n                        noTestMethods++;\n                    }\n                }\n                free(methods);\n            }\n        }\n        return noTestMethods;\n    }\n\n    namespace Matchers {\n        namespace Impl {\n        namespace NSStringMatchers {\n\n            template<typename MatcherT>\n            struct StringHolder : MatcherImpl<MatcherT, NSString*>{\n                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}\n                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}\n                StringHolder() {\n                    arcSafeRelease( m_substr );\n                }\n\n                NSString* m_substr;\n            };\n\n            struct Equals : StringHolder<Equals> {\n                Equals( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str isEqualToString:m_substr];\n                }\n\n                virtual std::string toString() const {\n                    return \"equals string: \" + Catch::toString( m_substr );\n                }\n            };\n\n            struct Contains : StringHolder<Contains> {\n                Contains( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location != NSNotFound;\n                }\n\n                virtual std::string toString() const {\n                    return \"contains string: \" + Catch::toString( m_substr );\n                }\n            };\n\n            struct StartsWith : StringHolder<StartsWith> {\n                StartsWith( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == 0;\n                }\n\n                virtual std::string toString() const {\n                    return \"starts with: \" + Catch::toString( m_substr );\n                }\n            };\n            struct EndsWith : StringHolder<EndsWith> {\n                EndsWith( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];\n                }\n\n                virtual std::string toString() const {\n                    return \"ends with: \" + Catch::toString( m_substr );\n                }\n            };\n\n        } // namespace NSStringMatchers\n        } // namespace Impl\n\n        inline Impl::NSStringMatchers::Equals\n            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }\n\n        inline Impl::NSStringMatchers::Contains\n            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }\n\n        inline Impl::NSStringMatchers::StartsWith\n            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }\n\n        inline Impl::NSStringMatchers::EndsWith\n            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }\n\n    } // namespace Matchers\n\n    using namespace Matchers;\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define OC_TEST_CASE( name, desc )\\\n+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \\\n{\\\nreturn @ name; \\\n}\\\n+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \\\n{ \\\nreturn @ desc; \\\n} \\\n-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )\n\n#endif\n\n#ifdef CATCH_IMPL\n// #included from: internal/catch_impl.hpp\n#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED\n\n// Collect all the implementation files together here\n// These are the equivalent of what would usually be cpp files\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#endif\n\n// #included from: ../catch_session.hpp\n#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED\n\n// #included from: internal/catch_commandline.hpp\n#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED\n\n// #included from: catch_config.hpp\n#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED\n\n// #included from: catch_test_spec_parser.hpp\n#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// #included from: catch_test_spec.hpp\n#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// #included from: catch_wildcard_pattern.hpp\n#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED\n\nnamespace Catch\n{\n    class WildcardPattern {\n        enum WildcardPosition {\n            NoWildcard = 0,\n            WildcardAtStart = 1,\n            WildcardAtEnd = 2,\n            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd\n        };\n\n    public:\n\n        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )\n        :   m_caseSensitivity( caseSensitivity ),\n            m_wildcard( NoWildcard ),\n            m_pattern( adjustCase( pattern ) )\n        {\n            if( startsWith( m_pattern, \"*\" ) ) {\n                m_pattern = m_pattern.substr( 1 );\n                m_wildcard = WildcardAtStart;\n            }\n            if( endsWith( m_pattern, \"*\" ) ) {\n                m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );\n                m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );\n            }\n        }\n        virtual ~WildcardPattern();\n        virtual bool matches( std::string const& str ) const {\n            switch( m_wildcard ) {\n                case NoWildcard:\n                    return m_pattern == adjustCase( str );\n                case WildcardAtStart:\n                    return endsWith( adjustCase( str ), m_pattern );\n                case WildcardAtEnd:\n                    return startsWith( adjustCase( str ), m_pattern );\n                case WildcardAtBothEnds:\n                    return contains( adjustCase( str ), m_pattern );\n            }\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunreachable-code\"\n#endif\n            throw std::logic_error( \"Unknown enum\" );\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n        }\n    private:\n        std::string adjustCase( std::string const& str ) const {\n            return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;\n        }\n        CaseSensitive::Choice m_caseSensitivity;\n        WildcardPosition m_wildcard;\n        std::string m_pattern;\n    };\n}\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec {\n        struct Pattern : SharedImpl<> {\n            virtual ~Pattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const = 0;\n        };\n        class NamePattern : public Pattern {\n        public:\n            NamePattern( std::string const& name )\n            : m_wildcardPattern( toLower( name ), CaseSensitive::No )\n            {}\n            virtual ~NamePattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const {\n                return m_wildcardPattern.matches( toLower( testCase.name ) );\n            }\n        private:\n            WildcardPattern m_wildcardPattern;\n        };\n\n        class TagPattern : public Pattern {\n        public:\n            TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}\n            virtual ~TagPattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const {\n                return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();\n            }\n        private:\n            std::string m_tag;\n        };\n\n        class ExcludedPattern : public Pattern {\n        public:\n            ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}\n            virtual ~ExcludedPattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }\n        private:\n            Ptr<Pattern> m_underlyingPattern;\n        };\n\n        struct Filter {\n            std::vector<Ptr<Pattern> > m_patterns;\n\n            bool matches( TestCaseInfo const& testCase ) const {\n                // All patterns in a filter must match for the filter to be a match\n                for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {\n                    if( !(*it)->matches( testCase ) )\n                        return false;\n                }\n                return true;\n            }\n        };\n\n    public:\n        bool hasFilters() const {\n            return !m_filters.empty();\n        }\n        bool matches( TestCaseInfo const& testCase ) const {\n            // A TestSpec matches if any filter matches\n            for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )\n                if( it->matches( testCase ) )\n                    return true;\n            return false;\n        }\n\n    private:\n        std::vector<Filter> m_filters;\n\n        friend class TestSpecParser;\n    };\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\nnamespace Catch {\n\n    class TestSpecParser {\n        enum Mode{ None, Name, QuotedName, Tag, EscapedName };\n        Mode m_mode;\n        bool m_exclusion;\n        std::size_t m_start, m_pos;\n        std::string m_arg;\n        std::vector<std::size_t> m_escapeChars;\n        TestSpec::Filter m_currentFilter;\n        TestSpec m_testSpec;\n        ITagAliasRegistry const* m_tagAliases;\n\n    public:\n        TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}\n\n        TestSpecParser& parse( std::string const& arg ) {\n            m_mode = None;\n            m_exclusion = false;\n            m_start = std::string::npos;\n            m_arg = m_tagAliases->expandAliases( arg );\n            m_escapeChars.clear();\n            for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )\n                visitChar( m_arg[m_pos] );\n            if( m_mode == Name )\n                addPattern<TestSpec::NamePattern>();\n            return *this;\n        }\n        TestSpec testSpec() {\n            addFilter();\n            return m_testSpec;\n        }\n    private:\n        void visitChar( char c ) {\n            if( m_mode == None ) {\n                switch( c ) {\n                case ' ': return;\n                case '~': m_exclusion = true; return;\n                case '[': return startNewMode( Tag, ++m_pos );\n                case '\"': return startNewMode( QuotedName, ++m_pos );\n                case '\\\\': return escape();\n                default: startNewMode( Name, m_pos ); break;\n                }\n            }\n            if( m_mode == Name ) {\n                if( c == ',' ) {\n                    addPattern<TestSpec::NamePattern>();\n                    addFilter();\n                }\n                else if( c == '[' ) {\n                    if( subString() == \"exclude:\" )\n                        m_exclusion = true;\n                    else\n                        addPattern<TestSpec::NamePattern>();\n                    startNewMode( Tag, ++m_pos );\n                }\n                else if( c == '\\\\' )\n                    escape();\n            }\n            else if( m_mode == EscapedName )\n                m_mode = Name;\n            else if( m_mode == QuotedName && c == '\"' )\n                addPattern<TestSpec::NamePattern>();\n            else if( m_mode == Tag && c == ']' )\n                addPattern<TestSpec::TagPattern>();\n        }\n        void startNewMode( Mode mode, std::size_t start ) {\n            m_mode = mode;\n            m_start = start;\n        }\n        void escape() {\n            m_mode = EscapedName;\n            m_escapeChars.push_back( m_pos );\n        }\n        std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }\n        template<typename T>\n        void addPattern() {\n            std::string token = subString();\n            for( size_t i = 0; i < m_escapeChars.size(); ++i )\n                token = token.substr( 0, m_escapeChars[i] ) + token.substr( m_escapeChars[i]+1 );\n            m_escapeChars.clear();\n            if( startsWith( token, \"exclude:\" ) ) {\n                m_exclusion = true;\n                token = token.substr( 8 );\n            }\n            if( !token.empty() ) {\n                Ptr<TestSpec::Pattern> pattern = new T( token );\n                if( m_exclusion )\n                    pattern = new TestSpec::ExcludedPattern( pattern );\n                m_currentFilter.m_patterns.push_back( pattern );\n            }\n            m_exclusion = false;\n            m_mode = None;\n        }\n        void addFilter() {\n            if( !m_currentFilter.m_patterns.empty() ) {\n                m_testSpec.m_filters.push_back( m_currentFilter );\n                m_currentFilter = TestSpec::Filter();\n            }\n        }\n    };\n    inline TestSpec parseTestSpec( std::string const& arg ) {\n        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();\n    }\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// #included from: catch_interfaces_config.h\n#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED\n\n#include <iostream>\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    struct Verbosity { enum Level {\n        NoOutput = 0,\n        Quiet,\n        Normal\n    }; };\n\n    struct WarnAbout { enum What {\n        Nothing = 0x00,\n        NoAssertions = 0x01\n    }; };\n\n    struct ShowDurations { enum OrNot {\n        DefaultForReporter,\n        Always,\n        Never\n    }; };\n    struct RunTests { enum InWhatOrder {\n        InDeclarationOrder,\n        InLexicographicalOrder,\n        InRandomOrder\n    }; };\n    struct UseColour { enum YesOrNo {\n        Auto,\n        Yes,\n        No\n    }; };\n\n    class TestSpec;\n\n    struct IConfig : IShared {\n\n        virtual ~IConfig();\n\n        virtual bool allowThrows() const = 0;\n        virtual std::ostream& stream() const = 0;\n        virtual std::string name() const = 0;\n        virtual bool includeSuccessfulResults() const = 0;\n        virtual bool shouldDebugBreak() const = 0;\n        virtual bool warnAboutMissingAssertions() const = 0;\n        virtual int abortAfter() const = 0;\n        virtual bool showInvisibles() const = 0;\n        virtual ShowDurations::OrNot showDurations() const = 0;\n        virtual TestSpec const& testSpec() const = 0;\n        virtual RunTests::InWhatOrder runOrder() const = 0;\n        virtual unsigned int rngSeed() const = 0;\n        virtual UseColour::YesOrNo useColour() const = 0;\n    };\n}\n\n// #included from: catch_stream.h\n#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED\n\n// #included from: catch_streambuf.h\n#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED\n\n#include <streambuf>\n\nnamespace Catch {\n\n    class StreamBufBase : public std::streambuf {\n    public:\n        virtual ~StreamBufBase() CATCH_NOEXCEPT;\n    };\n}\n\n#include <streambuf>\n#include <ostream>\n#include <fstream>\n#include <memory>\n\nnamespace Catch {\n\n    std::ostream& cout();\n    std::ostream& cerr();\n\n    struct IStream {\n        virtual ~IStream() CATCH_NOEXCEPT;\n        virtual std::ostream& stream() const = 0;\n    };\n\n    class FileStream : public IStream {\n        mutable std::ofstream m_ofs;\n    public:\n        FileStream( std::string const& filename );\n        virtual ~FileStream() CATCH_NOEXCEPT;\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n\n    class CoutStream : public IStream {\n        mutable std::ostream m_os;\n    public:\n        CoutStream();\n        virtual ~CoutStream() CATCH_NOEXCEPT;\n\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n\n    class DebugOutStream : public IStream {\n        CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;\n        mutable std::ostream m_os;\n    public:\n        DebugOutStream();\n        virtual ~DebugOutStream() CATCH_NOEXCEPT;\n\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n}\n\n#include <memory>\n#include <vector>\n#include <string>\n#include <iostream>\n#include <ctime>\n\n#ifndef CATCH_CONFIG_CONSOLE_WIDTH\n#define CATCH_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\n\n    struct ConfigData {\n\n        ConfigData()\n        :   listTests( false ),\n            listTags( false ),\n            listReporters( false ),\n            listTestNamesOnly( false ),\n            showSuccessfulTests( false ),\n            shouldDebugBreak( false ),\n            noThrow( false ),\n            showHelp( false ),\n            showInvisibles( false ),\n            filenamesAsTags( false ),\n            abortAfter( -1 ),\n            rngSeed( 0 ),\n            verbosity( Verbosity::Normal ),\n            warnings( WarnAbout::Nothing ),\n            showDurations( ShowDurations::DefaultForReporter ),\n            runOrder( RunTests::InDeclarationOrder ),\n            useColour( UseColour::Auto )\n        {}\n\n        bool listTests;\n        bool listTags;\n        bool listReporters;\n        bool listTestNamesOnly;\n\n        bool showSuccessfulTests;\n        bool shouldDebugBreak;\n        bool noThrow;\n        bool showHelp;\n        bool showInvisibles;\n        bool filenamesAsTags;\n\n        int abortAfter;\n        unsigned int rngSeed;\n\n        Verbosity::Level verbosity;\n        WarnAbout::What warnings;\n        ShowDurations::OrNot showDurations;\n        RunTests::InWhatOrder runOrder;\n        UseColour::YesOrNo useColour;\n\n        std::string outputFilename;\n        std::string name;\n        std::string processName;\n\n        std::vector<std::string> reporterNames;\n        std::vector<std::string> testsOrTags;\n    };\n\n    class Config : public SharedImpl<IConfig> {\n    private:\n        Config( Config const& other );\n        Config& operator = ( Config const& other );\n        virtual void dummy();\n    public:\n\n        Config()\n        {}\n\n        Config( ConfigData const& data )\n        :   m_data( data ),\n            m_stream( openStream() )\n        {\n            if( !data.testsOrTags.empty() ) {\n                TestSpecParser parser( ITagAliasRegistry::get() );\n                for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )\n                    parser.parse( data.testsOrTags[i] );\n                m_testSpec = parser.testSpec();\n            }\n        }\n\n        virtual ~Config() {\n        }\n\n        std::string const& getFilename() const {\n            return m_data.outputFilename ;\n        }\n\n        bool listTests() const { return m_data.listTests; }\n        bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }\n        bool listTags() const { return m_data.listTags; }\n        bool listReporters() const { return m_data.listReporters; }\n\n        std::string getProcessName() const { return m_data.processName; }\n\n        bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }\n\n        std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }\n\n        int abortAfter() const { return m_data.abortAfter; }\n\n        TestSpec const& testSpec() const { return m_testSpec; }\n\n        bool showHelp() const { return m_data.showHelp; }\n        bool showInvisibles() const { return m_data.showInvisibles; }\n\n        // IConfig interface\n        virtual bool allowThrows() const        { return !m_data.noThrow; }\n        virtual std::ostream& stream() const    { return m_stream->stream(); }\n        virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }\n        virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }\n        virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }\n        virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }\n        virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }\n        virtual unsigned int rngSeed() const    { return m_data.rngSeed; }\n        virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }\n\n    private:\n\n        IStream const* openStream() {\n            if( m_data.outputFilename.empty() )\n                return new CoutStream();\n            else if( m_data.outputFilename[0] == '%' ) {\n                if( m_data.outputFilename == \"%debug\" )\n                    return new DebugOutStream();\n                else\n                    throw std::domain_error( \"Unrecognised stream: \" + m_data.outputFilename );\n            }\n            else\n                return new FileStream( m_data.outputFilename );\n        }\n        ConfigData m_data;\n\n        CATCH_AUTO_PTR( IStream const ) m_stream;\n        TestSpec m_testSpec;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_clara.h\n#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED\n\n// Use Catch's value for console width (store Clara's off to the side, if present)\n#ifdef CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH\n#undef CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH\n\n// Declare Clara inside the Catch namespace\n#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {\n// #included from: ../external/clara.h\n\n// Version 0.0.2.4\n\n// Only use header guard if we are not using an outer namespace\n#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)\n\n#ifndef STITCH_CLARA_OPEN_NAMESPACE\n#define TWOBLUECUBES_CLARA_H_INCLUDED\n#define STITCH_CLARA_OPEN_NAMESPACE\n#define STITCH_CLARA_CLOSE_NAMESPACE\n#else\n#define STITCH_CLARA_CLOSE_NAMESPACE }\n#endif\n\n#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE\n\n// ----------- #included from tbc_text_format.h -----------\n\n// Only use header guard if we are not using an outer namespace\n#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)\n#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n#define TBC_TEXT_FORMAT_H_INCLUDED\n#endif\n\n#include <string>\n#include <vector>\n#include <sstream>\n#include <algorithm>\n\n// Use optional outer namespace\n#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\nnamespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {\n#endif\n\nnamespace Tbc {\n\n#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH\n    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n    struct TextAttributes {\n        TextAttributes()\n        :   initialIndent( std::string::npos ),\n            indent( 0 ),\n            width( consoleWidth-1 ),\n            tabChar( '\\t' )\n        {}\n\n        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }\n        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }\n        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }\n        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }\n\n        std::size_t initialIndent;  // indent of first line, or npos\n        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos\n        std::size_t width;          // maximum width of text, including indent. Longer text will wrap\n        char tabChar;               // If this char is seen the indent is changed to current pos\n    };\n\n    class Text {\n    public:\n        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )\n        : attr( _attr )\n        {\n            std::string wrappableChars = \" [({.,/|\\\\-\";\n            std::size_t indent = _attr.initialIndent != std::string::npos\n                ? _attr.initialIndent\n                : _attr.indent;\n            std::string remainder = _str;\n\n            while( !remainder.empty() ) {\n                if( lines.size() >= 1000 ) {\n                    lines.push_back( \"... message truncated due to excessive size\" );\n                    return;\n                }\n                std::size_t tabPos = std::string::npos;\n                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );\n                std::size_t pos = remainder.find_first_of( '\\n' );\n                if( pos <= width ) {\n                    width = pos;\n                }\n                pos = remainder.find_last_of( _attr.tabChar, width );\n                if( pos != std::string::npos ) {\n                    tabPos = pos;\n                    if( remainder[width] == '\\n' )\n                        width--;\n                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );\n                }\n\n                if( width == remainder.size() ) {\n                    spliceLine( indent, remainder, width );\n                }\n                else if( remainder[width] == '\\n' ) {\n                    spliceLine( indent, remainder, width );\n                    if( width <= 1 || remainder.size() != 1 )\n                        remainder = remainder.substr( 1 );\n                    indent = _attr.indent;\n                }\n                else {\n                    pos = remainder.find_last_of( wrappableChars, width );\n                    if( pos != std::string::npos && pos > 0 ) {\n                        spliceLine( indent, remainder, pos );\n                        if( remainder[0] == ' ' )\n                            remainder = remainder.substr( 1 );\n                    }\n                    else {\n                        spliceLine( indent, remainder, width-1 );\n                        lines.back() += \"-\";\n                    }\n                    if( lines.size() == 1 )\n                        indent = _attr.indent;\n                    if( tabPos != std::string::npos )\n                        indent += tabPos;\n                }\n            }\n        }\n\n        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {\n            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );\n            _remainder = _remainder.substr( _pos );\n        }\n\n        typedef std::vector<std::string>::const_iterator const_iterator;\n\n        const_iterator begin() const { return lines.begin(); }\n        const_iterator end() const { return lines.end(); }\n        std::string const& last() const { return lines.back(); }\n        std::size_t size() const { return lines.size(); }\n        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << *this;\n            return oss.str();\n        }\n\n        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {\n            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();\n                it != itEnd; ++it ) {\n                if( it != _text.begin() )\n                    _stream << \"\\n\";\n                _stream << *it;\n            }\n            return _stream;\n        }\n\n    private:\n        std::string str;\n        TextAttributes attr;\n        std::vector<std::string> lines;\n    };\n\n} // end namespace Tbc\n\n#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n} // end outer namespace\n#endif\n\n#endif // TBC_TEXT_FORMAT_H_INCLUDED\n\n// ----------- end of #include from tbc_text_format.h -----------\n// ........... back in clara.h\n\n#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE\n\n// ----------- #included from clara_compilers.h -----------\n\n#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n\n// Detect a number of compiler features - mostly C++11/14 conformance - by compiler\n// The following features are defined:\n//\n// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?\n// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?\n// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods\n// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?\n// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)\n\n// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?\n\n// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11\n\n#ifdef __clang__\n\n#if __has_feature(cxx_nullptr)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n#if __has_feature(cxx_noexcept)\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#endif\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// GCC\n#ifdef __GNUC__\n\n#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n// - otherwise more recent versions define __cplusplus >= 201103L\n// and will get picked up below\n\n#endif // __GNUC__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#ifdef _MSC_VER\n\n#if (_MSC_VER >= 1600)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#endif\n\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n// C++ language feature support\n\n// catch all support for C++11\n#if defined(__cplusplus) && __cplusplus >= 201103L\n\n#define CLARA_CPP11_OR_GREATER\n\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#endif\n\n#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#endif\n\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)\n#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE\n#endif\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)\n#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#endif // __cplusplus >= 201103L\n\n// Now set the actual defines based on the above + anything the user has configured\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_NULLPTR\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_NOEXCEPT\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_GENERATED_METHODS\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_OVERRIDE\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n// noexcept support:\n#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)\n#define CLARA_NOEXCEPT noexcept\n#  define CLARA_NOEXCEPT_IS(x) noexcept(x)\n#else\n#define CLARA_NOEXCEPT throw()\n#  define CLARA_NOEXCEPT_IS(x)\n#endif\n\n// nullptr support\n#ifdef CLARA_CONFIG_CPP11_NULLPTR\n#define CLARA_NULL nullptr\n#else\n#define CLARA_NULL NULL\n#endif\n\n// override support\n#ifdef CLARA_CONFIG_CPP11_OVERRIDE\n#define CLARA_OVERRIDE override\n#else\n#define CLARA_OVERRIDE\n#endif\n\n// unique_ptr support\n#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR\n#   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>\n#else\n#   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>\n#endif\n\n#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n\n// ----------- end of #include from clara_compilers.h -----------\n// ........... back in clara.h\n\n#include <map>\n#include <stdexcept>\n#include <memory>\n\n#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)\n#define CLARA_PLATFORM_WINDOWS\n#endif\n\n// Use optional outer namespace\n#ifdef STITCH_CLARA_OPEN_NAMESPACE\nSTITCH_CLARA_OPEN_NAMESPACE\n#endif\n\nnamespace Clara {\n\n    struct UnpositionalTag {};\n\n    extern UnpositionalTag _;\n\n#ifdef CLARA_CONFIG_MAIN\n    UnpositionalTag _;\n#endif\n\n    namespace Detail {\n\n#ifdef CLARA_CONSOLE_WIDTH\n    const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n        using namespace Tbc;\n\n        inline bool startsWith( std::string const& str, std::string const& prefix ) {\n            return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;\n        }\n\n        template<typename T> struct RemoveConstRef{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T&>{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T const>{ typedef T type; };\n\n        template<typename T>    struct IsBool       { static const bool value = false; };\n        template<>              struct IsBool<bool> { static const bool value = true; };\n\n        template<typename T>\n        void convertInto( std::string const& _source, T& _dest ) {\n            std::stringstream ss;\n            ss << _source;\n            ss >> _dest;\n            if( ss.fail() )\n                throw std::runtime_error( \"Unable to convert \" + _source + \" to destination type\" );\n        }\n        inline void convertInto( std::string const& _source, std::string& _dest ) {\n            _dest = _source;\n        }\n        char toLowerCh(char c) {\n            return static_cast<char>( ::tolower( c ) );\n        }\n        inline void convertInto( std::string const& _source, bool& _dest ) {\n            std::string sourceLC = _source;\n            std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );\n            if( sourceLC == \"y\" || sourceLC == \"1\" || sourceLC == \"true\" || sourceLC == \"yes\" || sourceLC == \"on\" )\n                _dest = true;\n            else if( sourceLC == \"n\" || sourceLC == \"0\" || sourceLC == \"false\" || sourceLC == \"no\" || sourceLC == \"off\" )\n                _dest = false;\n            else\n                throw std::runtime_error( \"Expected a boolean value but did not recognise:\\n  '\" + _source + \"'\" );\n        }\n\n        template<typename ConfigT>\n        struct IArgFunction {\n            virtual ~IArgFunction() {}\n#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS\n            IArgFunction()                      = default;\n            IArgFunction( IArgFunction const& ) = default;\n#endif\n            virtual void set( ConfigT& config, std::string const& value ) const = 0;\n            virtual bool takesArg() const = 0;\n            virtual IArgFunction* clone() const = 0;\n        };\n\n        template<typename ConfigT>\n        class BoundArgFunction {\n        public:\n            BoundArgFunction() : functionObj( CLARA_NULL ) {}\n            BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}\n            BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}\n            BoundArgFunction& operator = ( BoundArgFunction const& other ) {\n                IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;\n                delete functionObj;\n                functionObj = newFunctionObj;\n                return *this;\n            }\n            ~BoundArgFunction() { delete functionObj; }\n\n            void set( ConfigT& config, std::string const& value ) const {\n                functionObj->set( config, value );\n            }\n            bool takesArg() const { return functionObj->takesArg(); }\n\n            bool isSet() const {\n                return functionObj != CLARA_NULL;\n            }\n        private:\n            IArgFunction<ConfigT>* functionObj;\n        };\n\n        template<typename C>\n        struct NullBinder : IArgFunction<C>{\n            virtual void set( C&, std::string const& ) const {}\n            virtual bool takesArg() const { return true; }\n            virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }\n        };\n\n        template<typename C, typename M>\n        struct BoundDataMember : IArgFunction<C>{\n            BoundDataMember( M C::* _member ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                convertInto( stringValue, p.*member );\n            }\n            virtual bool takesArg() const { return !IsBool<M>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }\n            M C::* member;\n        };\n        template<typename C, typename M>\n        struct BoundUnaryMethod : IArgFunction<C>{\n            BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                typename RemoveConstRef<M>::type value;\n                convertInto( stringValue, value );\n                (p.*member)( value );\n            }\n            virtual bool takesArg() const { return !IsBool<M>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }\n            void (C::*member)( M );\n        };\n        template<typename C>\n        struct BoundNullaryMethod : IArgFunction<C>{\n            BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                bool value;\n                convertInto( stringValue, value );\n                if( value )\n                    (p.*member)();\n            }\n            virtual bool takesArg() const { return false; }\n            virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }\n            void (C::*member)();\n        };\n\n        template<typename C>\n        struct BoundUnaryFunction : IArgFunction<C>{\n            BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}\n            virtual void set( C& obj, std::string const& stringValue ) const {\n                bool value;\n                convertInto( stringValue, value );\n                if( value )\n                    function( obj );\n            }\n            virtual bool takesArg() const { return false; }\n            virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }\n            void (*function)( C& );\n        };\n\n        template<typename C, typename T>\n        struct BoundBinaryFunction : IArgFunction<C>{\n            BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}\n            virtual void set( C& obj, std::string const& stringValue ) const {\n                typename RemoveConstRef<T>::type value;\n                convertInto( stringValue, value );\n                function( obj, value );\n            }\n            virtual bool takesArg() const { return !IsBool<T>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }\n            void (*function)( C&, T );\n        };\n\n    } // namespace Detail\n\n    inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {\n        std::vector<std::string> args( static_cast<std::size_t>( argc ) );\n        for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )\n            args[i] = argv[i];\n\n        return args;\n    }\n\n    class Parser {\n        enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };\n        Mode mode;\n        std::size_t from;\n        bool inQuotes;\n    public:\n\n        struct Token {\n            enum Type { Positional, ShortOpt, LongOpt };\n            Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}\n            Type type;\n            std::string data;\n        };\n\n        Parser() : mode( None ), from( 0 ), inQuotes( false ){}\n\n        void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {\n            const std::string doubleDash = \"--\";\n            for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )\n                parseIntoTokens( args[i], tokens);\n        }\n\n        void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {\n            for( std::size_t i = 0; i <= arg.size(); ++i ) {\n                char c = arg[i];\n                if( c == '\"' )\n                    inQuotes = !inQuotes;\n                mode = handleMode( i, c, arg, tokens );\n            }\n        }\n        Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            switch( mode ) {\n                case None: return handleNone( i, c );\n                case MaybeShortOpt: return handleMaybeShortOpt( i, c );\n                case ShortOpt:\n                case LongOpt:\n                case SlashOpt: return handleOpt( i, c, arg, tokens );\n                case Positional: return handlePositional( i, c, arg, tokens );\n                default: throw std::logic_error( \"Unknown mode\" );\n            }\n        }\n\n        Mode handleNone( std::size_t i, char c ) {\n            if( inQuotes ) {\n                from = i;\n                return Positional;\n            }\n            switch( c ) {\n                case '-': return MaybeShortOpt;\n#ifdef CLARA_PLATFORM_WINDOWS\n                case '/': from = i+1; return SlashOpt;\n#endif\n                default: from = i; return Positional;\n            }\n        }\n        Mode handleMaybeShortOpt( std::size_t i, char c ) {\n            switch( c ) {\n                case '-': from = i+1; return LongOpt;\n                default: from = i; return ShortOpt;\n            }\n        }\n        Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            if( std::string( \":=\\0\", 3 ).find( c ) == std::string::npos )\n                return mode;\n\n            std::string optName = arg.substr( from, i-from );\n            if( mode == ShortOpt )\n                for( std::size_t j = 0; j < optName.size(); ++j )\n                    tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );\n            else if( mode == SlashOpt && optName.size() == 1 )\n                tokens.push_back( Token( Token::ShortOpt, optName ) );\n            else\n                tokens.push_back( Token( Token::LongOpt, optName ) );\n            return None;\n        }\n        Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            if( inQuotes || std::string( \"\\0\", 1 ).find( c ) == std::string::npos )\n                return mode;\n\n            std::string data = arg.substr( from, i-from );\n            tokens.push_back( Token( Token::Positional, data ) );\n            return None;\n        }\n    };\n\n    template<typename ConfigT>\n    struct CommonArgProperties {\n        CommonArgProperties() {}\n        CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}\n\n        Detail::BoundArgFunction<ConfigT> boundField;\n        std::string description;\n        std::string detail;\n        std::string placeholder; // Only value if boundField takes an arg\n\n        bool takesArg() const {\n            return !placeholder.empty();\n        }\n        void validate() const {\n            if( !boundField.isSet() )\n                throw std::logic_error( \"option not bound\" );\n        }\n    };\n    struct OptionArgProperties {\n        std::vector<std::string> shortNames;\n        std::string longName;\n\n        bool hasShortName( std::string const& shortName ) const {\n            return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();\n        }\n        bool hasLongName( std::string const& _longName ) const {\n            return _longName == longName;\n        }\n    };\n    struct PositionalArgProperties {\n        PositionalArgProperties() : position( -1 ) {}\n        int position; // -1 means non-positional (floating)\n\n        bool isFixedPositional() const {\n            return position != -1;\n        }\n    };\n\n    template<typename ConfigT>\n    class CommandLine {\n\n        struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {\n            Arg() {}\n            Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}\n\n            using CommonArgProperties<ConfigT>::placeholder; // !TBD\n\n            std::string dbgName() const {\n                if( !longName.empty() )\n                    return \"--\" + longName;\n                if( !shortNames.empty() )\n                    return \"-\" + shortNames[0];\n                return \"positional args\";\n            }\n            std::string commands() const {\n                std::ostringstream oss;\n                bool first = true;\n                std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();\n                for(; it != itEnd; ++it ) {\n                    if( first )\n                        first = false;\n                    else\n                        oss << \", \";\n                    oss << \"-\" << *it;\n                }\n                if( !longName.empty() ) {\n                    if( !first )\n                        oss << \", \";\n                    oss << \"--\" << longName;\n                }\n                if( !placeholder.empty() )\n                    oss << \" <\" << placeholder << \">\";\n                return oss.str();\n            }\n        };\n\n        typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;\n\n        friend void addOptName( Arg& arg, std::string const& optName )\n        {\n            if( optName.empty() )\n                return;\n            if( Detail::startsWith( optName, \"--\" ) ) {\n                if( !arg.longName.empty() )\n                    throw std::logic_error( \"Only one long opt may be specified. '\"\n                        + arg.longName\n                        + \"' already specified, now attempting to add '\"\n                        + optName + \"'\" );\n                arg.longName = optName.substr( 2 );\n            }\n            else if( Detail::startsWith( optName, \"-\" ) )\n                arg.shortNames.push_back( optName.substr( 1 ) );\n            else\n                throw std::logic_error( \"option must begin with - or --. Option was: '\" + optName + \"'\" );\n        }\n        friend void setPositionalArg( Arg& arg, int position )\n        {\n            arg.position = position;\n        }\n\n        class ArgBuilder {\n        public:\n            ArgBuilder( Arg* arg ) : m_arg( arg ) {}\n\n            // Bind a non-boolean data member (requires placeholder string)\n            template<typename C, typename M>\n            void bind( M C::* field, std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundDataMember<C,M>( field );\n                m_arg->placeholder = placeholder;\n            }\n            // Bind a boolean data member (no placeholder required)\n            template<typename C>\n            void bind( bool C::* field ) {\n                m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );\n            }\n\n            // Bind a method taking a single, non-boolean argument (requires a placeholder string)\n            template<typename C, typename M>\n            void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );\n                m_arg->placeholder = placeholder;\n            }\n\n            // Bind a method taking a single, boolean argument (no placeholder string required)\n            template<typename C>\n            void bind( void (C::* unaryMethod)( bool ) ) {\n                m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );\n            }\n\n            // Bind a method that takes no arguments (will be called if opt is present)\n            template<typename C>\n            void bind( void (C::* nullaryMethod)() ) {\n                m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );\n            }\n\n            // Bind a free function taking a single argument - the object to operate on (no placeholder string required)\n            template<typename C>\n            void bind( void (* unaryFunction)( C& ) ) {\n                m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );\n            }\n\n            // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)\n            template<typename C, typename T>\n            void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );\n                m_arg->placeholder = placeholder;\n            }\n\n            ArgBuilder& describe( std::string const& description ) {\n                m_arg->description = description;\n                return *this;\n            }\n            ArgBuilder& detail( std::string const& detail ) {\n                m_arg->detail = detail;\n                return *this;\n            }\n\n        protected:\n            Arg* m_arg;\n        };\n\n        class OptBuilder : public ArgBuilder {\n        public:\n            OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}\n            OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}\n\n            OptBuilder& operator[]( std::string const& optName ) {\n                addOptName( *ArgBuilder::m_arg, optName );\n                return *this;\n            }\n        };\n\n    public:\n\n        CommandLine()\n        :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),\n            m_highestSpecifiedArgPosition( 0 ),\n            m_throwOnUnrecognisedTokens( false )\n        {}\n        CommandLine( CommandLine const& other )\n        :   m_boundProcessName( other.m_boundProcessName ),\n            m_options ( other.m_options ),\n            m_positionalArgs( other.m_positionalArgs ),\n            m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),\n            m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )\n        {\n            if( other.m_floatingArg.get() )\n                m_floatingArg.reset( new Arg( *other.m_floatingArg ) );\n        }\n\n        CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {\n            m_throwOnUnrecognisedTokens = shouldThrow;\n            return *this;\n        }\n\n        OptBuilder operator[]( std::string const& optName ) {\n            m_options.push_back( Arg() );\n            addOptName( m_options.back(), optName );\n            OptBuilder builder( &m_options.back() );\n            return builder;\n        }\n\n        ArgBuilder operator[]( int position ) {\n            m_positionalArgs.insert( std::make_pair( position, Arg() ) );\n            if( position > m_highestSpecifiedArgPosition )\n                m_highestSpecifiedArgPosition = position;\n            setPositionalArg( m_positionalArgs[position], position );\n            ArgBuilder builder( &m_positionalArgs[position] );\n            return builder;\n        }\n\n        // Invoke this with the _ instance\n        ArgBuilder operator[]( UnpositionalTag ) {\n            if( m_floatingArg.get() )\n                throw std::logic_error( \"Only one unpositional argument can be added\" );\n            m_floatingArg.reset( new Arg() );\n            ArgBuilder builder( m_floatingArg.get() );\n            return builder;\n        }\n\n        template<typename C, typename M>\n        void bindProcessName( M C::* field ) {\n            m_boundProcessName = new Detail::BoundDataMember<C,M>( field );\n        }\n        template<typename C, typename M>\n        void bindProcessName( void (C::*_unaryMethod)( M ) ) {\n            m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );\n        }\n\n        void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {\n            typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;\n            std::size_t maxWidth = 0;\n            for( it = itBegin; it != itEnd; ++it )\n                maxWidth = (std::max)( maxWidth, it->commands().size() );\n\n            for( it = itBegin; it != itEnd; ++it ) {\n                Detail::Text usage( it->commands(), Detail::TextAttributes()\n                                                        .setWidth( maxWidth+indent )\n                                                        .setIndent( indent ) );\n                Detail::Text desc( it->description, Detail::TextAttributes()\n                                                        .setWidth( width - maxWidth - 3 ) );\n\n                for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {\n                    std::string usageCol = i < usage.size() ? usage[i] : \"\";\n                    os << usageCol;\n\n                    if( i < desc.size() && !desc[i].empty() )\n                        os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )\n                            << desc[i];\n                    os << \"\\n\";\n                }\n            }\n        }\n        std::string optUsage() const {\n            std::ostringstream oss;\n            optUsage( oss );\n            return oss.str();\n        }\n\n        void argSynopsis( std::ostream& os ) const {\n            for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {\n                if( i > 1 )\n                    os << \" \";\n                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );\n                if( it != m_positionalArgs.end() )\n                    os << \"<\" << it->second.placeholder << \">\";\n                else if( m_floatingArg.get() )\n                    os << \"<\" << m_floatingArg->placeholder << \">\";\n                else\n                    throw std::logic_error( \"non consecutive positional arguments with no floating args\" );\n            }\n            // !TBD No indication of mandatory args\n            if( m_floatingArg.get() ) {\n                if( m_highestSpecifiedArgPosition > 1 )\n                    os << \" \";\n                os << \"[<\" << m_floatingArg->placeholder << \"> ...]\";\n            }\n        }\n        std::string argSynopsis() const {\n            std::ostringstream oss;\n            argSynopsis( oss );\n            return oss.str();\n        }\n\n        void usage( std::ostream& os, std::string const& procName ) const {\n            validate();\n            os << \"usage:\\n  \" << procName << \" \";\n            argSynopsis( os );\n            if( !m_options.empty() ) {\n                os << \" [options]\\n\\nwhere options are: \\n\";\n                optUsage( os, 2 );\n            }\n            os << \"\\n\";\n        }\n        std::string usage( std::string const& procName ) const {\n            std::ostringstream oss;\n            usage( oss, procName );\n            return oss.str();\n        }\n\n        ConfigT parse( std::vector<std::string> const& args ) const {\n            ConfigT config;\n            parseInto( args, config );\n            return config;\n        }\n\n        std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {\n            std::string processName = args[0];\n            std::size_t lastSlash = processName.find_last_of( \"/\\\\\" );\n            if( lastSlash != std::string::npos )\n                processName = processName.substr( lastSlash+1 );\n            m_boundProcessName.set( config, processName );\n            std::vector<Parser::Token> tokens;\n            Parser parser;\n            parser.parseIntoTokens( args, tokens );\n            return populate( tokens, config );\n        }\n\n        std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            validate();\n            std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );\n            unusedTokens = populateFixedArgs( unusedTokens, config );\n            unusedTokens = populateFloatingArgs( unusedTokens, config );\n            return unusedTokens;\n        }\n\n        std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            std::vector<Parser::Token> unusedTokens;\n            std::vector<std::string> errors;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();\n                for(; it != itEnd; ++it ) {\n                    Arg const& arg = *it;\n\n                    try {\n                        if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||\n                            ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {\n                            if( arg.takesArg() ) {\n                                if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )\n                                    errors.push_back( \"Expected argument to option: \" + token.data );\n                                else\n                                    arg.boundField.set( config, tokens[++i].data );\n                            }\n                            else {\n                                arg.boundField.set( config, \"true\" );\n                            }\n                            break;\n                        }\n                    }\n                    catch( std::exception& ex ) {\n                        errors.push_back( std::string( ex.what() ) + \"\\n- while parsing: (\" + arg.commands() + \")\" );\n                    }\n                }\n                if( it == itEnd ) {\n                    if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )\n                        unusedTokens.push_back( token );\n                    else if( errors.empty() && m_throwOnUnrecognisedTokens )\n                        errors.push_back( \"unrecognised option: \" + token.data );\n                }\n            }\n            if( !errors.empty() ) {\n                std::ostringstream oss;\n                for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();\n                        it != itEnd;\n                        ++it ) {\n                    if( it != errors.begin() )\n                        oss << \"\\n\";\n                    oss << *it;\n                }\n                throw std::runtime_error( oss.str() );\n            }\n            return unusedTokens;\n        }\n        std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            std::vector<Parser::Token> unusedTokens;\n            int position = 1;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );\n                if( it != m_positionalArgs.end() )\n                    it->second.boundField.set( config, token.data );\n                else\n                    unusedTokens.push_back( token );\n                if( token.type == Parser::Token::Positional )\n                    position++;\n            }\n            return unusedTokens;\n        }\n        std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            if( !m_floatingArg.get() )\n                return tokens;\n            std::vector<Parser::Token> unusedTokens;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                if( token.type == Parser::Token::Positional )\n                    m_floatingArg->boundField.set( config, token.data );\n                else\n                    unusedTokens.push_back( token );\n            }\n            return unusedTokens;\n        }\n\n        void validate() const\n        {\n            if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )\n                throw std::logic_error( \"No options or arguments specified\" );\n\n            for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),\n                                                            itEnd = m_options.end();\n                    it != itEnd; ++it )\n                it->validate();\n        }\n\n    private:\n        Detail::BoundArgFunction<ConfigT> m_boundProcessName;\n        std::vector<Arg> m_options;\n        std::map<int, Arg> m_positionalArgs;\n        ArgAutoPtr m_floatingArg;\n        int m_highestSpecifiedArgPosition;\n        bool m_throwOnUnrecognisedTokens;\n    };\n\n} // end namespace Clara\n\nSTITCH_CLARA_CLOSE_NAMESPACE\n#undef STITCH_CLARA_OPEN_NAMESPACE\n#undef STITCH_CLARA_CLOSE_NAMESPACE\n\n#endif // TWOBLUECUBES_CLARA_H_INCLUDED\n#undef STITCH_CLARA_OPEN_NAMESPACE\n\n// Restore Clara's value for console width, if present\n#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n#include <fstream>\n\nnamespace Catch {\n\n    inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }\n    inline void abortAfterX( ConfigData& config, int x ) {\n        if( x < 1 )\n            throw std::runtime_error( \"Value after -x or --abortAfter must be greater than zero\" );\n        config.abortAfter = x;\n    }\n    inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }\n    inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }\n\n    inline void addWarning( ConfigData& config, std::string const& _warning ) {\n        if( _warning == \"NoAssertions\" )\n            config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );\n        else\n            throw std::runtime_error( \"Unrecognised warning: '\" + _warning + \"'\" );\n    }\n    inline void setOrder( ConfigData& config, std::string const& order ) {\n        if( startsWith( \"declared\", order ) )\n            config.runOrder = RunTests::InDeclarationOrder;\n        else if( startsWith( \"lexical\", order ) )\n            config.runOrder = RunTests::InLexicographicalOrder;\n        else if( startsWith( \"random\", order ) )\n            config.runOrder = RunTests::InRandomOrder;\n        else\n            throw std::runtime_error( \"Unrecognised ordering: '\" + order + \"'\" );\n    }\n    inline void setRngSeed( ConfigData& config, std::string const& seed ) {\n        if( seed == \"time\" ) {\n            config.rngSeed = static_cast<unsigned int>( std::time(0) );\n        }\n        else {\n            std::stringstream ss;\n            ss << seed;\n            ss >> config.rngSeed;\n            if( ss.fail() )\n                throw std::runtime_error( \"Argment to --rng-seed should be the word 'time' or a number\" );\n        }\n    }\n    inline void setVerbosity( ConfigData& config, int level ) {\n        // !TBD: accept strings?\n        config.verbosity = static_cast<Verbosity::Level>( level );\n    }\n    inline void setShowDurations( ConfigData& config, bool _showDurations ) {\n        config.showDurations = _showDurations\n            ? ShowDurations::Always\n            : ShowDurations::Never;\n    }\n    inline void setUseColour( ConfigData& config, std::string const& value ) {\n        std::string mode = toLower( value );\n\n        if( mode == \"yes\" )\n            config.useColour = UseColour::Yes;\n        else if( mode == \"no\" )\n            config.useColour = UseColour::No;\n        else if( mode == \"auto\" )\n            config.useColour = UseColour::Auto;\n        else\n            throw std::runtime_error( \"colour mode must be one of: auto, yes or no\" );\n    }\n    inline void forceColour( ConfigData& config ) {\n        config.useColour = UseColour::Yes;\n    }\n    inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {\n        std::ifstream f( _filename.c_str() );\n        if( !f.is_open() )\n            throw std::domain_error( \"Unable to load input file: \" + _filename );\n\n        std::string line;\n        while( std::getline( f, line ) ) {\n            line = trim(line);\n            if( !line.empty() && !startsWith( line, \"#\" ) ) {\n                if( !startsWith( line, \"\\\"\" ) )\n                    line = \"\\\"\" + line + \"\\\"\";\n                addTestOrTags( config, line + \",\" );\n            }\n        }\n    }\n\n    inline Clara::CommandLine<ConfigData> makeCommandLineParser() {\n\n        using namespace Clara;\n        CommandLine<ConfigData> cli;\n\n        cli.bindProcessName( &ConfigData::processName );\n\n        cli[\"-?\"][\"-h\"][\"--help\"]\n            .describe( \"display usage information\" )\n            .bind( &ConfigData::showHelp );\n\n        cli[\"-l\"][\"--list-tests\"]\n            .describe( \"list all/matching test cases\" )\n            .bind( &ConfigData::listTests );\n\n        cli[\"-t\"][\"--list-tags\"]\n            .describe( \"list all/matching tags\" )\n            .bind( &ConfigData::listTags );\n\n        cli[\"-s\"][\"--success\"]\n            .describe( \"include successful tests in output\" )\n            .bind( &ConfigData::showSuccessfulTests );\n\n        cli[\"-b\"][\"--break\"]\n            .describe( \"break into debugger on failure\" )\n            .bind( &ConfigData::shouldDebugBreak );\n\n        cli[\"-e\"][\"--nothrow\"]\n            .describe( \"skip exception tests\" )\n            .bind( &ConfigData::noThrow );\n\n        cli[\"-i\"][\"--invisibles\"]\n            .describe( \"show invisibles (tabs, newlines)\" )\n            .bind( &ConfigData::showInvisibles );\n\n        cli[\"-o\"][\"--out\"]\n            .describe( \"output filename\" )\n            .bind( &ConfigData::outputFilename, \"filename\" );\n\n        cli[\"-r\"][\"--reporter\"]\n//            .placeholder( \"name[:filename]\" )\n            .describe( \"reporter to use (defaults to console)\" )\n            .bind( &addReporterName, \"name\" );\n\n        cli[\"-n\"][\"--name\"]\n            .describe( \"suite name\" )\n            .bind( &ConfigData::name, \"name\" );\n\n        cli[\"-a\"][\"--abort\"]\n            .describe( \"abort at first failure\" )\n            .bind( &abortAfterFirst );\n\n        cli[\"-x\"][\"--abortx\"]\n            .describe( \"abort after x failures\" )\n            .bind( &abortAfterX, \"no. failures\" );\n\n        cli[\"-w\"][\"--warn\"]\n            .describe( \"enable warnings\" )\n            .bind( &addWarning, \"warning name\" );\n\n// - needs updating if reinstated\n//        cli.into( &setVerbosity )\n//            .describe( \"level of verbosity (0=no output)\" )\n//            .shortOpt( \"v\")\n//            .longOpt( \"verbosity\" )\n//            .placeholder( \"level\" );\n\n        cli[_]\n            .describe( \"which test or tests to use\" )\n            .bind( &addTestOrTags, \"test name, pattern or tags\" );\n\n        cli[\"-d\"][\"--durations\"]\n            .describe( \"show test durations\" )\n            .bind( &setShowDurations, \"yes|no\" );\n\n        cli[\"-f\"][\"--input-file\"]\n            .describe( \"load test names to run from a file\" )\n            .bind( &loadTestNamesFromFile, \"filename\" );\n\n        cli[\"-#\"][\"--filenames-as-tags\"]\n            .describe( \"adds a tag for the filename\" )\n            .bind( &ConfigData::filenamesAsTags );\n\n        // Less common commands which don't have a short form\n        cli[\"--list-test-names-only\"]\n            .describe( \"list all/matching test cases names only\" )\n            .bind( &ConfigData::listTestNamesOnly );\n\n        cli[\"--list-reporters\"]\n            .describe( \"list all reporters\" )\n            .bind( &ConfigData::listReporters );\n\n        cli[\"--order\"]\n            .describe( \"test case order (defaults to decl)\" )\n            .bind( &setOrder, \"decl|lex|rand\" );\n\n        cli[\"--rng-seed\"]\n            .describe( \"set a specific seed for random numbers\" )\n            .bind( &setRngSeed, \"'time'|number\" );\n\n        cli[\"--force-colour\"]\n            .describe( \"force colourised output (deprecated)\" )\n            .bind( &forceColour );\n\n        cli[\"--use-colour\"]\n            .describe( \"should output be colourised\" )\n            .bind( &setUseColour, \"yes|no\" );\n\n        return cli;\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_list.hpp\n#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED\n\n// #included from: catch_text.h\n#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED\n\n#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH\n\n#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch\n// #included from: ../external/tbc_text_format.h\n// Only use header guard if we are not using an outer namespace\n#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED\n#  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#  endif\n# else\n#  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED\n# endif\n#endif\n#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#include <string>\n#include <vector>\n#include <sstream>\n\n// Use optional outer namespace\n#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\nnamespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {\n#endif\n\nnamespace Tbc {\n\n#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH\n    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n    struct TextAttributes {\n        TextAttributes()\n        :   initialIndent( std::string::npos ),\n            indent( 0 ),\n            width( consoleWidth-1 ),\n            tabChar( '\\t' )\n        {}\n\n        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }\n        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }\n        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }\n        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }\n\n        std::size_t initialIndent;  // indent of first line, or npos\n        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos\n        std::size_t width;          // maximum width of text, including indent. Longer text will wrap\n        char tabChar;               // If this char is seen the indent is changed to current pos\n    };\n\n    class Text {\n    public:\n        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )\n        : attr( _attr )\n        {\n            std::string wrappableChars = \" [({.,/|\\\\-\";\n            std::size_t indent = _attr.initialIndent != std::string::npos\n                ? _attr.initialIndent\n                : _attr.indent;\n            std::string remainder = _str;\n\n            while( !remainder.empty() ) {\n                if( lines.size() >= 1000 ) {\n                    lines.push_back( \"... message truncated due to excessive size\" );\n                    return;\n                }\n                std::size_t tabPos = std::string::npos;\n                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );\n                std::size_t pos = remainder.find_first_of( '\\n' );\n                if( pos <= width ) {\n                    width = pos;\n                }\n                pos = remainder.find_last_of( _attr.tabChar, width );\n                if( pos != std::string::npos ) {\n                    tabPos = pos;\n                    if( remainder[width] == '\\n' )\n                        width--;\n                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );\n                }\n\n                if( width == remainder.size() ) {\n                    spliceLine( indent, remainder, width );\n                }\n                else if( remainder[width] == '\\n' ) {\n                    spliceLine( indent, remainder, width );\n                    if( width <= 1 || remainder.size() != 1 )\n                        remainder = remainder.substr( 1 );\n                    indent = _attr.indent;\n                }\n                else {\n                    pos = remainder.find_last_of( wrappableChars, width );\n                    if( pos != std::string::npos && pos > 0 ) {\n                        spliceLine( indent, remainder, pos );\n                        if( remainder[0] == ' ' )\n                            remainder = remainder.substr( 1 );\n                    }\n                    else {\n                        spliceLine( indent, remainder, width-1 );\n                        lines.back() += \"-\";\n                    }\n                    if( lines.size() == 1 )\n                        indent = _attr.indent;\n                    if( tabPos != std::string::npos )\n                        indent += tabPos;\n                }\n            }\n        }\n\n        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {\n            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );\n            _remainder = _remainder.substr( _pos );\n        }\n\n        typedef std::vector<std::string>::const_iterator const_iterator;\n\n        const_iterator begin() const { return lines.begin(); }\n        const_iterator end() const { return lines.end(); }\n        std::string const& last() const { return lines.back(); }\n        std::size_t size() const { return lines.size(); }\n        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << *this;\n            return oss.str();\n        }\n\n        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {\n            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();\n                it != itEnd; ++it ) {\n                if( it != _text.begin() )\n                    _stream << \"\\n\";\n                _stream << *it;\n            }\n            return _stream;\n        }\n\n    private:\n        std::string str;\n        TextAttributes attr;\n        std::vector<std::string> lines;\n    };\n\n} // end namespace Tbc\n\n#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n} // end outer namespace\n#endif\n\n#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n\nnamespace Catch {\n    using Tbc::Text;\n    using Tbc::TextAttributes;\n}\n\n// #included from: catch_console_colour.hpp\n#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct Colour {\n        enum Code {\n            None = 0,\n\n            White,\n            Red,\n            Green,\n            Blue,\n            Cyan,\n            Yellow,\n            Grey,\n\n            Bright = 0x10,\n\n            BrightRed = Bright | Red,\n            BrightGreen = Bright | Green,\n            LightGrey = Bright | Grey,\n            BrightWhite = Bright | White,\n\n            // By intention\n            FileName = LightGrey,\n            Warning = Yellow,\n            ResultError = BrightRed,\n            ResultSuccess = BrightGreen,\n            ResultExpectedFailure = Warning,\n\n            Error = BrightRed,\n            Success = Green,\n\n            OriginalExpression = Cyan,\n            ReconstructedExpression = Yellow,\n\n            SecondaryText = LightGrey,\n            Headers = White\n        };\n\n        // Use constructed object for RAII guard\n        Colour( Code _colourCode );\n        Colour( Colour const& other );\n        ~Colour();\n\n        // Use static method for one-shot changes\n        static void use( Code _colourCode );\n\n    private:\n        bool m_moved;\n    };\n\n    inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }\n\n} // end namespace Catch\n\n// #included from: catch_interfaces_reporter.h\n#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED\n\n#include <string>\n#include <ostream>\n#include <map>\n#include <assert.h>\n\nnamespace Catch\n{\n    struct ReporterConfig {\n        explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )\n        :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}\n\n        ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )\n        :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}\n\n        std::ostream& stream() const    { return *m_stream; }\n        Ptr<IConfig const> fullConfig() const { return m_fullConfig; }\n\n    private:\n        std::ostream* m_stream;\n        Ptr<IConfig const> m_fullConfig;\n    };\n\n    struct ReporterPreferences {\n        ReporterPreferences()\n        : shouldRedirectStdOut( false )\n        {}\n\n        bool shouldRedirectStdOut;\n    };\n\n    template<typename T>\n    struct LazyStat : Option<T> {\n        LazyStat() : used( false ) {}\n        LazyStat& operator=( T const& _value ) {\n            Option<T>::operator=( _value );\n            used = false;\n            return *this;\n        }\n        void reset() {\n            Option<T>::reset();\n            used = false;\n        }\n        bool used;\n    };\n\n    struct TestRunInfo {\n        TestRunInfo( std::string const& _name ) : name( _name ) {}\n        std::string name;\n    };\n    struct GroupInfo {\n        GroupInfo(  std::string const& _name,\n                    std::size_t _groupIndex,\n                    std::size_t _groupsCount )\n        :   name( _name ),\n            groupIndex( _groupIndex ),\n            groupsCounts( _groupsCount )\n        {}\n\n        std::string name;\n        std::size_t groupIndex;\n        std::size_t groupsCounts;\n    };\n\n    struct AssertionStats {\n        AssertionStats( AssertionResult const& _assertionResult,\n                        std::vector<MessageInfo> const& _infoMessages,\n                        Totals const& _totals )\n        :   assertionResult( _assertionResult ),\n            infoMessages( _infoMessages ),\n            totals( _totals )\n        {\n            if( assertionResult.hasMessage() ) {\n                // Copy message into messages list.\n                // !TBD This should have been done earlier, somewhere\n                MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );\n                builder << assertionResult.getMessage();\n                builder.m_info.message = builder.m_stream.str();\n\n                infoMessages.push_back( builder.m_info );\n            }\n        }\n        virtual ~AssertionStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        AssertionStats( AssertionStats const& )              = default;\n        AssertionStats( AssertionStats && )                  = default;\n        AssertionStats& operator = ( AssertionStats const& ) = default;\n        AssertionStats& operator = ( AssertionStats && )     = default;\n#  endif\n\n        AssertionResult assertionResult;\n        std::vector<MessageInfo> infoMessages;\n        Totals totals;\n    };\n\n    struct SectionStats {\n        SectionStats(   SectionInfo const& _sectionInfo,\n                        Counts const& _assertions,\n                        double _durationInSeconds,\n                        bool _missingAssertions )\n        :   sectionInfo( _sectionInfo ),\n            assertions( _assertions ),\n            durationInSeconds( _durationInSeconds ),\n            missingAssertions( _missingAssertions )\n        {}\n        virtual ~SectionStats();\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        SectionStats( SectionStats const& )              = default;\n        SectionStats( SectionStats && )                  = default;\n        SectionStats& operator = ( SectionStats const& ) = default;\n        SectionStats& operator = ( SectionStats && )     = default;\n#  endif\n\n        SectionInfo sectionInfo;\n        Counts assertions;\n        double durationInSeconds;\n        bool missingAssertions;\n    };\n\n    struct TestCaseStats {\n        TestCaseStats(  TestCaseInfo const& _testInfo,\n                        Totals const& _totals,\n                        std::string const& _stdOut,\n                        std::string const& _stdErr,\n                        bool _aborting )\n        : testInfo( _testInfo ),\n            totals( _totals ),\n            stdOut( _stdOut ),\n            stdErr( _stdErr ),\n            aborting( _aborting )\n        {}\n        virtual ~TestCaseStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestCaseStats( TestCaseStats const& )              = default;\n        TestCaseStats( TestCaseStats && )                  = default;\n        TestCaseStats& operator = ( TestCaseStats const& ) = default;\n        TestCaseStats& operator = ( TestCaseStats && )     = default;\n#  endif\n\n        TestCaseInfo testInfo;\n        Totals totals;\n        std::string stdOut;\n        std::string stdErr;\n        bool aborting;\n    };\n\n    struct TestGroupStats {\n        TestGroupStats( GroupInfo const& _groupInfo,\n                        Totals const& _totals,\n                        bool _aborting )\n        :   groupInfo( _groupInfo ),\n            totals( _totals ),\n            aborting( _aborting )\n        {}\n        TestGroupStats( GroupInfo const& _groupInfo )\n        :   groupInfo( _groupInfo ),\n            aborting( false )\n        {}\n        virtual ~TestGroupStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestGroupStats( TestGroupStats const& )              = default;\n        TestGroupStats( TestGroupStats && )                  = default;\n        TestGroupStats& operator = ( TestGroupStats const& ) = default;\n        TestGroupStats& operator = ( TestGroupStats && )     = default;\n#  endif\n\n        GroupInfo groupInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    struct TestRunStats {\n        TestRunStats(   TestRunInfo const& _runInfo,\n                        Totals const& _totals,\n                        bool _aborting )\n        :   runInfo( _runInfo ),\n            totals( _totals ),\n            aborting( _aborting )\n        {}\n        virtual ~TestRunStats();\n\n#  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestRunStats( TestRunStats const& _other )\n        :   runInfo( _other.runInfo ),\n            totals( _other.totals ),\n            aborting( _other.aborting )\n        {}\n#  else\n        TestRunStats( TestRunStats const& )              = default;\n        TestRunStats( TestRunStats && )                  = default;\n        TestRunStats& operator = ( TestRunStats const& ) = default;\n        TestRunStats& operator = ( TestRunStats && )     = default;\n#  endif\n\n        TestRunInfo runInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    class MultipleReporters;\n\n    struct IStreamingReporter : IShared {\n        virtual ~IStreamingReporter();\n\n        // Implementing class must also provide the following static method:\n        // static std::string getDescription();\n\n        virtual ReporterPreferences getPreferences() const = 0;\n\n        virtual void noMatchingTestCases( std::string const& spec ) = 0;\n\n        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;\n\n        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;\n\n        // The return value indicates if the messages buffer should be cleared:\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;\n        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;\n\n        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;\n\n        virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }\n    };\n\n    struct IReporterFactory : IShared {\n        virtual ~IReporterFactory();\n        virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;\n        virtual std::string getDescription() const = 0;\n    };\n\n    struct IReporterRegistry {\n        typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;\n        typedef std::vector<Ptr<IReporterFactory> > Listeners;\n\n        virtual ~IReporterRegistry();\n        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;\n        virtual FactoryMap const& getFactories() const = 0;\n        virtual Listeners const& getListeners() const = 0;\n    };\n\n    Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );\n\n}\n\n#include <limits>\n#include <algorithm>\n\nnamespace Catch {\n\n    inline std::size_t listTests( Config const& config ) {\n\n        TestSpec testSpec = config.testSpec();\n        if( config.testSpec().hasFilters() )\n            Catch::cout() << \"Matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available test cases:\\n\";\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        }\n\n        std::size_t matchedTests = 0;\n        TextAttributes nameAttr, tagsAttr;\n        nameAttr.setInitialIndent( 2 ).setIndent( 4 );\n        tagsAttr.setIndent( 6 );\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            matchedTests++;\n            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();\n            Colour::Code colour = testCaseInfo.isHidden()\n                ? Colour::SecondaryText\n                : Colour::None;\n            Colour colourGuard( colour );\n\n            Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;\n            if( !testCaseInfo.tags.empty() )\n                Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;\n        }\n\n        if( !config.testSpec().hasFilters() )\n            Catch::cout() << pluralise( matchedTests, \"test case\" ) << \"\\n\" << std::endl;\n        else\n            Catch::cout() << pluralise( matchedTests, \"matching test case\" ) << \"\\n\" << std::endl;\n        return matchedTests;\n    }\n\n    inline std::size_t listTestsNamesOnly( Config const& config ) {\n        TestSpec testSpec = config.testSpec();\n        if( !config.testSpec().hasFilters() )\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        std::size_t matchedTests = 0;\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            matchedTests++;\n            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();\n            if( startsWith( testCaseInfo.name, \"#\" ) )\n               Catch::cout() << \"\\\"\" << testCaseInfo.name << \"\\\"\" << std::endl;\n            else\n               Catch::cout() << testCaseInfo.name << std::endl;\n        }\n        return matchedTests;\n    }\n\n    struct TagInfo {\n        TagInfo() : count ( 0 ) {}\n        void add( std::string const& spelling ) {\n            ++count;\n            spellings.insert( spelling );\n        }\n        std::string all() const {\n            std::string out;\n            for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();\n                        it != itEnd;\n                        ++it )\n                out += \"[\" + *it + \"]\";\n            return out;\n        }\n        std::set<std::string> spellings;\n        std::size_t count;\n    };\n\n    inline std::size_t listTags( Config const& config ) {\n        TestSpec testSpec = config.testSpec();\n        if( config.testSpec().hasFilters() )\n            Catch::cout() << \"Tags for matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available tags:\\n\";\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        }\n\n        std::map<std::string, TagInfo> tagCounts;\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),\n                                                        tagItEnd = it->getTestCaseInfo().tags.end();\n                    tagIt != tagItEnd;\n                    ++tagIt ) {\n                std::string tagName = *tagIt;\n                std::string lcaseTagName = toLower( tagName );\n                std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );\n                if( countIt == tagCounts.end() )\n                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;\n                countIt->second.add( tagName );\n            }\n        }\n\n        for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),\n                                                            countItEnd = tagCounts.end();\n                countIt != countItEnd;\n                ++countIt ) {\n            std::ostringstream oss;\n            oss << \"  \" << std::setw(2) << countIt->second.count << \"  \";\n            Text wrapper( countIt->second.all(), TextAttributes()\n                                                    .setInitialIndent( 0 )\n                                                    .setIndent( oss.str().size() )\n                                                    .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );\n            Catch::cout() << oss.str() << wrapper << \"\\n\";\n        }\n        Catch::cout() << pluralise( tagCounts.size(), \"tag\" ) << \"\\n\" << std::endl;\n        return tagCounts.size();\n    }\n\n    inline std::size_t listReporters( Config const& /*config*/ ) {\n        Catch::cout() << \"Available reporters:\\n\";\n        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n        IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;\n        std::size_t maxNameLen = 0;\n        for(it = itBegin; it != itEnd; ++it )\n            maxNameLen = (std::max)( maxNameLen, it->first.size() );\n\n        for(it = itBegin; it != itEnd; ++it ) {\n            Text wrapper( it->second->getDescription(), TextAttributes()\n                                                        .setInitialIndent( 0 )\n                                                        .setIndent( 7+maxNameLen )\n                                                        .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );\n            Catch::cout() << \"  \"\n                    << it->first\n                    << \":\"\n                    << std::string( maxNameLen - it->first.size() + 2, ' ' )\n                    << wrapper << \"\\n\";\n        }\n        Catch::cout() << std::endl;\n        return factories.size();\n    }\n\n    inline Option<std::size_t> list( Config const& config ) {\n        Option<std::size_t> listedCount;\n        if( config.listTests() )\n            listedCount = listedCount.valueOr(0) + listTests( config );\n        if( config.listTestNamesOnly() )\n            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );\n        if( config.listTags() )\n            listedCount = listedCount.valueOr(0) + listTags( config );\n        if( config.listReporters() )\n            listedCount = listedCount.valueOr(0) + listReporters( config );\n        return listedCount;\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_run_context.hpp\n#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED\n\n// #included from: catch_test_case_tracker.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED\n\n#include <map>\n#include <string>\n#include <assert.h>\n#include <vector>\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    struct ITracker : SharedImpl<> {\n        virtual ~ITracker();\n\n        // static queries\n        virtual std::string name() const = 0;\n\n        // dynamic queries\n        virtual bool isComplete() const = 0; // Successfully completed or failed\n        virtual bool isSuccessfullyCompleted() const = 0;\n        virtual bool isOpen() const = 0; // Started but not complete\n        virtual bool hasChildren() const = 0;\n\n        virtual ITracker& parent() = 0;\n\n        // actions\n        virtual void close() = 0; // Successfully complete\n        virtual void fail() = 0;\n        virtual void markAsNeedingAnotherRun() = 0;\n\n        virtual void addChild( Ptr<ITracker> const& child ) = 0;\n        virtual ITracker* findChild( std::string const& name ) = 0;\n        virtual void openChild() = 0;\n\n        // Debug/ checking\n        virtual bool isSectionTracker() const = 0;\n        virtual bool isIndexTracker() const = 0;\n    };\n\n    class TrackerContext {\n\n        enum RunState {\n            NotStarted,\n            Executing,\n            CompletedCycle\n        };\n\n        Ptr<ITracker> m_rootTracker;\n        ITracker* m_currentTracker;\n        RunState m_runState;\n\n    public:\n\n        static TrackerContext& instance() {\n            static TrackerContext s_instance;\n            return s_instance;\n        }\n\n        TrackerContext()\n        :   m_currentTracker( CATCH_NULL ),\n            m_runState( NotStarted )\n        {}\n\n        ITracker& startRun();\n\n        void endRun() {\n            m_rootTracker.reset();\n            m_currentTracker = CATCH_NULL;\n            m_runState = NotStarted;\n        }\n\n        void startCycle() {\n            m_currentTracker = m_rootTracker.get();\n            m_runState = Executing;\n        }\n        void completeCycle() {\n            m_runState = CompletedCycle;\n        }\n\n        bool completedCycle() const {\n            return m_runState == CompletedCycle;\n        }\n        ITracker& currentTracker() {\n            return *m_currentTracker;\n        }\n        void setCurrentTracker( ITracker* tracker ) {\n            m_currentTracker = tracker;\n        }\n    };\n\n    class TrackerBase : public ITracker {\n    protected:\n        enum CycleState {\n            NotStarted,\n            Executing,\n            ExecutingChildren,\n            NeedsAnotherRun,\n            CompletedSuccessfully,\n            Failed\n        };\n        class TrackerHasName {\n            std::string m_name;\n        public:\n            TrackerHasName( std::string const& name ) : m_name( name ) {}\n            bool operator ()( Ptr<ITracker> const& tracker ) {\n                return tracker->name() == m_name;\n            }\n        };\n        typedef std::vector<Ptr<ITracker> > Children;\n        std::string m_name;\n        TrackerContext& m_ctx;\n        ITracker* m_parent;\n        Children m_children;\n        CycleState m_runState;\n    public:\n        TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )\n        :   m_name( name ),\n            m_ctx( ctx ),\n            m_parent( parent ),\n            m_runState( NotStarted )\n        {}\n        virtual ~TrackerBase();\n\n        virtual std::string name() const CATCH_OVERRIDE {\n            return m_name;\n        }\n        virtual bool isComplete() const CATCH_OVERRIDE {\n            return m_runState == CompletedSuccessfully || m_runState == Failed;\n        }\n        virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {\n            return m_runState == CompletedSuccessfully;\n        }\n        virtual bool isOpen() const CATCH_OVERRIDE {\n            return m_runState != NotStarted && !isComplete();\n        }\n        virtual bool hasChildren() const CATCH_OVERRIDE {\n            return !m_children.empty();\n        }\n\n        virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {\n            m_children.push_back( child );\n        }\n\n        virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {\n            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );\n            return( it != m_children.end() )\n                ? it->get()\n                : CATCH_NULL;\n        }\n        virtual ITracker& parent() CATCH_OVERRIDE {\n            assert( m_parent ); // Should always be non-null except for root\n            return *m_parent;\n        }\n\n        virtual void openChild() CATCH_OVERRIDE {\n            if( m_runState != ExecutingChildren ) {\n                m_runState = ExecutingChildren;\n                if( m_parent )\n                    m_parent->openChild();\n            }\n        }\n\n        virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }\n        virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }\n\n        void open() {\n            m_runState = Executing;\n            moveToThis();\n            if( m_parent )\n                m_parent->openChild();\n        }\n\n        virtual void close() CATCH_OVERRIDE {\n\n            // Close any still open children (e.g. generators)\n            while( &m_ctx.currentTracker() != this )\n                m_ctx.currentTracker().close();\n\n            switch( m_runState ) {\n                case NotStarted:\n                case CompletedSuccessfully:\n                case Failed:\n                    throw std::logic_error( \"Illogical state\" );\n\n                case NeedsAnotherRun:\n                    break;;\n\n                case Executing:\n                    m_runState = CompletedSuccessfully;\n                    break;\n                case ExecutingChildren:\n                    if( m_children.empty() || m_children.back()->isComplete() )\n                        m_runState = CompletedSuccessfully;\n                    break;\n\n                default:\n                    throw std::logic_error( \"Unexpected state\" );\n            }\n            moveToParent();\n            m_ctx.completeCycle();\n        }\n        virtual void fail() CATCH_OVERRIDE {\n            m_runState = Failed;\n            if( m_parent )\n                m_parent->markAsNeedingAnotherRun();\n            moveToParent();\n            m_ctx.completeCycle();\n        }\n        virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {\n            m_runState = NeedsAnotherRun;\n        }\n    private:\n        void moveToParent() {\n            assert( m_parent );\n            m_ctx.setCurrentTracker( m_parent );\n        }\n        void moveToThis() {\n            m_ctx.setCurrentTracker( this );\n        }\n    };\n\n    class SectionTracker : public TrackerBase {\n    public:\n        SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )\n        :   TrackerBase( name, ctx, parent )\n        {}\n        virtual ~SectionTracker();\n\n        virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }\n\n        static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {\n            SectionTracker* section = CATCH_NULL;\n\n            ITracker& currentTracker = ctx.currentTracker();\n            if( ITracker* childTracker = currentTracker.findChild( name ) ) {\n                assert( childTracker );\n                assert( childTracker->isSectionTracker() );\n                section = static_cast<SectionTracker*>( childTracker );\n            }\n            else {\n                section = new SectionTracker( name, ctx, &currentTracker );\n                currentTracker.addChild( section );\n            }\n            if( !ctx.completedCycle() && !section->isComplete() ) {\n\n                section->open();\n            }\n            return *section;\n        }\n    };\n\n    class IndexTracker : public TrackerBase {\n        int m_size;\n        int m_index;\n    public:\n        IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )\n        :   TrackerBase( name, ctx, parent ),\n            m_size( size ),\n            m_index( -1 )\n        {}\n        virtual ~IndexTracker();\n\n        virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }\n\n        static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {\n            IndexTracker* tracker = CATCH_NULL;\n\n            ITracker& currentTracker = ctx.currentTracker();\n            if( ITracker* childTracker = currentTracker.findChild( name ) ) {\n                assert( childTracker );\n                assert( childTracker->isIndexTracker() );\n                tracker = static_cast<IndexTracker*>( childTracker );\n            }\n            else {\n                tracker = new IndexTracker( name, ctx, &currentTracker, size );\n                currentTracker.addChild( tracker );\n            }\n\n            if( !ctx.completedCycle() && !tracker->isComplete() ) {\n                if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )\n                    tracker->moveNext();\n                tracker->open();\n            }\n\n            return *tracker;\n        }\n\n        int index() const { return m_index; }\n\n        void moveNext() {\n            m_index++;\n            m_children.clear();\n        }\n\n        virtual void close() CATCH_OVERRIDE {\n            TrackerBase::close();\n            if( m_runState == CompletedSuccessfully && m_index < m_size-1 )\n                m_runState = Executing;\n        }\n    };\n\n    inline ITracker& TrackerContext::startRun() {\n        m_rootTracker = new SectionTracker( \"{root}\", *this, CATCH_NULL );\n        m_currentTracker = CATCH_NULL;\n        m_runState = Executing;\n        return *m_rootTracker;\n    }\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\nusing TestCaseTracking::IndexTracker;\n\n} // namespace Catch\n\n// #included from: catch_fatal_condition.hpp\n#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED\n\nnamespace Catch {\n\n    // Report the error condition then exit the process\n    inline void fatal( std::string const& message, int exitCode ) {\n        IContext& context = Catch::getCurrentContext();\n        IResultCapture* resultCapture = context.getResultCapture();\n        resultCapture->handleFatalErrorCondition( message );\n\n\t\tif( Catch::alwaysTrue() ) // avoids \"no return\" warnings\n            exit( exitCode );\n    }\n\n} // namespace Catch\n\n#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////\n\nnamespace Catch {\n\n    struct FatalConditionHandler {\n\t\tvoid reset() {}\n\t};\n\n} // namespace Catch\n\n#else // Not Windows - assumed to be POSIX compatible //////////////////////////\n\n#include <signal.h>\n\nnamespace Catch {\n\n    struct SignalDefs { int id; const char* name; };\n    extern SignalDefs signalDefs[];\n    SignalDefs signalDefs[] = {\n            { SIGINT,  \"SIGINT - Terminal interrupt signal\" },\n            { SIGILL,  \"SIGILL - Illegal instruction signal\" },\n            { SIGFPE,  \"SIGFPE - Floating point error signal\" },\n            { SIGSEGV, \"SIGSEGV - Segmentation violation signal\" },\n            { SIGTERM, \"SIGTERM - Termination request signal\" },\n            { SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\" }\n        };\n\n    struct FatalConditionHandler {\n\n        static void handleSignal( int sig ) {\n            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                if( sig == signalDefs[i].id )\n                    fatal( signalDefs[i].name, -sig );\n            fatal( \"<unknown signal>\", -sig );\n        }\n\n        FatalConditionHandler() : m_isSet( true ) {\n            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                signal( signalDefs[i].id, handleSignal );\n        }\n        ~FatalConditionHandler() {\n            reset();\n        }\n        void reset() {\n            if( m_isSet ) {\n                for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                    signal( signalDefs[i].id, SIG_DFL );\n                m_isSet = false;\n            }\n        }\n\n        bool m_isSet;\n    };\n\n} // namespace Catch\n\n#endif // not Windows\n\n#include <set>\n#include <string>\n\nnamespace Catch {\n\n    class StreamRedirect {\n\n    public:\n        StreamRedirect( std::ostream& stream, std::string& targetString )\n        :   m_stream( stream ),\n            m_prevBuf( stream.rdbuf() ),\n            m_targetString( targetString )\n        {\n            stream.rdbuf( m_oss.rdbuf() );\n        }\n\n        ~StreamRedirect() {\n            m_targetString += m_oss.str();\n            m_stream.rdbuf( m_prevBuf );\n        }\n\n    private:\n        std::ostream& m_stream;\n        std::streambuf* m_prevBuf;\n        std::ostringstream m_oss;\n        std::string& m_targetString;\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class RunContext : public IResultCapture, public IRunner {\n\n        RunContext( RunContext const& );\n        void operator =( RunContext const& );\n\n    public:\n\n        explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )\n        :   m_runInfo( _config->name() ),\n            m_context( getCurrentMutableContext() ),\n            m_activeTestCase( CATCH_NULL ),\n            m_config( _config ),\n            m_reporter( reporter )\n        {\n            m_context.setRunner( this );\n            m_context.setConfig( m_config );\n            m_context.setResultCapture( this );\n            m_reporter->testRunStarting( m_runInfo );\n        }\n\n        virtual ~RunContext() {\n            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );\n        }\n\n        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {\n            m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );\n        }\n        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {\n            m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );\n        }\n\n        Totals runTest( TestCase const& testCase ) {\n            Totals prevTotals = m_totals;\n\n            std::string redirectedCout;\n            std::string redirectedCerr;\n\n            TestCaseInfo testInfo = testCase.getTestCaseInfo();\n\n            m_reporter->testCaseStarting( testInfo );\n\n            m_activeTestCase = &testCase;\n\n            do {\n                m_trackerContext.startRun();\n                do {\n                    m_trackerContext.startCycle();\n                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );\n                    runCurrentTest( redirectedCout, redirectedCerr );\n                }\n                while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );\n            }\n            // !TBD: deprecated - this will be replaced by indexed trackers\n            while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );\n\n            Totals deltaTotals = m_totals.delta( prevTotals );\n            if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {\n                deltaTotals.assertions.failed++;\n                deltaTotals.testCases.passed--;\n                deltaTotals.testCases.failed++;\n            }\n            m_totals.testCases += deltaTotals.testCases;\n            m_reporter->testCaseEnded( TestCaseStats(   testInfo,\n                                                        deltaTotals,\n                                                        redirectedCout,\n                                                        redirectedCerr,\n                                                        aborting() ) );\n\n            m_activeTestCase = CATCH_NULL;\n            m_testCaseTracker = CATCH_NULL;\n\n            return deltaTotals;\n        }\n\n        Ptr<IConfig const> config() const {\n            return m_config;\n        }\n\n    private: // IResultCapture\n\n        virtual void assertionEnded( AssertionResult const& result ) {\n            if( result.getResultType() == ResultWas::Ok ) {\n                m_totals.assertions.passed++;\n            }\n            else if( !result.isOk() ) {\n                m_totals.assertions.failed++;\n            }\n\n            if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )\n                m_messages.clear();\n\n            // Reset working state\n            m_lastAssertionInfo = AssertionInfo( \"\", m_lastAssertionInfo.lineInfo, \"{Unknown expression after the reported line}\" , m_lastAssertionInfo.resultDisposition );\n            m_lastResult = result;\n        }\n\n        virtual bool sectionStarted (\n            SectionInfo const& sectionInfo,\n            Counts& assertions\n        )\n        {\n            std::ostringstream oss;\n            oss << sectionInfo.name << \"@\" << sectionInfo.lineInfo;\n\n            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );\n            if( !sectionTracker.isOpen() )\n                return false;\n            m_activeSections.push_back( &sectionTracker );\n\n            m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;\n\n            m_reporter->sectionStarting( sectionInfo );\n\n            assertions = m_totals.assertions;\n\n            return true;\n        }\n        bool testForMissingAssertions( Counts& assertions ) {\n            if( assertions.total() != 0 )\n                return false;\n            if( !m_config->warnAboutMissingAssertions() )\n                return false;\n            if( m_trackerContext.currentTracker().hasChildren() )\n                return false;\n            m_totals.assertions.failed++;\n            assertions.failed++;\n            return true;\n        }\n\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) {\n            Counts assertions = m_totals.assertions - endInfo.prevAssertions;\n            bool missingAssertions = testForMissingAssertions( assertions );\n\n            if( !m_activeSections.empty() ) {\n                m_activeSections.back()->close();\n                m_activeSections.pop_back();\n            }\n\n            m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );\n            m_messages.clear();\n        }\n\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {\n            if( m_unfinishedSections.empty() )\n                m_activeSections.back()->fail();\n            else\n                m_activeSections.back()->close();\n            m_activeSections.pop_back();\n\n            m_unfinishedSections.push_back( endInfo );\n        }\n\n        virtual void pushScopedMessage( MessageInfo const& message ) {\n            m_messages.push_back( message );\n        }\n\n        virtual void popScopedMessage( MessageInfo const& message ) {\n            m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );\n        }\n\n        virtual std::string getCurrentTestName() const {\n            return m_activeTestCase\n                ? m_activeTestCase->getTestCaseInfo().name\n                : \"\";\n        }\n\n        virtual const AssertionResult* getLastResult() const {\n            return &m_lastResult;\n        }\n\n        virtual void handleFatalErrorCondition( std::string const& message ) {\n            ResultBuilder resultBuilder = makeUnexpectedResultBuilder();\n            resultBuilder.setResultType( ResultWas::FatalErrorCondition );\n            resultBuilder << message;\n            resultBuilder.captureExpression();\n\n            handleUnfinishedSections();\n\n            // Recreate section for test case (as we will lose the one that was in scope)\n            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );\n\n            Counts assertions;\n            assertions.failed = 1;\n            SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );\n            m_reporter->sectionEnded( testCaseSectionStats );\n\n            TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();\n\n            Totals deltaTotals;\n            deltaTotals.testCases.failed = 1;\n            m_reporter->testCaseEnded( TestCaseStats(   testInfo,\n                                                        deltaTotals,\n                                                        \"\",\n                                                        \"\",\n                                                        false ) );\n            m_totals.testCases.failed++;\n            testGroupEnded( \"\", m_totals, 1, 1 );\n            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );\n        }\n\n    public:\n        // !TBD We need to do this another way!\n        bool aborting() const {\n            return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );\n        }\n\n    private:\n\n        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {\n            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );\n            m_reporter->sectionStarting( testCaseSection );\n            Counts prevAssertions = m_totals.assertions;\n            double duration = 0;\n            try {\n                m_lastAssertionInfo = AssertionInfo( \"TEST_CASE\", testCaseInfo.lineInfo, \"\", ResultDisposition::Normal );\n\n                seedRng( *m_config );\n\n                Timer timer;\n                timer.start();\n                if( m_reporter->getPreferences().shouldRedirectStdOut ) {\n                    StreamRedirect coutRedir( Catch::cout(), redirectedCout );\n                    StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );\n                    invokeActiveTestCase();\n                }\n                else {\n                    invokeActiveTestCase();\n                }\n                duration = timer.getElapsedSeconds();\n            }\n            catch( TestFailureException& ) {\n                // This just means the test was aborted due to failure\n            }\n            catch(...) {\n                makeUnexpectedResultBuilder().useActiveException();\n            }\n            m_testCaseTracker->close();\n            handleUnfinishedSections();\n            m_messages.clear();\n\n            Counts assertions = m_totals.assertions - prevAssertions;\n            bool missingAssertions = testForMissingAssertions( assertions );\n\n            if( testCaseInfo.okToFail() ) {\n                std::swap( assertions.failedButOk, assertions.failed );\n                m_totals.assertions.failed -= assertions.failedButOk;\n                m_totals.assertions.failedButOk += assertions.failedButOk;\n            }\n\n            SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );\n            m_reporter->sectionEnded( testCaseSectionStats );\n        }\n\n        void invokeActiveTestCase() {\n            FatalConditionHandler fatalConditionHandler; // Handle signals\n            m_activeTestCase->invoke();\n            fatalConditionHandler.reset();\n        }\n\n    private:\n\n        ResultBuilder makeUnexpectedResultBuilder() const {\n            return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),\n                                    m_lastAssertionInfo.lineInfo,\n                                    m_lastAssertionInfo.capturedExpression.c_str(),\n                                    m_lastAssertionInfo.resultDisposition );\n        }\n\n        void handleUnfinishedSections() {\n            // If sections ended prematurely due to an exception we stored their\n            // infos here so we can tear them down outside the unwind process.\n            for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),\n                        itEnd = m_unfinishedSections.rend();\n                    it != itEnd;\n                    ++it )\n                sectionEnded( *it );\n            m_unfinishedSections.clear();\n        }\n\n        TestRunInfo m_runInfo;\n        IMutableContext& m_context;\n        TestCase const* m_activeTestCase;\n        ITracker* m_testCaseTracker;\n        ITracker* m_currentSectionTracker;\n        AssertionResult m_lastResult;\n\n        Ptr<IConfig const> m_config;\n        Totals m_totals;\n        Ptr<IStreamingReporter> m_reporter;\n        std::vector<MessageInfo> m_messages;\n        AssertionInfo m_lastAssertionInfo;\n        std::vector<SectionEndInfo> m_unfinishedSections;\n        std::vector<ITracker*> m_activeSections;\n        TrackerContext m_trackerContext;\n    };\n\n    IResultCapture& getResultCapture() {\n        if( IResultCapture* capture = getCurrentContext().getResultCapture() )\n            return *capture;\n        else\n            throw std::logic_error( \"No result capture instance\" );\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_version.h\n#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED\n\nnamespace Catch {\n\n    // Versioning information\n    struct Version {\n        Version(    unsigned int _majorVersion,\n                    unsigned int _minorVersion,\n                    unsigned int _patchNumber,\n                    std::string const& _branchName,\n                    unsigned int _buildNumber );\n\n        unsigned int const majorVersion;\n        unsigned int const minorVersion;\n        unsigned int const patchNumber;\n\n        // buildNumber is only used if branchName is not null\n        std::string const branchName;\n        unsigned int const buildNumber;\n\n        friend std::ostream& operator << ( std::ostream& os, Version const& version );\n\n    private:\n        void operator=( Version const& );\n    };\n\n    extern Version libraryVersion;\n}\n\n#include <fstream>\n#include <stdlib.h>\n#include <limits>\n\nnamespace Catch {\n\n    Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {\n        Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );\n        if( !reporter ) {\n            std::ostringstream oss;\n            oss << \"No reporter registered with name: '\" << reporterName << \"'\";\n            throw std::domain_error( oss.str() );\n        }\n        return reporter;\n    }\n\n    Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {\n        std::vector<std::string> reporters = config->getReporterNames();\n        if( reporters.empty() )\n            reporters.push_back( \"console\" );\n\n        Ptr<IStreamingReporter> reporter;\n        for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();\n                it != itEnd;\n                ++it )\n            reporter = addReporter( reporter, createReporter( *it, config ) );\n        return reporter;\n    }\n    Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {\n        IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();\n        for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();\n                it != itEnd;\n                ++it )\n            reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );\n        return reporters;\n    }\n\n    Totals runTests( Ptr<Config> const& config ) {\n\n        Ptr<IConfig const> iconfig = config.get();\n\n        Ptr<IStreamingReporter> reporter = makeReporter( config );\n        reporter = addListeners( iconfig, reporter );\n\n        RunContext context( iconfig, reporter );\n\n        Totals totals;\n\n        context.testGroupStarting( config->name(), 1, 1 );\n\n        TestSpec testSpec = config->testSpec();\n        if( !testSpec.hasFilters() )\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"~[.]\" ).testSpec(); // All not hidden tests\n\n        std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );\n        for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();\n                it != itEnd;\n                ++it ) {\n            if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )\n                totals += context.runTest( *it );\n            else\n                reporter->skipTest( *it );\n        }\n\n        context.testGroupEnded( iconfig->name(), totals, 1, 1 );\n        return totals;\n    }\n\n    void applyFilenamesAsTags( IConfig const& config ) {\n        std::vector<TestCase> const& tests = getAllTestCasesSorted( config );\n        for(std::size_t i = 0; i < tests.size(); ++i ) {\n            TestCase& test = const_cast<TestCase&>( tests[i] );\n            std::set<std::string> tags = test.tags;\n\n            std::string filename = test.lineInfo.file;\n            std::string::size_type lastSlash = filename.find_last_of( \"\\\\/\" );\n            if( lastSlash != std::string::npos )\n                filename = filename.substr( lastSlash+1 );\n\n            std::string::size_type lastDot = filename.find_last_of( \".\" );\n            if( lastDot != std::string::npos )\n                filename = filename.substr( 0, lastDot );\n\n            tags.insert( \"#\" + filename );\n            setTags( test, tags );\n        }\n    }\n\n    class Session : NonCopyable {\n        static bool alreadyInstantiated;\n\n    public:\n\n        struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };\n\n        Session()\n        : m_cli( makeCommandLineParser() ) {\n            if( alreadyInstantiated ) {\n                std::string msg = \"Only one instance of Catch::Session can ever be used\";\n                Catch::cerr() << msg << std::endl;\n                throw std::logic_error( msg );\n            }\n            alreadyInstantiated = true;\n        }\n        ~Session() {\n            Catch::cleanUp();\n        }\n\n        void showHelp( std::string const& processName ) {\n            Catch::cout() << \"\\nCatch v\" << libraryVersion << \"\\n\";\n\n            m_cli.usage( Catch::cout(), processName );\n            Catch::cout() << \"For more detail usage please see the project docs\\n\" << std::endl;\n        }\n\n        int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {\n            try {\n                m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );\n                m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );\n                if( m_configData.showHelp )\n                    showHelp( m_configData.processName );\n                m_config.reset();\n            }\n            catch( std::exception& ex ) {\n                {\n                    Colour colourGuard( Colour::Red );\n                    Catch::cerr()\n                        << \"\\nError(s) in input:\\n\"\n                        << Text( ex.what(), TextAttributes().setIndent(2) )\n                        << \"\\n\\n\";\n                }\n                m_cli.usage( Catch::cout(), m_configData.processName );\n                return (std::numeric_limits<int>::max)();\n            }\n            return 0;\n        }\n\n        void useConfigData( ConfigData const& _configData ) {\n            m_configData = _configData;\n            m_config.reset();\n        }\n\n        int run( int argc, char const* const* const argv ) {\n\n            int returnCode = applyCommandLine( argc, argv );\n            if( returnCode == 0 )\n                returnCode = run();\n            return returnCode;\n        }\n\n        int run() {\n            if( m_configData.showHelp )\n                return 0;\n\n            try\n            {\n                config(); // Force config to be constructed\n\n                seedRng( *m_config );\n\n                if( m_configData.filenamesAsTags )\n                    applyFilenamesAsTags( *m_config );\n\n                // Handle list request\n                if( Option<std::size_t> listed = list( config() ) )\n                    return static_cast<int>( *listed );\n\n                return static_cast<int>( runTests( m_config ).assertions.failed );\n            }\n            catch( std::exception& ex ) {\n                Catch::cerr() << ex.what() << std::endl;\n                return (std::numeric_limits<int>::max)();\n            }\n        }\n\n        Clara::CommandLine<ConfigData> const& cli() const {\n            return m_cli;\n        }\n        std::vector<Clara::Parser::Token> const& unusedTokens() const {\n            return m_unusedTokens;\n        }\n        ConfigData& configData() {\n            return m_configData;\n        }\n        Config& config() {\n            if( !m_config )\n                m_config = new Config( m_configData );\n            return *m_config;\n        }\n    private:\n        Clara::CommandLine<ConfigData> m_cli;\n        std::vector<Clara::Parser::Token> m_unusedTokens;\n        ConfigData m_configData;\n        Ptr<Config> m_config;\n    };\n\n    bool Session::alreadyInstantiated = false;\n\n} // end namespace Catch\n\n// #included from: catch_registry_hub.hpp\n#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED\n\n// #included from: catch_test_case_registry_impl.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED\n\n#include <vector>\n#include <set>\n#include <sstream>\n#include <iostream>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct RandomNumberGenerator {\n        typedef std::ptrdiff_t result_type;\n\n        result_type operator()( result_type n ) const { return std::rand() % n; }\n\n#ifdef CATCH_CONFIG_CPP11_SHUFFLE\n        static constexpr result_type min() { return 0; }\n        static constexpr result_type max() { return 1000000; }\n        result_type operator()() const { return std::rand() % max(); }\n#endif\n        template<typename V>\n        static void shuffle( V& vector ) {\n            RandomNumberGenerator rng;\n#ifdef CATCH_CONFIG_CPP11_SHUFFLE\n            std::shuffle( vector.begin(), vector.end(), rng );\n#else\n            std::random_shuffle( vector.begin(), vector.end(), rng );\n#endif\n        }\n    };\n\n    inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {\n\n        std::vector<TestCase> sorted = unsortedTestCases;\n\n        switch( config.runOrder() ) {\n            case RunTests::InLexicographicalOrder:\n                std::sort( sorted.begin(), sorted.end() );\n                break;\n            case RunTests::InRandomOrder:\n                {\n                    seedRng( config );\n                    RandomNumberGenerator::shuffle( sorted );\n                }\n                break;\n            case RunTests::InDeclarationOrder:\n                // already in declaration order\n                break;\n        }\n        return sorted;\n    }\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {\n        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );\n    }\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {\n        std::set<TestCase> seenFunctions;\n        for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();\n            it != itEnd;\n            ++it ) {\n            std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );\n            if( !prev.second ) {\n                std::ostringstream ss;\n\n                ss  << Colour( Colour::Red )\n                    << \"error: TEST_CASE( \\\"\" << it->name << \"\\\" ) already defined.\\n\"\n                    << \"\\tFirst seen at \" << prev.first->getTestCaseInfo().lineInfo << \"\\n\"\n                    << \"\\tRedefined at \" << it->getTestCaseInfo().lineInfo << std::endl;\n\n                throw std::runtime_error(ss.str());\n            }\n        }\n    }\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {\n        std::vector<TestCase> filtered;\n        filtered.reserve( testCases.size() );\n        for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();\n                it != itEnd;\n                ++it )\n            if( matchTest( *it, testSpec, config ) )\n                filtered.push_back( *it );\n        return filtered;\n    }\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {\n        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );\n    }\n\n    class TestRegistry : public ITestCaseRegistry {\n    public:\n        TestRegistry()\n        :   m_currentSortOrder( RunTests::InDeclarationOrder ),\n            m_unnamedCount( 0 )\n        {}\n        virtual ~TestRegistry();\n\n        virtual void registerTest( TestCase const& testCase ) {\n            std::string name = testCase.getTestCaseInfo().name;\n            if( name == \"\" ) {\n                std::ostringstream oss;\n                oss << \"Anonymous test case \" << ++m_unnamedCount;\n                return registerTest( testCase.withName( oss.str() ) );\n            }\n            m_functions.push_back( testCase );\n        }\n\n        virtual std::vector<TestCase> const& getAllTests() const {\n            return m_functions;\n        }\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {\n            if( m_sortedFunctions.empty() )\n                enforceNoDuplicateTestCases( m_functions );\n\n            if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {\n                m_sortedFunctions = sortTests( config, m_functions );\n                m_currentSortOrder = config.runOrder();\n            }\n            return m_sortedFunctions;\n        }\n\n    private:\n        std::vector<TestCase> m_functions;\n        mutable RunTests::InWhatOrder m_currentSortOrder;\n        mutable std::vector<TestCase> m_sortedFunctions;\n        size_t m_unnamedCount;\n        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class FreeFunctionTestCase : public SharedImpl<ITestCase> {\n    public:\n\n        FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}\n\n        virtual void invoke() const {\n            m_fun();\n        }\n\n    private:\n        virtual ~FreeFunctionTestCase();\n\n        TestFunction m_fun;\n    };\n\n    inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {\n        std::string className = classOrQualifiedMethodName;\n        if( startsWith( className, \"&\" ) )\n        {\n            std::size_t lastColons = className.rfind( \"::\" );\n            std::size_t penultimateColons = className.rfind( \"::\", lastColons-1 );\n            if( penultimateColons == std::string::npos )\n                penultimateColons = 1;\n            className = className.substr( penultimateColons, lastColons-penultimateColons );\n        }\n        return className;\n    }\n\n    void registerTestCase\n        (   ITestCase* testCase,\n            char const* classOrQualifiedMethodName,\n            NameAndDesc const& nameAndDesc,\n            SourceLineInfo const& lineInfo ) {\n\n        getMutableRegistryHub().registerTest\n            ( makeTestCase\n                (   testCase,\n                    extractClassName( classOrQualifiedMethodName ),\n                    nameAndDesc.name,\n                    nameAndDesc.description,\n                    lineInfo ) );\n    }\n    void registerTestCaseFunction\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc ) {\n        registerTestCase( new FreeFunctionTestCase( function ), \"\", nameAndDesc, lineInfo );\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    AutoReg::AutoReg\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc ) {\n        registerTestCaseFunction( function, lineInfo, nameAndDesc );\n    }\n\n    AutoReg::~AutoReg() {}\n\n} // end namespace Catch\n\n// #included from: catch_reporter_registry.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED\n\n#include <map>\n\nnamespace Catch {\n\n    class ReporterRegistry : public IReporterRegistry {\n\n    public:\n\n        virtual ~ReporterRegistry() CATCH_OVERRIDE {}\n\n        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {\n            FactoryMap::const_iterator it =  m_factories.find( name );\n            if( it == m_factories.end() )\n                return CATCH_NULL;\n            return it->second->create( ReporterConfig( config ) );\n        }\n\n        void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {\n            m_factories.insert( std::make_pair( name, factory ) );\n        }\n        void registerListener( Ptr<IReporterFactory> const& factory ) {\n            m_listeners.push_back( factory );\n        }\n\n        virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {\n            return m_factories;\n        }\n        virtual Listeners const& getListeners() const CATCH_OVERRIDE {\n            return m_listeners;\n        }\n\n    private:\n        FactoryMap m_factories;\n        Listeners m_listeners;\n    };\n}\n\n// #included from: catch_exception_translator_registry.hpp\n#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED\n\n#ifdef __OBJC__\n#import \"Foundation/Foundation.h\"\n#endif\n\nnamespace Catch {\n\n    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {\n    public:\n        ~ExceptionTranslatorRegistry() {\n            deleteAll( m_translators );\n        }\n\n        virtual void registerTranslator( const IExceptionTranslator* translator ) {\n            m_translators.push_back( translator );\n        }\n\n        virtual std::string translateActiveException() const {\n            try {\n#ifdef __OBJC__\n                // In Objective-C try objective-c exceptions first\n                @try {\n                    return tryTranslators();\n                }\n                @catch (NSException *exception) {\n                    return Catch::toString( [exception description] );\n                }\n#else\n                return tryTranslators();\n#endif\n            }\n            catch( TestFailureException& ) {\n                throw;\n            }\n            catch( std::exception& ex ) {\n                return ex.what();\n            }\n            catch( std::string& msg ) {\n                return msg;\n            }\n            catch( const char* msg ) {\n                return msg;\n            }\n            catch(...) {\n                return \"Unknown exception\";\n            }\n        }\n\n        std::string tryTranslators() const {\n            if( m_translators.empty() )\n                throw;\n            else\n                return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );\n        }\n\n    private:\n        std::vector<const IExceptionTranslator*> m_translators;\n    };\n}\n\nnamespace Catch {\n\n    namespace {\n\n        class RegistryHub : public IRegistryHub, public IMutableRegistryHub {\n\n            RegistryHub( RegistryHub const& );\n            void operator=( RegistryHub const& );\n\n        public: // IRegistryHub\n            RegistryHub() {\n            }\n            virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {\n                return m_reporterRegistry;\n            }\n            virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {\n                return m_testCaseRegistry;\n            }\n            virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {\n                return m_exceptionTranslatorRegistry;\n            }\n\n        public: // IMutableRegistryHub\n            virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {\n                m_reporterRegistry.registerReporter( name, factory );\n            }\n            virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {\n                m_reporterRegistry.registerListener( factory );\n            }\n            virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {\n                m_testCaseRegistry.registerTest( testInfo );\n            }\n            virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {\n                m_exceptionTranslatorRegistry.registerTranslator( translator );\n            }\n\n        private:\n            TestRegistry m_testCaseRegistry;\n            ReporterRegistry m_reporterRegistry;\n            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;\n        };\n\n        // Single, global, instance\n        inline RegistryHub*& getTheRegistryHub() {\n            static RegistryHub* theRegistryHub = CATCH_NULL;\n            if( !theRegistryHub )\n                theRegistryHub = new RegistryHub();\n            return theRegistryHub;\n        }\n    }\n\n    IRegistryHub& getRegistryHub() {\n        return *getTheRegistryHub();\n    }\n    IMutableRegistryHub& getMutableRegistryHub() {\n        return *getTheRegistryHub();\n    }\n    void cleanUp() {\n        delete getTheRegistryHub();\n        getTheRegistryHub() = CATCH_NULL;\n        cleanUpContext();\n    }\n    std::string translateActiveException() {\n        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_notimplemented_exception.hpp\n#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED\n\n#include <ostream>\n\nnamespace Catch {\n\n    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )\n    :   m_lineInfo( lineInfo ) {\n        std::ostringstream oss;\n        oss << lineInfo << \": function \";\n        oss << \"not implemented\";\n        m_what = oss.str();\n    }\n\n    const char* NotImplementedException::what() const CATCH_NOEXCEPT {\n        return m_what.c_str();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_context_impl.hpp\n#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED\n\n// #included from: catch_stream.hpp\n#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED\n\n#include <stdexcept>\n#include <cstdio>\n#include <iostream>\n\nnamespace Catch {\n\n    template<typename WriterF, size_t bufferSize=256>\n    class StreamBufImpl : public StreamBufBase {\n        char data[bufferSize];\n        WriterF m_writer;\n\n    public:\n        StreamBufImpl() {\n            setp( data, data + sizeof(data) );\n        }\n\n        ~StreamBufImpl() CATCH_NOEXCEPT {\n            sync();\n        }\n\n    private:\n        int overflow( int c ) {\n            sync();\n\n            if( c != EOF ) {\n                if( pbase() == epptr() )\n                    m_writer( std::string( 1, static_cast<char>( c ) ) );\n                else\n                    sputc( static_cast<char>( c ) );\n            }\n            return 0;\n        }\n\n        int sync() {\n            if( pbase() != pptr() ) {\n                m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );\n                setp( pbase(), epptr() );\n            }\n            return 0;\n        }\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    FileStream::FileStream( std::string const& filename ) {\n        m_ofs.open( filename.c_str() );\n        if( m_ofs.fail() ) {\n            std::ostringstream oss;\n            oss << \"Unable to open file: '\" << filename << \"'\";\n            throw std::domain_error( oss.str() );\n        }\n    }\n\n    std::ostream& FileStream::stream() const {\n        return m_ofs;\n    }\n\n    struct OutputDebugWriter {\n\n        void operator()( std::string const&str ) {\n            writeToDebugConsole( str );\n        }\n    };\n\n    DebugOutStream::DebugOutStream()\n    :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),\n        m_os( m_streamBuf.get() )\n    {}\n\n    std::ostream& DebugOutStream::stream() const {\n        return m_os;\n    }\n\n    // Store the streambuf from cout up-front because\n    // cout may get redirected when running tests\n    CoutStream::CoutStream()\n    :   m_os( Catch::cout().rdbuf() )\n    {}\n\n    std::ostream& CoutStream::stream() const {\n        return m_os;\n    }\n\n#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions\n    std::ostream& cout() {\n        return std::cout;\n    }\n    std::ostream& cerr() {\n        return std::cerr;\n    }\n#endif\n}\n\nnamespace Catch {\n\n    class Context : public IMutableContext {\n\n        Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}\n        Context( Context const& );\n        void operator=( Context const& );\n\n    public:\n        virtual ~Context() {\n            deleteAllValues( m_generatorsByTestName );\n        }\n\n    public: // IContext\n        virtual IResultCapture* getResultCapture() {\n            return m_resultCapture;\n        }\n        virtual IRunner* getRunner() {\n            return m_runner;\n        }\n        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {\n            return getGeneratorsForCurrentTest()\n            .getGeneratorInfo( fileInfo, totalSize )\n            .getCurrentIndex();\n        }\n        virtual bool advanceGeneratorsForCurrentTest() {\n            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();\n            return generators && generators->moveNext();\n        }\n\n        virtual Ptr<IConfig const> getConfig() const {\n            return m_config;\n        }\n\n    public: // IMutableContext\n        virtual void setResultCapture( IResultCapture* resultCapture ) {\n            m_resultCapture = resultCapture;\n        }\n        virtual void setRunner( IRunner* runner ) {\n            m_runner = runner;\n        }\n        virtual void setConfig( Ptr<IConfig const> const& config ) {\n            m_config = config;\n        }\n\n        friend IMutableContext& getCurrentMutableContext();\n\n    private:\n        IGeneratorsForTest* findGeneratorsForCurrentTest() {\n            std::string testName = getResultCapture()->getCurrentTestName();\n\n            std::map<std::string, IGeneratorsForTest*>::const_iterator it =\n                m_generatorsByTestName.find( testName );\n            return it != m_generatorsByTestName.end()\n                ? it->second\n                : CATCH_NULL;\n        }\n\n        IGeneratorsForTest& getGeneratorsForCurrentTest() {\n            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();\n            if( !generators ) {\n                std::string testName = getResultCapture()->getCurrentTestName();\n                generators = createGeneratorsForTest();\n                m_generatorsByTestName.insert( std::make_pair( testName, generators ) );\n            }\n            return *generators;\n        }\n\n    private:\n        Ptr<IConfig const> m_config;\n        IRunner* m_runner;\n        IResultCapture* m_resultCapture;\n        std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;\n    };\n\n    namespace {\n        Context* currentContext = CATCH_NULL;\n    }\n    IMutableContext& getCurrentMutableContext() {\n        if( !currentContext )\n            currentContext = new Context();\n        return *currentContext;\n    }\n    IContext& getCurrentContext() {\n        return getCurrentMutableContext();\n    }\n\n    void cleanUpContext() {\n        delete currentContext;\n        currentContext = CATCH_NULL;\n    }\n}\n\n// #included from: catch_console_colour_impl.hpp\n#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED\n\nnamespace Catch {\n    namespace {\n\n        struct IColourImpl {\n            virtual ~IColourImpl() {}\n            virtual void use( Colour::Code _colourCode ) = 0;\n        };\n\n        struct NoColourImpl : IColourImpl {\n            void use( Colour::Code ) {}\n\n            static IColourImpl* instance() {\n                static NoColourImpl s_instance;\n                return &s_instance;\n            }\n        };\n\n    } // anon namespace\n} // namespace Catch\n\n#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )\n#   ifdef CATCH_PLATFORM_WINDOWS\n#       define CATCH_CONFIG_COLOUR_WINDOWS\n#   else\n#       define CATCH_CONFIG_COLOUR_ANSI\n#   endif\n#endif\n\n#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////\n\n// #included from: catch_windows_h_proxy.h\n\n#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED\n\n#ifdef CATCH_DEFINES_NOMINMAX\n#  define NOMINMAX\n#endif\n#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef CATCH_DEFINES_NOMINMAX\n#  undef NOMINMAX\n#endif\n#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  undef WIN32_LEAN_AND_MEAN\n#endif\n\nnamespace Catch {\nnamespace {\n\n    class Win32ColourImpl : public IColourImpl {\n    public:\n        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )\n        {\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );\n            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );\n            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );\n        }\n\n        virtual void use( Colour::Code _colourCode ) {\n            switch( _colourCode ) {\n                case Colour::None:      return setTextAttribute( originalForegroundAttributes );\n                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );\n                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );\n                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );\n                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );\n                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );\n                case Colour::Grey:      return setTextAttribute( 0 );\n\n                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );\n                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );\n                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );\n                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n\n                case Colour::Bright: throw std::logic_error( \"not a colour\" );\n            }\n        }\n\n    private:\n        void setTextAttribute( WORD _textAttribute ) {\n            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );\n        }\n        HANDLE stdoutHandle;\n        WORD originalForegroundAttributes;\n        WORD originalBackgroundAttributes;\n    };\n\n    IColourImpl* platformColourInstance() {\n        static Win32ColourImpl s_instance;\n\n        Ptr<IConfig const> config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = !isDebuggerActive()\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? &s_instance\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////\n\n#include <unistd.h>\n\nnamespace Catch {\nnamespace {\n\n    // use POSIX/ ANSI console terminal codes\n    // Thanks to Adam Strzelecki for original contribution\n    // (http://github.com/nanoant)\n    // https://github.com/philsquared/Catch/pull/131\n    class PosixColourImpl : public IColourImpl {\n    public:\n        virtual void use( Colour::Code _colourCode ) {\n            switch( _colourCode ) {\n                case Colour::None:\n                case Colour::White:     return setColour( \"[0m\" );\n                case Colour::Red:       return setColour( \"[0;31m\" );\n                case Colour::Green:     return setColour( \"[0;32m\" );\n                case Colour::Blue:      return setColour( \"[0;34m\" );\n                case Colour::Cyan:      return setColour( \"[0;36m\" );\n                case Colour::Yellow:    return setColour( \"[0;33m\" );\n                case Colour::Grey:      return setColour( \"[1;30m\" );\n\n                case Colour::LightGrey:     return setColour( \"[0;37m\" );\n                case Colour::BrightRed:     return setColour( \"[1;31m\" );\n                case Colour::BrightGreen:   return setColour( \"[1;32m\" );\n                case Colour::BrightWhite:   return setColour( \"[1;37m\" );\n\n                case Colour::Bright: throw std::logic_error( \"not a colour\" );\n            }\n        }\n        static IColourImpl* instance() {\n            static PosixColourImpl s_instance;\n            return &s_instance;\n        }\n\n    private:\n        void setColour( const char* _escapeCode ) {\n            Catch::cout() << '\\033' << _escapeCode;\n        }\n    };\n\n    IColourImpl* platformColourInstance() {\n        Ptr<IConfig const> config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? PosixColourImpl::instance()\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#else  // not Windows or ANSI ///////////////////////////////////////////////\n\nnamespace Catch {\n\n    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }\n\n} // end namespace Catch\n\n#endif // Windows/ ANSI/ None\n\nnamespace Catch {\n\n    Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }\n    Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }\n    Colour::~Colour(){ if( !m_moved ) use( None ); }\n\n    void Colour::use( Code _colourCode ) {\n        static IColourImpl* impl = platformColourInstance();\n        impl->use( _colourCode );\n    }\n\n} // end namespace Catch\n\n// #included from: catch_generators_impl.hpp\n#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED\n\n#include <vector>\n#include <string>\n#include <map>\n\nnamespace Catch {\n\n    struct GeneratorInfo : IGeneratorInfo {\n\n        GeneratorInfo( std::size_t size )\n        :   m_size( size ),\n            m_currentIndex( 0 )\n        {}\n\n        bool moveNext() {\n            if( ++m_currentIndex == m_size ) {\n                m_currentIndex = 0;\n                return false;\n            }\n            return true;\n        }\n\n        std::size_t getCurrentIndex() const {\n            return m_currentIndex;\n        }\n\n        std::size_t m_size;\n        std::size_t m_currentIndex;\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class GeneratorsForTest : public IGeneratorsForTest {\n\n    public:\n        ~GeneratorsForTest() {\n            deleteAll( m_generatorsInOrder );\n        }\n\n        IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {\n            std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );\n            if( it == m_generatorsByName.end() ) {\n                IGeneratorInfo* info = new GeneratorInfo( size );\n                m_generatorsByName.insert( std::make_pair( fileInfo, info ) );\n                m_generatorsInOrder.push_back( info );\n                return *info;\n            }\n            return *it->second;\n        }\n\n        bool moveNext() {\n            std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();\n            std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();\n            for(; it != itEnd; ++it ) {\n                if( (*it)->moveNext() )\n                    return true;\n            }\n            return false;\n        }\n\n    private:\n        std::map<std::string, IGeneratorInfo*> m_generatorsByName;\n        std::vector<IGeneratorInfo*> m_generatorsInOrder;\n    };\n\n    IGeneratorsForTest* createGeneratorsForTest()\n    {\n        return new GeneratorsForTest();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_assertionresult.hpp\n#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED\n\nnamespace Catch {\n\n    AssertionInfo::AssertionInfo(   std::string const& _macroName,\n                                    SourceLineInfo const& _lineInfo,\n                                    std::string const& _capturedExpression,\n                                    ResultDisposition::Flags _resultDisposition )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        capturedExpression( _capturedExpression ),\n        resultDisposition( _resultDisposition )\n    {}\n\n    AssertionResult::AssertionResult() {}\n\n    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )\n    :   m_info( info ),\n        m_resultData( data )\n    {}\n\n    AssertionResult::~AssertionResult() {}\n\n    // Result was a success\n    bool AssertionResult::succeeded() const {\n        return Catch::isOk( m_resultData.resultType );\n    }\n\n    // Result was a success, or failure is suppressed\n    bool AssertionResult::isOk() const {\n        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );\n    }\n\n    ResultWas::OfType AssertionResult::getResultType() const {\n        return m_resultData.resultType;\n    }\n\n    bool AssertionResult::hasExpression() const {\n        return !m_info.capturedExpression.empty();\n    }\n\n    bool AssertionResult::hasMessage() const {\n        return !m_resultData.message.empty();\n    }\n\n    std::string AssertionResult::getExpression() const {\n        if( isFalseTest( m_info.resultDisposition ) )\n            return \"!\" + m_info.capturedExpression;\n        else\n            return m_info.capturedExpression;\n    }\n    std::string AssertionResult::getExpressionInMacro() const {\n        if( m_info.macroName.empty() )\n            return m_info.capturedExpression;\n        else\n            return m_info.macroName + \"( \" + m_info.capturedExpression + \" )\";\n    }\n\n    bool AssertionResult::hasExpandedExpression() const {\n        return hasExpression() && getExpandedExpression() != getExpression();\n    }\n\n    std::string AssertionResult::getExpandedExpression() const {\n        return m_resultData.reconstructedExpression;\n    }\n\n    std::string AssertionResult::getMessage() const {\n        return m_resultData.message;\n    }\n    SourceLineInfo AssertionResult::getSourceInfo() const {\n        return m_info.lineInfo;\n    }\n\n    std::string AssertionResult::getTestMacroName() const {\n        return m_info.macroName;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_test_case_info.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED\n\nnamespace Catch {\n\n    inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {\n        if( startsWith( tag, \".\" ) ||\n            tag == \"hide\" ||\n            tag == \"!hide\" )\n            return TestCaseInfo::IsHidden;\n        else if( tag == \"!throws\" )\n            return TestCaseInfo::Throws;\n        else if( tag == \"!shouldfail\" )\n            return TestCaseInfo::ShouldFail;\n        else if( tag == \"!mayfail\" )\n            return TestCaseInfo::MayFail;\n        else\n            return TestCaseInfo::None;\n    }\n    inline bool isReservedTag( std::string const& tag ) {\n        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );\n    }\n    inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {\n        if( isReservedTag( tag ) ) {\n            {\n                Colour colourGuard( Colour::Red );\n                Catch::cerr()\n                    << \"Tag name [\" << tag << \"] not allowed.\\n\"\n                    << \"Tag names starting with non alpha-numeric characters are reserved\\n\";\n            }\n            {\n                Colour colourGuard( Colour::FileName );\n                Catch::cerr() << _lineInfo << std::endl;\n            }\n            exit(1);\n        }\n    }\n\n    TestCase makeTestCase(  ITestCase* _testCase,\n                            std::string const& _className,\n                            std::string const& _name,\n                            std::string const& _descOrTags,\n                            SourceLineInfo const& _lineInfo )\n    {\n        bool isHidden( startsWith( _name, \"./\" ) ); // Legacy support\n\n        // Parse out tags\n        std::set<std::string> tags;\n        std::string desc, tag;\n        bool inTag = false;\n        for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {\n            char c = _descOrTags[i];\n            if( !inTag ) {\n                if( c == '[' )\n                    inTag = true;\n                else\n                    desc += c;\n            }\n            else {\n                if( c == ']' ) {\n                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );\n                    if( prop == TestCaseInfo::IsHidden )\n                        isHidden = true;\n                    else if( prop == TestCaseInfo::None )\n                        enforceNotReservedTag( tag, _lineInfo );\n\n                    tags.insert( tag );\n                    tag.clear();\n                    inTag = false;\n                }\n                else\n                    tag += c;\n            }\n        }\n        if( isHidden ) {\n            tags.insert( \"hide\" );\n            tags.insert( \".\" );\n        }\n\n        TestCaseInfo info( _name, _className, desc, tags, _lineInfo );\n        return TestCase( _testCase, info );\n    }\n\n    void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )\n    {\n        testCaseInfo.tags = tags;\n        testCaseInfo.lcaseTags.clear();\n\n        std::ostringstream oss;\n        for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {\n            oss << \"[\" << *it << \"]\";\n            std::string lcaseTag = toLower( *it );\n            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );\n            testCaseInfo.lcaseTags.insert( lcaseTag );\n        }\n        testCaseInfo.tagsAsString = oss.str();\n    }\n\n    TestCaseInfo::TestCaseInfo( std::string const& _name,\n                                std::string const& _className,\n                                std::string const& _description,\n                                std::set<std::string> const& _tags,\n                                SourceLineInfo const& _lineInfo )\n    :   name( _name ),\n        className( _className ),\n        description( _description ),\n        lineInfo( _lineInfo ),\n        properties( None )\n    {\n        setTags( *this, _tags );\n    }\n\n    TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )\n    :   name( other.name ),\n        className( other.className ),\n        description( other.description ),\n        tags( other.tags ),\n        lcaseTags( other.lcaseTags ),\n        tagsAsString( other.tagsAsString ),\n        lineInfo( other.lineInfo ),\n        properties( other.properties )\n    {}\n\n    bool TestCaseInfo::isHidden() const {\n        return ( properties & IsHidden ) != 0;\n    }\n    bool TestCaseInfo::throws() const {\n        return ( properties & Throws ) != 0;\n    }\n    bool TestCaseInfo::okToFail() const {\n        return ( properties & (ShouldFail | MayFail ) ) != 0;\n    }\n    bool TestCaseInfo::expectedToFail() const {\n        return ( properties & (ShouldFail ) ) != 0;\n    }\n\n    TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}\n\n    TestCase::TestCase( TestCase const& other )\n    :   TestCaseInfo( other ),\n        test( other.test )\n    {}\n\n    TestCase TestCase::withName( std::string const& _newName ) const {\n        TestCase other( *this );\n        other.name = _newName;\n        return other;\n    }\n\n    void TestCase::swap( TestCase& other ) {\n        test.swap( other.test );\n        name.swap( other.name );\n        className.swap( other.className );\n        description.swap( other.description );\n        tags.swap( other.tags );\n        lcaseTags.swap( other.lcaseTags );\n        tagsAsString.swap( other.tagsAsString );\n        std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );\n        std::swap( lineInfo, other.lineInfo );\n    }\n\n    void TestCase::invoke() const {\n        test->invoke();\n    }\n\n    bool TestCase::operator == ( TestCase const& other ) const {\n        return  test.get() == other.test.get() &&\n                name == other.name &&\n                className == other.className;\n    }\n\n    bool TestCase::operator < ( TestCase const& other ) const {\n        return name < other.name;\n    }\n    TestCase& TestCase::operator = ( TestCase const& other ) {\n        TestCase temp( other );\n        swap( temp );\n        return *this;\n    }\n\n    TestCaseInfo const& TestCase::getTestCaseInfo() const\n    {\n        return *this;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_version.hpp\n#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED\n\nnamespace Catch {\n\n    Version::Version\n        (   unsigned int _majorVersion,\n            unsigned int _minorVersion,\n            unsigned int _patchNumber,\n            std::string const& _branchName,\n            unsigned int _buildNumber )\n    :   majorVersion( _majorVersion ),\n        minorVersion( _minorVersion ),\n        patchNumber( _patchNumber ),\n        branchName( _branchName ),\n        buildNumber( _buildNumber )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, Version const& version ) {\n        os  << version.majorVersion << \".\"\n            << version.minorVersion << \".\"\n            << version.patchNumber;\n\n        if( !version.branchName.empty() ) {\n            os  << \"-\" << version.branchName\n                << \".\" << version.buildNumber;\n        }\n        return os;\n    }\n\n    Version libraryVersion( 1, 6, 1, \"\", 0 );\n\n}\n\n// #included from: catch_message.hpp\n#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED\n\nnamespace Catch {\n\n    MessageInfo::MessageInfo(   std::string const& _macroName,\n                                SourceLineInfo const& _lineInfo,\n                                ResultWas::OfType _type )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        type( _type ),\n        sequence( ++globalCount )\n    {}\n\n    // This may need protecting if threading support is added\n    unsigned int MessageInfo::globalCount = 0;\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    ScopedMessage::ScopedMessage( MessageBuilder const& builder )\n    : m_info( builder.m_info )\n    {\n        m_info.message = builder.m_stream.str();\n        getResultCapture().pushScopedMessage( m_info );\n    }\n    ScopedMessage::ScopedMessage( ScopedMessage const& other )\n    : m_info( other.m_info )\n    {}\n\n    ScopedMessage::~ScopedMessage() {\n        getResultCapture().popScopedMessage( m_info );\n    }\n\n} // end namespace Catch\n\n// #included from: catch_legacy_reporter_adapter.hpp\n#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED\n\n// #included from: catch_legacy_reporter_adapter.h\n#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED\n\nnamespace Catch\n{\n    // Deprecated\n    struct IReporter : IShared {\n        virtual ~IReporter();\n\n        virtual bool shouldRedirectStdout() const = 0;\n\n        virtual void StartTesting() = 0;\n        virtual void EndTesting( Totals const& totals ) = 0;\n        virtual void StartGroup( std::string const& groupName ) = 0;\n        virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;\n        virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;\n        virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;\n        virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;\n        virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;\n        virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;\n        virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;\n        virtual void Aborted() = 0;\n        virtual void Result( AssertionResult const& result ) = 0;\n    };\n\n    class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>\n    {\n    public:\n        LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );\n        virtual ~LegacyReporterAdapter();\n\n        virtual ReporterPreferences getPreferences() const;\n        virtual void noMatchingTestCases( std::string const& );\n        virtual void testRunStarting( TestRunInfo const& );\n        virtual void testGroupStarting( GroupInfo const& groupInfo );\n        virtual void testCaseStarting( TestCaseInfo const& testInfo );\n        virtual void sectionStarting( SectionInfo const& sectionInfo );\n        virtual void assertionStarting( AssertionInfo const& );\n        virtual bool assertionEnded( AssertionStats const& assertionStats );\n        virtual void sectionEnded( SectionStats const& sectionStats );\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats );\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats );\n        virtual void testRunEnded( TestRunStats const& testRunStats );\n        virtual void skipTest( TestCaseInfo const& );\n\n    private:\n        Ptr<IReporter> m_legacyReporter;\n    };\n}\n\nnamespace Catch\n{\n    LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )\n    :   m_legacyReporter( legacyReporter )\n    {}\n    LegacyReporterAdapter::~LegacyReporterAdapter() {}\n\n    ReporterPreferences LegacyReporterAdapter::getPreferences() const {\n        ReporterPreferences prefs;\n        prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();\n        return prefs;\n    }\n\n    void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}\n    void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {\n        m_legacyReporter->StartTesting();\n    }\n    void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {\n        m_legacyReporter->StartGroup( groupInfo.name );\n    }\n    void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        m_legacyReporter->StartTestCase( testInfo );\n    }\n    void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {\n        m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );\n    }\n    void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {\n        // Not on legacy interface\n    }\n\n    bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {\n        if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {\n            for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();\n                    it != itEnd;\n                    ++it ) {\n                if( it->type == ResultWas::Info ) {\n                    ResultBuilder rb( it->macroName.c_str(), it->lineInfo, \"\", ResultDisposition::Normal );\n                    rb << it->message;\n                    rb.setResultType( ResultWas::Info );\n                    AssertionResult result = rb.build();\n                    m_legacyReporter->Result( result );\n                }\n            }\n        }\n        m_legacyReporter->Result( assertionStats.assertionResult );\n        return true;\n    }\n    void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {\n        if( sectionStats.missingAssertions )\n            m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );\n        m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );\n    }\n    void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        m_legacyReporter->EndTestCase\n            (   testCaseStats.testInfo,\n                testCaseStats.totals,\n                testCaseStats.stdOut,\n                testCaseStats.stdErr );\n    }\n    void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        if( testGroupStats.aborting )\n            m_legacyReporter->Aborted();\n        m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );\n    }\n    void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {\n        m_legacyReporter->EndTesting( testRunStats.totals );\n    }\n    void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {\n    }\n}\n\n// #included from: catch_timer.hpp\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wc++11-long-long\"\n#endif\n\n#ifdef CATCH_PLATFORM_WINDOWS\n#else\n#include <sys/time.h>\n#endif\n\nnamespace Catch {\n\n    namespace {\n#ifdef CATCH_PLATFORM_WINDOWS\n        uint64_t getCurrentTicks() {\n            static uint64_t hz=0, hzo=0;\n            if (!hz) {\n                QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );\n                QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );\n            }\n            uint64_t t;\n            QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );\n            return ((t-hzo)*1000000)/hz;\n        }\n#else\n        uint64_t getCurrentTicks() {\n            timeval t;\n            gettimeofday(&t,CATCH_NULL);\n            return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );\n        }\n#endif\n    }\n\n    void Timer::start() {\n        m_ticks = getCurrentTicks();\n    }\n    unsigned int Timer::getElapsedMicroseconds() const {\n        return static_cast<unsigned int>(getCurrentTicks() - m_ticks);\n    }\n    unsigned int Timer::getElapsedMilliseconds() const {\n        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);\n    }\n    double Timer::getElapsedSeconds() const {\n        return getElapsedMicroseconds()/1000000.0;\n    }\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n// #included from: catch_common.hpp\n#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED\n\nnamespace Catch {\n\n    bool startsWith( std::string const& s, std::string const& prefix ) {\n        return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;\n    }\n    bool endsWith( std::string const& s, std::string const& suffix ) {\n        return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;\n    }\n    bool contains( std::string const& s, std::string const& infix ) {\n        return s.find( infix ) != std::string::npos;\n    }\n    char toLowerCh(char c) {\n        return static_cast<char>( ::tolower( c ) );\n    }\n    void toLowerInPlace( std::string& s ) {\n        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );\n    }\n    std::string toLower( std::string const& s ) {\n        std::string lc = s;\n        toLowerInPlace( lc );\n        return lc;\n    }\n    std::string trim( std::string const& str ) {\n        static char const* whitespaceChars = \"\\n\\r\\t \";\n        std::string::size_type start = str.find_first_not_of( whitespaceChars );\n        std::string::size_type end = str.find_last_not_of( whitespaceChars );\n\n        return start != std::string::npos ? str.substr( start, 1+end-start ) : \"\";\n    }\n\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {\n        bool replaced = false;\n        std::size_t i = str.find( replaceThis );\n        while( i != std::string::npos ) {\n            replaced = true;\n            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );\n            if( i < str.size()-withThis.size() )\n                i = str.find( replaceThis, i+withThis.size() );\n            else\n                i = std::string::npos;\n        }\n        return replaced;\n    }\n\n    pluralise::pluralise( std::size_t count, std::string const& label )\n    :   m_count( count ),\n        m_label( label )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {\n        os << pluraliser.m_count << \" \" << pluraliser.m_label;\n        if( pluraliser.m_count != 1 )\n            os << \"s\";\n        return os;\n    }\n\n    SourceLineInfo::SourceLineInfo() : line( 0 ){}\n    SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )\n    :   file( _file ),\n        line( _line )\n    {}\n    SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )\n    :   file( other.file ),\n        line( other.line )\n    {}\n    bool SourceLineInfo::empty() const {\n        return file.empty();\n    }\n    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {\n        return line == other.line && file == other.file;\n    }\n    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {\n        return line < other.line || ( line == other.line  && file < other.file );\n    }\n\n    void seedRng( IConfig const& config ) {\n        if( config.rngSeed() != 0 )\n            std::srand( config.rngSeed() );\n    }\n    unsigned int rngSeed() {\n        return getCurrentContext().getConfig()->rngSeed();\n    }\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {\n#ifndef __GNUG__\n        os << info.file << \"(\" << info.line << \")\";\n#else\n        os << info.file << \":\" << info.line;\n#endif\n        return os;\n    }\n\n    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {\n        std::ostringstream oss;\n        oss << locationInfo << \": Internal Catch error: '\" << message << \"'\";\n        if( alwaysTrue() )\n            throw std::logic_error( oss.str() );\n    }\n}\n\n// #included from: catch_section.hpp\n#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED\n\nnamespace Catch {\n\n    SectionInfo::SectionInfo\n        (   SourceLineInfo const& _lineInfo,\n            std::string const& _name,\n            std::string const& _description )\n    :   name( _name ),\n        description( _description ),\n        lineInfo( _lineInfo )\n    {}\n\n    Section::Section( SectionInfo const& info )\n    :   m_info( info ),\n        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )\n    {\n        m_timer.start();\n    }\n\n    Section::~Section() {\n        if( m_sectionIncluded ) {\n            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );\n            if( std::uncaught_exception() )\n                getResultCapture().sectionEndedEarly( endInfo );\n            else\n                getResultCapture().sectionEnded( endInfo );\n        }\n    }\n\n    // This indicates whether the section should be executed or not\n    Section::operator bool() const {\n        return m_sectionIncluded;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_debugger.hpp\n#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED\n\n#include <iostream>\n\n#ifdef CATCH_PLATFORM_MAC\n\n    #include <assert.h>\n    #include <stdbool.h>\n    #include <sys/types.h>\n    #include <unistd.h>\n    #include <sys/sysctl.h>\n\n    namespace Catch{\n\n        // The following function is taken directly from the following technical note:\n        // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html\n\n        // Returns true if the current process is being debugged (either\n        // running under the debugger or has a debugger attached post facto).\n        bool isDebuggerActive(){\n\n            int                 mib[4];\n            struct kinfo_proc   info;\n            size_t              size;\n\n            // Initialize the flags so that, if sysctl fails for some bizarre\n            // reason, we get a predictable result.\n\n            info.kp_proc.p_flag = 0;\n\n            // Initialize mib, which tells sysctl the info we want, in this case\n            // we're looking for information about a specific process ID.\n\n            mib[0] = CTL_KERN;\n            mib[1] = KERN_PROC;\n            mib[2] = KERN_PROC_PID;\n            mib[3] = getpid();\n\n            // Call sysctl.\n\n            size = sizeof(info);\n            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {\n                Catch::cerr() << \"\\n** Call to sysctl failed - unable to determine if debugger is active **\\n\" << std::endl;\n                return false;\n            }\n\n            // We're being debugged if the P_TRACED flag is set.\n\n            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n        }\n    } // namespace Catch\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    #include <fstream>\n    #include <string>\n\n    namespace Catch{\n        // The standard POSIX way of detecting a debugger is to attempt to\n        // ptrace() the process, but this needs to be done from a child and not\n        // this process itself to still allow attaching to this process later\n        // if wanted, so is rather heavy. Under Linux we have the PID of the\n        // \"debugger\" (which doesn't need to be gdb, of course, it could also\n        // be strace, for example) in /proc/$PID/status, so just get it from\n        // there instead.\n        bool isDebuggerActive(){\n            std::ifstream in(\"/proc/self/status\");\n            for( std::string line; std::getline(in, line); ) {\n                static const int PREFIX_LEN = 11;\n                if( line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0 ) {\n                    // We're traced if the PID is not 0 and no other PID starts\n                    // with 0 digit, so it's enough to check for just a single\n                    // character.\n                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n                }\n            }\n\n            return false;\n        }\n    } // namespace Catch\n#elif defined(_MSC_VER)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#else\n    namespace Catch {\n       inline bool isDebuggerActive() { return false; }\n    }\n#endif // Platform\n\n#ifdef CATCH_PLATFORM_WINDOWS\n    extern \"C\" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            ::OutputDebugStringA( text.c_str() );\n        }\n    }\n#else\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            // !TBD: Need a version for Mac/ XCode and other IDEs\n            Catch::cout() << text;\n        }\n    }\n#endif // Platform\n\n// #included from: catch_tostring.hpp\n#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED\n\nnamespace Catch {\n\nnamespace Detail {\n\n    const std::string unprintableString = \"{?}\";\n\n    namespace {\n        const int hexThreshold = 255;\n\n        struct Endianness {\n            enum Arch { Big, Little };\n\n            static Arch which() {\n                union _{\n                    int asInt;\n                    char asChar[sizeof (int)];\n                } u;\n\n                u.asInt = 1;\n                return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;\n            }\n        };\n    }\n\n    std::string rawMemoryToString( const void *object, std::size_t size )\n    {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>( size ), inc = 1;\n        if( Endianness::which() == Endianness::Little ) {\n            i = end-1;\n            end = inc = -1;\n        }\n\n        unsigned char const *bytes = static_cast<unsigned char const *>(object);\n        std::ostringstream os;\n        os << \"0x\" << std::setfill('0') << std::hex;\n        for( ; i != end; i += inc )\n             os << std::setw(2) << static_cast<unsigned>(bytes[i]);\n       return os.str();\n    }\n}\n\nstd::string toString( std::string const& value ) {\n    std::string s = value;\n    if( getCurrentContext().getConfig()->showInvisibles() ) {\n        for(size_t i = 0; i < s.size(); ++i ) {\n            std::string subs;\n            switch( s[i] ) {\n            case '\\n': subs = \"\\\\n\"; break;\n            case '\\t': subs = \"\\\\t\"; break;\n            default: break;\n            }\n            if( !subs.empty() ) {\n                s = s.substr( 0, i ) + subs + s.substr( i+1 );\n                ++i;\n            }\n        }\n    }\n    return \"\\\"\" + s + \"\\\"\";\n}\nstd::string toString( std::wstring const& value ) {\n\n    std::string s;\n    s.reserve( value.size() );\n    for(size_t i = 0; i < value.size(); ++i )\n        s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';\n    return Catch::toString( s );\n}\n\nstd::string toString( const char* const value ) {\n    return value ? Catch::toString( std::string( value ) ) : std::string( \"{null string}\" );\n}\n\nstd::string toString( char* const value ) {\n    return Catch::toString( static_cast<const char*>( value ) );\n}\n\nstd::string toString( const wchar_t* const value )\n{\n\treturn value ? Catch::toString( std::wstring(value) ) : std::string( \"{null string}\" );\n}\n\nstd::string toString( wchar_t* const value )\n{\n\treturn Catch::toString( static_cast<const wchar_t*>( value ) );\n}\n\nstd::string toString( int value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n\nstd::string toString( unsigned long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n\nstd::string toString( unsigned int value ) {\n    return Catch::toString( static_cast<unsigned long>( value ) );\n}\n\ntemplate<typename T>\nstd::string fpToString( T value, int precision ) {\n    std::ostringstream oss;\n    oss << std::setprecision( precision )\n        << std::fixed\n        << value;\n    std::string d = oss.str();\n    std::size_t i = d.find_last_not_of( '0' );\n    if( i != std::string::npos && i != d.size()-1 ) {\n        if( d[i] == '.' )\n            i++;\n        d = d.substr( 0, i+1 );\n    }\n    return d;\n}\n\nstd::string toString( const double value ) {\n    return fpToString( value, 10 );\n}\nstd::string toString( const float value ) {\n    return fpToString( value, 5 ) + \"f\";\n}\n\nstd::string toString( bool value ) {\n    return value ? \"true\" : \"false\";\n}\n\nstd::string toString( char value ) {\n    return value < ' '\n        ? toString( static_cast<unsigned int>( value ) )\n        : Detail::makeString( value );\n}\n\nstd::string toString( signed char value ) {\n    return toString( static_cast<char>( value ) );\n}\n\nstd::string toString( unsigned char value ) {\n    return toString( static_cast<char>( value ) );\n}\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\nstd::string toString( long long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\nstd::string toString( unsigned long long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\nstd::string toString( std::nullptr_t ) {\n    return \"nullptr\";\n}\n#endif\n\n#ifdef __OBJC__\n    std::string toString( NSString const * const& nsstring ) {\n        if( !nsstring )\n            return \"nil\";\n        return \"@\" + toString([nsstring UTF8String]);\n    }\n    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {\n        if( !nsstring )\n            return \"nil\";\n        return \"@\" + toString([nsstring UTF8String]);\n    }\n    std::string toString( NSObject* const& nsObject ) {\n        return toString( [nsObject description] );\n    }\n#endif\n\n} // end namespace Catch\n\n// #included from: catch_result_builder.hpp\n#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED\n\nnamespace Catch {\n\n    std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {\n        return secondArg.empty() || secondArg == \"\\\"\\\"\"\n            ? capturedExpression\n            : capturedExpression + \", \" + secondArg;\n    }\n    ResultBuilder::ResultBuilder(   char const* macroName,\n                                    SourceLineInfo const& lineInfo,\n                                    char const* capturedExpression,\n                                    ResultDisposition::Flags resultDisposition,\n                                    char const* secondArg )\n    :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),\n        m_shouldDebugBreak( false ),\n        m_shouldThrow( false )\n    {}\n\n    ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {\n        m_data.resultType = result;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setResultType( bool result ) {\n        m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {\n        m_exprComponents.lhs = lhs;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {\n        m_exprComponents.rhs = rhs;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setOp( std::string const& op ) {\n        m_exprComponents.op = op;\n        return *this;\n    }\n\n    void ResultBuilder::endExpression() {\n        m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );\n        captureExpression();\n    }\n\n    void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {\n        m_assertionInfo.resultDisposition = resultDisposition;\n        m_stream.oss << Catch::translateActiveException();\n        captureResult( ResultWas::ThrewException );\n    }\n\n    void ResultBuilder::captureResult( ResultWas::OfType resultType ) {\n        setResultType( resultType );\n        captureExpression();\n    }\n    void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {\n        if( expectedMessage.empty() )\n            captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );\n        else\n            captureExpectedException( Matchers::Equals( expectedMessage ) );\n    }\n\n    void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {\n\n        assert( m_exprComponents.testFalse == false );\n        AssertionResultData data = m_data;\n        data.resultType = ResultWas::Ok;\n        data.reconstructedExpression = m_assertionInfo.capturedExpression;\n\n        std::string actualMessage = Catch::translateActiveException();\n        if( !matcher.match( actualMessage ) ) {\n            data.resultType = ResultWas::ExpressionFailed;\n            data.reconstructedExpression = actualMessage;\n        }\n        AssertionResult result( m_assertionInfo, data );\n        handleResult( result );\n    }\n\n    void ResultBuilder::captureExpression() {\n        AssertionResult result = build();\n        handleResult( result );\n    }\n    void ResultBuilder::handleResult( AssertionResult const& result )\n    {\n        getResultCapture().assertionEnded( result );\n\n        if( !result.isOk() ) {\n            if( getCurrentContext().getConfig()->shouldDebugBreak() )\n                m_shouldDebugBreak = true;\n            if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )\n                m_shouldThrow = true;\n        }\n    }\n    void ResultBuilder::react() {\n        if( m_shouldThrow )\n            throw Catch::TestFailureException();\n    }\n\n    bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }\n    bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }\n\n    AssertionResult ResultBuilder::build() const\n    {\n        assert( m_data.resultType != ResultWas::Unknown );\n\n        AssertionResultData data = m_data;\n\n        // Flip bool results if testFalse is set\n        if( m_exprComponents.testFalse ) {\n            if( data.resultType == ResultWas::Ok )\n                data.resultType = ResultWas::ExpressionFailed;\n            else if( data.resultType == ResultWas::ExpressionFailed )\n                data.resultType = ResultWas::Ok;\n        }\n\n        data.message = m_stream.oss.str();\n        data.reconstructedExpression = reconstructExpression();\n        if( m_exprComponents.testFalse ) {\n            if( m_exprComponents.op == \"\" )\n                data.reconstructedExpression = \"!\" + data.reconstructedExpression;\n            else\n                data.reconstructedExpression = \"!(\" + data.reconstructedExpression + \")\";\n        }\n        return AssertionResult( m_assertionInfo, data );\n    }\n    std::string ResultBuilder::reconstructExpression() const {\n        if( m_exprComponents.op == \"\" )\n            return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs;\n        else if( m_exprComponents.op == \"matches\" )\n            return m_exprComponents.lhs + \" \" + m_exprComponents.rhs;\n        else if( m_exprComponents.op != \"!\" ) {\n            if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&\n                m_exprComponents.lhs.find(\"\\n\") == std::string::npos &&\n                m_exprComponents.rhs.find(\"\\n\") == std::string::npos )\n                return m_exprComponents.lhs + \" \" + m_exprComponents.op + \" \" + m_exprComponents.rhs;\n            else\n                return m_exprComponents.lhs + \"\\n\" + m_exprComponents.op + \"\\n\" + m_exprComponents.rhs;\n        }\n        else\n            return \"{can't expand - use \" + m_assertionInfo.macroName + \"_FALSE( \" + m_assertionInfo.capturedExpression.substr(1) + \" ) instead of \" + m_assertionInfo.macroName + \"( \" + m_assertionInfo.capturedExpression + \" ) for better diagnostics}\";\n    }\n\n} // end namespace Catch\n\n// #included from: catch_tag_alias_registry.hpp\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED\n\n// #included from: catch_tag_alias_registry.h\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED\n\n#include <map>\n\nnamespace Catch {\n\n    class TagAliasRegistry : public ITagAliasRegistry {\n    public:\n        virtual ~TagAliasRegistry();\n        virtual Option<TagAlias> find( std::string const& alias ) const;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;\n        void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n        static TagAliasRegistry& get();\n\n    private:\n        std::map<std::string, TagAlias> m_registry;\n    };\n\n} // end namespace Catch\n\n#include <map>\n#include <iostream>\n\nnamespace Catch {\n\n    TagAliasRegistry::~TagAliasRegistry() {}\n\n    Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {\n        std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );\n        if( it != m_registry.end() )\n            return it->second;\n        else\n            return Option<TagAlias>();\n    }\n\n    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {\n        std::string expandedTestSpec = unexpandedTestSpec;\n        for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();\n                it != itEnd;\n                ++it ) {\n            std::size_t pos = expandedTestSpec.find( it->first );\n            if( pos != std::string::npos ) {\n                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +\n                                    it->second.tag +\n                                    expandedTestSpec.substr( pos + it->first.size() );\n            }\n        }\n        return expandedTestSpec;\n    }\n\n    void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {\n\n        if( !startsWith( alias, \"[@\" ) || !endsWith( alias, \"]\" ) ) {\n            std::ostringstream oss;\n            oss << \"error: tag alias, \\\"\" << alias << \"\\\" is not of the form [@alias name].\\n\" << lineInfo;\n            throw std::domain_error( oss.str().c_str() );\n        }\n        if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {\n            std::ostringstream oss;\n            oss << \"error: tag alias, \\\"\" << alias << \"\\\" already registered.\\n\"\n                << \"\\tFirst seen at \" << find(alias)->lineInfo << \"\\n\"\n                << \"\\tRedefined at \" << lineInfo;\n            throw std::domain_error( oss.str().c_str() );\n        }\n    }\n\n    TagAliasRegistry& TagAliasRegistry::get() {\n        static TagAliasRegistry instance;\n        return instance;\n\n    }\n\n    ITagAliasRegistry::~ITagAliasRegistry() {}\n    ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }\n\n    RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {\n        try {\n            TagAliasRegistry::get().add( alias, tag, lineInfo );\n        }\n        catch( std::exception& ex ) {\n            Colour colourGuard( Colour::Red );\n            Catch::cerr() << ex.what() << std::endl;\n            exit(1);\n        }\n    }\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_multi.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED\n\nnamespace Catch {\n\nclass MultipleReporters : public SharedImpl<IStreamingReporter> {\n    typedef std::vector<Ptr<IStreamingReporter> > Reporters;\n    Reporters m_reporters;\n\npublic:\n    void add( Ptr<IStreamingReporter> const& reporter ) {\n        m_reporters.push_back( reporter );\n    }\n\npublic: // IStreamingReporter\n\n    virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n        return m_reporters[0]->getPreferences();\n    }\n\n    virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->noMatchingTestCases( spec );\n    }\n\n    virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testRunStarting( testRunInfo );\n    }\n\n    virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testGroupStarting( groupInfo );\n    }\n\n    virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testCaseStarting( testInfo );\n    }\n\n    virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->sectionStarting( sectionInfo );\n    }\n\n    virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->assertionStarting( assertionInfo );\n    }\n\n    // The return value indicates if the messages buffer should be cleared:\n    virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n        bool clearBuffer = false;\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            clearBuffer |= (*it)->assertionEnded( assertionStats );\n        return clearBuffer;\n    }\n\n    virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->sectionEnded( sectionStats );\n    }\n\n    virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testCaseEnded( testCaseStats );\n    }\n\n    virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testGroupEnded( testGroupStats );\n    }\n\n    virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testRunEnded( testRunStats );\n    }\n\n    virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->skipTest( testInfo );\n    }\n\n    virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {\n        return this;\n    }\n\n};\n\nPtr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {\n    Ptr<IStreamingReporter> resultingReporter;\n\n    if( existingReporter ) {\n        MultipleReporters* multi = existingReporter->tryAsMulti();\n        if( !multi ) {\n            multi = new MultipleReporters;\n            resultingReporter = Ptr<IStreamingReporter>( multi );\n            if( existingReporter )\n                multi->add( existingReporter );\n        }\n        else\n            resultingReporter = existingReporter;\n        multi->add( additionalReporter );\n    }\n    else\n        resultingReporter = additionalReporter;\n\n    return resultingReporter;\n}\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_xml.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED\n\n// #included from: catch_reporter_bases.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED\n\n#include <cstring>\n\nnamespace Catch {\n\n    struct StreamingReporterBase : SharedImpl<IStreamingReporter> {\n\n        StreamingReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n        }\n\n        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n            return m_reporterPrefs;\n        }\n\n        virtual ~StreamingReporterBase() CATCH_OVERRIDE;\n\n        virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}\n\n        virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {\n            currentTestRunInfo = _testRunInfo;\n        }\n        virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {\n            currentGroupInfo = _groupInfo;\n        }\n\n        virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {\n            currentTestCaseInfo = _testInfo;\n        }\n        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {\n            m_sectionStack.push_back( _sectionInfo );\n        }\n\n        virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {\n            m_sectionStack.pop_back();\n        }\n        virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {\n            currentTestCaseInfo.reset();\n        }\n        virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {\n            currentGroupInfo.reset();\n        }\n        virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {\n            currentTestCaseInfo.reset();\n            currentGroupInfo.reset();\n            currentTestRunInfo.reset();\n        }\n\n        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {\n            // Don't do anything with this by default.\n            // It can optionally be overridden in the derived class.\n        }\n\n        Ptr<IConfig const> m_config;\n        std::ostream& stream;\n\n        LazyStat<TestRunInfo> currentTestRunInfo;\n        LazyStat<GroupInfo> currentGroupInfo;\n        LazyStat<TestCaseInfo> currentTestCaseInfo;\n\n        std::vector<SectionInfo> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {\n        template<typename T, typename ChildNodeT>\n        struct Node : SharedImpl<> {\n            explicit Node( T const& _value ) : value( _value ) {}\n            virtual ~Node() {}\n\n            typedef std::vector<Ptr<ChildNodeT> > ChildNodes;\n            T value;\n            ChildNodes children;\n        };\n        struct SectionNode : SharedImpl<> {\n            explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}\n            virtual ~SectionNode();\n\n            bool operator == ( SectionNode const& other ) const {\n                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;\n            }\n            bool operator == ( Ptr<SectionNode> const& other ) const {\n                return operator==( *other );\n            }\n\n            SectionStats stats;\n            typedef std::vector<Ptr<SectionNode> > ChildSections;\n            typedef std::vector<AssertionStats> Assertions;\n            ChildSections childSections;\n            Assertions assertions;\n            std::string stdOut;\n            std::string stdErr;\n        };\n\n        struct BySectionInfo {\n            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}\n\t\t\tBySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}\n            bool operator() ( Ptr<SectionNode> const& node ) const {\n                return node->stats.sectionInfo.lineInfo == m_other.lineInfo;\n            }\n        private:\n\t\t\tvoid operator=( BySectionInfo const& );\n            SectionInfo const& m_other;\n        };\n\n        typedef Node<TestCaseStats, SectionNode> TestCaseNode;\n        typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;\n        typedef Node<TestRunStats, TestGroupNode> TestRunNode;\n\n        CumulativeReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n        }\n        ~CumulativeReporterBase();\n\n        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n            return m_reporterPrefs;\n        }\n\n        virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}\n        virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}\n\n        virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}\n\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );\n            Ptr<SectionNode> node;\n            if( m_sectionStack.empty() ) {\n                if( !m_rootSection )\n                    m_rootSection = new SectionNode( incompleteStats );\n                node = m_rootSection;\n            }\n            else {\n                SectionNode& parentNode = *m_sectionStack.back();\n                SectionNode::ChildSections::const_iterator it =\n                    std::find_if(   parentNode.childSections.begin(),\n                                    parentNode.childSections.end(),\n                                    BySectionInfo( sectionInfo ) );\n                if( it == parentNode.childSections.end() ) {\n                    node = new SectionNode( incompleteStats );\n                    parentNode.childSections.push_back( node );\n                }\n                else\n                    node = *it;\n            }\n            m_sectionStack.push_back( node );\n            m_deepestSection = node;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            assert( !m_sectionStack.empty() );\n            SectionNode& sectionNode = *m_sectionStack.back();\n            sectionNode.assertions.push_back( assertionStats );\n            return true;\n        }\n        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n            assert( !m_sectionStack.empty() );\n            SectionNode& node = *m_sectionStack.back();\n            node.stats = sectionStats;\n            m_sectionStack.pop_back();\n        }\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );\n            assert( m_sectionStack.size() == 0 );\n            node->children.push_back( m_rootSection );\n            m_testCases.push_back( node );\n            m_rootSection.reset();\n\n            assert( m_deepestSection );\n            m_deepestSection->stdOut = testCaseStats.stdOut;\n            m_deepestSection->stdErr = testCaseStats.stdErr;\n        }\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );\n            node->children.swap( m_testCases );\n            m_testGroups.push_back( node );\n        }\n        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n            Ptr<TestRunNode> node = new TestRunNode( testRunStats );\n            node->children.swap( m_testGroups );\n            m_testRuns.push_back( node );\n            testRunEndedCumulative();\n        }\n        virtual void testRunEndedCumulative() = 0;\n\n        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}\n\n        Ptr<IConfig const> m_config;\n        std::ostream& stream;\n        std::vector<AssertionStats> m_assertions;\n        std::vector<std::vector<Ptr<SectionNode> > > m_sections;\n        std::vector<Ptr<TestCaseNode> > m_testCases;\n        std::vector<Ptr<TestGroupNode> > m_testGroups;\n\n        std::vector<Ptr<TestRunNode> > m_testRuns;\n\n        Ptr<SectionNode> m_rootSection;\n        Ptr<SectionNode> m_deepestSection;\n        std::vector<Ptr<SectionNode> > m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n\n    };\n\n    template<char C>\n    char const* getLineOfChars() {\n        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};\n        if( !*line ) {\n            memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );\n            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;\n        }\n        return line;\n    }\n\n    struct TestEventListenerBase : StreamingReporterBase {\n        TestEventListenerBase( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config )\n        {}\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}\n        virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {\n            return false;\n        }\n    };\n\n} // end namespace Catch\n\n// #included from: ../internal/catch_reporter_registrars.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED\n\nnamespace Catch {\n\n    template<typename T>\n    class LegacyReporterRegistrar {\n\n        class ReporterFactory : public IReporterFactory {\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new LegacyReporterAdapter( new T( config ) );\n            }\n\n            virtual std::string getDescription() const {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        LegacyReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );\n        }\n    };\n\n    template<typename T>\n    class ReporterRegistrar {\n\n        class ReporterFactory : public SharedImpl<IReporterFactory> {\n\n            // *** Please Note ***:\n            // - If you end up here looking at a compiler error because it's trying to register\n            // your custom reporter class be aware that the native reporter interface has changed\n            // to IStreamingReporter. The \"legacy\" interface, IReporter, is still supported via\n            // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.\n            // However please consider updating to the new interface as the old one is now\n            // deprecated and will probably be removed quite soon!\n            // Please contact me via github if you have any questions at all about this.\n            // In fact, ideally, please contact me anyway to let me know you've hit this - as I have\n            // no idea who is actually using custom reporters at all (possibly no-one!).\n            // The new interface is designed to minimise exposure to interface changes in the future.\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new T( config );\n            }\n\n            virtual std::string getDescription() const {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        ReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );\n        }\n    };\n\n    template<typename T>\n    class ListenerRegistrar {\n\n        class ListenerFactory : public SharedImpl<IReporterFactory> {\n\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new T( config );\n            }\n            virtual std::string getDescription() const {\n                return \"\";\n            }\n        };\n\n    public:\n\n        ListenerRegistrar() {\n            getMutableRegistryHub().registerListener( new ListenerFactory() );\n        }\n    };\n}\n\n#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \\\n    namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }\n\n#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \\\n    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }\n\n#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \\\n    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }\n\n// #included from: ../internal/catch_xmlwriter.hpp\n#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED\n\n#include <sstream>\n#include <string>\n#include <vector>\n#include <iomanip>\n\nnamespace Catch {\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )\n        :   m_str( str ),\n            m_forWhat( forWhat )\n        {}\n\n        void encodeTo( std::ostream& os ) const {\n\n            // Apostrophe escaping not necessary if we always use \" to write attributes\n            // (see: http://www.w3.org/TR/xml/#syntax)\n\n            for( std::size_t i = 0; i < m_str.size(); ++ i ) {\n                char c = m_str[i];\n                switch( c ) {\n                    case '<':   os << \"&lt;\"; break;\n                    case '&':   os << \"&amp;\"; break;\n\n                    case '>':\n                        // See: http://www.w3.org/TR/xml/#syntax\n                        if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )\n                            os << \"&gt;\";\n                        else\n                            os << c;\n                        break;\n\n                    case '\\\"':\n                        if( m_forWhat == ForAttributes )\n                            os << \"&quot;\";\n                        else\n                            os << c;\n                        break;\n\n                    default:\n                        // Escape control chars - based on contribution by @espenalb in PR #465 and\n                        // by @mrpi PR #588\n                        if ( ( c >= 0 && c < '\\x09' ) || ( c > '\\x0D' && c < '\\x20') || c=='\\x7F' )\n                            os << \"&#x\" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';\n                        else\n                            os << c;\n                }\n            }\n        }\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n            xmlEncode.encodeTo( os );\n            return os;\n        }\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer )\n            :   m_writer( writer )\n            {}\n\n            ScopedElement( ScopedElement const& other )\n            :   m_writer( other.m_writer ){\n                other.m_writer = CATCH_NULL;\n            }\n\n            ~ScopedElement() {\n                if( m_writer )\n                    m_writer->endElement();\n            }\n\n            ScopedElement& writeText( std::string const& text, bool indent = true ) {\n                m_writer->writeText( text, indent );\n                return *this;\n            }\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer;\n        };\n\n        XmlWriter()\n        :   m_tagIsOpen( false ),\n            m_needsNewline( false ),\n            m_os( &Catch::cout() )\n        {\n            // We encode control characters, which requires\n            // XML 1.1\n            // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n            *m_os << \"<?xml version=\\\"1.1\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n        }\n\n        XmlWriter( std::ostream& os )\n        :   m_tagIsOpen( false ),\n            m_needsNewline( false ),\n            m_os( &os )\n        {\n            *m_os << \"<?xml version=\\\"1.1\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n        }\n\n        ~XmlWriter() {\n            while( !m_tags.empty() )\n                endElement();\n        }\n\n        XmlWriter& startElement( std::string const& name ) {\n            ensureTagClosed();\n            newlineIfNecessary();\n            stream() << m_indent << \"<\" << name;\n            m_tags.push_back( name );\n            m_indent += \"  \";\n            m_tagIsOpen = true;\n            return *this;\n        }\n\n        ScopedElement scopedElement( std::string const& name ) {\n            ScopedElement scoped( this );\n            startElement( name );\n            return scoped;\n        }\n\n        XmlWriter& endElement() {\n            newlineIfNecessary();\n            m_indent = m_indent.substr( 0, m_indent.size()-2 );\n            if( m_tagIsOpen ) {\n                stream() << \"/>\\n\";\n                m_tagIsOpen = false;\n            }\n            else {\n                stream() << m_indent << \"</\" << m_tags.back() << \">\\n\";\n            }\n            m_tags.pop_back();\n            return *this;\n        }\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {\n            if( !name.empty() && !attribute.empty() )\n                stream() << \" \" << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << \"\\\"\";\n            return *this;\n        }\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute ) {\n            stream() << \" \" << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << \"\\\"\";\n            return *this;\n        }\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n            std::ostringstream oss;\n            oss << attribute;\n            return writeAttribute( name, oss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, bool indent = true ) {\n            if( !text.empty() ){\n                bool tagWasOpen = m_tagIsOpen;\n                ensureTagClosed();\n                if( tagWasOpen && indent )\n                    stream() << m_indent;\n                stream() << XmlEncode( text );\n                m_needsNewline = true;\n            }\n            return *this;\n        }\n\n        XmlWriter& writeComment( std::string const& text ) {\n            ensureTagClosed();\n            stream() << m_indent << \"<!--\" << text << \"-->\";\n            m_needsNewline = true;\n            return *this;\n        }\n\n        XmlWriter& writeBlankLine() {\n            ensureTagClosed();\n            stream() << \"\\n\";\n            return *this;\n        }\n\n        void setStream( std::ostream& os ) {\n            m_os = &os;\n        }\n\n    private:\n        XmlWriter( XmlWriter const& );\n        void operator=( XmlWriter const& );\n\n        std::ostream& stream() {\n            return *m_os;\n        }\n\n        void ensureTagClosed() {\n            if( m_tagIsOpen ) {\n                stream() << \">\\n\";\n                m_tagIsOpen = false;\n            }\n        }\n\n        void newlineIfNecessary() {\n            if( m_needsNewline ) {\n                stream() << \"\\n\";\n                m_needsNewline = false;\n            }\n        }\n\n        bool m_tagIsOpen;\n        bool m_needsNewline;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream* m_os;\n    };\n\n}\n// #included from: catch_reenable_warnings.h\n\n#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED\n\n#ifdef __clang__\n#    ifdef __ICC // icpc defines the __clang__ macro\n#        pragma warning(pop)\n#    else\n#        pragma clang diagnostic pop\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic pop\n#endif\n\n\nnamespace Catch {\n    class XmlReporter : public StreamingReporterBase {\n    public:\n        XmlReporter( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config ),\n            m_xml(_config.stream()),\n            m_sectionDepth( 0 )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n        }\n\n        virtual ~XmlReporter() CATCH_OVERRIDE;\n\n        static std::string getDescription() {\n            return \"Reports test results as an XML document\";\n        }\n\n    public: // StreamingReporterBase\n\n        virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {\n            StreamingReporterBase::noMatchingTestCases( s );\n        }\n\n        virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testRunStarting( testInfo );\n            m_xml.startElement( \"Catch\" );\n            if( !m_config->name().empty() )\n                m_xml.writeAttribute( \"name\", m_config->name() );\n        }\n\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testGroupStarting( groupInfo );\n            m_xml.startElement( \"Group\" )\n                .writeAttribute( \"name\", groupInfo.name );\n        }\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseStarting(testInfo);\n            m_xml.startElement( \"TestCase\" ).writeAttribute( \"name\", testInfo.name );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                m_testCaseTimer.start();\n        }\n\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::sectionStarting( sectionInfo );\n            if( m_sectionDepth++ > 0 ) {\n                m_xml.startElement( \"Section\" )\n                    .writeAttribute( \"name\", trim( sectionInfo.name ) )\n                    .writeAttribute( \"description\", sectionInfo.description );\n            }\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            const AssertionResult& assertionResult = assertionStats.assertionResult;\n\n            // Print any info messages in <Info> tags.\n            if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {\n                for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();\n                        it != itEnd;\n                        ++it ) {\n                    if( it->type == ResultWas::Info ) {\n                        m_xml.scopedElement( \"Info\" )\n                            .writeText( it->message );\n                    } else if ( it->type == ResultWas::Warning ) {\n                        m_xml.scopedElement( \"Warning\" )\n                            .writeText( it->message );\n                    }\n                }\n            }\n\n            // Drop out if result was successful but we're not printing them.\n            if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )\n                return true;\n\n            // Print the expression if there is one.\n            if( assertionResult.hasExpression() ) {\n                m_xml.startElement( \"Expression\" )\n                    .writeAttribute( \"success\", assertionResult.succeeded() )\n\t\t\t\t\t.writeAttribute( \"type\", assertionResult.getTestMacroName() )\n                    .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                    .writeAttribute( \"line\", assertionResult.getSourceInfo().line );\n\n                m_xml.scopedElement( \"Original\" )\n                    .writeText( assertionResult.getExpression() );\n                m_xml.scopedElement( \"Expanded\" )\n                    .writeText( assertionResult.getExpandedExpression() );\n            }\n\n            // And... Print a result applicable to each result type.\n            switch( assertionResult.getResultType() ) {\n                case ResultWas::ThrewException:\n                    m_xml.scopedElement( \"Exception\" )\n                        .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                        .writeAttribute( \"line\", assertionResult.getSourceInfo().line )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::FatalErrorCondition:\n                    m_xml.scopedElement( \"FatalErrorCondition\" )\n                        .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                        .writeAttribute( \"line\", assertionResult.getSourceInfo().line )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::Info:\n                    m_xml.scopedElement( \"Info\" )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::Warning:\n                    // Warning will already have been written\n                    break;\n                case ResultWas::ExplicitFailure:\n                    m_xml.scopedElement( \"Failure\" )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                default:\n                    break;\n            }\n\n            if( assertionResult.hasExpression() )\n                m_xml.endElement();\n\n            return true;\n        }\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::sectionEnded( sectionStats );\n            if( --m_sectionDepth > 0 ) {\n                XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResults\" );\n                e.writeAttribute( \"successes\", sectionStats.assertions.passed );\n                e.writeAttribute( \"failures\", sectionStats.assertions.failed );\n                e.writeAttribute( \"expectedFailures\", sectionStats.assertions.failedButOk );\n\n                if ( m_config->showDurations() == ShowDurations::Always )\n                    e.writeAttribute( \"durationInSeconds\", sectionStats.durationInSeconds );\n\n                m_xml.endElement();\n            }\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseEnded( testCaseStats );\n            XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResult\" );\n            e.writeAttribute( \"success\", testCaseStats.totals.assertions.allOk() );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                e.writeAttribute( \"durationInSeconds\", m_testCaseTimer.getElapsedSeconds() );\n\n            m_xml.endElement();\n        }\n\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testGroupEnded( testGroupStats );\n            // TODO: Check testGroupStats.aborting and act accordingly.\n            m_xml.scopedElement( \"OverallResults\" )\n                .writeAttribute( \"successes\", testGroupStats.totals.assertions.passed )\n                .writeAttribute( \"failures\", testGroupStats.totals.assertions.failed )\n                .writeAttribute( \"expectedFailures\", testGroupStats.totals.assertions.failedButOk );\n            m_xml.endElement();\n        }\n\n        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testRunEnded( testRunStats );\n            m_xml.scopedElement( \"OverallResults\" )\n                .writeAttribute( \"successes\", testRunStats.totals.assertions.passed )\n                .writeAttribute( \"failures\", testRunStats.totals.assertions.failed )\n                .writeAttribute( \"expectedFailures\", testRunStats.totals.assertions.failedButOk );\n            m_xml.endElement();\n        }\n\n    private:\n        Timer m_testCaseTimer;\n        XmlWriter m_xml;\n        int m_sectionDepth;\n    };\n\n     INTERNAL_CATCH_REGISTER_REPORTER( \"xml\", XmlReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_junit.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED\n\n#include <assert.h>\n\nnamespace Catch {\n\n    namespace {\n        std::string getCurrentTimestamp() {\n            // Beware, this is not reentrant because of backward compatibility issues\n            // Also, UTC only, again because of backward compatibility (%z is C++11)\n            time_t rawtime;\n            std::time(&rawtime);\n            const size_t timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n#ifdef CATCH_PLATFORM_WINDOWS\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &rawtime);\n#else\n            std::tm* timeInfo;\n            timeInfo = std::gmtime(&rawtime);\n#endif\n\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef CATCH_PLATFORM_WINDOWS\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp);\n        }\n\n    }\n\n    class JunitReporter : public CumulativeReporterBase {\n    public:\n        JunitReporter( ReporterConfig const& _config )\n        :   CumulativeReporterBase( _config ),\n            xml( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n        }\n\n        virtual ~JunitReporter() CATCH_OVERRIDE;\n\n        static std::string getDescription() {\n            return \"Reports test results in an XML format that looks like Ant's junitreport target\";\n        }\n\n        virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}\n\n        virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {\n            CumulativeReporterBase::testRunStarting( runInfo );\n            xml.startElement( \"testsuites\" );\n        }\n\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n            suiteTimer.start();\n            stdOutForSuite.str(\"\");\n            stdErrForSuite.str(\"\");\n            unexpectedExceptions = 0;\n            CumulativeReporterBase::testGroupStarting( groupInfo );\n        }\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )\n                unexpectedExceptions++;\n            return CumulativeReporterBase::assertionEnded( assertionStats );\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            stdOutForSuite << testCaseStats.stdOut;\n            stdErrForSuite << testCaseStats.stdErr;\n            CumulativeReporterBase::testCaseEnded( testCaseStats );\n        }\n\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            double suiteTime = suiteTimer.getElapsedSeconds();\n            CumulativeReporterBase::testGroupEnded( testGroupStats );\n            writeGroup( *m_testGroups.back(), suiteTime );\n        }\n\n        virtual void testRunEndedCumulative() CATCH_OVERRIDE {\n            xml.endElement();\n        }\n\n        void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {\n            XmlWriter::ScopedElement e = xml.scopedElement( \"testsuite\" );\n            TestGroupStats const& stats = groupNode.value;\n            xml.writeAttribute( \"name\", stats.groupInfo.name );\n            xml.writeAttribute( \"errors\", unexpectedExceptions );\n            xml.writeAttribute( \"failures\", stats.totals.assertions.failed-unexpectedExceptions );\n            xml.writeAttribute( \"tests\", stats.totals.assertions.total() );\n            xml.writeAttribute( \"hostname\", \"tbd\" ); // !TBD\n            if( m_config->showDurations() == ShowDurations::Never )\n                xml.writeAttribute( \"time\", \"\" );\n            else\n                xml.writeAttribute( \"time\", suiteTime );\n            xml.writeAttribute( \"timestamp\", getCurrentTimestamp() );\n\n            // Write test cases\n            for( TestGroupNode::ChildNodes::const_iterator\n                    it = groupNode.children.begin(), itEnd = groupNode.children.end();\n                    it != itEnd;\n                    ++it )\n                writeTestCase( **it );\n\n            xml.scopedElement( \"system-out\" ).writeText( trim( stdOutForSuite.str() ), false );\n            xml.scopedElement( \"system-err\" ).writeText( trim( stdErrForSuite.str() ), false );\n        }\n\n        void writeTestCase( TestCaseNode const& testCaseNode ) {\n            TestCaseStats const& stats = testCaseNode.value;\n\n            // All test cases have exactly one section - which represents the\n            // test case itself. That section may have 0-n nested sections\n            assert( testCaseNode.children.size() == 1 );\n            SectionNode const& rootSection = *testCaseNode.children.front();\n\n            std::string className = stats.testInfo.className;\n\n            if( className.empty() ) {\n                if( rootSection.childSections.empty() )\n                    className = \"global\";\n            }\n            writeSection( className, \"\", rootSection );\n        }\n\n        void writeSection(  std::string const& className,\n                            std::string const& rootName,\n                            SectionNode const& sectionNode ) {\n            std::string name = trim( sectionNode.stats.sectionInfo.name );\n            if( !rootName.empty() )\n                name = rootName + \"/\" + name;\n\n            if( !sectionNode.assertions.empty() ||\n                !sectionNode.stdOut.empty() ||\n                !sectionNode.stdErr.empty() ) {\n                XmlWriter::ScopedElement e = xml.scopedElement( \"testcase\" );\n                if( className.empty() ) {\n                    xml.writeAttribute( \"classname\", name );\n                    xml.writeAttribute( \"name\", \"root\" );\n                }\n                else {\n                    xml.writeAttribute( \"classname\", className );\n                    xml.writeAttribute( \"name\", name );\n                }\n                xml.writeAttribute( \"time\", Catch::toString( sectionNode.stats.durationInSeconds ) );\n\n                writeAssertions( sectionNode );\n\n                if( !sectionNode.stdOut.empty() )\n                    xml.scopedElement( \"system-out\" ).writeText( trim( sectionNode.stdOut ), false );\n                if( !sectionNode.stdErr.empty() )\n                    xml.scopedElement( \"system-err\" ).writeText( trim( sectionNode.stdErr ), false );\n            }\n            for( SectionNode::ChildSections::const_iterator\n                    it = sectionNode.childSections.begin(),\n                    itEnd = sectionNode.childSections.end();\n                    it != itEnd;\n                    ++it )\n                if( className.empty() )\n                    writeSection( name, \"\", **it );\n                else\n                    writeSection( className, name, **it );\n        }\n\n        void writeAssertions( SectionNode const& sectionNode ) {\n            for( SectionNode::Assertions::const_iterator\n                    it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();\n                    it != itEnd;\n                    ++it )\n                writeAssertion( *it );\n        }\n        void writeAssertion( AssertionStats const& stats ) {\n            AssertionResult const& result = stats.assertionResult;\n            if( !result.isOk() ) {\n                std::string elementName;\n                switch( result.getResultType() ) {\n                    case ResultWas::ThrewException:\n                    case ResultWas::FatalErrorCondition:\n                        elementName = \"error\";\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        elementName = \"failure\";\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        elementName = \"failure\";\n                        break;\n                    case ResultWas::DidntThrowException:\n                        elementName = \"failure\";\n                        break;\n\n                    // We should never see these here:\n                    case ResultWas::Info:\n                    case ResultWas::Warning:\n                    case ResultWas::Ok:\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        elementName = \"internalError\";\n                        break;\n                }\n\n                XmlWriter::ScopedElement e = xml.scopedElement( elementName );\n\n                xml.writeAttribute( \"message\", result.getExpandedExpression() );\n                xml.writeAttribute( \"type\", result.getTestMacroName() );\n\n                std::ostringstream oss;\n                if( !result.getMessage().empty() )\n                    oss << result.getMessage() << \"\\n\";\n                for( std::vector<MessageInfo>::const_iterator\n                        it = stats.infoMessages.begin(),\n                        itEnd = stats.infoMessages.end();\n                            it != itEnd;\n                            ++it )\n                    if( it->type == ResultWas::Info )\n                        oss << it->message << \"\\n\";\n\n                oss << \"at \" << result.getSourceInfo();\n                xml.writeText( oss.str(), false );\n            }\n        }\n\n        XmlWriter xml;\n        Timer suiteTimer;\n        std::ostringstream stdOutForSuite;\n        std::ostringstream stdErrForSuite;\n        unsigned int unexpectedExceptions;\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"junit\", JunitReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_console.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct ConsoleReporter : StreamingReporterBase {\n        ConsoleReporter( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config ),\n            m_headerPrinted( false )\n        {}\n\n        virtual ~ConsoleReporter() CATCH_OVERRIDE;\n        static std::string getDescription() {\n            return \"Reports test results as plain lines of text\";\n        }\n\n        virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {\n            stream << \"No test cases matched '\" << spec << \"'\" << std::endl;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {\n        }\n\n        virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            lazyPrint();\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n            stream << std::endl;\n            return true;\n        }\n\n        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {\n            m_headerPrinted = false;\n            StreamingReporterBase::sectionStarting( _sectionInfo );\n        }\n        virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {\n            if( _sectionStats.missingAssertions ) {\n                lazyPrint();\n                Colour colour( Colour::ResultError );\n                if( m_sectionStack.size() > 1 )\n                    stream << \"\\nNo assertions in section\";\n                else\n                    stream << \"\\nNo assertions in test case\";\n                stream << \" '\" << _sectionStats.sectionInfo.name << \"'\\n\" << std::endl;\n            }\n            if( m_headerPrinted ) {\n                if( m_config->showDurations() == ShowDurations::Always )\n                    stream << \"Completed in \" << _sectionStats.durationInSeconds << \"s\" << std::endl;\n                m_headerPrinted = false;\n            }\n            else {\n                if( m_config->showDurations() == ShowDurations::Always )\n                    stream << _sectionStats.sectionInfo.name << \" completed in \" << _sectionStats.durationInSeconds << \"s\" << std::endl;\n            }\n            StreamingReporterBase::sectionEnded( _sectionStats );\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseEnded( _testCaseStats );\n            m_headerPrinted = false;\n        }\n        virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {\n            if( currentGroupInfo.used ) {\n                printSummaryDivider();\n                stream << \"Summary for group '\" << _testGroupStats.groupInfo.name << \"':\\n\";\n                printTotals( _testGroupStats.totals );\n                stream << \"\\n\" << std::endl;\n            }\n            StreamingReporterBase::testGroupEnded( _testGroupStats );\n        }\n        virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {\n            printTotalsDivider( _testRunStats.totals );\n            printTotals( _testRunStats.totals );\n            stream << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n    private:\n\n        class AssertionPrinter {\n            void operator= ( AssertionPrinter const& );\n        public:\n            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )\n            :   stream( _stream ),\n                stats( _stats ),\n                result( _stats.assertionResult ),\n                colour( Colour::None ),\n                message( result.getMessage() ),\n                messages( _stats.infoMessages ),\n                printInfoMessages( _printInfoMessages )\n            {\n                switch( result.getResultType() ) {\n                    case ResultWas::Ok:\n                        colour = Colour::Success;\n                        passOrFail = \"PASSED\";\n                        //if( result.hasMessage() )\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"with messages\";\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        if( result.isOk() ) {\n                            colour = Colour::Success;\n                            passOrFail = \"FAILED - but was ok\";\n                        }\n                        else {\n                            colour = Colour::Error;\n                            passOrFail = \"FAILED\";\n                        }\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"with messages\";\n                        break;\n                    case ResultWas::ThrewException:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"due to unexpected exception with message\";\n                        break;\n                    case ResultWas::FatalErrorCondition:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"due to a fatal error condition\";\n                        break;\n                    case ResultWas::DidntThrowException:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"because no exception was thrown where one was expected\";\n                        break;\n                    case ResultWas::Info:\n                        messageLabel = \"info\";\n                        break;\n                    case ResultWas::Warning:\n                        messageLabel = \"warning\";\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        passOrFail = \"FAILED\";\n                        colour = Colour::Error;\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"explicitly with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"explicitly with messages\";\n                        break;\n                    // These cases are here to prevent compiler warnings\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        passOrFail = \"** internal error **\";\n                        colour = Colour::Error;\n                        break;\n                }\n            }\n\n            void print() const {\n                printSourceInfo();\n                if( stats.totals.assertions.total() > 0 ) {\n                    if( result.isOk() )\n                        stream << \"\\n\";\n                    printResultType();\n                    printOriginalExpression();\n                    printReconstructedExpression();\n                }\n                else {\n                    stream << \"\\n\";\n                }\n                printMessage();\n            }\n\n        private:\n            void printResultType() const {\n                if( !passOrFail.empty() ) {\n                    Colour colourGuard( colour );\n                    stream << passOrFail << \":\\n\";\n                }\n            }\n            void printOriginalExpression() const {\n                if( result.hasExpression() ) {\n                    Colour colourGuard( Colour::OriginalExpression );\n                    stream  << \"  \";\n                    stream << result.getExpressionInMacro();\n                    stream << \"\\n\";\n                }\n            }\n            void printReconstructedExpression() const {\n                if( result.hasExpandedExpression() ) {\n                    stream << \"with expansion:\\n\";\n                    Colour colourGuard( Colour::ReconstructedExpression );\n                    stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << \"\\n\";\n                }\n            }\n            void printMessage() const {\n                if( !messageLabel.empty() )\n                    stream << messageLabel << \":\" << \"\\n\";\n                for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();\n                        it != itEnd;\n                        ++it ) {\n                    // If this assertion is a warning ignore any INFO messages\n                    if( printInfoMessages || it->type != ResultWas::Info )\n                        stream << Text( it->message, TextAttributes().setIndent(2) ) << \"\\n\";\n                }\n            }\n            void printSourceInfo() const {\n                Colour colourGuard( Colour::FileName );\n                stream << result.getSourceInfo() << \": \";\n            }\n\n            std::ostream& stream;\n            AssertionStats const& stats;\n            AssertionResult const& result;\n            Colour::Code colour;\n            std::string passOrFail;\n            std::string messageLabel;\n            std::string message;\n            std::vector<MessageInfo> messages;\n            bool printInfoMessages;\n        };\n\n        void lazyPrint() {\n\n            if( !currentTestRunInfo.used )\n                lazyPrintRunInfo();\n            if( !currentGroupInfo.used )\n                lazyPrintGroupInfo();\n\n            if( !m_headerPrinted ) {\n                printTestCaseAndSectionHeader();\n                m_headerPrinted = true;\n            }\n        }\n        void lazyPrintRunInfo() {\n            stream  << \"\\n\" << getLineOfChars<'~'>() << \"\\n\";\n            Colour colour( Colour::SecondaryText );\n            stream  << currentTestRunInfo->name\n                    << \" is a Catch v\"  << libraryVersion << \" host application.\\n\"\n                    << \"Run with -? for options\\n\\n\";\n\n            if( m_config->rngSeed() != 0 )\n                stream << \"Randomness seeded to: \" << m_config->rngSeed() << \"\\n\\n\";\n\n            currentTestRunInfo.used = true;\n        }\n        void lazyPrintGroupInfo() {\n            if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {\n                printClosedHeader( \"Group: \" + currentGroupInfo->name );\n                currentGroupInfo.used = true;\n            }\n        }\n        void printTestCaseAndSectionHeader() {\n            assert( !m_sectionStack.empty() );\n            printOpenHeader( currentTestCaseInfo->name );\n\n            if( m_sectionStack.size() > 1 ) {\n                Colour colourGuard( Colour::Headers );\n\n                std::vector<SectionInfo>::const_iterator\n                    it = m_sectionStack.begin()+1, // Skip first section (test case)\n                    itEnd = m_sectionStack.end();\n                for( ; it != itEnd; ++it )\n                    printHeaderString( it->name, 2 );\n            }\n\n            SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;\n\n            if( !lineInfo.empty() ){\n                stream << getLineOfChars<'-'>() << \"\\n\";\n                Colour colourGuard( Colour::FileName );\n                stream << lineInfo << \"\\n\";\n            }\n            stream << getLineOfChars<'.'>() << \"\\n\" << std::endl;\n        }\n\n        void printClosedHeader( std::string const& _name ) {\n            printOpenHeader( _name );\n            stream << getLineOfChars<'.'>() << \"\\n\";\n        }\n        void printOpenHeader( std::string const& _name ) {\n            stream  << getLineOfChars<'-'>() << \"\\n\";\n            {\n                Colour colourGuard( Colour::Headers );\n                printHeaderString( _name );\n            }\n        }\n\n        // if string has a : in first line will set indent to follow it on\n        // subsequent lines\n        void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {\n            std::size_t i = _string.find( \": \" );\n            if( i != std::string::npos )\n                i+=2;\n            else\n                i = 0;\n            stream << Text( _string, TextAttributes()\n                                        .setIndent( indent+i)\n                                        .setInitialIndent( indent ) ) << \"\\n\";\n        }\n\n        struct SummaryColumn {\n\n            SummaryColumn( std::string const& _label, Colour::Code _colour )\n            :   label( _label ),\n                colour( _colour )\n            {}\n            SummaryColumn addRow( std::size_t count ) {\n                std::ostringstream oss;\n                oss << count;\n                std::string row = oss.str();\n                for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {\n                    while( it->size() < row.size() )\n                        *it = \" \" + *it;\n                    while( it->size() > row.size() )\n                        row = \" \" + row;\n                }\n                rows.push_back( row );\n                return *this;\n            }\n\n            std::string label;\n            Colour::Code colour;\n            std::vector<std::string> rows;\n\n        };\n\n        void printTotals( Totals const& totals ) {\n            if( totals.testCases.total() == 0 ) {\n                stream << Colour( Colour::Warning ) << \"No tests ran\\n\";\n            }\n            else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {\n                stream << Colour( Colour::ResultSuccess ) << \"All tests passed\";\n                stream << \" (\"\n                        << pluralise( totals.assertions.passed, \"assertion\" ) << \" in \"\n                        << pluralise( totals.testCases.passed, \"test case\" ) << \")\"\n                        << \"\\n\";\n            }\n            else {\n\n                std::vector<SummaryColumn> columns;\n                columns.push_back( SummaryColumn( \"\", Colour::None )\n                                        .addRow( totals.testCases.total() )\n                                        .addRow( totals.assertions.total() ) );\n                columns.push_back( SummaryColumn( \"passed\", Colour::Success )\n                                        .addRow( totals.testCases.passed )\n                                        .addRow( totals.assertions.passed ) );\n                columns.push_back( SummaryColumn( \"failed\", Colour::ResultError )\n                                        .addRow( totals.testCases.failed )\n                                        .addRow( totals.assertions.failed ) );\n                columns.push_back( SummaryColumn( \"failed as expected\", Colour::ResultExpectedFailure )\n                                        .addRow( totals.testCases.failedButOk )\n                                        .addRow( totals.assertions.failedButOk ) );\n\n                printSummaryRow( \"test cases\", columns, 0 );\n                printSummaryRow( \"assertions\", columns, 1 );\n            }\n        }\n        void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {\n            for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {\n                std::string value = it->rows[row];\n                if( it->label.empty() ) {\n                    stream << label << \": \";\n                    if( value != \"0\" )\n                        stream << value;\n                    else\n                        stream << Colour( Colour::Warning ) << \"- none -\";\n                }\n                else if( value != \"0\" ) {\n                    stream  << Colour( Colour::LightGrey ) << \" | \";\n                    stream  << Colour( it->colour )\n                            << value << \" \" << it->label;\n                }\n            }\n            stream << \"\\n\";\n        }\n\n        static std::size_t makeRatio( std::size_t number, std::size_t total ) {\n            std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;\n            return ( ratio == 0 && number > 0 ) ? 1 : ratio;\n        }\n        static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {\n            if( i > j && i > k )\n                return i;\n            else if( j > k )\n                return j;\n            else\n                return k;\n        }\n\n        void printTotalsDivider( Totals const& totals ) {\n            if( totals.testCases.total() > 0 ) {\n                std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );\n                std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );\n                std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );\n                while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )\n                    findMax( failedRatio, failedButOkRatio, passedRatio )++;\n                while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )\n                    findMax( failedRatio, failedButOkRatio, passedRatio )--;\n\n                stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );\n                stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );\n                if( totals.testCases.allPassed() )\n                    stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );\n                else\n                    stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );\n            }\n            else {\n                stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );\n            }\n            stream << \"\\n\";\n        }\n        void printSummaryDivider() {\n            stream << getLineOfChars<'-'>() << \"\\n\";\n        }\n\n    private:\n        bool m_headerPrinted;\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"console\", ConsoleReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_compact.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct CompactReporter : StreamingReporterBase {\n\n        CompactReporter( ReporterConfig const& _config )\n        : StreamingReporterBase( _config )\n        {}\n\n        virtual ~CompactReporter();\n\n        static std::string getDescription() {\n            return \"Reports test results on a single line, suitable for IDEs\";\n        }\n\n        virtual ReporterPreferences getPreferences() const {\n            ReporterPreferences prefs;\n            prefs.shouldRedirectStdOut = false;\n            return prefs;\n        }\n\n        virtual void noMatchingTestCases( std::string const& spec ) {\n            stream << \"No test cases matched '\" << spec << \"'\" << std::endl;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) {\n        }\n\n        virtual bool assertionEnded( AssertionStats const& _assertionStats ) {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n\n            stream << std::endl;\n            return true;\n        }\n\n        virtual void testRunEnded( TestRunStats const& _testRunStats ) {\n            printTotals( _testRunStats.totals );\n            stream << \"\\n\" << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n    private:\n        class AssertionPrinter {\n            void operator= ( AssertionPrinter const& );\n        public:\n            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )\n            : stream( _stream )\n            , stats( _stats )\n            , result( _stats.assertionResult )\n            , messages( _stats.infoMessages )\n            , itMessage( _stats.infoMessages.begin() )\n            , printInfoMessages( _printInfoMessages )\n            {}\n\n            void print() {\n                printSourceInfo();\n\n                itMessage = messages.begin();\n\n                switch( result.getResultType() ) {\n                    case ResultWas::Ok:\n                        printResultType( Colour::ResultSuccess, passedString() );\n                        printOriginalExpression();\n                        printReconstructedExpression();\n                        if ( ! result.hasExpression() )\n                            printRemainingMessages( Colour::None );\n                        else\n                            printRemainingMessages();\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        if( result.isOk() )\n                            printResultType( Colour::ResultSuccess, failedString() + std::string( \" - but was ok\" ) );\n                        else\n                            printResultType( Colour::Error, failedString() );\n                        printOriginalExpression();\n                        printReconstructedExpression();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::ThrewException:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"unexpected exception with message:\" );\n                        printMessage();\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::FatalErrorCondition:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"fatal error condition with message:\" );\n                        printMessage();\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::DidntThrowException:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"expected exception, got none\" );\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::Info:\n                        printResultType( Colour::None, \"info\" );\n                        printMessage();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::Warning:\n                        printResultType( Colour::None, \"warning\" );\n                        printMessage();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"explicitly\" );\n                        printRemainingMessages( Colour::None );\n                        break;\n                    // These cases are here to prevent compiler warnings\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        printResultType( Colour::Error, \"** internal error **\" );\n                        break;\n                }\n            }\n\n        private:\n            // Colour::LightGrey\n\n            static Colour::Code dimColour() { return Colour::FileName; }\n\n#ifdef CATCH_PLATFORM_MAC\n            static const char* failedString() { return \"FAILED\"; }\n            static const char* passedString() { return \"PASSED\"; }\n#else\n            static const char* failedString() { return \"failed\"; }\n            static const char* passedString() { return \"passed\"; }\n#endif\n\n            void printSourceInfo() const {\n                Colour colourGuard( Colour::FileName );\n                stream << result.getSourceInfo() << \":\";\n            }\n\n            void printResultType( Colour::Code colour, std::string passOrFail ) const {\n                if( !passOrFail.empty() ) {\n                    {\n                        Colour colourGuard( colour );\n                        stream << \" \" << passOrFail;\n                    }\n                    stream << \":\";\n                }\n            }\n\n            void printIssue( std::string issue ) const {\n                stream << \" \" << issue;\n            }\n\n            void printExpressionWas() {\n                if( result.hasExpression() ) {\n                    stream << \";\";\n                    {\n                        Colour colour( dimColour() );\n                        stream << \" expression was:\";\n                    }\n                    printOriginalExpression();\n                }\n            }\n\n            void printOriginalExpression() const {\n                if( result.hasExpression() ) {\n                    stream << \" \" << result.getExpression();\n                }\n            }\n\n            void printReconstructedExpression() const {\n                if( result.hasExpandedExpression() ) {\n                    {\n                        Colour colour( dimColour() );\n                        stream << \" for: \";\n                    }\n                    stream << result.getExpandedExpression();\n                }\n            }\n\n            void printMessage() {\n                if ( itMessage != messages.end() ) {\n                    stream << \" '\" << itMessage->message << \"'\";\n                    ++itMessage;\n                }\n            }\n\n            void printRemainingMessages( Colour::Code colour = dimColour() ) {\n                if ( itMessage == messages.end() )\n                    return;\n\n                // using messages.end() directly yields compilation error:\n                std::vector<MessageInfo>::const_iterator itEnd = messages.end();\n                const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );\n\n                {\n                    Colour colourGuard( colour );\n                    stream << \" with \" << pluralise( N, \"message\" ) << \":\";\n                }\n\n                for(; itMessage != itEnd; ) {\n                    // If this assertion is a warning ignore any INFO messages\n                    if( printInfoMessages || itMessage->type != ResultWas::Info ) {\n                        stream << \" '\" << itMessage->message << \"'\";\n                        if ( ++itMessage != itEnd ) {\n                            Colour colourGuard( dimColour() );\n                            stream << \" and\";\n                        }\n                    }\n                }\n            }\n\n        private:\n            std::ostream& stream;\n            AssertionStats const& stats;\n            AssertionResult const& result;\n            std::vector<MessageInfo> messages;\n            std::vector<MessageInfo>::const_iterator itMessage;\n            bool printInfoMessages;\n        };\n\n        // Colour, message variants:\n        // - white: No tests ran.\n        // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.\n        // - white: Passed [both/all] N test cases (no assertions).\n        // -   red: Failed N tests cases, failed M assertions.\n        // - green: Passed [both/all] N tests cases with M assertions.\n\n        std::string bothOrAll( std::size_t count ) const {\n            return count == 1 ? \"\" : count == 2 ? \"both \" : \"all \" ;\n        }\n\n        void printTotals( const Totals& totals ) const {\n            if( totals.testCases.total() == 0 ) {\n                stream << \"No tests ran.\";\n            }\n            else if( totals.testCases.failed == totals.testCases.total() ) {\n                Colour colour( Colour::ResultError );\n                const std::string qualify_assertions_failed =\n                    totals.assertions.failed == totals.assertions.total() ?\n                        bothOrAll( totals.assertions.failed ) : \"\";\n                stream <<\n                    \"Failed \" << bothOrAll( totals.testCases.failed )\n                              << pluralise( totals.testCases.failed, \"test case\"  ) << \", \"\n                    \"failed \" << qualify_assertions_failed <<\n                                 pluralise( totals.assertions.failed, \"assertion\" ) << \".\";\n            }\n            else if( totals.assertions.total() == 0 ) {\n                stream <<\n                    \"Passed \" << bothOrAll( totals.testCases.total() )\n                              << pluralise( totals.testCases.total(), \"test case\" )\n                              << \" (no assertions).\";\n            }\n            else if( totals.assertions.failed ) {\n                Colour colour( Colour::ResultError );\n                stream <<\n                    \"Failed \" << pluralise( totals.testCases.failed, \"test case\"  ) << \", \"\n                    \"failed \" << pluralise( totals.assertions.failed, \"assertion\" ) << \".\";\n            }\n            else {\n                Colour colour( Colour::ResultSuccess );\n                stream <<\n                    \"Passed \" << bothOrAll( totals.testCases.passed )\n                              << pluralise( totals.testCases.passed, \"test case\"  ) <<\n                    \" with \"  << pluralise( totals.assertions.passed, \"assertion\" ) << \".\";\n            }\n        }\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"compact\", CompactReporter )\n\n} // end namespace Catch\n\nnamespace Catch {\n    // These are all here to avoid warnings about not having any out of line\n    // virtual methods\n    NonCopyable::~NonCopyable() {}\n    IShared::~IShared() {}\n    IStream::~IStream() CATCH_NOEXCEPT {}\n    FileStream::~FileStream() CATCH_NOEXCEPT {}\n    CoutStream::~CoutStream() CATCH_NOEXCEPT {}\n    DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}\n    StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}\n    IContext::~IContext() {}\n    IResultCapture::~IResultCapture() {}\n    ITestCase::~ITestCase() {}\n    ITestCaseRegistry::~ITestCaseRegistry() {}\n    IRegistryHub::~IRegistryHub() {}\n    IMutableRegistryHub::~IMutableRegistryHub() {}\n    IExceptionTranslator::~IExceptionTranslator() {}\n    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}\n    IReporter::~IReporter() {}\n    IReporterFactory::~IReporterFactory() {}\n    IReporterRegistry::~IReporterRegistry() {}\n    IStreamingReporter::~IStreamingReporter() {}\n    AssertionStats::~AssertionStats() {}\n    SectionStats::~SectionStats() {}\n    TestCaseStats::~TestCaseStats() {}\n    TestGroupStats::~TestGroupStats() {}\n    TestRunStats::~TestRunStats() {}\n    CumulativeReporterBase::SectionNode::~SectionNode() {}\n    CumulativeReporterBase::~CumulativeReporterBase() {}\n\n    StreamingReporterBase::~StreamingReporterBase() {}\n    ConsoleReporter::~ConsoleReporter() {}\n    CompactReporter::~CompactReporter() {}\n    IRunner::~IRunner() {}\n    IMutableContext::~IMutableContext() {}\n    IConfig::~IConfig() {}\n    XmlReporter::~XmlReporter() {}\n    JunitReporter::~JunitReporter() {}\n    TestRegistry::~TestRegistry() {}\n    FreeFunctionTestCase::~FreeFunctionTestCase() {}\n    IGeneratorInfo::~IGeneratorInfo() {}\n    IGeneratorsForTest::~IGeneratorsForTest() {}\n    WildcardPattern::~WildcardPattern() {}\n    TestSpec::Pattern::~Pattern() {}\n    TestSpec::NamePattern::~NamePattern() {}\n    TestSpec::TagPattern::~TagPattern() {}\n    TestSpec::ExcludedPattern::~ExcludedPattern() {}\n\n    Matchers::Impl::StdString::Equals::~Equals() {}\n    Matchers::Impl::StdString::Contains::~Contains() {}\n    Matchers::Impl::StdString::StartsWith::~StartsWith() {}\n    Matchers::Impl::StdString::EndsWith::~EndsWith() {}\n\n    void Config::dummy() {}\n\n    namespace TestCaseTracking {\n        ITracker::~ITracker() {}\n        TrackerBase::~TrackerBase() {}\n        SectionTracker::~SectionTracker() {}\n        IndexTracker::~IndexTracker() {}\n    }\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#endif\n\n#ifdef CATCH_CONFIG_MAIN\n// #included from: internal/catch_default_main.hpp\n#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED\n\n#ifndef __OBJC__\n\n// Standard C/C++ main entry point\nint main (int argc, char * argv[]) {\n    return Catch::Session().run( argc, argv );\n}\n\n#else // __OBJC__\n\n// Objective-C entry point\nint main (int argc, char * const argv[]) {\n#if !CATCH_ARC_ENABLED\n    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n#endif\n\n    Catch::registerTestMethods();\n    int result = Catch::Session().run( argc, (char* const*)argv );\n\n#if !CATCH_ARC_ENABLED\n    [pool drain];\n#endif\n\n    return result;\n}\n\n#endif // __OBJC__\n\n#endif\n\n#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED\n#  undef CLARA_CONFIG_MAIN\n#endif\n\n//////\n\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE\" )\n#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \"CATCH_REQUIRE_FALSE\" )\n\n#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, \"\", \"CATCH_REQUIRE_THROWS\" )\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_THROWS_AS\" )\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, \"CATCH_REQUIRE_THROWS_WITH\" )\n#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_NOTHROW\" )\n\n#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK\" )\n#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, \"CATCH_CHECK_FALSE\" )\n#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECKED_IF\" )\n#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECKED_ELSE\" )\n#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \"CATCH_CHECK_NOFAIL\" )\n\n#define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, \"\", \"CATCH_CHECK_THROWS\" )\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_THROWS_AS\" )\n#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, \"CATCH_CHECK_THROWS_WITH\" )\n#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_NOTHROW\" )\n\n#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_THAT\" )\n#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_THAT\" )\n\n#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"CATCH_INFO\" )\n#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_WARN\", msg )\n#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"CATCH_INFO\" )\n#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CATCH_CAPTURE\" )\n#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CATCH_CAPTURE\" )\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n    #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n    #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n    #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n    #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n    #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"CATCH_FAIL\", __VA_ARGS__ )\n    #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_SUCCEED\", __VA_ARGS__ )\n#else\n    #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )\n    #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )\n    #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )\n    #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )\n    #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )\n    #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"CATCH_FAIL\", msg )\n    #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_SUCCEED\", msg )\n#endif\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( \"\", \"\" )\n\n#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )\n#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )\n\n#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )\n\n// \"BDD-style\" convenience wrappers\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#else\n#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( \"Scenario: \" name, tags )\n#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" name, tags )\n#endif\n#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( \"Given: \") + desc, \"\" )\n#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( \" When: \") + desc, \"\" )\n#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( \"  And: \") + desc, \"\" )\n#define CATCH_THEN( desc )     CATCH_SECTION( std::string( \" Then: \") + desc, \"\" )\n#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( \"  And: \") + desc, \"\" )\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, \"REQUIRE\" )\n#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \"REQUIRE_FALSE\" )\n\n#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, \"\", \"REQUIRE_THROWS\" )\n#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, \"REQUIRE_THROWS_AS\" )\n#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, \"REQUIRE_THROWS_WITH\" )\n#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, \"REQUIRE_NOTHROW\" )\n\n#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECK\" )\n#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, \"CHECK_FALSE\" )\n#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECKED_IF\" )\n#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECKED_ELSE\" )\n#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \"CHECK_NOFAIL\" )\n\n#define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, \"\", \"CHECK_THROWS\" )\n#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_THROWS_AS\" )\n#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, \"CHECK_THROWS_WITH\" )\n#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_NOTHROW\" )\n\n#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_THAT\" )\n#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, \"REQUIRE_THAT\" )\n\n#define INFO( msg ) INTERNAL_CATCH_INFO( msg, \"INFO\" )\n#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, \"WARN\", msg )\n#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"INFO\" )\n#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CAPTURE\" )\n#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CAPTURE\" )\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n    #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n    #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n    #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n    #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n    #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"FAIL\", __VA_ARGS__ )\n    #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"SUCCEED\", __VA_ARGS__ )\n#else\n    #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )\n    #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )\n    #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )\n    #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )\n    #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )\n    #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"FAIL\", msg )\n    #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"SUCCEED\", msg )\n#endif\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( \"\", \"\" )\n\n#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )\n#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )\n\n#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )\n\n// \"BDD-style\" convenience wrappers\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n#define SCENARIO( ... ) TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#else\n#define SCENARIO( name, tags ) TEST_CASE( \"Scenario: \" name, tags )\n#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" name, tags )\n#endif\n#define GIVEN( desc )    SECTION( std::string(\"   Given: \") + desc, \"\" )\n#define WHEN( desc )     SECTION( std::string(\"    When: \") + desc, \"\" )\n#define AND_WHEN( desc ) SECTION( std::string(\"And when: \") + desc, \"\" )\n#define THEN( desc )     SECTION( std::string(\"    Then: \") + desc, \"\" )\n#define AND_THEN( desc ) SECTION( std::string(\"     And: \") + desc, \"\" )\n\nusing Catch::Detail::Approx;\n\n#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n"
  },
  {
    "path": "examples/modules/plus-number/unittest/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"plus-number.h\"\n\n#define CATCH_CONFIG_MAIN\n#include \"catch/catch.hpp\"\n\nusing namespace napa::demo;\n\nTEST_CASE(\"PlusNumber: add the given value\", \"[add]\") {\n    PlusNumber plusNumber(3);\n\n    REQUIRE(plusNumber.Add(2) == 5);\n    REQUIRE(plusNumber.Add(3) != 7);\n}\n"
  },
  {
    "path": "examples/modules/plus-number/unittest/run.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar path = require('path');\nvar childProcess = require('child_process');\n\ntry {\n    childProcess.execFileSync(\n        path.join(__dirname, 'bin', process.platform === 'win32'? 'library-test.exe': 'library-test'),\n        [],\n        {\n            cwd: path.join(__dirname, 'bin'),\n            stdio: 'inherit'\n        }\n    );\n}\ncatch(err) {\n    process.exit(1); // Error\n}\n"
  },
  {
    "path": "examples/tutorial/estimate-pi-in-parallel/README.md",
    "content": "# Estimate PI in parallel\nThis example implements an algorithm to [estimate PI using Monte Carlo method](http://mathfaculty.fullerton.edu/mathews/n2003/montecarlopimod.html). It demonstrates how to fan out sub-tasks into multiple JavaScript threads, execute them in parallel and aggregate output into a final result.\n\nIn the implementation, multiple batches of points are evaluated simultaneously in a [napa zone](https://github.com/Microsoft/napajs/wiki/introduction#zone) of 4 workers. Results are aggregated to calculate the final PI after all batches finishes.\n\n## How to run\n1. Go to directory of `examples/tutorial/estimate-pi-in-parallel`\n2. Run `npm install` to install napajs\n3. Run `node estimate-pi-in-parallel.js`\n\n## Program output\nThe table below shows results of PI calculated under different settings, each setting emulates 4,000,000 points evaluated by a napa zone of 4 workers. \n\nThese 4,000,000 points are divided into multiple batches, each setting differs only in number of batches. For settings (1-batch, 2-batch, and 4-batch) whose batch number is less than the worker number, total latency is proportional to the number of batches, that means we have enough workers to pick up coming batches. On the contrary, the 8-batch setting cannot scale linearly due to insufficient free worker, which is expected.\n```\n        # of points     # of batches    # of workers    latency in MS   estimated π     deviation\n        ---------------------------------------------------------------------------------------\n        4000000         1               4               218             3.141958        0.0003653464\n        4000000         2               4               110             3.141953        0.0003603464\n        4000000         4               4               78              3.139600        0.001992654\n        4000000         8               4               62              3.142732        0.001139346\n```\nWe got results under environment:\n\n| Name              | Value                                                                                 |\n|-------------------|---------------------------------------------------------------------------------------|\n|**Processor**      |Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz, 2000 Mhz, 6 Core(s), 12 Logical Processor(s) |\n|**System Type**    |x64-based PC                                                                           |\n|**Physical Memory**|32.0 GB                                                                                |\n|**OS version**     |Microsoft Windows Server 2016 Datacenter                                               |\n"
  },
  {
    "path": "examples/tutorial/estimate-pi-in-parallel/estimate-pi-in-parallel.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar napa = require(\"napajs\");\n\n// Change this value to control number of napa workers initialized.\nconst NUMBER_OF_WORKERS = 4;\n\n// Create a napa zone with number_of_workers napa workers.\nvar zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\n/*\nEstimate the value of π by using a Monte Carlo method.\nTake `points` samples of random x and y values on a\n[0,1][0,1] plane. Calculating the length of the diagonal\ntells us whether the point lies inside, or outside a\nquarter circle running from 0,1 to 1,0. The ratio of the\nnumber of points inside to outside gives us an\napproximation of π/4.\nSee https://en.wikipedia.org/wiki/File:Pi_30K.gif\nfor a visualization of how this works.\n*/\n\nfunction estimatePI(points) {\n    var i = points;\n    var inside = 0;\n\n    while (i-- > 0) {\n        var x = Math.random();\n        var y = Math.random();\n        if ((x * x) + (y * y) <= 1) {\n            inside++;\n        }\n    }\n\n    return inside / points * 4;\n}\n\nfunction run(points, batches) {\n    var start = Date.now();\n\n    var promises = [];\n    for (var i = 0; i < batches; i++) {\n        promises[i] = zone.execute(estimatePI, [points / batches]);\n    }\n    \n    return Promise.all(promises).then(values => {\n        var aggregate = 0;\n        values.forEach(result => aggregate += result.value);\n        printResult(points, batches, aggregate / batches, Date.now() - start);\n    });\n}\n\nfunction printResult(points, batches, pi, ms) {\n    console.log('\\t' + points\n          + '\\t\\t' + batches\n          + '\\t\\t' + NUMBER_OF_WORKERS\n          + '\\t\\t' + ms\n          + '\\t\\t' + pi.toPrecision(7)\n          + '\\t' + Math.abs(pi - Math.PI).toPrecision(7));\n}\n\nconsole.log();\nconsole.log('\\t# of points\\t# of batches\\t# of workers\\tlatency in MS\\testimated π\\tdeviation');\nconsole.log('\\t---------------------------------------------------------------------------------------');\n\n// Run with different # of points and batches in sequence.\nrun(4000000, 1)\n.then(result => run(4000000, 2))\n.then(result => run(4000000, 4))\n.then(result => run(4000000, 8))\n"
  },
  {
    "path": "examples/tutorial/estimate-pi-in-parallel/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"main\": \"./estimate-pi-in-parallel.js\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.0\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/max-square-sub-matrix/README.md",
    "content": "# Max square sub matrix\nThis example implements an algorithm to solve [Max square sub-matrix of all 1s](http://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/) using dynamic programming. It demonstrates parallelism among multiple JavaScript threads via [zone](https://github.com/Microsoft/napajs/wiki/introduction#zone) and cross-thread data sharing via [store](https://github.com/Microsoft/napajs/wiki/introduction#cross-worker-storage).\n\nIn this implementation, all units to be evaluated were divided into 2 * size of the square matrix + 1 layers. Units in next layer were evaluated based on results of units from previous layers. Different layers were evaluated in sequence, while units within the same layer were evaluated in parallel, for there is no dependency between them. Results from previous layers were communicated by a store. \n\nPlease note that this example is to demonstrate the programming paradigm, while itself is NOT performance efficient, since each worker does too little CPU operation and major overhead is on communication.\n\n## How to run\n1. Go to directory of `examples/tutorial/max-square-sub-matrix`\n2. Run `npm install` to install napajs\n3. Run `node max-square-sub-matrix.js`\n\n**Note**: This example uses 'async / await', so Node version that supports ES6 is required. (newer than v7.6.0).\n\n## Program output\nThe output below shows the result of the implementation. By a napa zone with 4 workers, it took 15 ms to find out the max square sub matrix with all 1s for the given 6 * 6 square binary matrix.\n```\n        [ [ 0, 1, 1, 0, 1, 1 ],\n          [ 1, 1, 0, 1, 0, 1 ],\n          [ 0, 1, 1, 1, 0, 1 ],\n          [ 1, 1, 1, 1, 0, 0 ],\n          [ 1, 1, 1, 1, 1, 1 ],\n          [ 0, 0, 0, 0, 0, 0 ] ]\n\n        Max square sub matrix with all 1s\n        -------------------------------------\n            I ends at           : 4\n            J ends at           : 3\n            matrix size         : 3\n            # of workers        : 4\n            Latency in MS       : 15\n        -------------------------------------\n```\nWe got results under environment:\n\n| Name              | Value                                                                                 |\n|-------------------|---------------------------------------------------------------------------------------|\n|**Processor**      |Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz, 2000 Mhz, 6 Core(s), 12 Logical Processor(s) |\n|**System Type**    |x64-based PC                                                                           |\n|**Physical Memory**|32.0 GB                                                                                |\n|**OS version**     |Microsoft Windows Server 2016 Datacenter                                               |\n"
  },
  {
    "path": "examples/tutorial/max-square-sub-matrix/max-square-sub-matrix.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar napa = require(\"napajs\");\n\n// Change this value to control number of napa workers initialized.\nconst NUMBER_OF_WORKERS = 4;\n\n// Create a napa zone with number_of_workers napa workers.\nvar zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\n// Create a napa store with 'sub-matrix-size-store' as its key.\n// It is used to communicate max sub binary matrix size across isolates.\nvar subMatrixSizeStore = napa.store.create('sub-matrix-size-store');\n\nfunction run() {\n    var squareMatrix = [\n        [0, 1, 1, 0, 1, 1],\n        [1, 1, 0, 1, 0, 1],\n        [0, 1, 1, 1, 0, 1],\n        [1, 1, 1, 1, 0, 0],\n        [1, 1, 1, 1, 1, 1],\n        [0, 0, 0, 0, 0, 0]\n    ];\n\n    // Setup all workers with functions to be executed.\n    zone.broadcast(' \\\n        var napa = require(\"napajs\"); \\\n        var zone = napa.zone.get(\"zone\"); \\\n        var store = napa.store.get(\"sub-matrix-size-store\"); \\\n    ');\n    zone.broadcast(get_key_of_store.toString());\n    zone.broadcast(max_square_sub_matrix_with_all_1s_ended_at.toString());\n    zone.broadcast(max_square_sub_matrix_with_all_1s_at_layer.toString());\n    zone.broadcast(max_square_sub_matrix_with_all_1s.toString());\n\n    var start = Date.now();\n\n    // Start to execute.\n    return zone.execute('', 'max_square_sub_matrix_with_all_1s', [squareMatrix])\n        .then(result => {\n            print_result(squareMatrix, Date.now() - start);\n        });\n}\n\n/*\nGiven a binary square matrix, find out the maximum square sub matrix with all 1s. \nFor example, consider the below binary matrix [example_matrix],\n\n    0   1   1   0   1   1\n    1   1   0   1   0   1\n    0   1   1   1   0   1\n    1   1   1   1   0   0\n    1   1   1   1   1   1\n    0   0   0   0   0   0\n\nthe max square sub matrix with all 1s is\n\n    -   -   -   -   -   -\n    -   -   -   -   -   -\n    -   1   1   1   -   -\n    -   1   1   1   -   -\n    -   1   1   1   -   -\n    -   -   -   -   -   -\n\nwith size = 3, and the lowest-rightest element = example_matrix[4, 3].\n\nNotation:\n    SubMatrixSize[i, j]: represents the size of the max square sub matrix with all 1s,\n        whose lowest-rightest element is example_matrix[i, j].\n    Layer of element:\n        Layer_0: [0,0]\n        Layer_1: [0,1][1,0]\n        Layer_2: [0,2][1,1][2,0]\n        Layer_3: [0,3][1,2][2,1][3,0]\n        Layer_4: [0,4][1,3][2,2][3,1][4,0]\n        Layer_5: [0,5][1,4][2,3][3,2][4,1][5,0]\n        Layer_6: [5,1][4,2][3,3][2,4][1,5]\n        Layer_7: [5,2][4,3][3,4][2,5]\n        Layer_8: [5,3][4,4][3,5]\n        Layer_9: [5,4][4,5]\n        Layer_10:[5,5]\n\nAlgorithm:\n    1. SubMatrixSize[i, j] = example_matrix[i, j] when i === 0 or j === 0;\n    2. SubMatrixSize[i, j] = example_matrix[i, j] === 0 ? 0 : \n       Min(SubMatrixSize[i - 1, j], SubMatrixSize[i - 1, j - 1], SubMatrixSize[i, j - 1]) + 1;\n\nBy the above algorithm, the lower-righter layer (with larger layer #)\ncan be evaluated from the results of the upper-lefter layer (with smaller layer #).\nThere are no dependencies between evaluation of the elements in the same layer,\nso evaluation of the elements in the same layer could be parallel.\n*/\nasync function max_square_sub_matrix_with_all_1s(squareMatrix) {\n    var n = squareMatrix.length;\n    var layer = 0;\n\n    // All the layers are evaluated in sequence from upp-left to low-right.\n    while (layer < 2 * n - 1) {\n        await zone.execute('',\n            'max_square_sub_matrix_with_all_1s_at_layer',\n            [squareMatrix, layer]);\n        layer++;\n    }\n}\n\nfunction max_square_sub_matrix_with_all_1s_at_layer(squareMatrix, layer) {\n    var n = squareMatrix.length;\n    var promises = [];\n    var promiseIndex = 0;\n\n    // Evaluate the elements in the current layer in parallel.\n    if (layer < n) {\n        for (var i = 0; i <= layer; i++) {\n            promises[promiseIndex++] = \n                zone.execute('',\n                    'max_square_sub_matrix_with_all_1s_ended_at',\n                    [squareMatrix, i, layer - i]\n                );\n        }\n    }\n    else {\n        for (var j = layer - n + 1; j < n; j++) {\n            promises[promiseIndex++] = \n                zone.execute('',\n                    'max_square_sub_matrix_with_all_1s_ended_at',\n                    [squareMatrix, layer - j, j]\n                );\n        }\n    }\n\n    return Promise.all(promises).then(result => {\n        });\n}\n\n// Evaluate the size of max square sub matrix with all 1s\n// whose lowest-rightest element is the squareMatrix[i, j].\nfunction max_square_sub_matrix_with_all_1s_ended_at(squareMatrix, i, j) {\n    if (i === 0 || j === 0) {\n        store.set(get_key_of_store(i, j), squareMatrix[i][j]);\n    }\n    else {\n        store.set(get_key_of_store(i, j), \n            squareMatrix[i][j] === 0 ?\n                0\n                :\n                Math.min(\n                    store.get(get_key_of_store(i - 1, j)),\n                    store.get(get_key_of_store(i, j - 1)),\n                    store.get(get_key_of_store(i - 1, j - 1))\n                ) + 1\n        );\n    }\n}\n\nfunction get_key_of_store(i, j) {\n    return i + '-' + j;\n}\n\nfunction print_result(squareMatrix, ms) {\n    var n = squareMatrix.length;\n    var maxSize = 0, maxI = 0, maxJ = 0;\n    for (var i = 0; i < n; i++) {\n        for (var j = 0; j < n; j++) {\n            var maxIJ = subMatrixSizeStore.get(get_key_of_store(i, j));\n            if (maxIJ > maxSize) {\n                maxI = i;\n                maxJ = j;\n                maxSize = maxIJ;\n            }\n        }\n    }\n\n    console.log();\n    console.log(squareMatrix);\n\n    console.log();\n    console.log('Max square sub matrix with all 1s');\n    console.log('-------------------------------------');\n    console.log('    I ends at\\t\\t:', maxI);\n    console.log('    J ends at\\t\\t:', maxJ);\n    console.log('    matrix size\\t\\t:', maxSize);\n    console.log('    # of workers\\t:', NUMBER_OF_WORKERS);\n    console.log('    Latency in MS\\t:', ms);\n    console.log('-------------------------------------');\n}\n\n// Run program.\nrun();\n"
  },
  {
    "path": "examples/tutorial/max-square-sub-matrix/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"main\": \"./max-square-sub-matrix.js\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.0\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/napa-runner/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"napa-runer\")\n\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nset(NAPAJS_ROOT ${PROJECT_SOURCE_DIR}/../../..)\nset(NAPAJS_INC ${NAPAJS_ROOT}/inc)\nfind_library(NAPAJS_LIB NAMES napa PATHS ${NAPAJS_ROOT}/bin)\n\n# A stable node version that can build as a library.\nset(NODE_ROOT ${NAPAJS_ROOT}/build/node-v6.10.3)\n\nset(BUILD_TYPE \"Release\")\nif ((DEFINED CMAKE_BUILD_TYPE) AND (CMAKE_BUILD_TYPE STREQUAL \"debug\"))\n    set(BUILD_TYPE \"Debug\")\nendif()\n\n\nset(TARGET_NAME \"${PROJECT_NAME}\")\n\nadd_executable(${TARGET_NAME} \"main.cpp\")\n\ntarget_compile_definitions(${TARGET_NAME} PRIVATE BUILDING_NAPA_EXTENSION)\n\nif(\"${CMAKE_SYSTEM}\" MATCHES \"Linux\")\n\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -pthread\")\n\n    # Include directories\n    target_include_directories(${TARGET_NAME} PRIVATE\n    ${NODE_ROOT}/deps/v8/include\n    ${NAPAJS_INC})\n\n    # TODO #124: Remove dependencies of v8_libbase and icustubdata to embed Napa.js into a c++ program, because they are already dependencies to build napa shared library.\n    find_library(V8_LIBBASE NAMES v8_libbase PATHS ${NODE_ROOT}/out/${BUILD_TYPE}/obj.target/deps/v8/tools/gyp)\n    find_library(ICUSTUBDATA_LIB NAMES icustubdata PATHS ${NODE_ROOT}/out/${BUILD_TYPE}/obj.target/tools/icu)\n\n    # Link libraries\n    target_link_libraries(${TARGET_NAME} PRIVATE\n    ${NAPAJS_LIB}\n    ${CMAKE_DL_LIBS}\n    ${V8_LIBBASE}\n    ${ICUSTUBDATA_LIB}\n    )\n\nelse()\n    message(FATAL_ERROR \"Build solution of this example is not provided for ${CMAKE_SYSTEM}\")\nendif()\n"
  },
  {
    "path": "examples/tutorial/napa-runner/README.md",
    "content": "# Napa runner\nNapa runner is an example to embed Napa.JS into a C++ program. It simply runs JavaScript with all Napa capability without Node dependency from command line.\n\n## How to build\n1. Go to napajs root directory and run `node build.js embed` to build napa library for embeded mode. \n\n**NOTE**: This step may take about 30 mins, because it will build V8 library from Node. We are using node v6.10.3, a stable version can build as a library. It is specified in [embedded.js](https://github.com/Microsoft/napajs/blob/master/scripts/embedded.js) and [napa-runner CMakeLists.txt](https://github.com/Microsoft/napajs/blob/master/examples/tutorial/napa-runner/CMakeLists.txt). Please update both of them if you want to use a different version of Node/V8.\n\n2. Go to directory of `examples/tutorial/napa-runner`, and run `cmake-js build` to build napa runner\n\n**NOTE**: Build solution of napa-runner is provided only for linux system so far. Windows / Mac OS support will come in near future.\n\n## How to use\n1. Run `npm install` to intall required npm modules\n2. Run `./bin/napa-runner emstimate-PI.js`\n\n"
  },
  {
    "path": "examples/tutorial/napa-runner/estimate-PI.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nfunction estimatePI(points) {\n    var i = points;\n    var inside = 0;\n    while (i-- > 0) {\n        if (i%10000 == 0) console.log(i);\n        var x = Math.random();\n        var y = Math.random();\n        if ((x * x) + (y * y) <= 1) {\n            inside++;\n        }\n    }\n        return inside / points * 4;\n}\n\nfunction run() {\n    console.log('start run');\n\n    var napa = require('napajs');\n    console.log('napajs loaded');\n    const NUMBER_OF_WORKERS = 4;\n    var zone = napa.zone.create('zone1', { workers: NUMBER_OF_WORKERS });\n    console.log('zone created with 4 workers');\n\n    var promises = [];\n    for (var i = 0; i < 4; i++) {\n        promises[i] = zone.execute(estimatePI, [40000]);\n    }\n\n    console.log('4 times napa.zone.execution issued.');\n    Promise.all(promises).then(values => {\n        var aggregate = 0;\n        values.forEach(result => aggregate += result.value);\n        console.log('PI: ', aggregate / 4);\n    });\n\n    return 'returned-value-to-cpp-world';\n}\n\nrun();\n"
  },
  {
    "path": "examples/tutorial/napa-runner/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa.h>\n\n#include <iostream>\n#include <fstream>\n#include <sstream>\n\nvoid ReadJSFromFile(std::stringstream& jsStream, const std::string& jsFileName);\n\nint main(int argc, char* argv[])\n{\n    if (argc != 2) {\n        std::cout << \"usage: napa-runner <js-file>\" << std::endl;\n        exit(0);\n    }\n\n    // Read js from user specifed js file.\n    std::stringstream jsStream;\n    ReadJSFromFile(jsStream, argv[1]);\n\n    // Initializes napa with glabal scope settings.\n    napa::Initialize();\n\n    // Create a napa zone with 1 worker.\n    auto mainZone = std::make_unique<napa::Zone>(\"main\", \"--workers 1\");\n\n    // Broadcast js workload.\n    napa::ResultCode resultCode = mainZone->BroadcastSync(jsStream.str());\n    if (resultCode != NAPA_RESULT_SUCCESS) {\n        std::cout << napa_result_code_to_string(resultCode) << std::endl;\n        // Shut down napa.\n        napa::Shutdown();\n        exit(1);\n    }\n\n    // Put a dead loop here to allow all tasks to complete in napa zones before shutting down napa.\n    // TODO #123: Support shut down napa gracefully to save this.\n    while (true) {\n        std::this_thread::sleep_for(std::chrono::milliseconds(1000));\n    }\n\n    // Shut down napa.\n    napa::Shutdown();\n\n    return 0;\n}\n\nvoid ReadJSFromFile(std::stringstream& jsStream, const std::string& jsFileName)\n{\n    std::ifstream jsFile;\n    jsFile.open(jsFileName);\n    if (!jsFile) {\n        std::cout << \"Failed to open js file: \" << jsFileName << std::endl;\n        exit(0);\n    }\n    jsStream << jsFile.rdbuf();\n    jsFile.close();\n}\n\n"
  },
  {
    "path": "examples/tutorial/napa-runner/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.4\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/parallel-quick-sort/README.md",
    "content": "# Parallel Quick Sort\nThis example implements a parallel version of quicksort by napa.js, and compares its performance to that of a serial version. It demonstrates\n1. How does napa.js transport a TypedArray (JavaScript built-in objects) among napa worker transparently. The TypedArray is created from a SharedArrayBuffer.\n2. How does napa.js accelerate a computation heavy task by parallelization.\n\n## How to run\n1. Go to directory of `examples/tutorial/parallel-quick-sort`.\n2. Run `npm install` to install napajs.\n3. Run `node parallel-quick-sort.js`.\n\n**Note**: This example involves TypedArray and SharedArrayBuffer. It requires Node v9.0.0 or newer.\n\n## Program output\nThe table below shows results of the serial quicksort and the parallel one.\n```\nquickSort:              It took ( 1006 ) MS to sort an array with  4194304  elements.\nparallelQuickSort:      It took ( 388 ) MS to sort an array with  4194304  elements.\n```\nBoth of them were executed on a 4 millions length Float64Array. The parallel implementation by napa.js brought 60+% performance gain under my test environment below.\n\n| Name              | Value                                                                                 |\n|-------------------|---------------------------------------------------------------------------------------|\n|**Processor**      |Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz, 2000 Mhz, 6 Core(s), 12 Logical Processor(s) |\n|**System Type**    |x64-based PC                                                                           |\n|**Physical Memory**|32.0 GB                                                                                |\n|**OS version**     |Microsoft Windows Server 2016 Datacenter                                               |\n"
  },
  {
    "path": "examples/tutorial/parallel-quick-sort/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"main\": \"./parallel-quick-sort.js\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.8\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/parallel-quick-sort/parallel-quick-sort.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nconst napa = require(\"napajs\");\nconst assert = require(\"assert\");\n\nconst MILLION = 1024 * 1024;\n\n// Change this value to control number of napa workers initialized.\nconst NUMBER_OF_WORKERS = 4;\n\n// Create a napa zone with number_of_workers napa workers.\nlet zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\n// Swap elements with index 'left' and 'right' in a TypedArray.\nfunction swap(typedArray, left, right) {\n    let temp = typedArray[left];\n    typedArray[left] = typedArray[right];\n    typedArray[right] = temp;\n}\n\nfunction partition(typedArray, left, right) {\n    let pi = left - 1;\n    let pivot = typedArray[right];\n\n    for (let index = left; index <= right; index++) {\n        if (typedArray[index] <= pivot) {\n            swap(typedArray, ++pi, index);\n        }\n    }\n\n    return pi;\n}\n\nfunction quickSort(typedArray, left, right) {\n    if (right <= left) return;\n\n    let pi = partition(typedArray, left, right);\n    quickSort(typedArray, left, pi - 1);\n    quickSort(typedArray, pi + 1, right);\n}\n\n// A parallel version of quicksort by napa.js.\n// After partition, if any part (left or right) is longer than parallelLength,\n// it will recursively execute parallelQuickSort, otherwise, it will execute quickSort.\nfunction parallelQuickSort(typedArray, left, right, parallelLength) {\n    if (right <= left) return;\n\n    let pi = global.partition(typedArray, left, right);\n\n    let promises = [];\n\n    if (pi - left >= parallelLength) {\n        promises.push(global.napa.zone.get('zone').execute('', 'parallelQuickSort', [typedArray, left, pi - 1, parallelLength]));\n    } else {\n        promises.push(global.napa.zone.get('zone').execute('', 'quickSort', [typedArray, left, pi - 1]));\n    }\n\n    if (right - pi >= parallelLength) {\n        promises.push(global.napa.zone.get('zone').execute('', 'parallelQuickSort', [typedArray, pi + 1, right, parallelLength]));\n    } else {\n        promises.push(global.napa.zone.get('zone').execute('', 'quickSort', [typedArray, pi + 1, right]));\n    }\n\n    return Promise.all(promises).then(values => {return true;});\n}\n\nfunction run(length) {\n    let sab1 = new SharedArrayBuffer(length * 8);\n    let ta1 = new Float64Array(sab1);\n    let sab2 = new SharedArrayBuffer(length * 8);\n    let ta2 = new Float64Array(sab2);\n\n    // Initialize the 2 TypedArrays with the same random numbers.\n    for (let i = 0; i < length; i++) {\n        let temp = Math.random();\n        ta1[i] = temp;\n        ta2[i] = temp;\n    }\n\n    // Execute quickSort.\n    let start1 = Date.now();\n    quickSort(ta1, 0, length - 1);\n    console.log('quickSort:\\t\\tIt took (', Date.now() - start1, ') MS to sort an array with ', length, ' elements.');\n    // Assert the TypedArray has been sorted in ascending order.\n    for (let i = 0; i < length - 1; i++) {\n        assert(ta1[i] <= ta1[i + 1], 'the array is not in ascending order after quicksort.')\n    }\n\n    // Execute parallelQuickSort.\n    let parallelLength = length / NUMBER_OF_WORKERS;\n    let start2 = Date.now();\n    return zone.execute(parallelQuickSort, [ta2, 0, length - 1, parallelLength]).then(result => {\n        console.log('parallelQuickSort:\\tIt took (', Date.now() - start2, ') MS to sort an array with ', length, ' elements.');\n\n        // Assert the TypedArray has been sorted in ascending order.\n        for (let i = 0; i < length - 1; i++) {\n            assert(ta2[i] <= ta2[i + 1], 'the array is not in ascending order after quicksort.')\n        }\n    });\n}\n\n// Bootstrap zone workers.\nzone.broadcast('napa = require(\"napajs\");');\nzone.broadcast(swap.toString());\nzone.broadcast(partition.toString());\nzone.broadcast(quickSort.toString());\nzone.broadcast(parallelQuickSort.toString());\n\nconsole.log();\n\n// Run with length of 4 millions.\nrun(4 * MILLION);\n"
  },
  {
    "path": "examples/tutorial/recursive-fibonacci/README.md",
    "content": "# Recursive Fibonacci\nThis example implements an algorithm to calculate [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) in a distributed recursive way. \n\nRecursion is supported on a single thread by JavaScript language, how if we want to involve multiple JavaScript threads to collaborate on a task? Since recursion will block caller until callee returns, dispatching recursive tasks to other threads will soon block all threads, which leads to deadlock. This example demonstrates recursive dispatching using [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), that is, current thread will continue to serve other tasks while its sub-tasks are pending, and resume work once sub-tasks complete. \n\nPlease note that this example is to demonstrate the programming paradigm, while itself is *NOT* performance efficient, since each worker does too little CPU operation (simply '+') and major overhead is on communication. \n\n## How to run\n1. Go to directory of `examples/tutorial/recursive-fibonacci`\n2. Run `npm install`to install napajs\n3. Run `node recursive-fibonacci.js`\n\n## Program output\nTable below shows statistics of calculating Nth Fibonacci number by a napa zone with 4 workers.\n```\n        Nth     Fibonacci       # of workers    latency in MS\n        -----------------------------------------------------------\n        10      55              4               46\n        11      89              4               47\n        12      144             4               47\n        13      233             4               47\n        14      377             4               94\n        15      610             4               140\n        16      987             4               266\n```\nWe got results under environment:\n\n| Name              | Value                                                                                 |\n|-------------------|---------------------------------------------------------------------------------------|\n|**Processor**      |Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz, 2000 Mhz, 6 Core(s), 12 Logical Processor(s) |\n|**System Type**    |x64-based PC                                                                           |\n|**Physical Memory**|32.0 GB                                                                                |\n|**OS version**     |Microsoft Windows Server 2016 Datacenter                                               |\n"
  },
  {
    "path": "examples/tutorial/recursive-fibonacci/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"main\": \"./recursive-fibonacci.js\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.0\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/recursive-fibonacci/recursive-fibonacci.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar napa = require(\"napajs\");\n\n// Change this value to control number of napa workers initialized.\nconst NUMBER_OF_WORKERS = 4;\n\n// Create a napa zone with number_of_workers napa workers.\nvar zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\n/*\nFibonacci sequence starts with 0 and 1,\nwhich we'll think of as the zeroth and first Fibonacci numbers,\nand each succeeding number is the sum of the two preceding Fibonacci numbers.\nThus, the second number is 0 + 1 = 1.\nAnd to get the third Fibonacci number, we'd sum the first (1) and the second (1) to get 2.\nAnd the fourth is the sum of the second (1) and the third (2), which is 3.\nAnd so on.\n\nn:              |   0   1   2   3   4   5   6   7   8   9   10  11  ...\n-------------------------------------------------------------------------\nNTH Fibonacci:  |   0   1   1   2   3   5   8   13  21  34  55  89  ...\n*/\n\nfunction fibonacci(n) {\n    if (n <= 1) {\n        return n;\n    }\n\n    var p1 = zone.execute(\"\", \"fibonacci\", [n - 1]);\n    var p2 = zone.execute(\"\", \"fibonacci\", [n - 2]);\n\n    // Returning promise to avoid blocking each worker.\n    return Promise.all([p1, p2]).then(([result1, result2]) => {\n        return result1.value + result2.value;\n    });\n}\n\nfunction run(n) {\n    var start = Date.now();\n\n    return zone.execute('', \"fibonacci\", [n])\n        .then(result => {\n            printResult(n, result.value, Date.now() - start);\n            return result.value;\n        });\n}\n\nfunction printResult(nth, fibonacci, ms) {\n    console.log('\\t' + nth\n          + '\\t' + fibonacci\n          + '\\t\\t' + NUMBER_OF_WORKERS\n          + '\\t\\t' + ms);\n}\n\nconsole.log();\nconsole.log('\\tNth\\tFibonacci\\t# of workers\\tlatency in MS');\nconsole.log('\\t-----------------------------------------------------------');\n\n// Broadcast declaration of 'napa' and 'zone' to napa workers.\nzone.broadcast(' \\\n    var napa = require(\"napajs\"); \\\n    var zone = napa.zone.get(\"zone\"); \\\n');\n// Broadcast function declaration of 'fibonacci' to napa workers.\nzone.broadcast(fibonacci.toString());\n\n// Run fibonacci evaluation in sequence.\nrun(10)\n.then(result => run(11))\n.then(result => run(12))\n.then(result => run(13))\n.then(result => run(14))\n.then(result => run(15))\n.then(result => run(16))\n"
  },
  {
    "path": "examples/tutorial/synchronized-loading/README.md",
    "content": "# Synchronized loading\nThis example implements a shared phone book component. The component will not load data until the first lookup request happens. When it starts to load data, it ensures the loading will run only once. \n\nThe component is implemented using lazy-loading pattern with the use of [`napa.sync.Lock`](./../../../docs/api/sync.md#interface-lock).\n\n## How to run\n1. Go to directory of `examples/tutorial/synchronized-loading`\n2. Run `npm install` to install napajs\n3. Run `node synchronized-loading.js`\n\n## Program output\nThe output below shows one possible result. The sequence of the output may be different but the data loading will always run once only.\n```\n[lookupPhoneNumber] Start to lookup phone number of david.\n[lookupPhoneNumber] Start to lookup phone number of wade.\n[load_data] loading...\n[lookupPhoneNumber] Start to lookup phone number of lisa.\n[lookupPhoneNumber] wade : <not found>.\n[lookupPhoneNumber] lisa : 567-888-9999.\n[lookupPhoneNumber] david : 123-444-5555.\n[run] All operations are completed.\n```\n"
  },
  {
    "path": "examples/tutorial/synchronized-loading/package.json",
    "content": "{\n    \"name\": \"napajs-tutorial\",\n    \"version\": \"0.1.0\",\n    \"author\": \"napajs\",\n    \"main\": \"./synchronized-loading.js\",\n    \"dependencies\": {\n        \"napajs\": \">= 0.1.8\"\n    }\n}\n"
  },
  {
    "path": "examples/tutorial/synchronized-loading/phone-book-data.json",
    "content": "{\n    \"ashley\": \"123-456-7890\",\n    \"david\": \"123-444-5555\",\n    \"lisa\": \"567-888-9999\",\n    \"tony\": \"456-789-0000\"\n}\n"
  },
  {
    "path": "examples/tutorial/synchronized-loading/phone-book.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nconst napa = require(\"napajs\");\nconst store = napa.store.getOrCreate('my-phone-book');\n\nconst initialize = function () {\n    store.set('_loadLock', napa.sync.createLock());\n}\n\nconst load_data = function () {\n    // load data. This function should run only once.\n    console.log('[load_data] loading...');\n    \n    const fs = require('fs');\n    let phoneBookData = JSON.parse(fs.readFileSync('./phone-book-data.json').toString());\n\n    for (let name in phoneBookData) {\n        store.set(name, phoneBookData[name]);\n    }\n    store.set('_loaded', true);\n}\n\nlet loaded = false;\nconst lookup = function (name) {\n    if (!loaded) {\n        const lock = store.get('_loadLock');\n        lock.guardSync(function() {\n            if (!store.get('_loaded')) {\n                load_data();\n            }\n        });\n        loaded = true;\n    }\n\n    return store.get(name);\n};\n\nmodule.exports.initialize = initialize;\nmodule.exports.lookup = lookup;\n"
  },
  {
    "path": "examples/tutorial/synchronized-loading/synchronized-loading.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nconst napa = require(\"napajs\");\n\n// Change this value to control number of napa workers initialized.\nconst NUMBER_OF_WORKERS = 4;\n\n// Create a napa zone with number_of_workers napa workers.\nconst zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\nfunction run() {\n    // Initialize the phone book component\n    const phoneBook = require('./phone-book');\n    phoneBook.initialize();\n    \n    // Setup all workers with functions to be executed.\n    zone.broadcast(' \\\n        var napa = require(\"napajs\"); \\\n        var zone = napa.zone.get(\"zone\"); \\\n        var phoneBook = require(\"./phone-book\"); \\\n    ');\n    zone.broadcast(lookupPhoneNumber.toString());\n\n    var tasks = [];\n    tasks.push(zone.execute('', 'lookupPhoneNumber', ['david']));\n    tasks.push(zone.execute('', 'lookupPhoneNumber', ['lisa']));\n    tasks.push(zone.execute('', 'lookupPhoneNumber', ['wade']));\n\n    Promise.all(tasks).then(function () {\n        console.log('[run] All operations are completed.');\n    });\n}\n\nfunction lookupPhoneNumber(name) {\n    console.log(`[lookupPhoneNumber] Start to lookup phone number of ${name}.`);\n    var n = phoneBook.lookup(name);\n    console.log(`[lookupPhoneNumber] ${name} : ${n ? n : '<not found>'}.`);\n}\n\n// Run program.\nrun();\n"
  },
  {
    "path": "inc/napa/assert.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <iostream>\n#include <exception> \n\n#include <stdarg.h>\n\n/// <summary> The maximum message length of a single assert call. Anything over will be truncated. </summary>\nstatic constexpr size_t MAX_ASSERT_MESSAGE_SIZE = 512;\n\ninline void OutputAssertMessage(const char* condition, const char* file, int line, const char* format, ...) {\n    char message[MAX_ASSERT_MESSAGE_SIZE];\n\n    va_list args;\n    va_start(args, format);\n    int size = vsnprintf(message, MAX_ASSERT_MESSAGE_SIZE, format, args);\n    va_end(args);\n\n    if (size >= 0) {\n        std::cerr << \"Assertion failed: `\" << condition << \"`, file \" << file << \", line \" << line\n            << \" : \" << message << \".\" << std::endl;\n    }\n}\n\n#define NAPA_ASSERT(condition, format, ...) do {                                    \\\n    if (!(condition)) {                                                             \\\n        OutputAssertMessage(#condition, __FILE__, __LINE__, format, ##__VA_ARGS__); \\\n        std::terminate();                                                           \\\n    }                                                                               \\\n} while (false)\n\n#define NAPA_FAIL(message) NAPA_ASSERT(false, message)"
  },
  {
    "path": "inc/napa/async.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#ifdef BUILDING_NAPA_EXTENSION\n#include \"napa/zone/napa-async-runner.h\"\n#else\n#include \"napa/zone/node-async-runner.h\"\n#endif\n\n"
  },
  {
    "path": "inc/napa/capi.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"napa/exports.h\"\n#include \"napa/types.h\"\n\n/// <summary> Creates a napa zone. </summary>\n/// <param name=\"id\"> A unique id for the zone. </param>\n/// <remarks>\n///     This function returns a handle that must be release when it's no longer needed.\n///     Napa keeps track of all zone handles and destroys the zone when all handles have been released.\n/// </remarks>\nEXTERN_C NAPA_API napa_zone_handle napa_zone_create(napa_string_ref id);\n\n/// <summary> Retrieves a zone by id. </summary>\n/// <param name=\"id\"> A unique id for the zone. </param>\n/// <returns> The zone handle if exists, null otherwise. </returns>\n/// <remarks>\n///     This function returns a handle that must be release when it's no longer needed.\n///     Napa keeps track of all zone handles and destroys the zone when all handles have been released.\n/// </remarks>\nEXTERN_C NAPA_API napa_zone_handle napa_zone_get(napa_string_ref id);\n\n/// <summary> Retrieves the current zone. </summary>\n/// <returns> The zone handle if this thread is associated with one, null otherwise. </returns>\n/// <remarks>\n///     This function returns a handle that must be release when it's no longer needed.\n///     Napa keeps track of all zone handles and destroys the zone when all handles have been released.\n/// </remarks>\nEXTERN_C NAPA_API napa_zone_handle napa_zone_get_current();\n\n/// <summary> Releases the zone handle. When all handles for a zone are released the zone is destroyed. </summary>\n/// <param name=\"handle\"> The zone handle. </param>\nEXTERN_C NAPA_API napa_result_code napa_zone_release(napa_zone_handle handle);\n\n/// <summary>\n///     Initializes the napa zone, providing specific settings.\n///     The provided settings override any settings that were previously set.\n///     TODO: specify public settings here\n/// </summary>\n/// <param name=\"handle\"> The zone handle. </param>\n/// <param name=\"settings\"> The settings string. </param>\nEXTERN_C NAPA_API napa_result_code napa_zone_init(\n    napa_zone_handle handle,\n    napa_string_ref settings);\n\n/// <summary> Retrieves the zone id. </summary>\n/// <param name=\"handle\"> The zone handle. </param>\nEXTERN_C NAPA_API napa_string_ref napa_zone_get_id(napa_zone_handle handle);\n\n/// <summary> Executes a pre-loaded function asynchronously on all zone workers. </summary>\n/// <param name=\"handle\"> The zone handle. </param>\n/// <param name=\"spec\"> The function spec to call. </param>\n/// <param name=\"callback\"> A callback that is triggered when broadcast is done. </param>\n/// <param name=\"context\"> An opaque pointer that is passed back in the callback. </param>\nEXTERN_C NAPA_API void napa_zone_broadcast(\n    napa_zone_handle handle,\n    napa_zone_function_spec spec,\n    napa_zone_broadcast_callback callback,\n    void* context);\n\n/// <summary> Executes a pre-loaded function asynchronously in a single zone worker. </summary>\n/// <param name=\"handle\"> The zone handle. </param>\n/// <param name=\"spec\"> The function spec to call. </param>\n/// <param name=\"callback\"> A callback that is triggered when execution is done. </param>\n/// <param name=\"context\"> An opaque pointer that is passed back in the callback. </param>\nEXTERN_C NAPA_API void napa_zone_execute(\n    napa_zone_handle handle,\n    napa_zone_function_spec spec,\n    napa_zone_execute_callback callback,\n    void* context);\n\n/// <summary>\n///     Global napa initialization. Invokes initialization steps that are cross zones.\n///     The settings passed represent the defaults for all the zones\n///     but can be overriden in the zone initialization API.\n///     TODO: specify public settings here.\n/// </summary>\n/// <param name=\"settings\"> The settings string. </param>\nEXTERN_C NAPA_API napa_result_code napa_initialize(napa_string_ref settings);\n\n/// <summary>\n///     Same as napa_initialize only accepts arguments as provided by console\n/// </summary>\n/// <param name=\"argc\"> Number of arguments. </param>\n/// <param name=\"argv\"> The arguments. </param>\nEXTERN_C NAPA_API napa_result_code napa_initialize_from_console(\n    int argc,\n    const char* argv[]);\n\n/// <summary> Invokes napa shutdown steps. All non released zones will be destroyed. </summary>\nEXTERN_C NAPA_API napa_result_code napa_shutdown();\n\n/// <summary> Convert the napa result code to its string representation. </summary>\n/// <param name=\"code\"> The result code. </param>\nEXTERN_C NAPA_API const char* napa_result_code_to_string(napa_result_code code);\n\n/// <summary> Set customized allocator, which will be used for napa_allocate and napa_deallocate.\n/// If user doesn't call napa_allocator_set, C runtime malloc/free from napa.dll will be used. </summary>\n/// <param name=\"allocate_callback\"> Function pointer for allocating memory, which should be valid during the entire process. </param>\n/// <param name=\"deallocate_callback\"> Function pointer for deallocating memory, which should be valid during the entire process. </param>\nEXTERN_C NAPA_API void napa_allocator_set(\n    napa_allocate_callback allocate_callback, \n    napa_deallocate_callback deallocate_callback);\n\n/// <summary> Allocate memory using napa allocator from napa_allocator_set, which is using C runtime ::malloc if not called. </summary>\n/// <param name=\"size\"> Size of memory requested in byte. </param>\n/// <returns> Allocated memory. </returns>\nEXTERN_C NAPA_API void* napa_allocate(size_t size);\n\n/// <summary> Free memory using napa allocator from napa_allocator_set, which is using C runtime ::free if not called. </summary>\n/// <param name=\"pointer\"> Pointer to memory to be freed. </param>\n/// <param name=\"size_hint\"> Hint of size to deallocate. </param>\nEXTERN_C NAPA_API void napa_deallocate(void* pointer, size_t size_hint);\n\n/// <summary> Allocate memory using C runtime ::malloc from napa.dll. </summary>\n/// <param name=\"size\"> Size of memory requested in byte. </param>\n/// <returns> Allocated memory. </returns>\nEXTERN_C NAPA_API void* napa_malloc(size_t size);\n\n/// <summary> Free memory using C runtime ::free from napa.dll. </summary>\n/// <param name=\"pointer\"> Pointer to memory to be freed. </param>\n/// <param name=\"size_hint\"> Hint of size to deallocate. </param>\nEXTERN_C NAPA_API void napa_free(void* pointer, size_t size_hint);\n"
  },
  {
    "path": "inc/napa/exports.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n// Microsoft Windows\n#if defined(_WIN32) || defined(__WIN32__)\n    #define DLL_EXPORT __declspec(dllexport)\n    #define DLL_IMPORT __declspec(dllimport)\n// Linux\n#elif defined(__GNUC__)\n    #define DLL_EXPORT __attribute__((visibility(\"default\")))\n    #define DLL_IMPORT\n#else\n    static_assert(false, \"Unknown dynamic link import/export semantics\");\n#endif\n\n// API exported from napa.dll\n#ifdef NAPA_EXPORTS\n    #define NAPA_API DLL_EXPORT\n#else\n    #define NAPA_API DLL_IMPORT\n#endif // NAPA_EXPORTS\n\n// API exported from napa-binding. (both napa.dll and napa-binding.node)\n#ifdef NAPA_BINDING_EXPORTS\n    #define NAPA_BINDING_API DLL_EXPORT\n#else\n    #define NAPA_BINDING_API DLL_IMPORT\n#endif // NAPA_BINDING_EXPORTS\n\n\n#ifdef __cplusplus\n#define EXTERN_C extern \"C\"\n#else\n#define EXTERN_C\n#endif // __cplusplus\n"
  },
  {
    "path": "inc/napa/log.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/assert.h>\n#include <napa/providers/logging.h>\n\n#include <stdarg.h>\n\n/// <summary> The maximum string length of a single log call. Anything over will be truncated. </summary>\nconst size_t LOG_MAX_SIZE = 512;\n\ninline void LogFormattedMessage(\n    napa::providers::LoggingProvider& logger,\n    const char* section,\n    napa::providers::LoggingProvider::Verboseness level,\n    const char* traceId,\n    const char* file,\n    int line,\n    const char* format, ...) {\n\n    char message[LOG_MAX_SIZE];\n    va_list args;\n    va_start(args, format);\n    int size = vsnprintf(message, LOG_MAX_SIZE, format, args);\n    va_end(args);\n\n    NAPA_ASSERT(size >= 0, \"Log formatting error, probably wrong format encoding\");\n    logger.LogMessage(section, level, traceId, file, line, message);\n}\n\n#ifndef NAPA_LOG_DISABLED\n\n#define LOG(section, level, traceId, format, ...) do {                                                   \\\n    auto& logger = napa::providers::GetLoggingProvider();                                                \\\n    if (logger.IsLogEnabled(section, level)) {                                                           \\\n        LogFormattedMessage(logger, section, level, traceId, __FILE__, __LINE__, format, ##__VA_ARGS__); \\\n    }                                                                                                    \\\n} while (false)\n\n#else\n\n// Do nothing without generating any \"unreferenced variable\" warnings.\ntemplate <typename... Types> inline void LOG(Types&&...) {}\n\n#endif\n\n#define LOG_ERROR(section, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Error, \"\", format, ##__VA_ARGS__)\n\n#define LOG_ERROR_WITH_TRACEID(section, traceId, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Error, traceId, format, ##__VA_ARGS__)\n\n#define LOG_WARNING(section, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Warning, \"\", format, ##__VA_ARGS__)\n\n#define LOG_WARNING_WITH_TRACEID(section, traceId, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Warning, traceId, format, ##__VA_ARGS__)\n\n#define LOG_INFO(section, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Info, \"\", format, ##__VA_ARGS__)\n\n#define LOG_INFO_WITH_TRACEID(section, traceId, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Info, traceId, format, ##__VA_ARGS__)\n\n#define LOG_DEBUG(section, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Debug, \"\", format, ##__VA_ARGS__)\n\n#define LOG_DEBUG_WITH_TRACEID(section, traceId, format, ...) \\\n    LOG(section, napa::providers::LoggingProvider::Verboseness::Debug, traceId, format, ##__VA_ARGS__)\n\n// Macro NAPA_DEBUG is used to help debugging Napa source code.\n#if defined(NAPA_DEBUG_ENABLED)\n\n#define NAPA_DEBUG(section, format, ...) LOG_DEBUG(section, format, ##__VA_ARGS__)\n\n#else\n\n// Do nothing without generating any \"unreferenced variable\" warnings.\n#define NAPA_DEBUG(section, format, ...) ((void)0)\n\n#endif\n"
  },
  {
    "path": "inc/napa/memory/allocator-debugger.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\r\n// Licensed under the MIT license.\r\n\r\n#pragma once\r\n\r\n#include <napa/memory/allocator.h>\r\n\r\n#include <atomic>\r\n#include <memory>\r\n#include <sstream>\r\n\r\nnamespace napa {\r\nnamespace memory {\r\n\r\n    /// <summary> Interface for allocator debugger. </summary>\r\n    class AllocatorDebugger: public Allocator {\r\n    public:\r\n        /// <summary> Get allocator debug information in JSON. \r\n        /// It's up to implementation to decide the schema of JSON.\r\n        /// </summary>\r\n        virtual std::string GetDebugInfo() const = 0;\r\n    \r\n    protected:\r\n        virtual ~AllocatorDebugger() = default;\r\n    };\r\n\r\n    /// <summary> Simple allocator debugger that reports total allocate/deallocate count and total size allocated. </summary>\r\n    class SimpleAllocatorDebugger: public AllocatorDebugger {\r\n    public:\r\n        /// <summary> Constructor </summary>\r\n        /// <param name=\"allocator\"> Actual allocator to allocate/deallocate memory. </summary>\r\n        SimpleAllocatorDebugger(std::shared_ptr<Allocator> allocator)\r\n          : _allocator(std::move(allocator)),\r\n            _allocateCount(0),\r\n            _deallocateCount(0),\r\n            _allocatedSize(0),\r\n            _deallocatedSize(0) {\r\n            std::stringstream stream;\r\n            stream << \"SimpleAllocatorDebugger<\"\r\n                << _allocator->GetType()\r\n                << \">\";\r\n            _typeName = stream.str();\r\n        }\r\n\r\n        /// <summary> Copy constructor </summary>\r\n        SimpleAllocatorDebugger(const SimpleAllocatorDebugger& other)\r\n          : _allocator(other._allocator),\r\n            _typeName(other._typeName),\r\n            _allocateCount(other._allocateCount.load()),\r\n            _deallocateCount(other._deallocateCount.load()),\r\n            _allocatedSize(other._allocatedSize.load()),\r\n            _deallocatedSize(other._deallocatedSize.load()) {\r\n        }\r\n\r\n        /// <summary> Allocate memory of given size. </summary>\r\n        /// <param name=\"size\"> Requested size. </summary>\r\n        /// <returns> Allocated memory. May throw if error happens. </returns>\r\n        void* Allocate(size_t size) override {\r\n            _allocateCount++;\r\n            _allocatedSize += size;\r\n            return _allocator->Allocate(size);\r\n        }\r\n\r\n        /// <summary> Deallocate memory allocated from this allocator. </summary>\r\n        /// <param name=\"memory\"> Pointer to the memory. </summary>\r\n        /// <param name=\"sizeHint\"> Hint of size to delete. 0 if not available from caller. </summary>\r\n        /// <returns> None. May throw if error happens. </returns>\r\n        void Deallocate(void* memory, size_t sizeHint) override {\r\n            _deallocateCount++;\r\n            _deallocatedSize += sizeHint;\r\n            _allocator->Deallocate(memory, sizeHint);\r\n        }\r\n\r\n        /// <summary> Get allocator type for better debuggability. </summary>\r\n        const char* GetType() const override {\r\n            return _typeName.c_str();\r\n        }\r\n\r\n        /// <summary> Get allocator debug information in JSON. \r\n        /// Allocator debugger should own returned buffer.\r\n        /// </summary>\r\n        std::string GetDebugInfo() const override {\r\n            std::stringstream stream;\r\n            stream << \"{ \"\r\n                << \"\\\"allocate\\\": \" << _allocateCount\r\n                << \", \"\r\n                << \"\\\"deallocate\\\": \" << _deallocateCount\r\n                << \", \"\r\n                << \"\\\"allocatedSize\\\": \" << _allocatedSize\r\n                << \", \"\r\n                << \"\\\"deallocatedSize\\\": \" << _deallocatedSize\r\n                << \" }\";\r\n\r\n            return stream.str();\r\n        }\r\n\r\n        /// <summary> Tell if another allocator equals to this allocator. </summary>\r\n        bool operator==(const Allocator& other) const override {\r\n            return strcmp(other.GetType(), GetType()) == 0\r\n                && (_allocator == dynamic_cast<const SimpleAllocatorDebugger*>(&other)->_allocator);\r\n        }\r\n\r\n    private:\r\n        std::shared_ptr<Allocator> _allocator;\r\n        std::string _typeName;\r\n\r\n        std::atomic<size_t> _allocateCount;\r\n        std::atomic<size_t> _deallocateCount;\r\n        std::atomic<size_t> _allocatedSize;\r\n        std::atomic<size_t> _deallocatedSize;\r\n    };\r\n}\r\n}\r\n"
  },
  {
    "path": "inc/napa/memory/allocator.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n#include <cstddef>\n\nnamespace napa {\nnamespace memory {\n\n    /// <summary> Interface for allocator. </summary>\n    class Allocator {\n    public:\n        /// <summary> Allocate memory of given size. </summary>\n        /// <param name=\"size\"> Requested size. </summary>\n        /// <returns> Allocated memory. May throw if error happens. </returns>\n        virtual void* Allocate(size_t size) = 0;\n\n        /// <summary> Deallocate memory allocated from this allocator. </summary>\n        /// <param name=\"memory\"> Pointer to the memory. </summary>\n        /// <param name=\"sizeHint\"> Hint of size to delete. 0 if not available from caller. </summary>\n        /// <returns> None. May throw if error happens. </returns>\n        virtual void Deallocate(void* memory, size_t sizeHint) = 0;\n\n        /// <summary> Get allocator type for better debuggability. </summary>\n        virtual const char* GetType() const = 0;\n\n        /// <summary> Tell if another allocator equals to this allocator. </summary>\n        virtual bool operator==(const Allocator& other) const = 0;\n\n        /// <summary> Can only be destructed by child class. </summary>\n        virtual ~Allocator() = default;\n    };\n\n    /// <summary> Get a long living CRT allocator for convenience. User can create their own as well.</summary>\n    NAPA_API Allocator& GetCrtAllocator();\n\n    /// <summary> Get a long living default allocator for convenience. User can create their own as well.</summary>\n    NAPA_API Allocator& GetDefaultAllocator();\n}\n}"
  },
  {
    "path": "inc/napa/memory/common.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/capi.h>\n#include <napa/memory/allocator.h>\n#include <napa/stl/allocator.h>\n#include <memory>\n#include <type_traits>\n\nnamespace napa {\nnamespace memory {\n    /// <summary> Deleter using Napa's default allocator. </summary>\n    template <typename T>\n    void DefaultDeleter(T* object) {\n        static_assert(std::is_destructible<T>::value, \"Not destructible.\");\n        object->~T();\n        ::napa_deallocate(object, sizeof(T));\n    }\n\n    /// <summary> std::unique_ptr using Napa default allocator. </summary>\n    template <typename T>\n    using UniquePtr = std::unique_ptr<T, void (*)(T*)>;\n\n    /// <summary> std::make_unique using Napa default allocator. </summary>\n    template <typename T, typename... Args>\n    UniquePtr<T> MakeUnique(Args&&... args) {\n        void* memory = ::napa_allocate(sizeof(T));\n        T* t = new (memory) T(std::forward<Args>(args)...);\n        return UniquePtr<T>(t, DefaultDeleter<T>);\n    }\n\n    /// <summary> std::allocate_shared using napa::memory::Allocator. </summary>\n    template <typename T, typename Alloc, typename... Args>\n    std::shared_ptr<T> AllocateShared(Alloc& allocator, Args&&... args) {\n        return std::allocate_shared<T>(\n            napa::stl::Allocator<T>(allocator), \n            std::forward<Args>(args)...);\n    }\n\n    /// <summary> std::make_shared using Napa default allocator. </summary>\n    template <typename T, typename... Args>\n    std::shared_ptr<T> MakeShared(Args&&... args) {\n        return AllocateShared<T>(\n            GetDefaultAllocator(), \n            std::forward<Args>(args)...);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/memory.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/capi.h>\n#include <napa/memory/allocator.h>\n#include <napa/memory/common.h>\n\n#define NAPA_MALLOC(size) ::napa_malloc(size)\n#define NAPA_FREE(pointer, sizeHint) ::napa_free(pointer, sizeHint)\n\n#define NAPA_SET_DEFAULT_ALLOCATOR(malloc, free) ::napa_allocator_set(malloc, free)\n#define NAPA_RESET_DEFAULT_ALLOCATOR() ::napa_allocator_set(napa_malloc, napa_free)\n#define NAPA_ALLOCATE(size) ::napa_allocate(size)\n#define NAPA_DEALLOCATE(pointer, sizeHint) ::napa_deallocate(pointer, sizeHint)\n\n#define NAPA_DEFAULT_ALLOCATOR napa::memory::GetDefaultAllocator()\n#define NAPA_CRT_ALLOCATOR napa::memory::GetCrtAllocator()\n\n#define NAPA_MAKE_UNIQUE napa::memory::MakeUnique\n#define NAPA_MAKE_SHARED napa::memory::MakeShared\n#define NAPA_ALLOCATE_SHARED napa::memory::AllocateShared"
  },
  {
    "path": "inc/napa/module/binding/basic-wraps.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/binding.h>\n#include <napa/module/shareable-wrap.h>\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\nnamespace binding {\n    /// <summary> It creates a new instance of wrapType with a shared_ptr<T>. </summary>\n    /// <param name=\"object\"> shared_ptr of object. </summary>\n    /// <param name=\"wrapType\"> wrap type from napa-binding, which extends napa::module::Sharable. </param>\n    /// <returns> V8 object of wrapType. </summary>\n    \n    template <typename T>\n    inline v8::Local<v8::Object> CreateShareableWrap(std::shared_ptr<T> object, const char* wrapType = \"SharedPtrWrap\") {\n        auto instance = NewInstance(wrapType, 0, nullptr).ToLocalChecked();\n        ShareableWrap::Set(instance, std::move(object));\n        return instance;\n    }\n}\n}\n}"
  },
  {
    "path": "inc/napa/module/binding/wraps.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/binding/basic-wraps.h>\n#include <napa/memory/allocator.h>\n#include <napa/memory/allocator-debugger.h>\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\nnamespace binding {\n\n    /// <summary> It creates a new instance of AllocatorWrap. </summary>\n    /// <param name=\"allocator\"> shared_ptr of allocator. </summary>\n    /// <returns> V8 object of AllocatorWrap. </summary>\n    inline v8::Local<v8::Object> CreateAllocatorWrap(std::shared_ptr<napa::memory::Allocator> allocator) {\n        return CreateShareableWrap(allocator, \"AllocatorWrap\");\n    }\n\n    /// <summary> It creates a new instance of AllocatorDebuggerWrap. </summary>\n    /// <param name=\"allocator\"> shared_ptr of allocatorDebugger. </summary>\n    /// <returns> V8 object of AllocatorDebuggerWrap. </summary>\n    inline v8::Local<v8::Object> CreateAllocatorDebuggerWrap(std::shared_ptr<napa::memory::AllocatorDebugger> allocatorDebugger) {\n        return CreateShareableWrap(allocatorDebugger, \"AllocatorDebuggerWrap\");\n    }\n}\n}\n}"
  },
  {
    "path": "inc/napa/module/binding.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/assert.h>\n#include <napa/exports.h>\n#include <napa/v8-helpers/maybe.h>\n#include <napa/v8-helpers/string.h>\n#include <napa/v8-helpers/flow.h>\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\nnamespace binding {\n\n    /// <summary> Get 'module' object of napa binding, which is napa-binding.node in Node.JS isolate or napa-binding from core-modules in Napa isolate. </summary>\n    /// <returns> 'module' object for napa binding (napajs/bin/napa-binding.node or napa.dll) </returns>\n    NAPA_BINDING_API v8::Local<v8::Object> GetModule();\n\n    /// <summary> Get 'module.exports' from napa binding. </summary>\n    /// <returns> 'module.exports' object for napa binding (napajs/bin/napa-binding.node or napa.dll) </returns>\n    inline v8::Local<v8::Object> GetBinding() {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::EscapableHandleScope scope(isolate);\n\n        auto bindingModule = GetModule();        \n        auto binding = bindingModule->Get(napa::v8_helpers::MakeV8String(isolate, \"exports\"));\n        NAPA_ASSERT(!binding.IsEmpty() && binding->IsObject(), \"\\\"exports\\\" is not available or not object type.\");\n\n        return scope.Escape(v8::Local<v8::Object>::Cast(binding));\n    }\n\n    /// <summary> It calls 'module.require' from context of napa binding in C++. </summary> \n    /// <param name=\"moduleName\"> Module name in node 'require' convention. </summary>\n    /// <returns> Object if success, or an empty handle with exception thrown. </summary>\n    /// <remarks> \n    ///  1) 'napajs' must be required from JS first before Require can be used. \n    ///  2) Base directory calling 'require' is from 'napajs/bin'. \n    /// </remarks>\n    inline v8::MaybeLocal<v8::Object> Require(const char* moduleName) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::EscapableHandleScope scope(isolate);\n        \n        auto bindingModule = GetModule();\n        auto require = bindingModule->Get(napa::v8_helpers::MakeV8String(isolate, \"require\"));\n        NAPA_ASSERT(!require.IsEmpty() && require->IsFunction(), \"Function \\\"require\\\" is not available from module object\");\n\n        v8::Local<v8::Value> argv[] = { napa::v8_helpers::MakeV8String(isolate, moduleName)};\n        return scope.Escape(\n            napa::v8_helpers::ToLocal<v8::Object>(\n                v8::Local<v8::Function>::Cast(require)->Call(isolate->GetCurrentContext(), bindingModule, 1, argv)));\n    }\n\n    /// <summary> Create a new instance of a wrap type exported from napa binding. </summary>\n    inline v8::MaybeLocal<v8::Object> NewInstance(const char* wrapType, int argc, v8::Local<v8::Value> argv[]) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::EscapableHandleScope scope(isolate);\n\n        auto binding = GetBinding();\n        auto constructor = binding->Get(napa::v8_helpers::MakeV8String(isolate, wrapType));\n        JS_ENSURE_WITH_RETURN(\n            isolate, \n            !constructor.IsEmpty() && constructor->IsFunction(), \n            v8::MaybeLocal<v8::Object>(), \n            \"Wrap type \\\"%s\\\" is not found in napa binding.\",\n            wrapType);\n\n        return scope.Escape(\n            v8::Local<v8::Function>::Cast(constructor)->NewInstance(isolate->GetCurrentContext(), argc, argv)\n                .FromMaybe(v8::Local<v8::Object>()));\n    }\n\n    /// <summary> Call a function from a module under current context </summary>\n    /// <param name=\"moduleName\"> Module name. </param>\n    /// <param name=\"functionName\"> Function from module. </param>\n    /// <param name=\"argc\"> Number of arguments. </param>\n    /// <param name=\"argv\"> Actual arguments. </param>\n    /// <returns> Return value of function, or an empty handle if exception is thrown. </returns>\n    /// <remarks> moduleName should take 'napajs/bin' as base directory. </remarks>\n    inline v8::MaybeLocal<v8::Object> NewInstance(\n        const char* moduleName, \n        const char* className, \n        int argc = 0, \n        v8::Local<v8::Value> argv[] = nullptr) {\n\n        auto isolate = v8::Isolate::GetCurrent();\n        auto context = isolate->GetCurrentContext();\n        v8::EscapableHandleScope scope(isolate);\n\n        auto moduleHandle = Require(moduleName);\n        RETURN_VALUE_ON_PENDING_EXCEPTION(moduleHandle, v8::MaybeLocal<v8::Object>());\n        \n        auto module = moduleHandle.ToLocalChecked();\n        auto constructor = v8::Local<v8::Function>::Cast(\n            module->Get(v8_helpers::MakeV8String(isolate, className)));\n\n        JS_ENSURE_WITH_RETURN(\n            isolate,\n            !constructor.IsEmpty(),\n            v8::MaybeLocal<v8::Object>(),\n            \"Class \\\"%s\\\" is not found in \\\"%s\\\".\",\n            className,\n            moduleName);\n\n        return scope.Escape(\n            constructor->NewInstance(context, argc, argv)\n                .FromMaybe(v8::Local<v8::Object>()));\n    }\n\n    /// <summary> Call a function from a module under current context </summary>\n    /// <param name=\"moduleName\"> Module name. </param>\n    /// <param name=\"functionName\"> Function from module. </param>\n    /// <param name=\"argc\"> Number of arguments. </param>\n    /// <param name=\"argv\"> Actual arguments. </param>\n    /// <returns> Return value of function, or an empty handle if exception is thrown. </returns>\n    /// <remarks> moduleName should take 'napajs/bin' as base directory. </remarks>\n    inline v8::MaybeLocal<v8::Value> Call(\n        const char* moduleName,\n        const char* functionName,\n        int argc = 0,\n        v8::Local<v8::Value> argv[] = nullptr) {\n\n        auto isolate = v8::Isolate::GetCurrent();\n        auto context = isolate->GetCurrentContext();\n        v8::EscapableHandleScope scope(isolate);\n\n        auto moduleHandle = Require(moduleName);\n        RETURN_VALUE_ON_PENDING_EXCEPTION(moduleHandle, v8::MaybeLocal<v8::Value>());\n\n        auto module = moduleHandle.ToLocalChecked();\n        auto function = module->Get(v8_helpers::MakeV8String(isolate, functionName));\n\n        JS_ENSURE_WITH_RETURN(\n            isolate,\n            !function.IsEmpty() && function->IsFunction(),\n            v8::MaybeLocal<v8::Value>(),\n            \"Function \\\"%s\\\" is not found in module \\\"%s\\\".\",\n            functionName,\n            moduleName);\n\n        return scope.Escape(\n            v8::Local<v8::Function>::Cast(function)->Call(context, module, argc, argv)\n                .FromMaybe(v8::Local<v8::Value>()));\n    }\n}\n}\n}"
  },
  {
    "path": "inc/napa/module/common.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers.h>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> It defines a default constructor for a NAPA_OBJECTWRAP sub-class from Javascript world. </summary>\n    /// <remarks>\n    ///     1. const char* WrapType::exportName must be present as a member of WrapType.\n    ///     2. DefaultConstructorCallback must be declared as a friend function in WrapType.\n    /// </remarks>\n    template <typename WrapType>\n    inline void DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate, args.Length() == 0, \"class \\\"%s\\\" doesn't accept any arguments in constructor.'\", WrapType::exportName);\n        JS_ENSURE(isolate, args.IsConstructCall(), \"class \\\"%s\\\" allows constructor call only.\", WrapType::exportName);\n\n        // It's deleted when its Javascript object is garbage collected by V8's GC.\n        auto wrap = new WrapType();\n        wrap->Wrap(args.This());\n        args.GetReturnValue().Set(args.This());\n    }\n\n    /// <summary> Create an instance of WrapType with arguments. </summary> \n    /// <remarks> There are 2 requirements on WrapType:\n    /// 1) static const char* WrapType::exportName must be present as a public member, or add NewInstance as a friend function.\n    /// 2) WrapType must put NAPA_DECLARE_PERSISTENT_CONSTRUCTOR in public, or add NewInstance as a friend function. \n    /// </remarks>\n    template <typename WrapType>\n    inline v8::MaybeLocal<v8::Object> NewInstance(int argc = 0, v8::Local<v8::Value> argv[] = nullptr) {\n        auto constructor = NAPA_GET_PERSISTENT_CONSTRUCTOR(WrapType::exportName, WrapType);\n        return constructor->NewInstance(v8::Isolate::GetCurrent()->GetCurrentContext(), argc, argv);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/module/module-internal.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\n#include <array>\n#include <string>\n#include <tuple>\n#include <unordered_map>\n#include <utility>\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> Napa module version. </summary>\n    static const int32_t MODULE_VERSION = 2;\n\n    /// <summary> Variable name to export for module registration. </summary>\n    static const char* NAPA_MODULE_EXPORT = \"_napa_module\";\n\n    /// <summary> Function pointer to initialize a module. It's called after a module is loaded. </summary>\n    typedef void(*ModuleInitializer)(v8::Local<v8::Object> exports,\n                                     v8::Local<v8::Value> module);\n\n    /// <summary> Module information. </summary>\n    struct NapaModule {\n        /// <summary> Current module version. </summary>\n        int32_t version;\n\n        /// <summary> Module name. </summary>\n        const char* moduleName;\n\n        /// <summary> Function pointer to initialize a module. </summary>\n        ModuleInitializer initializer;\n    };\n\n    /// <summary> It binds the method name with V8 function. </summary>\n    /// <param name=\"exports\"> V8 object to bind with the given callback function. </param>\n    /// <param name=\"name\"> Method name. </param>\n    /// <param name=\"callback\"> Binding V8 function object. </param>\n    template <typename T>\n    void SetMethod(const T& exports,\n                   const char* name,\n                   v8::FunctionCallback callback) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope handleScope(isolate);\n\n        auto functionTemplate = v8::FunctionTemplate::New(isolate, callback);\n        auto function = functionTemplate->GetFunction();\n        auto functionName = v8::String::NewFromUtf8(isolate, name);\n        function->SetName(functionName);\n\n        exports->Set(functionName, function);\n    }\n\n    /// <summary> It binds the method name with V8 prototype function object. </summary>\n    /// <param name=\"functionTemplate\"> V8 function template object to bind with the given callback function. </param>\n    /// <param name=\"name\"> Method name. </param>\n    /// <param name=\"callback\"> Binding V8 function object. </param>\n    inline void SetPrototypeMethod(v8::Local<v8::FunctionTemplate> functionTemplate,\n                                   const char* name,\n                                   v8::FunctionCallback callback) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope handleScope(isolate);\n\n        auto signature = v8::Signature::New(isolate, functionTemplate);\n        functionTemplate->PrototypeTemplate()->Set(\n            v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal).ToLocalChecked(),\n            v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), signature));\n    }\n\n    #define NAPA_REGISTER_MODULE(name, function) \\\n        extern \"C\" { \\\n            DLL_EXPORT napa::module::NapaModule _napa_module = { \\\n                napa::module::MODULE_VERSION, \\\n                #name, \\\n                reinterpret_cast<napa::module::ModuleInitializer>(function) \\\n            }; \\\n        }\n\n    /// <summary> It sets the persistent constructor at the current V8 isolate. </summary>\n    /// <param name=\"name\"> Unique constructor name. It's recommended to use the same name as module. </param>\n    /// <param name=\"constructor\"> V8 persistent function to constructor V8 object. </param>\n    NAPA_API void SetPersistentConstructor(const char* name, v8::Local<v8::Function> constructor);\n\n    /// <summary> It gets the given persistent constructor from the current V8 isolate. </summary>\n    /// <param name=\"name\"> Unique constructor name given at SetPersistentConstructor() call. </param>\n    /// <returns> V8 local function object. </returns>\n    NAPA_API v8::Local<v8::Function> GetPersistentConstructor(const char* name);\n    \n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "inc/napa/module/module-node-compat.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n/// <summary> It binds the method name with V8 function object. </summary>\n#define NODE_SET_METHOD napa::module::SetMethod\n\n/// <summary> It binds the method name with V8 prototype function object. </summary>\n#define NODE_SET_PROTOTYPE_METHOD napa::module::SetPrototypeMethod\n\n/// <summary> It registers the module with the name and the initializer. </summary>\n#define NODE_MODULE NAPA_REGISTER_MODULE"
  },
  {
    "path": "inc/napa/module/object-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <cassert>\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n    // Base class C++ class wrapper to manage lifetime.\n    // It comes from node_object_wrap.h.\n    class ObjectWrap {\n    public:\n\n        ObjectWrap() {\n            _refs = 0;\n        }\n\n        virtual ~ObjectWrap() {\n            if (persistent().IsEmpty()) {\n                return;\n            }\n\n            assert(persistent().IsNearDeath());\n            persistent().ClearWeak();\n            persistent().Reset();\n        }\n\n        template <class T>\n        static inline T* Unwrap(v8::Local<v8::Object> handle) {\n            assert(!handle.IsEmpty());\n            assert(handle->InternalFieldCount() > 0);\n\n            // Cast to ObjectWrap before casting to T.  A direct cast from void\n            // to T won't work right when T has more than one base class.\n            void* ptr = handle->GetAlignedPointerFromInternalField(0);\n            ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);\n            return static_cast<T*>(wrap);\n        }\n\n        v8::Local<v8::Object> handle() {\n            return handle(v8::Isolate::GetCurrent());\n        }\n\n        v8::Local<v8::Object> handle(v8::Isolate* isolate) {\n            return v8::Local<v8::Object>::New(isolate, persistent());\n        }\n\n        v8::Persistent<v8::Object>& persistent() {\n            return _handle;\n        }\n\n    protected:\n\n        void Wrap(v8::Local<v8::Object> handle) {\n            assert(persistent().IsEmpty());\n            assert(handle->InternalFieldCount() > 0);\n            handle->SetAlignedPointerInInternalField(0, this);\n            persistent().Reset(v8::Isolate::GetCurrent(), handle);\n            MakeWeak();\n        }\n\n        void MakeWeak(void) {\n            persistent().SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);\n            persistent().MarkIndependent();\n        }\n\n        /* Ref() marks the object as being attached to an event loop.\n        * Refed objects will not be garbage collected, even if\n        * all references are lost.\n        */\n        virtual void Ref() {\n            assert(!persistent().IsEmpty());\n            persistent().ClearWeak();\n            _refs++;\n        }\n\n        /* Unref() marks an object as detached from the event loop.  This is its\n        * default state.  When an object with a \"weak\" reference changes from\n        * attached to detached state it will be freed. Be careful not to access\n        * the object after making this call as it might be gone!\n        * (A \"weak reference\" means an object that only has a\n        * persistant handle.)\n        *\n        * DO NOT CALL THIS FROM DESTRUCTOR\n        */\n        virtual void Unref() {\n            assert(!persistent().IsEmpty());\n            assert(!persistent().IsWeak());\n            assert(_refs > 0);\n            if (--_refs == 0) {\n                MakeWeak();\n            }\n        }\n\n        // Reference counter.\n        int _refs;\n\n    private:\n\n        static void WeakCallback(const v8::WeakCallbackInfo<ObjectWrap>& data) {\n            ObjectWrap* wrap = data.GetParameter();\n            assert(wrap->_refs == 0);\n            wrap->_handle.Reset();\n            delete wrap;\n        }\n\n        v8::Persistent<v8::Object> _handle;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "inc/napa/module/shareable-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/module/transport-context-wrap.h>\n#include <napa/transport.h>\n\n#include <memory>\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> Abstract class for wraps that contains a C++ std::shared_ptr<T> and allow it be shared across isolates. </summary>\n    /// <remarks> see napajs/lib/memory/shareable.ts </remarks>\n    class ShareableWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> It initialize constructor template of a sub-class of ShareableWrap. </summary>\n        /// <param name=\"constructorTemplate\"> Constructor template of wrap class. </param>\n        /// <remarks> Should call this method in sub-class Init. </remarks>\n        template <typename WrapType>\n        static void InitConstructorTemplate(v8::Local<v8::FunctionTemplate> constructorTemplate) {\n            // Blessed with methods from napajs.transport.Transportable.\n            napa::transport::TransportableObject::InitConstructorTemplate(constructorTemplate);\n\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"load\", WrapType::LoadCallback);\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"save\", WrapType::SaveCallback);\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"isNull\", WrapType::IsNullCallback);\n            NAPA_SET_ACCESSOR(constructorTemplate, \"refCount\", WrapType::RefCountCallback, nullptr);\n            NAPA_SET_ACCESSOR(constructorTemplate, \"handle\", WrapType::GetHandleCallback, nullptr);\n        }\n\n        /// <summary> It initialize constructor of a sub-class of ShareableWrap. </summary>\n        /// <remarks> Should call this method in sub-class Init. </remarks>\n        /// <param name=\"cid\"> Cid used for transporting the wrap. </param>\n        /// <param name='constructor'> Constructor of wrap class. </param>\n        static void InitConstructor(const char* cid, v8::Local<v8::Function> constructor) {\n            napa::transport::TransportableObject::InitConstructor(cid, constructor);\n        }\n\n        /// <summary> Set an instance of ShareableWrap child-class with shared_ptr of T. </summary>\n        template <typename T>\n        static void Set(v8::Local<v8::Object> wrap, std::shared_ptr<T> object) {\n            auto shareable = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(wrap);\n            shareable->_object = std::static_pointer_cast<void>(std::move(object));\n        }\n\n        /// <summary> Get shared_ptr of T, which is the type of contained native object. </summary>\n        template <typename T = void>\n        typename std::enable_if_t<!std::is_same<void, T>::value, std::shared_ptr<T>> Get() {\n            return std::static_pointer_cast<T>(_object);\n        }\n\n        /// <summary> Get shared_ptr of void to a native object. </summary>\n        template <typename T = void>\n        typename std::enable_if<std::is_same<void, T>::value, std::shared_ptr<void>>::type Get() {\n            return _object;\n        }\n\n        /// <summary> Get reference of T, which is the type of contained native object. </summary>\n        template <typename T>\n        typename std::enable_if_t<!std::is_same<void, T>::value, T&> GetRef() {\n            return *std::static_pointer_cast<T>(_object);\n        }\n\n        /// <summary> It creates a new instance of WrapType of shared_ptr<T>, WrapType is a sub-class of ShareableWrap. </summary>\n        /// <param name=\"object\"> shared_ptr of object. </summary>\n        /// <returns> V8 object of type ShareableWrap. </summary>\n        template <typename WrapType, typename T>\n        static v8::Local<v8::Object> NewInstance(std::shared_ptr<T> object) {\n            auto instance = napa::module::NewInstance<WrapType>().ToLocalChecked();\n            Set(instance, std::move(object));\n            return instance;\n        }\n\n    protected:\n        /// <summary> Friend default constructor callback to access protected method NAPA_OBJECTWRAP::Unwrap. </summary>\n        template <typename T>\n        friend void napa::module::DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n        /// <summary> Default constructor. </summary>\n        ShareableWrap() = default;\n\n        /// <summary> Constructor. </summary>\n        explicit ShareableWrap(std::shared_ptr<void> object) : _object(std::move(object)) {}\n\n        /// <summary> Allow inheritance. </summary>\n        virtual ~ShareableWrap() = default;\n\n        /// <summary> It implements readonly Shareable.handle : Handle </summary>\n        static void GetHandleCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args){\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n            args.GetReturnValue().Set(v8_helpers::PtrToV8Uint32Array(isolate, thisObject->_object.get()));\n        }\n\n        /// <summary> It implements Shareable.refCount(): boolean </summary>\n        static void RefCountCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args){\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n            args.GetReturnValue().Set(static_cast<int32_t>(thisObject->_object.use_count()));\n        }\n\n        /// <summary> It implements Shareable.isNull(): boolean </summary>\n        static void IsNullCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n            args.GetReturnValue().Set(thisObject->_object.get() == nullptr);\n        }\n\n        /// <summary> It implements TransportableObject.load(payload: object, transportContext: TransportContext): void </summary>\n        static void LoadCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n\n            CHECK_ARG(isolate, args.Length() == 2, \"2 arguments are required for \\\"load\\\".\");\n            CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"payload\\\" shall be 'Object' type.\");\n            CHECK_ARG(isolate, args[1]->IsObject(), \"Argument \\\"transportContext\\\" shall be 'TransportContextWrap' type.\");\n\n            auto payload = v8::Local<v8::Object>::Cast(args[0]);\n            auto numberArray = payload->Get(v8_helpers::MakeV8String(isolate, \"handle\"));\n            \n            auto result = v8_helpers::V8ValueToUintptr(isolate, numberArray);\n            JS_ENSURE(isolate, result.second, \"Unable to cast \\\"handle\\\" to pointer. Please check if it's in valid handle format.\");\n            \n            auto transportContextWrap = NAPA_OBJECTWRAP::Unwrap<TransportContextWrap>(v8::Local<v8::Object>::Cast(args[1]));\n            JS_ENSURE(isolate, transportContextWrap != nullptr, \"Argument \\\"transportContext\\\" should be 'TransportContextWrap' type.\");\n    \n            // Load object from transport context.\n            auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n            thisObject->_object = transportContextWrap->Get()->LoadShared<void>(result.first);\n        }\n\n        /// <summary> It implements TransportableObject.save(payload: object, transportContext: TransportContext): void </summary>\n        static void SaveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n            \n            CHECK_ARG(isolate, args.Length() == 2, \"2 arguments are required for \\\"save\\\".\");\n            CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"payload\\\" should be 'Object' type.\");\n            CHECK_ARG(isolate, args[1]->IsObject(), \"Argument \\\"transportContext\\\" should be 'TransportContextWrap' type.\");\n\n            auto payload = v8::Local<v8::Object>::Cast(args[0]);\n            auto transportContextWrap = NAPA_OBJECTWRAP::Unwrap<TransportContextWrap>(v8::Local<v8::Object>::Cast(args[1]));\n            JS_ENSURE(isolate, transportContextWrap != nullptr, \"Argument \\\"transportContext\\\" should be 'TransportContextWrap' type.\");\n\n            auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n            payload->CreateDataProperty(\n                context,\n                v8_helpers::MakeV8String(isolate, \"handle\"),\n                v8_helpers::PtrToV8Uint32Array(isolate, thisObject->_object.get()));\n\n            // Save object to transport context.\n            transportContextWrap->Get()->SaveShared(thisObject->_object);\n        }\n\n        /// <summary> Shared object. </summary>\n        std::shared_ptr<void> _object;\n    };\n}\n}"
  },
  {
    "path": "inc/napa/module/transport-context-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/transport/transport-context.h>\n\nnamespace napa {\nnamespace module {\n    /// <summary> Interface for TransportContextWrap. </summary>\n    class TransportContextWrap: public NAPA_OBJECTWRAP {\n    public:\n        /// <summary> Get transport context. </summary>\n        virtual napa::transport::TransportContext* Get() = 0;\n\n        virtual ~TransportContextWrap() = default;\n    };\n}\n}\n    "
  },
  {
    "path": "inc/napa/module.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n// Suppress 4100 warnings.\n#pragma warning(push)\n#pragma warning(disable: 4100)\n\n#ifdef BUILDING_NAPA_EXTENSION\n#include \"napa/module/module-internal.h\"\n#include \"napa/module/module-node-compat.h\"\n#include \"napa/module/object-wrap.h\"\n#else\n#include <node.h>\n#include <node_object_wrap.h>\n#endif\n\n#include \"napa/v8-helpers.h\"\n\n#pragma warning(pop)\n\n/// <summary> It binds the method name with V8 function object. </summary>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_SET_METHOD napa::module::SetMethod\n#else\n#define NAPA_SET_METHOD NODE_SET_METHOD\n#endif\n\n/// <summary> It binds the method name with V8 prototype function object. </summary>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_SET_PROTOTYPE_METHOD napa::module::SetPrototypeMethod\n#else\n#define NAPA_SET_PROTOTYPE_METHOD NODE_SET_PROTOTYPE_METHOD\n#endif\n\n/// <summary> It binds a name with a property with V8 prototype function object. </summary>\n#define NAPA_SET_PROTOTYPE_PROPERTY(functionTemplate, name, value) \\\n    functionTemplate->PrototypeTemplate()->Set(v8::Isolate::GetCurrent(), \\\n                                               name, \\\n                                               value)\n\n/// <summary> It registers the module with the name and the initializer. </summary>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_MODULE NAPA_REGISTER_MODULE\n#else\n#define NAPA_MODULE NODE_MODULE\n#endif\n\n/// <summary> It wraps V8 object, so its lifetime can be managed by napa/node. </summary>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_OBJECTWRAP napa::module::ObjectWrap\n#else\n#define NAPA_OBJECTWRAP node::ObjectWrap\n#endif\n\n/// <summary> It sets the accessors for the given V8 function template object. </summary>\n#define NAPA_SET_ACCESSOR(functionTemplate, name, getter, setter) \\\n    functionTemplate->InstanceTemplate()->SetAccessor(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), name), \\\n                                                      getter, \\\n                                                      setter)\n\n/// <summary> It sets the property for the given V8 function template object. </summary>\n#define NAPA_SET_PROPERTY(functionTemplate, name, value) \\\n    functionTemplate->InstanceTemplate()->Set(v8::Isolate::GetCurrent(), \\\n                                              name, \\\n                                              value)\n\n/// <summary> It declares the persistent constructor. </summary>\n/// <remarks> Napa registers constructor at local thread storage. </remarks>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_DECLARE_PERSISTENT_CONSTRUCTOR()\n#else\n#define NAPA_DECLARE_PERSISTENT_CONSTRUCTOR() \\\n    static v8::Persistent<v8::Function> _constructor\n#endif\n\n/// <summary> It defines the persistent constructor. <summary>\n/// <remarks> Napa does nothing since it registers a constructor while setting it. </remarks>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_DEFINE_PERSISTENT_CONSTRUCTOR(className)\n#else\n#define NAPA_DEFINE_PERSISTENT_CONSTRUCTOR(className) \\\n    v8::Persistent<v8::Function> className::_constructor\n#endif\n\n/// <summary> It defines the template class's persistent constructor. <summary>\n/// <remarks> Napa does nothing since it registers a constructor while setting it. </remarks>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_DEFINE_TEMPLATE_PERSISTENT_CONSTRUCTOR(className)\n#else\n#define NAPA_DEFINE_TEMPLATE_PERSISTENT_CONSTRUCTOR(className) \\\n    template <typename T> \\\n    v8::Persistent<v8::Function> className<T>::_constructor\n#endif\n\n/// <summary> It sets the persistent constructor at the current V8 isolate. </summary>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_SET_PERSISTENT_CONSTRUCTOR(name, function) \\\n    napa::module::SetPersistentConstructor(name, function)\n#else\n#define NAPA_SET_PERSISTENT_CONSTRUCTOR(name, function) \\\n    _constructor.Reset(v8::Isolate::GetCurrent(), function)\n#endif\n\n/// <summary> It gets the given persistent constructor from the current V8 isolate. </summary>\n/// <returns> V8 local function object. </returns>\n#ifdef BUILDING_NAPA_EXTENSION\n#define NAPA_GET_PERSISTENT_CONSTRUCTOR(exportName, className) \\\n    napa::module::GetPersistentConstructor(exportName)\n#else\n#define NAPA_GET_PERSISTENT_CONSTRUCTOR(exportName, className) \\\n    v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), className::_constructor)\n#endif\n\n/// <summary> It exports a NAPA_OBJECTWRAP subclass to addon exports object. </summary>\n#define NAPA_EXPORT_OBJECTWRAP(exports, exportName, className) \\\n    exports->Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), exportName), \\\n                 NAPA_GET_PERSISTENT_CONSTRUCTOR(exportName, className))\n\n// Depends on NAPA_GET_PERSISTENT_CONSTRUCTOR.\n#include \"napa/module/common.h\"\n"
  },
  {
    "path": "inc/napa/providers/logging.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\nnamespace napa {\nnamespace providers {\n\n    /// <summary> Interface for a generic logging provider. </summary>\n    /// <remarks> \n    ///     Ownership of this logging provider belongs to the shared library which created it. Hence the explicit\n    ///     Destroy method in this class. To simplify memory management across multiple shared libraries, this class\n    ///     can only be created via a factory method provided by the shared library. When it is no longer needed,\n    ///     the caller may call Destroy() which will tell the shared library which created it to dispose of the object.\n    /// </remarks>\n    class LoggingProvider {\n    public:\n\n        /// <summary> Represents verboseness for logging. </summary>\n        enum class Verboseness {\n            Error = 0,\n            Warning,\n            Info,\n            Debug\n        };\n\n        /// <summary> Logs a message. </summary>\n        /// <param name=\"section\"> Logging section. </param>\n        /// <param name=\"level\"> Logging verboseness level. </param>\n        /// <param name=\"traceId\"> Trace ID. </param>\n        /// <param name=\"file\"> The source file this log message originated from. </param>\n        /// <param name=\"line\"> The source line this log message originated from. </param>\n        /// <param name=\"message\"> The message. </param>\n        virtual void LogMessage(\n            const char* section,\n            Verboseness level,\n            const char* traceId,\n            const char* file,\n            int line,\n            const char* message) = 0;\n\n        /// <summary> Returns if logging is enabled for section/level/title. </summary>\n        /// <param name=\"section\"> Logging section. </param>\n        /// <param name=\"level\"> Logging verboseness level. </param>\n        /// <returns> True if logging will occur for section/level, false otherwise. </returns>\n        virtual bool IsLogEnabled(const char* section, Verboseness level) = 0;\n\n        /// <summary> Explicitly destroys the logging provider. </summary>\n        virtual void Destroy() = 0;\n\n    protected:\n\n        /// <summary> Prevent calling delete on the interface. Must use Destroy! </summary>\n        virtual ~LoggingProvider() = default;\n    };\n\n    /// <summary> Exports a getter function for retrieves the configured logging provider. </summary>\n    NAPA_API LoggingProvider& GetLoggingProvider();\n\n    /// <summary> Singnature  of the logging provider factory method. </summary>\n    typedef LoggingProvider* (*CreateLoggingProvider)();\n}\n}\n"
  },
  {
    "path": "inc/napa/providers/metric.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\n#include <cstddef>\n#include <stdint.h>\n\nnamespace napa {\nnamespace providers {\n\n    /// <summary> Enumeration of metric type. </summary>\n    enum class MetricType {\n        Number = 0,\n        Rate,\n        Percentile,\n    };\n\n    /// <summary> Interface to represents a multi-dimensional metric with a maximum dimensionality of 64. </summary>\n    class Metric {\n    public:\n\n        /// <summary> Sets a metric value with variadic dimension arguments. </summary>\n        /// <param name=\"value\"> Int64 value. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions provided when\n        ///     creating this metric.\n        /// </remarks>\n        virtual bool Set(int64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary>\n        ///     Increments a metric value with variadic dimension arguments.\n        ///     Use mainly to simplify rate counters.\n        /// </summary>\n        /// <param name=\"value\"> UInt64 value to increment. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions\n        ///     provided when creating this metric.\n        /// </remarks>\n        virtual bool Increment(uint64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary>\n        ///     Decrements metric value with variadic dimension arguments.\n        ///     Use mainly to simplify rate counters.\n        /// </summary>\n        /// <param name=\"value\"> UInt64 value to decrement. </param>\n        /// <param name=\"numberOfDimensions\"> Number of dimensions being set. </param>\n        /// <param name=\"dimensionValues\"> Array of dimension value names. </param>\n        /// <returns> Success/Fail. </returns>\n        /// <remarks>\n        ///     The number of dimension values must exactly match the number of dimensions\n        ///     provided when creating this metric.\n        /// </remarks>\n        virtual bool Decrement(uint64_t value, size_t numberOfDimensions, const char* dimensionValues[]) = 0;\n\n        /// <summary> Explicitly destroys the Metric. </summary>\n        /// <remarks>\n        ///     Consumers are not required to call this.\n        ///     The MetricProvider owns this class and will automatically perform cleanup on shutdown.\n        /// </remarks>\n        virtual void Destroy() = 0;\n\n    protected:\n\n        ///<summary> Prevent calling delete on the interface. Must use Destroy! </summary>\n        virtual ~Metric() = default;\n    };\n\n\n    /// <summary> Interface for a generic metric provider. </summary>\n    /// <remarks> \n    ///     Ownership of this metric provider belongs to the shared library which created it. Hence the explicit\n    ///     Destroy method in this class. To simplify memory management across multiple shared libraries, this class\n    ///     can only be created via a factory method provided by the shared library. When it is no longer needed,\n    ///     the caller may call Destroy() which will tell the shared library which created it to dispose of the object.\n    /// </remarks>\n    class MetricProvider {\n    public:\n\n        /// <summary>\n        ///     Gets or creates a N-dimensional metric. Metric objects are owned and cached by this class.\n        ///     Up to 64 dimensions may be used.</summary>\n        /// <param name=\"section\"> Section of the metric.</param>\n        /// <param name=\"name\"> Name of the metric.</param>\n        /// <param name=\"type\"> Type of the metric.</param>\n        /// <param name=\"dimensions\">\n        ///     Number of dimensions requested for this metric.\n        ///     Represents the size of the array passed in for p_dimensionNames.\n        /// </param>\n        /// <param name=\"dimensionNames\"> Array of dimension names being requested for this metric.</param>\n        /// <remarks>\n        ///     The IMetric class returned is owned and cached by this class.\n        ///     Callers are not required to call destroy() on the Metric.\n        /// </remarks>\n        virtual Metric* GetMetric(\n            const char* section,\n            const char* name,\n            MetricType type,\n            size_t dimensions,\n            const char* dimensionNames[]) = 0;\n\n        ///<summary> Explicitly destroys the metric provider. </summary>\n        virtual void Destroy() = 0;\n\n    protected:\n\n        ///<summary> Prevent calling delete on the interface. Must use Destroy! </summary>\n        virtual ~MetricProvider() = default;\n    };\n\n    /// <summary> Exports a getter function for retrieves the configured metric provider. </summary>\n    NAPA_API MetricProvider& GetMetricProvider();\n\n    typedef MetricProvider* (*CreateMetricProvider)();\n}\n}\n"
  },
  {
    "path": "inc/napa/result-codes.inc",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n///\n/// Napa result codes definition file!\n///\n/// Guidelines:\n///     1. Use NAPA_RESULT_CODE_DEF to define new codes.\n///     2. Add new codes at the end of the list.\n///     3. Make sure to add a comma at the end of the previous result code defintion\n/// \n///    |----------------------- symbol name ---------- string representation --|\n///     NAPA_RESULT_CODE_DEF( EXAMPLE_NAME1,        \"Example string message1\"),\n///     NAPA_RESULT_CODE_DEF( EXAMPLE_NAME2,        \"Example string message2\")\n/// Always add news codes\n///\n\n#ifndef NAPA_RESULT_CODE_DEF\n#error NAPA_RESULT_CODE_DEF must be defined before including response_code.inc\n#endif\n\nNAPA_RESULT_CODE_DEF( SUCCESS,                         \"Success\"),\nNAPA_RESULT_CODE_DEF( UNDEFINED,                       \"Undefined\"),\nNAPA_RESULT_CODE_DEF( INTERNAL_ERROR,                  \"Napa internal error\"),\nNAPA_RESULT_CODE_DEF( TIMEOUT,                         \"The request timed out\"),\nNAPA_RESULT_CODE_DEF( ZONE_INIT_ERROR,                 \"Failed to initialize zone\"),\nNAPA_RESULT_CODE_DEF( BROADCAST_SCRIPT_ERROR,          \"Failed to broadcast JavaScript code in zone\"),\nNAPA_RESULT_CODE_DEF( EXECUTE_FUNC_ERROR,              \"Failed to execute the JavaScript function\"),\nNAPA_RESULT_CODE_DEF( SETTINGS_PARSER_ERROR,           \"Failed to parse settings\"),\nNAPA_RESULT_CODE_DEF( PROVIDERS_INIT_ERROR,            \"Failed to initialize providers\"),\nNAPA_RESULT_CODE_DEF( V8_INIT_ERROR,                   \"Failed to initialize V8\"),\nNAPA_RESULT_CODE_DEF( GLOBAL_VALUE_ERROR,              \"Failed to set global value\")\n"
  },
  {
    "path": "inc/napa/stl/allocator.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/memory/allocator.h>\n#include <limits>\n\nnamespace napa {\nnamespace stl {\n    /// <summary> Allocator is a is a wrapper class for napa::memory::Allocator. It is used to\n    /// create an allocator that is compatible with the STL container classes\n    /// like map and vector.\n    ///\n    /// This template declaration is a subset of the declaration in the C++98\n    /// spec (ISO/IEC 14882:1998), section 20.4.1.\n    /// See specification draft: http://www.open-std.org/jtc1/sc22/open/n2356/.\n    /// Also see http://www.codeguru.com/Cpp/Cpp/cpp_mfc/stl/article.php/c4079/.\n    /// </summary>\n    template <typename T> class Allocator {\n    public:\n        typedef size_t    size_type;\n        typedef ptrdiff_t difference_type;\n        typedef T*        pointer;\n        typedef const T*  const_pointer;\n        typedef T&        reference;\n        typedef const T&  const_reference;\n        typedef T         value_type;\n\n        template <typename U> struct rebind\n        {\n            typedef Allocator<U> other;\n        };\n\n        /// <summary> Constructor that uses NAPA_DEFAULT_ALLOCATOR. </summary>\n        Allocator();\n\n        /// <summary> Constructor that accepts a custom allocator </summary>\n        explicit Allocator(napa::memory::Allocator& allocator);\n\n        /// <summary> Copy constructor will be used in assignment of std::shared_ptr in GCC </summary>\n        Allocator(const Allocator& other) = default;\n        Allocator& operator=(const Allocator&) = default;\n\n        template <typename U> Allocator(const Allocator<U>&) throw();\n\n        /// The following method is in the C++98 specification but was\n        /// not implemented. Keeping the declarations here to document\n        /// differences from the specification and to help with debugging.\n        /// ~Allocator() throw();\n\n        pointer address(reference x) const;\n        const_pointer address(const_reference x) const;\n\n        pointer allocate(size_type count, const void* hint = 0);\n        void deallocate(pointer p, size_type n);\n\n        size_type max_size() const throw();\n\n        void construct(pointer p, const_reference val);\n        void destroy(pointer p);\n\n        bool operator==(const Allocator&) const;\n        bool operator!=(const Allocator&) const;\n\n    private:\n        template <typename U>\n        friend class Allocator;\n\n        napa::memory::Allocator* _allocator;\n    };\n\n    template <typename T>\n    Allocator<T>::Allocator()\n        : _allocator(&napa::memory::GetDefaultAllocator()) {\n    }\n\n    template <typename T>\n    Allocator<T>::Allocator(napa::memory::Allocator& allocator)\n        : _allocator(&allocator) {\n    }\n\n    template <typename T>\n    template <typename U>\n    Allocator<T>::Allocator(const Allocator<U>& rhs) throw()\n        : _allocator(rhs._allocator) {\n    }\n\n    template <typename T>\n    typename Allocator<T>::pointer Allocator<T>::address(typename Allocator<T>::reference x) const {\n        return &x;\n    }\n\n    template <typename T>\n    typename Allocator<T>::const_pointer Allocator<T>::address(typename Allocator<T>::const_reference x) const {\n        return &x;\n    }\n\n    template <typename T>\n    typename Allocator<T>::pointer Allocator<T>::allocate(typename Allocator<T>::size_type count, const void* /*hint*/) {\n        return static_cast<Allocator<T>::pointer>(_allocator->Allocate(sizeof(T) * count));\n    }\n\n    template <typename T>\n    void Allocator<T>::deallocate(typename Allocator<T>::pointer p, typename Allocator<T>::size_type count) {\n        _allocator->Deallocate(p, sizeof(T) * count);\n    }\n\n    template <typename T>\n    typename Allocator<T>::size_type Allocator<T>::max_size() const throw() {\n        return std::numeric_limits<Allocator<T>::size_type>::max();\n    }\n\n    template <typename T>\n    void Allocator<T>::construct(typename Allocator<T>::pointer ptr, typename Allocator<T>::const_reference val) {\n        new (ptr) T(val);\n    }\n\n#pragma warning(push)\n#pragma warning(disable:4100)\n    // Warning C4100 says that 'ptr' is unreferenced as a formal parameter.\n    // This happens when T is a simple type like int. In this case it seems that\n    // the compiler optimizes away the call to ptr->~T(), causing the ptr to\n    // seem unreferenced. This seems like a compiler bug.\n    template <typename T>\n    void Allocator<T>::destroy(typename Allocator<T>::pointer ptr) {\n        ptr->~T();\n    }\n#pragma warning(pop)\n\n    template <typename T>\n    bool Allocator<T>::operator==(const Allocator& other) const {\n        return *_allocator == *(other._allocator);\n    }\n\n    template <typename T>\n    bool Allocator<T>::operator!=(const Allocator& other) const {\n        return !(*_allocator == *(other._allocator));\n    }\n}\n}\n"
  },
  {
    "path": "inc/napa/stl/deque.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <deque>\n\nnamespace napa {\n    namespace stl {\n        template <typename T>\n        using Deque = std::deque<T, napa::stl::Allocator<T>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/list.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <list>\n\nnamespace napa {\n    namespace stl {\n        template <typename T>\n        using List = std::list<T, napa::stl::Allocator<T>>;\n    }\n}\n\n"
  },
  {
    "path": "inc/napa/stl/map.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <map>\n\nnamespace napa {\n    namespace stl {\n        template <typename Key, typename T, typename Compare = std::less<Key>>\n        using Map = std::map<Key, T, Compare, napa::stl::Allocator<std::pair<const Key, T>>>;\n        \n        template <typename Key, typename T, typename Compare = std::less<Key>>\n        using MultiMap = std::multimap<Key, T, Compare, napa::stl::Allocator<std::pair<const Key, T>>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/queue.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <queue>\n\nnamespace napa {\n    namespace stl {\n        template <typename T>\n        using Queue = std::queue<T, std::deque<T, napa::stl::Allocator<T>>>;\n\n        template <typename T>\n        using PriorityQueue = std::priority_queue<T, std::vector<T, napa::stl::Allocator<T>>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/set.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <set>\n\nnamespace napa {\n    namespace stl {\n        template <typename Key, typename Compare = std::less<Key>>\n        using Set = std::set<Key, Compare, napa::stl::Allocator<Key>>;\n\n        template <typename Key, typename Compare = std::less<Key>>\n        using MultiSet = std::multiset<Key, Compare, napa::stl::Allocator<Key>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/stack.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <stack>\n\nnamespace napa {\n    namespace stl {\n        template <typename T>\n        using Stack = std::priority_queue<T, std::deque<T, napa::stl::Allocator<T>>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/string.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <string>\n\nnamespace napa {\n    namespace stl {\n        template <typename CharT, typename Traits = std::char_traits<CharT>>\n        using BasicString = std::basic_string<CharT, Traits, napa::stl::Allocator<CharT>>;\n\n        typedef BasicString<char> String;\n        typedef BasicString<char16_t> U16String;\n    }\n}\n\n#if defined(__GNUC__) && !defined(__clang__)\n\nnamespace std {\n    // std::hash specialization for napa::stl::String.\n    template<>\n    struct hash<napa::stl::String> : public __hash_base<size_t, napa::stl::String> {\n        size_t operator()(const napa::stl::String& s) const noexcept {\n            return std::_Hash_impl::hash(s.data(), s.length() * sizeof(char));\n        }\n    };\n\n    template<>\n    struct __is_fast_hash<hash<napa::stl::String>> : std::false_type {\n    };\n\n    // std::hash specialization for napa::stl::U16String.\n    template<>\n    struct hash<napa::stl::U16String> : public __hash_base<size_t, napa::stl::U16String> {\n        size_t operator()(const napa::stl::U16String& s) const noexcept {\n            return std::_Hash_impl::hash(s.data(), s.length() * sizeof(char16_t));\n        }\n    };\n\n    template<>\n    struct __is_fast_hash<hash<napa::stl::U16String>> : std::false_type {\n    };\n}\n\n#endif\n"
  },
  {
    "path": "inc/napa/stl/unordered_map.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <unordered_map>\n\nnamespace napa {\n    namespace stl {\n        template <\n            typename Key, \n            typename T, \n            typename Hash = std::hash<Key>,\n            typename KeyEqual = std::equal_to<Key>\n        >\n        using UnorderedMap = std::unordered_map<\n            Key, \n            T, \n            Hash, \n            KeyEqual, \n            napa::stl::Allocator<std::pair<const Key, T>>>;\n\n        template <\n            typename Key, \n            typename T, \n            typename Hash = std::hash<Key>,\n            typename KeyEqual = std::equal_to<Key>\n        >\n        using UnorderedMultiMap = std::unordered_multimap<\n            Key, \n            T, \n            Hash, \n            KeyEqual, \n            napa::stl::Allocator<std::pair<const Key, T>>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/unordered_set.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <unordered_set>\n\nnamespace napa {\n    namespace stl {\n        template <\n            typename Key, \n            typename Hash = std::hash<Key>,\n            typename KeyEqual = std::equal_to<Key>\n        >\n        using UnorderedSet = std::unordered_set<Key, Hash, KeyEqual, napa::stl::Allocator<Key>>;\n\n        template <\n            typename Key, \n            typename Hash = std::hash<Key>,\n            typename KeyEqual = std::equal_to<Key>\n        >\n        using UnorderedMultiSet = std::unordered_multiset<Key, Hash, KeyEqual, napa::stl::Allocator<Key>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/stl/vector.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/allocator.h>\n#include <vector>\n\nnamespace napa {\n    namespace stl {\n        template <typename T>\n        using Vector = std::vector<T, napa::stl::Allocator<T>>;\n    }\n}\n"
  },
  {
    "path": "inc/napa/transport/transport-context.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/stl/unordered_map.h>\n#include <memory>\n\nnamespace napa {\nnamespace transport {\n    \n    /// <summary> It facilitates transportation of C++ objects \n    /// which need to transfer/extend their ownership across isolates by assignment operator. \n    ///\n    /// Known cases are:\n    /// 1) Transfer/extend ownership via passing shared objects in arguments to Zone::execute.\n    /// 2) Extend ownership by cross-isolate sharing via memory.global.set/get or Zone.global.set/get.\n    ///\n    /// At this time, only transport std::shared_ptr is supported of transfering ownership. \n    /// </summary>\n    class TransportContext {\n\n    public:\n        /// <summary> Default constructor. </summary>\n        TransportContext() = default;\n\n        /// <summary> Move constructor. </summary>\n        TransportContext(TransportContext&& other) \n            : _sharedDepot(std::move(other._sharedDepot)) {\n        }\n\n        /// <summary> Move assignment. </summary>\n        TransportContext& operator=(TransportContext&& other) {\n            _sharedDepot = std::move(other._sharedDepot);\n            return *this;\n        }\n\n        /// <summary> Non-copyable. </summary>\n        TransportContext(const TransportContext&) = delete;\n        TransportContext& operator=(const TransportContext&) = delete;\n\n        /// <summary> It saves a shared pointer that can be loaded later. </summary>\n        /// <param name=\"pointer\"> Shared pointer to transfer ownership to another isolate. </param>\n        template <typename T>\n        void SaveShared(std::shared_ptr<T> pointer) {\n            _sharedDepot[reinterpret_cast<uintptr_t>(pointer.get())] = std::move(pointer);\n        }\n\n        /// <summary> It loads a previously saved shared pointer. </summary>\n        /// <param name=\"handle\"> uintptr_t value. </summary>\n        /// <returns> shared_ptr for requested handle, or empty shared_ptr if not found. </returns>\n        template <typename T>\n        std::shared_ptr<T> LoadShared(uintptr_t handle) {\n            auto it = _sharedDepot.find(handle);\n            if (it != _sharedDepot.end()) {\n                return std::static_pointer_cast<T>(it->second);\n            }\n            return std::shared_ptr<T>();\n        }\n\n        /// <summary> Get count of saved shared_ptr. </summary> \n        uint32_t GetSharedCount() {\n            return static_cast<uint32_t>(_sharedDepot.size());\n        }\n\n    private:\n\n        /// <summary> shared_ptr depot. </summary>\n        napa::stl::UnorderedMap<uintptr_t, std::shared_ptr<void>> _sharedDepot;\n    };\n}\n}\n    "
  },
  {
    "path": "inc/napa/transport/transport.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/binding.h>\n#include <napa/transport/transport-context.h>\n#include <napa/v8-helpers.h>\n\nnamespace napa {\nnamespace transport {\n\n    /// <summary> Register a Transportable object wrap with transport. </summary>\n    /// <param name=\"constructor\"> Constructor of wrap type. </param>\n    /// <remarks> 'napajs/lib/transport/transport' is required instead of 'napajs/lib/transport' to avoid circular dependency on addon. </remarks>\n    inline void Register(v8::Local<v8::Function> constructor) {\n        v8::Local<v8::Value> argv[] = { constructor };\n        (void)napa::module::binding::Call(\"../lib/transport/transport\", \"register\", sizeof(argv) / sizeof(v8::Local<v8::Value>), argv);\n    }\n\n    /// <summary> Marshall an object with transport context. C++ modules can use this helper function to marshall its members. </summary>\n    /// <param name=\"object\"> Object to marshall, it can be built-in JavaScript types or object implements napajs.transport.Transportable. </param>\n    /// <param name=\"transportContextWrap\"> TransportContextWrap to save shareable states if any. </param>\n    /// <returns> Payload in V8 string of marshalled object. </summary>\n    /// <remarks> 'napajs/lib/transport/transport' is required instead of 'napajs/lib/transport' to avoid circular dependency on addon. </remarks>\n    inline v8::MaybeLocal<v8::String> Marshall(v8::Local<v8::Value> object, v8::Local<v8::Object> transportContextWrap) {\n        v8::Local<v8::Value> argv[] = { object, transportContextWrap };\n        return v8_helpers::MaybeCast<v8::String>(napa::module::binding::Call(\n            \"../lib/transport/transport\", \n            \"marshall\", \n            sizeof(argv) / sizeof(v8::Local<v8::Value>), \n            argv));\n    }\n\n    /// <summary> Marshall an object with transport context. C++ modules can use this helper function to marshall its members. </summary>\n    /// <param name=\"object\"> Object to marshall, it can be built-in JavaScript types or object implements napajs.transport.Transportable. </param>\n    /// <param name=\"transportContext\"> TransportContext to save shareable states if any. </param>\n    /// <returns> Payload in V8 string of marshalled object. </summary>\n    /// <remarks> 'napajs/lib/transport/transport' is required instead of 'napajs/lib/transport' to avoid circular dependency on addon. </remarks>\n    inline v8::MaybeLocal<v8::String> Marshall(v8::Local<v8::Value> object, napa::transport::TransportContext* transportContext) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::Local<v8::Value> argv[] = { \n            v8::Boolean::New(isolate, false),                           // Not owning since wrap is temporary.\n            v8_helpers::PtrToV8Uint32Array(isolate, transportContext) \n        };\n        auto transportContextWrap = napa::module::binding::NewInstance(\n            \"TransportContextWrap\", \n            sizeof(argv) / sizeof(v8::Local<v8::Value>), \n            argv).ToLocalChecked();\n\n        return Marshall(object, transportContextWrap);\n    }\n\n    /// <summary> Unmarshall a payload with transport context. C++ modules can use this helper function to unmarshall its members. </summary>\n    /// <param name=\"payload\"> Payload to unmarshall, it is plain JS object generated by transport.marshallSingle. </param>\n    /// <param name=\"transportContextWrap\"> TransportContextWrap to load shareable states if any. </param>\n    /// <returns> Unmarshalled V8 value from payload. </summary>\n    /// <remarks> 'napajs/lib/transport/transport' is required instead of 'napajs/lib/transport' to avoid circular dependency on addon. </remarks>\n    inline v8::MaybeLocal<v8::Value> Unmarshall(v8::Local<v8::Value> payload, v8::Local<v8::Object> transportContextWrap) {\n        v8::Local<v8::Value> argv[] = { payload, transportContextWrap };\n        return napa::module::binding::Call(\"../lib/transport/transport\", \"unmarshall\", sizeof(argv) / sizeof(v8::Local<v8::Value>), argv);\n    }\n\n    /// <summary> Unmarshall a payload with transport context. C++ modules can use this helper function to unmarshall its members. </summary>\n    /// <param name=\"payload\"> Payload to unmarshall, it is plain JS object generated by transport.marshallSingle. </param>\n    /// <param name=\"transportContext\"> TransportContext to load shareable states if any. </param>\n    /// <returns> Unmarshalled V8 value from payload. </summary>\n    /// <remarks> 'napajs/lib/transport/transport' is required instead of 'napajs/lib/transport' to avoid circular dependency on addon. </remarks>\n    inline v8::MaybeLocal<v8::Value> Unmarshall(v8::Local<v8::Value> payload, const napa::transport::TransportContext* transportContext) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::Local<v8::Value> argv[] = { \n            v8::Boolean::New(isolate, false),                           // Not owning since wrap is temporary.\n            v8_helpers::PtrToV8Uint32Array(isolate, transportContext) \n        };\n        auto transportContextWrap = napa::module::binding::NewInstance(\n            \"TransportContextWrap\", \n            sizeof(argv) / sizeof(v8::Local<v8::Value>), \n            argv).ToLocalChecked();\n\n        return Unmarshall(payload, transportContextWrap);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/transport/transportable.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/transport/transport-context.h>\n#include <napa/transport/transport.h>\n\nnamespace napa {\nnamespace transport {\n\n    /// <summary> Helper for extending TransportableObject </summary>\n    /// <remarks> Reference: napajs/lib/transport/transportable.ts#TransportableObject </remarks>\n    struct TransportableObject {\n\n        /// <summary> It initialize a wrap object constructor template with TransportableObject methods. </summary>\n        /// <param name='constructorTemplate'> Constructor function template of the wrap. </param>\n        static void InitConstructorTemplate(v8::Local<v8::FunctionTemplate> constructorTemplate) {\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"marshall\", TransportableObject::MarshallCallback);\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"unmarshall\", TransportableObject::UnmarshallCallback);\n            NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"cid\", TransportableObject::GetCidCallback);\n        }\n\n        /// <summary> It initialize a wrap constructor with static property _cid. </summary>\n        /// <param name=\"cid\"> Cid used for transporting the wrap. </param>\n        /// <param name='constructor'> Constructor function of the wrap. </param>\n        static void InitConstructor(const char* cid, v8::Local<v8::Function> constructor) {\n            auto isolate = v8::Isolate::GetCurrent();\n            constructor->Set(v8_helpers::MakeV8String(isolate, \"_cid\"), v8_helpers::MakeV8String(isolate, cid));\n            napa::transport::Register(constructor);\n        }\n\n        /// <summary> It implements Transportable.cid() : string </summary>\n        static void GetCidCallback(const v8::FunctionCallbackInfo<v8::Value>& args){\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto prototype = v8::Local<v8::Object>::Cast(args.Holder()->GetPrototype());\n            auto constructor = v8::Local<v8::Function>::Cast(prototype->Get(\n                v8_helpers::MakeV8String(isolate, \"constructor\")));\n            args.GetReturnValue().Set(constructor->Get(v8_helpers::MakeV8String(isolate, \"_cid\")));\n        }\n\n        /// <summary> It implements Transportable.marshall(context: TransportContext): object </summary>\n        static void MarshallCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n\n            CHECK_ARG(isolate, args.Length() == 1, \"1 argument is required for calling 'marshall'.\");\n            CHECK_ARG(isolate, args[0]->IsObject(), \"The 1st argument of 'marshall' shall be object of TransportContext.\");\n\n            // Get cid from property '_cid' of constructor and class name.\n            auto holder = args.Holder();\n            auto proto = v8::Local<v8::Object>::Cast(holder->GetPrototype());\n            JS_ENSURE(isolate, !proto.IsEmpty(), \"Prototype is not Object type\");\n\n            auto constructor = v8::Local<v8::Function>::Cast(\n                proto->Get(v8_helpers::MakeV8String(isolate, \"constructor\")));\n\n            auto cid = constructor->Get(v8_helpers::MakeV8String(isolate, \"_cid\"));\n\n            // Save property \"_cid\".\n            auto payload = v8::Object::New(isolate);\n            payload->CreateDataProperty(\n                context, \n                v8_helpers::MakeV8String(isolate, \"_cid\"), \n                cid);\n            \n            // Delegate to sub-class to save its members.\n            auto saveMethod = v8::Local<v8::Function>::Cast(\n                holder->Get(v8_helpers::MakeV8String(isolate, \"save\")));\n            JS_ENSURE(isolate, \n                !saveMethod.IsEmpty(), \n                \"\\\"save\\\" method doesn't exist.\");\n            \n            constexpr int argc = 2;\n            v8::Local<v8::Value> argv[argc] = {payload, args[0]};\n            saveMethod->Call(\n                context, \n                holder,\n                argc,\n                argv);\n\n            args.GetReturnValue().Set(payload);\n        }\n\n        /// <summary> It implements Transportable.unmarshall(payload: object, context: TransportContext): void </summary>\n        static void UnmarshallCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n\n            CHECK_ARG(isolate, args.Length() == 2, \"Two arguments are required for calling 'unmarshall'. \");\n\n            auto holder = args.Holder();\n\n            // Delegate to sub-class to load its members.\n            auto loadMethod = v8::Local<v8::Function>::Cast(holder->Get(v8_helpers::MakeV8String(isolate, \"load\")));\n            JS_ENSURE(isolate, !loadMethod.IsEmpty(), \"\\\"load\\\" method doesn't exist.\");\n           \n            constexpr int argc = 2;\n            v8::Local<v8::Value> argv[argc] = {args[0], args[1]};\n            loadMethod->Call(\n                context, \n                holder,\n                argc,\n                argv);\n        }\n    };\n}\n}\n"
  },
  {
    "path": "inc/napa/transport.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/transport/transport-context.h>\n#include <napa/transport/transportable.h>\n#include <napa/transport/transport.h>\n"
  },
  {
    "path": "inc/napa/types.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"stddef.h\"\n#include \"stdint.h\"\n\n/// <summary> Simple non owning string. Should only be used for binding. </summary>\ntypedef struct {\n    const char* data;\n    size_t size;\n} napa_string_ref;\n\n#define NAPA_STRING_REF_WITH_SIZE(data, size) (napa_string_ref { (data), (size) })\n#define NAPA_STRING_REF(data) NAPA_STRING_REF_WITH_SIZE(data, strlen(data))\n\nconst napa_string_ref EMPTY_NAPA_STRING_REF = NAPA_STRING_REF_WITH_SIZE(0, 0);\n\n#ifdef __cplusplus\n\nnamespace napa {\n    typedef napa_string_ref StringRef;\n}\n\n#define STD_STRING_TO_NAPA_STRING_REF(str) (napa_string_ref { (str).data(), (str).size() })\n#define NAPA_STRING_REF_TO_STD_STRING(str) (std::string((str).data, (str).size))\n\n#endif // __cplusplus\n\n/// <summary> Represents result code in napa zone apis. </summary>\n#define NAPA_RESULT_CODE_DEF(symbol, ...) NAPA_RESULT_##symbol\n\ntypedef enum {\n\n#include \"napa/result-codes.inc\"\n\n} napa_result_code;\n\n#undef NAPA_RESULT_CODE_DEF\n\n#ifdef __cplusplus\n\nnamespace napa {\n    typedef napa_result_code ResultCode;\n}\n\n#endif // __cplusplus\n\n/// <summary> Represents option for transporting objects in zone.execute. </summary>\ntypedef enum {\n\n    /// <summary> \n    ///     transport.marshall/unmarshall will be done by `napajs` automatically.\n    ///     This is the most common way, but may not be performance optimal with objects\n    ///     that will be shared in multiple zone.execute.\n    /// </summary>\n    AUTO,\n\n    /// <summary> transport.marshall/unmarshall will be done by user manually. </summary>\n    MANUAL,\n} napa_transport_option;\n\n#ifdef __cplusplus\n\nnamespace napa {\n    typedef napa_transport_option TransportOption;\n}\n\n#endif // __cplusplus\n\n/// <summary> Represents options for calling a function. </summary>\ntypedef struct {\n\n    /// <summary> Timeout in milliseconds - Use 0 for inifinite. </summary>\n    uint32_t timeout;\n\n    /// <summary> Arguments transport option. Default is AUTO. </summary>\n    napa_transport_option transport;\n} napa_zone_call_options;\n\n#ifdef __cplusplus\n\nnamespace napa {\n    typedef napa_zone_call_options CallOptions;\n}\n\n#endif // __cplusplus\n\n/// <summary> Represents a function to run within a zone, with binded arguments . </summary>\ntypedef struct {\n\n    /// <summary> The module that exports the function to execute. </summary>\n    napa_string_ref module;\n\n    /// <summary> The function to execute. </summary>\n    napa_string_ref function;\n\n    /// <summary> The function arguments. </summary>\n    const napa_string_ref* arguments;\n\n    /// <summary> The number of arguments. </summary>\n    size_t arguments_count;\n\n    /// <summary> Options. </summary>\n    napa_zone_call_options options;\n\n    /// <summary> A context used for transporting handles across zones/workers. </summary>\n    void* transport_context;\n} napa_zone_function_spec;\n\n#ifdef __cplusplus\n\n#include <napa/transport/transport-context.h>\n#include <memory>\n#include <string>\n#include <vector>\n\nnamespace napa {\n    /// <summary> Represents a function to call with its arguments. </summary>\n    struct FunctionSpec {\n\n        /// <summary> The module that exports the function to execute. </summary>\n        StringRef module = EMPTY_NAPA_STRING_REF;\n\n        /// <summary> The function to execute. </summary>\n        StringRef function = EMPTY_NAPA_STRING_REF;\n\n        /// <summary> The function arguments. </summary>\n        std::vector<StringRef> arguments;\n\n        /// <summary> Execute options. </summary>\n        CallOptions options = { 0, AUTO };\n\n        /// <summary> Used for transporting shared_ptr and unique_ptr across zones/workers. </summary>\n        mutable std::unique_ptr<napa::transport::TransportContext> transportContext;\n    };\n}\n\n#endif // __cplusplus\n\n/// <summary> Represents a result from executing in a zone. </summary>\ntypedef struct {\n\n    /// <summary> A result code. </summary>\n    napa_result_code code;\n\n    /// <summary> The error message in case of an error. </summary>\n    napa_string_ref error_message;\n\n    /// <summary> The return value in case of success. </summary>\n    napa_string_ref return_value;\n\n    /// <summary> A context used for transporting handles across zones/workers. </summary>\n    void* transport_context;\n} napa_zone_result;\n\n#ifdef __cplusplus\n\nnamespace napa {\n    /// <summary> Represents a function call result. </summary>\n    struct Result {\n\n        /// <summary> A result code. </summary>\n        ResultCode code;\n\n        /// <summary> The error message in case of an error. </summary>\n        std::string errorMessage;\n\n        /// <summary> The return value in case of success. </summary>\n        std::string returnValue;\n\n        /// <summary> Used for transporting shared_ptr and unique_ptr across zones/workers. </summary>\n        mutable std::unique_ptr<napa::transport::TransportContext> transportContext;\n    };\n}\n\n#endif // __cplusplus\n\n/// <summary> Callback signatures. </summary>\ntypedef void(*napa_zone_callback)(napa_zone_result result, void* context);\ntypedef napa_zone_callback napa_zone_broadcast_callback;\ntypedef napa_zone_callback napa_zone_execute_callback;\n\n#ifdef __cplusplus\n\n#include <functional>\n\nnamespace napa {\n    typedef std::function<void(Result)> ZoneCallback;\n    typedef ZoneCallback BroadcastCallback;\n    typedef ZoneCallback ExecuteCallback;\n}\n\n#endif // __cplusplus\n\n/// <summary> Zone handle type. </summary>\ntypedef struct napa_zone *napa_zone_handle;\n\n/// <summary> Callback for customized memory allocator. </summary>\ntypedef void* (*napa_allocate_callback)(size_t);\ntypedef void (*napa_deallocate_callback)(void*, size_t);\n"
  },
  {
    "path": "inc/napa/utils.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/assert.h>\n\n#include <cstdio>\n#include <stdarg.h>\n\nnamespace napa {\nnamespace utils {\n\n    /// <summary> Format message with truncation. </summary>\n    inline void FormatMessageWithTruncation(char* buffer, size_t bufferSize, const char* format, ...) {\n        va_list args;\n        va_start(args, format);\n        int size = vsnprintf(buffer, bufferSize, format, args);\n        va_end(args);\n\n        NAPA_ASSERT(size >= 0, \"Format message error, probably wrong format encoding\");\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/array.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"conversion.h\"\n\n#include <v8.h>\n#include <vector>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Convert V8::Array to std::vector </summary>\n    template <typename ValueType>\n    inline std::vector<ValueType> V8ArrayToVector(v8::Isolate* isolate, const v8::Local<v8::Array>& array) {\n        auto context = isolate->GetCurrentContext();\n\n        std::vector<ValueType> res;\n        res.reserve(array->Length());\n\n        for (uint32_t i = 0; i < array->Length(); i++) {\n            res.emplace_back(V8ValueTo<ValueType>(array->Get(context, i).ToLocalChecked()));\n        }\n        return res;\n    }\n}\n}\n"
  },
  {
    "path": "inc/napa/v8-helpers/console.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/string.h>\n#include <napa/v8-helpers/function.h>\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_helpers {\n    struct Console {\n        /// <summary> Call console.log from C++ </summary>\n        /// <param name=\"argc\"> Number of arguments. </param>\n        /// <param name=\"argv\"> Actual arguments. </param>\n        static void Log(int argc, v8::Local<v8::Value> argv[]) {\n            auto isolate = v8::Isolate::GetCurrent();\n            v8::HandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n\n            auto console = v8::Local<v8::Object>::Cast(context->Global()->Get(\n                v8_helpers::MakeV8String(isolate, \"console\")));\n\n            v8_helpers::Call(console, \"log\", argc, argv);\n        } \n    };\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/conversion.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/string.h>\n#include <napa/stl/string.h>\n#include <utility>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Unified method signature for convert V8 value to C++ types. </summary>\n    template <typename T>\n    inline T V8ValueTo(const v8::Local<v8::Value>& value) {\n        static_assert(sizeof(T) == -1, \"No specialization exists for this type\");\n    }\n\n    /// <summary> Convert a v8 value to std::string. </summary>\n    template <>\n    inline std::string V8ValueTo(const v8::Local<v8::Value>& value) {\n        v8::String::Utf8Value utf8Value(value);\n        return std::string(*utf8Value);\n    }\n\n    /// <summary> Convert a v8 value to std::u16string. </summary>\n    template <>\n    inline std::u16string V8ValueTo(const v8::Local<v8::Value>& value) {\n        v8::String::Value utf16Value(value);\n        return std::u16string(reinterpret_cast<const char16_t *>(*utf16Value));\n    }\n\n    /// <summary> Convert a v8 value to napa::stl::String. </summary>\n    template <>\n    inline napa::stl::String V8ValueTo(const v8::Local<v8::Value>& value) {\n        v8::String::Utf8Value utf8Value(value);\n        return napa::stl::String(*utf8Value);\n    }\n\n    /// <summary> Convert a v8 value to napa::stl::U16String. </summary>\n    template <>\n    inline napa::stl::U16String V8ValueTo(const v8::Local<v8::Value>& value) {\n        v8::String::Value utf16Value(value);\n        return napa::stl::U16String(reinterpret_cast<const char16_t *>(*utf16Value));\n    }\n\n    /// <summary> Convert a v8 value to a Utf8String. </summary>\n    template <>\n    inline Utf8String V8ValueTo(const v8::Local<v8::Value>& value) {\n        return Utf8String(value);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/flow.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/utils.h>\n#include <v8.h>\n#include <sstream>\n\n#define THROW_IF_FAIL(isolate, expression, result, function, line, format, ...)                                   \\\nif (!(expression)) {                                                                                              \\\n    constexpr int MAX_ERROR_MESSAGE_SIZE = 512;                                                                   \\\n    char message[MAX_ERROR_MESSAGE_SIZE];                                                                         \\\n    napa::utils::FormatMessageWithTruncation(message, MAX_ERROR_MESSAGE_SIZE, format, ##__VA_ARGS__);             \\\n    std::stringstream temp;                                                                                       \\\n    temp << function << \":\" << line << \" -- \" << message;                                                         \\\n    isolate->ThrowException(v8::Exception::TypeError(napa::v8_helpers::MakeV8String(isolate, temp.str())));       \\\n    return result;                                                                                                \\\n}\n\n#define CHECK_ARG(isolate, expression, format, ...)                                                               \\\n    THROW_IF_FAIL(isolate, expression, /* empty */, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)\n\n#define CHECK_ARG_WITH_RETURN(isolate, expression, result, format, ...)                                           \\\n    THROW_IF_FAIL(isolate, expression, result, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)\n\n#define JS_ASSERT(isolate, expression, format, ...) CHECK_ARG(isolate, expression, format, ##__VA_ARGS__)\n\n#define JS_ENSURE(isolate, expression, format, ...) CHECK_ARG(isolate, expression, format, ##__VA_ARGS__)\n\n#define JS_FAIL(isolate, format, ...) CHECK_ARG(isolate, false, format, ##__VA_ARGS__)\n\n#define JS_ENSURE_WITH_RETURN(isolate, expression, result, format, ...)                                           \\\n    CHECK_ARG_WITH_RETURN(isolate, expression, result, format, ##__VA_ARGS__)\n\n#define SHORT_CIRCUIT_ON_PENDING_EXCEPTION(maybe, result)                                                         \\\n    if (maybe.IsEmpty()) {                                                                                        \\\n        return result;                                                                                            \\\n    }\n\n#define RETURN_ON_PENDING_EXCEPTION(maybe)                                                                        \\\n    SHORT_CIRCUIT_ON_PENDING_EXCEPTION(maybe, /* empty */)\n\n#define RETURN_VALUE_ON_PENDING_EXCEPTION(maybe, result)                                                          \\\n    SHORT_CIRCUIT_ON_PENDING_EXCEPTION(maybe, result)\n"
  },
  {
    "path": "inc/napa/v8-helpers/function.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/flow.h>\n#include <napa/v8-helpers/maybe.h>\n#include <napa/v8-helpers/string.h>\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Call a function under current context </summary>\n    /// <param name=\"functionName\"> Function under current context. </param>\n    /// <param name=\"argc\"> Number of arguments. </param>\n    /// <param name=\"argv\"> Actual arguments. </param>\n    /// <returns> Return value of function, or an empty handle if exception is thrown. </returns>\n    inline v8::MaybeLocal<v8::Value> Call(\n        const char* functionName, \n        int argc = 0, \n        v8::Local<v8::Value> argv[] = nullptr) {\n\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::EscapableHandleScope scope(isolate);\n\n        auto context = isolate->GetCurrentContext();\n        auto function = context->Global()->Get(v8_helpers::MakeV8String(isolate, functionName));\n\n        JS_ENSURE_WITH_RETURN(\n            isolate,\n            !function.IsEmpty() && function->IsFunction(),\n            v8::MaybeLocal<v8::Value>(),\n            \"Function \\\"%s\\\" is not found in current context.\",\n            functionName);\n\n        return scope.Escape(\n            v8::Local<v8::Function>::Cast(function)->Call(context, context->Global(), argc, argv)\n                .FromMaybe(v8::Local<v8::Value>()));\n    }\n\n    /// <summary> Call a member function of an object </summary>\n    /// <param name=\"object\"> JavaScript object. </param>\n    /// <param name=\"functionName\"> Member function name. </param>\n    /// <param name=\"argc\"> Number of arguments. </param>\n    /// <param name=\"argv\"> Actual arguments. </param>\n    /// <returns> Return value of function, or empty handle if exception is thrown. </returns>\n    inline v8::MaybeLocal<v8::Value> Call(\n        v8::Local<v8::Object> object,\n        const char* functionName,\n        int argc = 0,\n        v8::Local<v8::Value> argv[] = nullptr) {\n\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::EscapableHandleScope scope(isolate);\n        \n        auto context = isolate->GetCurrentContext();\n        auto function = object->Get(v8_helpers::MakeV8String(isolate, functionName));\n\n        JS_ENSURE_WITH_RETURN(\n            isolate,\n            !function.IsEmpty() && function->IsFunction(),\n            v8::MaybeLocal<v8::Value>(),\n            \"Function \\\"%s\\\" is not found in object.\",\n            functionName);\n\n        return scope.Escape(\n            v8::Local<v8::Function>::Cast(function)->Call(context, object, argc, argv)\n                .FromMaybe(v8::Local<v8::Value>()));\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/json.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/maybe.h>\n#include <napa/v8-helpers/function.h>\n#include <napa/v8-helpers/flow.h>\n\nnamespace napa {\nnamespace v8_helpers {\n    namespace JSON {\n        /// <summary> JSON.stringify </summary>\n        /// TODO @asib: Use v8::JSON::Stringify when available\n        inline v8::MaybeLocal<v8::String> Stringify(v8::Isolate* isolate, const v8::Local<v8::Value>& value) {\n            v8::EscapableHandleScope scope(isolate);\n            auto context = isolate->GetCurrentContext();\n\n            auto json = context->Global()\n                ->Get(context, v8::String::NewFromUtf8(isolate, \"JSON\"))\n                .ToLocalChecked()->ToObject(context)\n                .ToLocalChecked();\n\n            constexpr int argc = 1;\n            v8::Local<v8::Value> argv[] = { value };\n            return scope.Escape(ToLocal<v8::String>(Call(json, \"stringify\", argc, argv)));\n        }\n\n        /// <summary> JSON.parse </summary>\n#if (V8_MINOR_VERSION >= 6)\n        inline v8::MaybeLocal<v8::Value> Parse(v8::Local<v8::Context> context, const v8::Local<v8::String>& jsonString) {\n            return v8::JSON::Parse(context, jsonString);\n        }\n#else\n        inline v8::MaybeLocal<v8::Value> Parse(const v8::Local<v8::String>& jsonString) {\n            return v8::JSON::Parse(jsonString);\n        }\n#endif\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/maybe.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Cast MaybeLocal from source type to target type. </summary>\n    template <typename T, typename S>\n    v8::MaybeLocal<T> MaybeCast(v8::MaybeLocal<S> handle) {\n        if (handle.IsEmpty()) {\n            return v8::MaybeLocal<T>();\n        }\n        return v8::Local<T>::Cast(handle.ToLocalChecked());\n    }\n\n    /// <summary> Cast MaybeLocal to Local from source type to target type with default value. </summary>\n    template <typename T, typename S>\n    v8::Local<T> ToLocal(v8::MaybeLocal<S> handle, v8::Local<T> defaultValue = v8::Local<T>()) {\n        if (handle.IsEmpty()) {\n            return defaultValue;\n        }\n        return v8::Local<T>::Cast(handle.ToLocalChecked());\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/object.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/string.h>\n#include <v8.h>\n#include <unordered_map>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Convert a V8 object to an map. </summary>\n    template <typename ValueType>\n    inline std::unordered_map<std::string, ValueType> V8ObjectToMap(\n        v8::Isolate* isolate,\n        const v8::Local<v8::Object>& obj) {\n\n        auto context = isolate->GetCurrentContext();\n        std::unordered_map<std::string, ValueType> res;\n\n        auto maybeProps = obj->GetOwnPropertyNames(context);\n        if (!maybeProps.IsEmpty()) {\n            auto props = maybeProps.ToLocalChecked();\n            res.reserve(props->Length());\n\n            for (uint32_t i = 0; i < props->Length(); i++) {\n                auto key = props->Get(context, i).ToLocalChecked();\n                auto value = obj->Get(context, key).ToLocalChecked();\n\n                v8::String::Utf8Value keyString(key->ToString(context).ToLocalChecked());\n                res.emplace(*keyString, V8ValueTo<ValueType>(value));\n            }\n        }\n        return res;\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/ptr.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n#include <utility>\n\nnamespace napa {\nnamespace v8_helpers {\n    /// <summary> Uint32ptr size of multiple 32-bits. </summary>\n    static const uint32_t UINTPTR_SIZE_IN_UINT32 = static_cast<uint32_t>(sizeof(uintptr_t) / sizeof(uint32_t)); \n\n    /// <summary> Convert a pointer value to V8 Uint32 array. </summary>\n    /// <param name=\"isolate\"> V8 Isolate instance. </summary>\n    /// <param name=\"source\"> Pointer value. </summary>\n    /// <returns> V8 uint32 array </returns>\n    inline v8::Local<v8::Array> UintptrToV8Uint32Array(v8::Isolate* isolate, uintptr_t source) {\n        v8::EscapableHandleScope scope(isolate);\n\n        auto context = isolate->GetCurrentContext();\n        auto target = v8::Array::New(isolate, UINTPTR_SIZE_IN_UINT32);\n        for (uint32_t i = 0; i < UINTPTR_SIZE_IN_UINT32; ++i) {\n            auto value = static_cast<uint32_t>(source);\n            target->CreateDataProperty(context, i, v8::Integer::NewFromUnsigned(isolate, value));\n            source >>= 32;\n        }\n        return scope.Escape(target);\n    }\n\n    /// <summary> Convert a void pointer to V8 Uint32 array. </summary>\n    /// <param name=\"isolate\"> V8 Isolate instance. </summary>\n    /// <param name=\"source\"> Void pointer. </summary>\n    /// <returns> V8 uint32 array </returns>\n    inline v8::Local<v8::Array> PtrToV8Uint32Array(v8::Isolate* isolate, const void* pointer) {\n        return UintptrToV8Uint32Array(isolate, reinterpret_cast<uintptr_t>(pointer));\n    }\n\n    /// <summary> Convert a V8 value (should be uint32 array) to uintptr. </summary>\n    /// <param name=\"isolate\"> V8 Isolate instance. </summary>\n    /// <param name=\"source\"> V8 uint32 array holding pointer value. </summary>\n    /// <returns> The pair of converted pointer value and success/failure. </returns>\n    inline std::pair<uintptr_t, bool> V8ValueToUintptr(v8::Isolate* isolate, const v8::Local<v8::Value>& source) {\n        if (!source->IsArray()) {\n            return std::make_pair(0, false);\n        } \n        \n        auto numberArray = v8::Local<v8::Array>::Cast(source);\n        if (numberArray->Length() != UINTPTR_SIZE_IN_UINT32) {\n            return std::make_pair(0, false);\n        }\n\n        auto context = isolate->GetCurrentContext();\n        uintptr_t result = 0;\n        for (uint32_t i = 0; i < numberArray->Length(); ++i) {\n            auto value = numberArray->Get(context, i).ToLocalChecked();\n            if (!value->IsUint32()) {\n                return std::make_pair(0, false);\n            }\n            result |= static_cast<uintptr_t>(value->Uint32Value()) << 32 * i;\n        }\n        return std::make_pair(result, true);\n    }\n\n    /// <summary> Convert a V8 value (should be uint32 array) to void pointer. </summary>\n    /// <param name=\"isolate\"> V8 Isolate instance. </summary>\n    /// <param name=\"source\"> V8 uint32 array holding pointer value. </summary>\n    /// <returns> The pair of success and converted void pointer. </returns>\n    template <typename T = void>\n    inline std::pair<T*, bool> V8ValueToPtr(v8::Isolate* isolate, const v8::Local<v8::Value>& source) {\n        auto result = V8ValueToUintptr(isolate, source);\n        return std::make_pair(static_cast<T*>(reinterpret_cast<void*>(result.first)), result.second);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/string.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n#include <napa/stl/string.h>\n#include <cstring>\n\nnamespace napa {\nnamespace v8_helpers {\n\n    /// <summary> Make a V8 string by making a copy of const char*. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const char* str, int length = -1) {\n        return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal, length).ToLocalChecked();\n    }\n\n    /// <summary> Make a V8 string from std::string. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const std::string& str) {\n        return MakeV8String(isolate, str.c_str(), static_cast<int>(str.length()));\n    }\n\n    /// <summary> Make a V8 string from napa::stl::String. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const napa::stl::String& str) {\n        return MakeV8String(isolate, str.c_str(), static_cast<int>(str.length()));\n    }\n\n    /// <summary> Make a V8 string by making a copy of const uint16_t*. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const uint16_t* str, int length = -1) {\n        return v8::String::NewFromTwoByte(isolate, str, v8::NewStringType::kNormal, length).ToLocalChecked();\n    }\n\n    /// <summary> Make a V8 string by making a copy of const char16_t*. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const char16_t* str, int length = -1) {\n        return MakeV8String(isolate, reinterpret_cast<const uint16_t *>(str), length);\n    }\n\n    /// <summary> Make a V8 string from std::u16string. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const std::u16string& str) {\n        return MakeV8String(isolate, str.c_str(), static_cast<int>(str.length()));\n    }\n\n    /// <summary> Make a V8 string from napa::stl::U16String. </summary>\n    inline v8::Local<v8::String> MakeV8String(v8::Isolate *isolate, const napa::stl::U16String& str) {\n        return MakeV8String(isolate, str.c_str(), static_cast<int>(str.length()));\n    }\n\n    using ExternalOneByteStringView = v8::ExternalOneByteStringResourceImpl;\n    class ExternalTwoByteStringView : public v8::String::ExternalStringResource {\n    public:\n        ExternalTwoByteStringView() : _data(nullptr), _length(0) {}\n        ExternalTwoByteStringView(const uint16_t* data, size_t length) : _data(data), _length(length) {}\n        const uint16_t* data() const { return _data; }\n        size_t length() const { return _length; }\n\n    private:\n        const uint16_t* _data;\n        size_t _length;\n    };\n\n    /// <summary> Make a V8 string from external const char*. </summary>\n    /// <remarks> The input data should only contains Latin-1 chars. </remarks>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const char* data, size_t length) {\n        // V8 garbage collection frees ExternalOneByteStringView.\n        auto externalResource = new ExternalOneByteStringView(data, length);\n        return v8::String::NewExternalOneByte(isolate, externalResource).ToLocalChecked();\n    }\n\n    /// <summary> Make a V8 string from external const char*. </summary>\n    /// <remarks> The input data should only contains Latin-1 chars. </remarks>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const char* data) {\n        return MakeExternalV8String(isolate, data, strlen(data));\n    }\n\n    /// <summary> Make a V8 string from external std::string. </sumary>\n    /// <remarks> The input data should only contains Latin-1 chars. </remarks>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const std::string& str) {\n        return MakeExternalV8String(isolate, str.data(), str.length());\n    }\n\n    /// <summary> Make a V8 string from external napa::stl::String. </sumary>\n    /// <remarks> The input data should only contains Latin-1 chars. </remarks>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const napa::stl::String& str) {\n        return MakeExternalV8String(isolate, str.data(), str.length());\n    }\n\n    /// <summary> Make a V8 string from external const uint16_t*. </summary>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const uint16_t* data, size_t length) {\n        // V8 garbage collection frees ExternalTwoByteStringView.\n        auto externalResource = new ExternalTwoByteStringView(data, length);\n        return v8::String::NewExternalTwoByte(isolate, externalResource).ToLocalChecked();\n    }\n\n    /// <summary> Make a V8 string from external const char16_t*. </summary>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const char16_t* data, size_t length) {\n        return MakeExternalV8String(isolate, reinterpret_cast<const uint16_t *>(data), length);\n    }\n\n    /// <summary> Make a V8 string from external std::u16string. </sumary>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const std::u16string& str) {\n        return MakeExternalV8String(isolate, str.data(), str.length());\n    }\n\n    /// <summary> Make a V8 string from external napa::stl::U16String. </sumary>\n    inline v8::Local<v8::String> MakeExternalV8String(v8::Isolate *isolate, const napa::stl::U16String& str) {\n        return MakeExternalV8String(isolate, str.data(), str.length());\n    }\n\n    /// <summary> Converts a V8 string object to a movable Utf8String which supports an allocator. </summary>\n    template <typename Alloc>\n    class Utf8StringWithAllocator {\n    public:\n        Utf8StringWithAllocator()\n            : _data(nullptr), _length(0) {\n        }\n\n        Utf8StringWithAllocator(\n            const v8::Local<v8::Value>& val, \n            const Alloc& alloc = Alloc()) \n            : _alloc(alloc),\n              _data(nullptr),\n              _length(0) {\n\n            if (val.IsEmpty()) {\n                return;\n            }\n            auto isolate = v8::Isolate::GetCurrent();\n            auto context = isolate->GetCurrentContext();\n            v8::Local<v8::String> str;\n            if (!val->ToString(context).ToLocal(&str)) {\n                return;\n            }\n            _length = str->Utf8Length();\n            _data = _alloc.allocate(_length + 1);\n            str->WriteUtf8(_data);\n        }\n\n        ~Utf8StringWithAllocator() {\n            if (_data != nullptr) {\n                _alloc.deallocate(_data, _length);\n            }\n        }\n\n        const char* Data() const {\n            return _data;\n        }\n\n        size_t Length() const {\n            return _length;\n        }\n\n        /// <summary> Non copyable. </summary>\n        Utf8StringWithAllocator(const Utf8StringWithAllocator&) = delete;\n        Utf8StringWithAllocator& operator=(const Utf8StringWithAllocator&) = delete;\n\n        /// <summary> Move constructor. </summary>\n        Utf8StringWithAllocator(Utf8StringWithAllocator&& rhs) :\n                                _data(rhs._data),\n                                _length(rhs._length),\n                                _alloc(std::move(rhs._alloc)) {\n            rhs._data = nullptr;\n            rhs._length = 0;\n        }\n\n        /// <summary> Move assignment. </summary>\n        Utf8StringWithAllocator& operator=(Utf8StringWithAllocator&& rhs) {\n            _data = rhs._data;\n            _length = rhs._length;\n            _alloc = std::move(rhs._alloc);\n\n            rhs._data = nullptr;\n            rhs._length = 0;\n\n            return *this;\n        }\n\n    private:\n        char* _data;\n        size_t _length;\n        Alloc _alloc;\n    };\n\n    /// <summary> Utf8String in C++. </summary>\n    typedef Utf8StringWithAllocator<std::allocator<char>> Utf8String;\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers/time.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n#include <napa/stl/string.h>\n\nnamespace napa {\nnamespace v8_helpers {\n\n    static const uint32_t NANOS_PER_SECOND = 1000000000;\n\n    /// <summary> Make a v8 array from high-resolution time. </summary>\n    inline v8::Local<v8::Array> HrtimeToV8Uint32Array(v8::Isolate* isolate, uint64_t time) {\n        v8::EscapableHandleScope scope(isolate);\n        auto context = isolate->GetCurrentContext();\n        \n        v8::Local<v8::Array> res = v8::Array::New(isolate, 2);\n        (void)res->CreateDataProperty(\n            context,\n            0,\n            v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(time / NANOS_PER_SECOND)));\n\n        (void)res->CreateDataProperty(\n            context,\n            1,\n            v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(time % NANOS_PER_SECOND)));\n\n        return scope.Escape(res);\n    }\n\n    /// <summary> Convert a 2-element v8 array to high-resolution time in nano-seconds. </summary>\n    inline std::pair<uint64_t, bool> V8Uint32ArrayToHrtime(v8::Isolate* isolate, v8::Local<v8::Value> value) {\n        v8::EscapableHandleScope scope(isolate);\n        auto context = isolate->GetCurrentContext();\n        \n        if (value.IsEmpty() || !value->IsArray()) {\n            return std::make_pair(0, false);\n        }\n\n        auto array = v8::Local<v8::Array>::Cast(value);\n        if (array->Length() != 2) {\n            return std::make_pair(0, false);\n        }\n        return std::make_pair(static_cast<uint64_t>(array->Get(0)->Uint32Value()) * NANOS_PER_SECOND + array->Get(1)->Uint32Value(), true);\n    }\n}\n}"
  },
  {
    "path": "inc/napa/v8-helpers.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/v8-helpers/array.h>\n#include <napa/v8-helpers/console.h>\n#include <napa/v8-helpers/conversion.h>\n#include <napa/v8-helpers/flow.h>\n#include <napa/v8-helpers/function.h>\n#include <napa/v8-helpers/json.h>\n#include <napa/v8-helpers/object.h>\n#include <napa/v8-helpers/ptr.h>\n#include <napa/v8-helpers/string.h>\n#include <napa/v8-helpers/time.h>"
  },
  {
    "path": "inc/napa/version.h",
    "content": "#pragma once\n\n#ifndef NAPA_VERSION\n\n#define NAPA_VERSION_MAJOR 0\n#define NAPA_VERSION_MINOR 1\n#define NAPA_VERSION_PATCH 0\n\n#endif\n"
  },
  {
    "path": "inc/napa/zone/napa-async-runner.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\n#include <v8.h>\n\n#include <functional>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Function to run asynchronously in separate thread. </summary>\n    /// <remarks> Return value will be the input to 'AsyncCompleteCallback'. </remarks>\n    using AsyncWork = std::function<void*()>;\n\n    /// <summary> Function to run async-supporting function in the current thread. </summary>\n    /// <remarks>\n    /// Completion function given as argument must be called with return values to notify asynchronous work completion.\n    /// </remarks>\n    using CompletionWork = std::function<void(std::function<void(void*)>)>;\n\n    /// <summary> Callback running in V8 isolate after asynchronous callback completes. </summary>\n    /// <remarks>\n    /// It's called inside v8::HandleScopoe.\n    /// Function has two arguments, Javascript callback and return value from asynchronous work.\n    /// </summary>\n    using AsyncCompleteCallback = std::function<void(v8::Local<v8::Function>, void*)>;\n\n    /// <summary> It runs a synchronous function in a separate thread and posts a completion into the current V8 execution loop. </summary>\n    /// <param name=\"jsCallback\"> Javascript callback. </summary>\n    /// <param name=\"asyncWork\"> Function to run asynchronously in separate thread. </param>\n    /// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous callback completes. </param>\n    NAPA_API void PostAsyncWork(v8::Local<v8::Function> jsCallback,\n                                AsyncWork asyncWork,\n                                AsyncCompleteCallback asyncCompleteCallback);\n\n    /// <summary> It runs an asynchronous function and post a completion into the current V8 execution loop. </summary>\n    /// <param name=\"jsCallback\"> Javascript callback. </summary>\n    /// <param name=\"asyncWork\"> Function to wrap async-supporting function. </param>\n    /// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous function completes. </param>\n    NAPA_API void DoAsyncWork(v8::Local<v8::Function> jsCallback,\n                              const CompletionWork& asyncWork,\n                              AsyncCompleteCallback asyncCompleteCallback);\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "inc/napa/zone/node-async-runner.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <node.h>\n#include <uv.h>\n\n#include <functional>\n#include <memory>\n#include <vector>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Function to run asynchronously in separate thread. </summary>\n    /// <remarks> Return value will be the input to 'AsyncCompleteCallback'. </remarks>\n    using AsyncWork = std::function<void*()>;\n\n    /// <summary> Function to run async-supporting function in the current thread. </summary>\n    /// <remarks>\n    /// Completion function given as argument must be called with return values to notify asynchronous work completion.\n    /// </remarks>\n    using CompletionWork = std::function<void(std::function<void(void*)>)>;\n\n    /// <summary> Callback running in V8 isolate after asynchronous callback completes. </summary>\n    /// <remarks>\n    /// It's called inside v8::HandleScopoe.\n    /// Function has two arguments, Javascript callback and return value from asynchronous work.\n    /// </summary>\n    using AsyncCompleteCallback = std::function<void(v8::Local<v8::Function>, void*)>;\n\n    /// <summary> Class holding asynchronous callbacks and libuv request. </summary>\n    struct AsyncContext {\n        /// <summary> libuv request. </summary>\n        uv_work_t work;\n\n        /// <summary> Javascript callback. </summary>\n        v8::Persistent<v8::Function> jsCallback;\n\n        /// <summary> Function to run asynchronously in separate thread. </summary>\n        AsyncWork asyncWork;\n\n        /// <summary> Result from asynchronous work. </summary>\n        void* result = nullptr;\n\n        /// <summary> Callback running in V8 isolate after asynchronous callback completes. </summary>\n        AsyncCompleteCallback asyncCompleteCallback;\n    };\n\n    /// <summary> Class holding completion callback and libuv request. </summary>\n    struct CompletionContext {\n        /// <summary> libuv request. </summary>\n        uv_async_t work;\n\n        /// <summary> Javascript callback. </summary>\n        v8::Persistent<v8::Function> jsCallback;\n\n        /// <summary> Result from asynchronous work. </summary>\n        void* result = nullptr;\n\n        /// <summary> Callback running in V8 isolate after asynchronous callback completes. </summary>\n        AsyncCompleteCallback asyncCompleteCallback;\n    };\n\n    /// <summary> Callback run asynchronously in separate thread. </summary>\n    /// <param name=\"work\"> libuv request holding asynchronous callbacks. </summary>\n    inline void RunAsyncWork(uv_work_t* work) {\n        auto context = static_cast<AsyncContext*>(work->data);\n        context->result = context->asyncWork();\n    }\n\n    /// <summary> Callback run in V8 isolate after asynchronous callback completes. </summary>\n    /// <param name=\"work\"> libuv request holding asynchronous callbacks. </summary>\n    /// <param name=\"status\"> O if asynchronous work is successful. </summary>\n    inline void RunAsyncCompleteCallback(uv_work_t* work, int status) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = static_cast<AsyncContext*>(work->data);\n\n        std::unique_ptr<AsyncContext, std::function<void(AsyncContext*)>> deferred(context, [](auto context) {\n            context->jsCallback.Reset();\n            delete context;\n        });\n\n        if (status != 0) {\n            return;\n        }\n\n        auto jsCallback = v8::Local<v8::Function>::New(isolate, context->jsCallback);\n        context->asyncCompleteCallback(jsCallback, context->result);\n    }\n\n    /// <summary> Callback run in node event loop. </summary>\n    /// <param name=\"work\"> libuv request holding asynchronous callbacks. </summary>\n    inline void RunCompletionCallback(uv_async_t* work) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = static_cast<CompletionContext*>(work->data);\n\n        auto jsCallback = v8::Local<v8::Function>::New(isolate, context->jsCallback);\n        context->asyncCompleteCallback(jsCallback, context->result);\n\n        uv_close(reinterpret_cast<uv_handle_t*>(work), [](auto work) {\n            auto context = static_cast<CompletionContext*>(work->data);\n            context->jsCallback.Reset();\n            delete context;\n        });\n    }\n\n    /// <summary> It runs a synchronous function in a separate thread and posts a completion into the current V8 execution loop. </summary>\n    /// <param name=\"jsCallback\"> Javascript callback. </summary>\n    /// <param name=\"asyncWork\"> Function to run asynchronously in separate thread. </param>\n    /// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous callback completes. </param>\n    /// <remarks> Return value from 'asyncWork' will be the input to 'asyncCompleteCallback'. </remarks>\n    inline void PostAsyncWork(v8::Local<v8::Function> jsCallback,\n                              AsyncWork asyncWork,\n                              AsyncCompleteCallback asyncCompleteCallback) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = new AsyncContext();\n\n        context->work.data = context;\n        context->jsCallback.Reset(isolate, jsCallback);\n        context->asyncWork = std::move(asyncWork);\n        context->asyncCompleteCallback = std::move(asyncCompleteCallback);\n\n        uv_queue_work(uv_default_loop(), &context->work, RunAsyncWork, RunAsyncCompleteCallback);\n    }\n\n    /// <summary> It runs an asynchronous function and post a completion into the current V8 execution loop. </summary>\n    /// <param name=\"jsCallback\"> Javascript callback. </summary>\n    /// <param name=\"asyncWork\"> Function to wrap async-supporting function. </param>\n    /// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous function completes. </param>\n    /// <remarks> Argument at 'asyncWork' completion callback will be the input to 'asyncCompleteCallback'. </remarks>\n    inline void DoAsyncWork(v8::Local<v8::Function> jsCallback,\n                            const CompletionWork& asyncWork,\n                            AsyncCompleteCallback asyncCompleteCallback) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = new CompletionContext();\n\n        context->work.data = context;\n        context->jsCallback.Reset(isolate, jsCallback);\n        context->asyncCompleteCallback = std::move(asyncCompleteCallback);\n\n        uv_async_init(uv_default_loop(), &context->work, RunCompletionCallback);\n\n        asyncWork([context](void* result) {\n            context->result = result;\n\n            uv_async_send(&context->work);\n        });\n    }\n\n}   // End of namespace module.\n}   // End of namespace napa.\n"
  },
  {
    "path": "inc/napa/zone.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"napa/capi.h\"\n\n#include <functional>\n#include <future>\n\nnamespace napa {\n\n    /// <summary> Initializes napa with global scope settings. </summary>\n    inline ResultCode Initialize(const std::string& settings = \"\") {\n        return napa_initialize(STD_STRING_TO_NAPA_STRING_REF(settings));\n    }\n\n    /// <summary> Initialize napa using console provided arguments. </summary>\n    inline ResultCode InitializeFromConsole(int argc, const char* argv[]) {\n        return napa_initialize_from_console(argc, argv);\n    }\n\n    /// <summary> Shut down napa. </summary>\n    inline ResultCode Shutdown() {\n        return napa_shutdown();\n    }\n\n    /// <summary> C++ proxy around napa Zone C APIs. </summary>\n    class Zone {\n    public:\n\n        /// <summary> Creates a new zone and wraps it with a zone proxy instance. </summary>\n        /// <param name=\"id\"> A unique id for the zone. </param>\n        /// <param name=\"settings\"> A settings string to set zone specific settings. </param>\n        explicit Zone(const std::string& id, const std::string& settings = \"\") : _zoneId(id) {\n            _handle = napa_zone_create(STD_STRING_TO_NAPA_STRING_REF(id));\n\n            auto res = napa_zone_init(_handle, STD_STRING_TO_NAPA_STRING_REF(settings));\n            if (res != NAPA_RESULT_SUCCESS) {\n                napa_zone_release(_handle);\n                throw std::runtime_error(napa_result_code_to_string(res));\n            }\n        }\n\n        /// <summary> Releases the underlying zone handle. </summary>\n        ~Zone() {\n            napa_zone_release(_handle);\n        }\n\n        /// <summary> Compiles and run the provided source code on all zone workers asynchronously. </summary>\n        /// <param name=\"source\"> The source code. </param>\n        /// <param name=\"callback\"> A callback that is triggered when broadcasting is done. </param>\n        const std::string& GetId() const {\n            return _zoneId;\n        }\n\n        /// <see cref=\"Zone::Broadcast\" />\n        void Broadcast(const FunctionSpec& spec, BroadcastCallback callback) {\n            // Will be deleted on when the callback scope ends.\n            auto context = new BroadcastCallback(std::move(callback));\n\n            napa_zone_function_spec req;\n            req.module = spec.module;\n            req.function = spec.function;\n            req.arguments = spec.arguments.data();\n            req.arguments_count = spec.arguments.size();\n            req.options = spec.options;\n\n            // Release ownership of transport context\n            req.transport_context = reinterpret_cast<void*>(spec.transportContext.release());\n\n            napa_zone_broadcast(_handle, req, [](napa_zone_result result, void* context) {\n                // Ensures the context is deleted when this scope ends.\n                std::unique_ptr<BroadcastCallback> callback(reinterpret_cast<BroadcastCallback*>(context));\n\n                Result res;\n                res.code = result.code;\n                res.errorMessage = NAPA_STRING_REF_TO_STD_STRING(result.error_message);\n                res.returnValue = NAPA_STRING_REF_TO_STD_STRING(result.return_value);\n\n                // Assume ownership of transport context\n                res.transportContext.reset(\n                    reinterpret_cast<napa::transport::TransportContext*>(result.transport_context));\n\n                (*callback)(std::move(res));\n            }, context);\n        }\n\n        /// <summary> Executes a pre-loaded JS function synchronously. </summary>\n        /// <param name=\"spec\"> A function spec to call. </param>\n        Result BroadcastSync(const FunctionSpec& spec) {\n            if (GetCurrent()->GetId() == GetId()) {\n                return {NAPA_RESULT_BROADCAST_SCRIPT_ERROR, \"Cannot call `broadcastSync` on current zone.\", \"\", nullptr};\n            }\n\n            std::promise<Result> prom;\n            auto fut = prom.get_future();\n\n            Broadcast(spec, [&prom](Result result) {\n                prom.set_value(std::move(result));\n            });\n\n            return fut.get();\n        }\n\n        /// <summary> Executes a pre-loaded JS function asynchronously. </summary>\n        /// <param name=\"spec\"> A function spec to call. </param>\n        /// <param name=\"callback\"> A callback that is triggered when execution is done. </param>\n        void Execute(const FunctionSpec& spec, ExecuteCallback callback) {\n            // Will be deleted on when the callback scope ends.\n            auto context = new ExecuteCallback(std::move(callback));\n\n            napa_zone_function_spec req;\n            req.module = spec.module;\n            req.function = spec.function;\n            req.arguments = spec.arguments.data();\n            req.arguments_count = spec.arguments.size();\n            req.options = spec.options;\n\n            // Release ownership of transport context\n            req.transport_context = reinterpret_cast<void*>(spec.transportContext.release());\n\n            napa_zone_execute(_handle, req, [](napa_zone_result result, void* context) {\n                // Ensures the context is deleted when this scope ends.\n                std::unique_ptr<ExecuteCallback> callback(reinterpret_cast<ExecuteCallback*>(context));\n\n                Result res;\n                res.code = result.code;\n                res.errorMessage = NAPA_STRING_REF_TO_STD_STRING(result.error_message);\n                res.returnValue = NAPA_STRING_REF_TO_STD_STRING(result.return_value);\n\n                // Assume ownership of transport context\n                res.transportContext.reset(\n                    reinterpret_cast<napa::transport::TransportContext*>(result.transport_context));\n\n                (*callback)(std::move(res));\n            }, context);\n        }\n\n        /// <summary> Executes a pre-loaded JS function synchronously. </summary>\n        /// <param name=\"spec\"> The function spec to call. </param>\n        Result ExecuteSync(const FunctionSpec& spec) {\n            std::promise<Result> prom;\n            auto fut = prom.get_future();\n\n            Execute(spec, [&prom](Result result) {\n                prom.set_value(std::move(result));\n            });\n\n            return fut.get();\n        }\n\n        /// <summary> Retrieves a new zone proxy for the zone id, throws if zone is not found. </summary>\n        static std::unique_ptr<Zone> Get(const std::string& id) {\n            auto handle = napa_zone_get(STD_STRING_TO_NAPA_STRING_REF(id));\n            if (!handle) {\n                throw std::runtime_error(\"No zone exists for id '\" + id + \"'\");\n            }\n\n            return std::unique_ptr<Zone>(new Zone(id, handle));\n        }\n\n        /// <summary> Creates a proxy to the current zone, throws if non is associated with this thread. </summary>\n        static std::unique_ptr<Zone> GetCurrent() {\n            auto handle = napa_zone_get_current();\n            if (!handle) {\n                throw std::runtime_error(\"The calling thread is not associated with a zone\");\n            }\n\n            auto zoneId = NAPA_STRING_REF_TO_STD_STRING(napa_zone_get_id(handle));\n            return std::unique_ptr<Zone>(new Zone(std::move(zoneId), handle));\n        }\n\n    private:\n\n        /// <summary> Private constructor to create a C++ zone proxy from a C handle. </summary>\n        explicit Zone(const std::string& id, napa_zone_handle handle) : _zoneId(id), _handle(handle) {}\n\n        /// <summary> The zone id. </summary>\n        std::string _zoneId;\n\n        /// <summary> Underlying zone handle. </summary>\n        napa_zone_handle _handle;\n    };\n}"
  },
  {
    "path": "inc/napa.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#ifdef BUILDING_NAPA_EXTENSION\n#define USING_V8_SHARED 1\n#endif\n\n#include <napa/version.h>\n\n#include <napa/assert.h>\n#include <napa/async.h>\n#include <napa/exports.h>\n#include <napa/memory.h>\n#include <napa/module.h>\n#include <napa/log.h>\n#include <napa/transport.h>\n#include <napa/types.h>\n#include <napa/v8-helpers.h>\n#include <napa/zone.h>\n"
  },
  {
    "path": "lib/binding.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nfunction checkNodeVersion() {\n    var semver = require('semver');\n    var currentNodeVersion = semver.coerce(process.version);\n    if (semver.gt(currentNodeVersion, 'v8.4.0')) {\n        var log = require('npmlog');\n        log.warn('napajs binding', 'Thanks for using Napa.js.');\n        log.warn('napajs binding', 'There is a compatibility issue on Node v8.5.0 and above.');\n        log.warn('napajs binding', 'The flag \"--noincremental-marking\" is set to disable V8 incremental marking as a workaround.');\n        log.warn('napajs binding', 'We are working with Node.js team on a fix in newer Node versions.');\n\n        require('v8').setFlagsFromString('--noincremental-marking');\n    } else if (semver.lt(currentNodeVersion, 'v4.5.0')) {\n        var errorMessage = 'Napa.js is not supported on Node version lower than v4.5';\n        require('npmlog').error('napajs binding', errorMessage);\n        throw new Error(errorMessage);\n    }\n}\n\nif (typeof __in_napa === 'undefined') {\n    checkNodeVersion();\n    module.exports = require('../bin/napa-binding');\n} else {\n    module.exports = process.binding('napa-binding');\n}\n"
  },
  {
    "path": "lib/core/.gitignore",
    "content": "# Ignore all .js files by default\n**/*.js\n\n# Specify all .js files to preserve explicitly\n!/assert.js\n!/events.js\n!/process.js\n!/tty.js\n!/util.js\n"
  },
  {
    "path": "lib/core/.npmignore",
    "content": "# Keep this file so that npm can pick up correct files.\n"
  },
  {
    "path": "lib/core/README.md",
    "content": "# Napa.js core modules development guideline\n\n## Summary\n\nA Napa.js **core module** is a module that provided by Napa.js and initialized ready for use in a Napa zone.\n\nThere are 2 types of core modules:\n\n- **Napa API core modules**: A set of Napa.js specific modules that described in [Napa.js modules](https://github.com/Microsoft/napajs/blob/master/docs/api/index.md#core-modules).\n\n- **Node API core modules**: A set of Napa.js modules that implement a subset of [Node.js modules](https://github.com/Microsoft/napajs/blob/master/docs/api/node-api.md).\n\nAll core modules can be imported by using global function `require(<module-name>)` in napa zone. If a module is a built-in module, it is already loaded and can be accessed by its name as a global object.\n\n## Core modules index\n\nHeader file [`/src/module/core-modules/core-modules.h`](https://github.com/Microsoft/napajs/blob/master/src/module/core-modules/core-modules.h) lists all native core modules to export.\n\nJSON file [`/lib/core/core-modules.json`](https://github.com/Microsoft/napajs/blob/master/lib/core/core-modules.json) lists all core modules available in Napa zone.\n\n## Napa API core modules\n\nNapa API core modules are implemented in C++ and Typescript.\n\nC++ implementation goes to folder `/src/module/core-modules/napa`. File [`/src/module/core-modules/napa/napa-binding.cpp`](https://github.com/Microsoft/napajs/blob/master/src/module/core-modules/napa/napa-binding.cpp) is the entry of native boundary.\n\nTypescript implementation goes to folder `/lib`. It uses `process.binding()` to access binary core modules and exports whatever defined in API document. File [`/lib/index.ts`](https://github.com/Microsoft/napajs/blob/master/lib/index.ts) is the entry of javascript boundary.\n\n## Node API core modules\n\nNapa API core modules are implemented in C++ and Typescript.\n\nC++ implementation goes to folder `/src/module/core-modules/node`.\n\nTypescript implementation goes to folder `/lib/core`. It uses `process.binding()` to access binary core modules and exports whatever defined in API document.\n\n## Developing guideline\n\n- To add a pure native module, follow the following steps:\n   - Create a module class in the correct folder (see above) with a static `Init()` method.\n   - Add the class to the list in `/src/module/core-modules/core-modules.h`.\n   - Add the module name in `/lib/core/core-modules.json`.\n\n- To add a pure typescript/javascript Node API module, follow the following steps:\n   - Add files under folder `/lib/core`.\n   - Update file `/lib/core/.gitignore` if any javascript file added under folder `/lib/core`.\n   - Add the module name in `/lib/core/core-modules.json`.\n\n- To add a native/js mixed Node API module, follow the steps of both as described above. Use `process.binding()` to access binary core modules in typescript/javascript.\n\n- To add a Napa API module usually means a big change to existing structure. May need a design review.\n\n- Try to always use typescript rather than javascript. Use javascript only when leveraging an existing javascript implementation.\n\n- Node API modules should be tested in Napa zone, and Napa API modules should be tested in both Node and Napa zone.\n\n- Pure native test goes to `/unittest` (Using [Catch](https://github.com/catchorg/Catch2)) and js test goes to `/test` (Using [mocha](https://github.com/mochajs/mocha))."
  },
  {
    "path": "lib/core/core-modules.json",
    "content": "[\n    {\n        \"name\": \"assert\",\n        \"type\": \"core\"\n    },\n    {\n        \"name\": \"events\",\n        \"type\": \"core\"\n    },\n    {\n        \"name\": \"process\",\n        \"type\": \"builtin\"\n    },\n    {\n        \"name\": \"tty\",\n        \"type\": \"core\"\n    },\n    {\n        \"name\": \"util\",\n        \"type\": \"core\"\n    },\n    {\n        \"name\": \"timers\",\n        \"type\": \"builtin\"\n    }\n]\n"
  },
  {
    "path": "lib/core/timers/timer-api.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { Timeout, Immediate } from './timer';\n\nlet binding = require('../../binding');\n\nexport function setImmediate(func: (...args: any[]) => void, ...args: any[]): Immediate {\n    let timeout = new Timeout(func, 0, 0, args);\n    binding.setImmediate(timeout);\n    return timeout;\n}\n\nexport function clearImmediate(immediate: Immediate): void {\n    immediate._active = false;\n}\n\nexport function setTimeout(func: (...args: any[]) => void, after: number, ...args: any[]): Timeout {\n    let timeout = new Timeout(func, after, 0, args);\n    binding.setTimers(timeout);\n    return timeout;\n}\n\nexport function clearTimeout(timeout: Timeout): void {\n    timeout._active = false;\n}\n\nexport function setInterval(func: (...args: any[]) => void, after: number, ...args: any[]): Timeout {\n    let timeout = new Timeout(func, after, after, args);\n    binding.setTimers(timeout);\n    return timeout;\n}\n\nexport function clearInterval(timeout: Timeout): void {\n    timeout._active = false;\n}\n"
  },
  {
    "path": "lib/core/timers/timer.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/// <summary> Timer is a facility to run timed callbacks in caller's isolates. </summary>\nexport interface Timer {\n}\n\nconst TIMEOUT_MAX = 2 ** 31 -1;\n\nexport class Timeout {\n    _callback: (...args: any[]) => void;\n    private _after: number;\n    private _repeat: number;\n    private _args: any[];\n    _active: boolean;\n    private _timer: Timer;\n\n    constructor(callback: (...args: any[]) => void, \n                after: number, repeat: number, args: any[]) {\n        if (after < 1) after = 0; //0 used for immediate\n        if (after > TIMEOUT_MAX) after = 1;\n\n        if (repeat < 1 || after == 0) repeat = 0; // do not repeat\n        if (repeat > TIMEOUT_MAX) repeat = 1;\n\n        this._callback = callback;\n        this._after = after;\n        this._repeat = repeat;\n        this._args = args;\n        this._timer = null;\n\n        this._active = true;\n    }\n}\n\nexport type Immediate = Timeout;\n"
  },
  {
    "path": "lib/core/timers.ts",
    "content": "export * from './timers/timer';\nexport * from './timers/timer-api';\n"
  },
  {
    "path": "lib/index.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { log } from './log';\nimport * as memory from './memory';\nimport * as metric from './metric';\nimport * as runtime from './runtime';\nimport * as store from './store';\nimport * as sync from './sync';\nimport * as transport from './transport';\nimport * as v8 from './v8';\nimport * as zone from './zone';\n\nexport { log, memory, metric, runtime, store, sync, transport, v8, zone };\n\n// Add execute proxy to global context.\nimport { call } from './zone/function-call';\n(<any>(global))[\"__napa_zone_call__\"] = call;\n\n// Export 'napa' in global for all isolates that require napajs.\n(<any>(global))[\"napa\"] = exports;\n"
  },
  {
    "path": "lib/log.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet binding = require('./binding');\n\nexport interface LogFunction {\n    (message: string): void;\n    (section: string, message: string): void;\n    (section: string, traceId: string, message: string): void;\n}\n\nexport interface Log extends LogFunction {\n    err(message: string): void;\n    err(section: string, message: string): void;\n    err(section: string, traceId: string, message: string): void;\n\n    warn(message: string): void;\n    warn(section: string, message: string): void;\n    warn(section: string, traceId: string, message: string): void;\n\n    info(message: string): void;\n    info(section: string, message: string): void;\n    info(section: string, traceId: string, message: string): void;\n\n    debug(message: string): void;\n    debug(section: string, message: string): void;\n    debug(section: string, traceId: string, message: string): void;\n}\n\nexport let log: Log = createLogObject();\n\nenum LogLevel {\n    Error = 0,\n    Warning = 1,\n    Info = 2,\n    Debug = 3,\n}\n\nfunction dispatchLog(level: LogLevel, arg1: string, arg2?: string, arg3?: string) {\n    if (arg3 != undefined) {\n        binding.log(level, arg1, arg2, arg3);\n    }\n    else if (arg2 != undefined) {\n        binding.log(level, arg1, undefined, arg2);\n    }\n    else {\n        binding.log(level, undefined, undefined, arg1);\n    }\n}\n\nfunction createLogObject() : Log {\n    // napa.log()\n    let logObj: any = function(arg1: string, arg2?: string, arg3?: string) {\n        dispatchLog(LogLevel.Info, arg1, arg2, arg3);\n    }\n    \n    // napa.log.err()\n    logObj.err = function(arg1: string, arg2?: string, arg3?: string) {\n        dispatchLog(LogLevel.Error, arg1, arg2, arg3);\n    }\n\n    // napa.log.warn()\n    logObj.warn = function(arg1: string, arg2?: string, arg3?: string) {\n        dispatchLog(LogLevel.Warning, arg1, arg2, arg3);\n    }\n\n    // napa.log.info()\n    logObj.info = function(arg1: string, arg2?: string, arg3?: string) {\n        dispatchLog(LogLevel.Info, arg1, arg2, arg3);\n    }\n\n    // napa.log.debug()\n    logObj.debug = function(arg1: string, arg2?: string, arg3?: string) {\n        dispatchLog(LogLevel.Debug, arg1, arg2, arg3);\n    }\n\n    return logObj;\n}"
  },
  {
    "path": "lib/memory/allocator.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { Handle } from './handle';\nimport { Shareable } from './shareable';\n\n/// <summary> Javascript interface for allocator.\n/// An allocator must be a native object shared by all isolates, which allocate memory.\n/// </summary> \nexport interface Allocator extends Shareable {\n    /// <summary> Allocate memory of requested size in bytes. </summary>\n    /// <param name=\"size\"> Size in bytes to allocate. </param>\n    allocate(size: number): Handle;\n\n    /// <summary> Deallocate memory of requested handle. </summary>\n    /// <param name=\"handle\"> Handle of memory to deallocate. </param>\n    /// <param name=\"sizeHint\"> Hint for the size of memory to deallocate. Pass 0 if unknown. </param>\n    deallocate(handle: Handle, sizeHint: number): void;\n\n    /// <summary> Type of allocator for better debuggability. </summary>\n    readonly type: string;\n}\n\n/// <summary> Javascript interface for allocator debugger. </summary>\nexport interface AllocatorDebugger extends Allocator {\n    /// <summary> Get debug info. </summary>\n    getDebugInfo(): string;\n}\n\nlet binding = require('../binding');\n\n/// <summary> Export Crt allocator from napa.dll. </summary>\nexport let crtAllocator: Allocator = binding.getCrtAllocator();\n\n/// <summary> Export default allocator from napa.dll. </summary>\nexport let defaultAllocator: Allocator = binding.getDefaultAllocator();\n\n/// <summary> Create a debug allocator around allocator. </summary>\n/// <param name=\"allocator\"> User allocator. </param>\nexport function debugAllocator(allocator: Allocator): AllocatorDebugger {\n    return new binding.AllocatorDebuggerWrap(allocator);\n}\n"
  },
  {
    "path": "lib/memory/handle.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport type Handle = [number, number] | [number, number, number];\n\n/// <summary> nullptr. </summary>\nexport const EMPTY_HANDLE: Handle = [0, 0];\n\n/// <summary> Tell if pointer is nullptr. </summary>\nexport function isEmpty(handle: Handle): boolean {\n    return handle == null ||\n        (handle[0] === 0 && handle[1] === 0);\n}\n\n/// <summary> Tell if a pointer has type information. </summary>\nexport function getTypeHash(handle: Handle): number {\n    return handle.length === 3 ? handle[2] : 0;\n}\n"
  },
  {
    "path": "lib/memory/shareable.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { Handle} from './handle';\nimport { Transportable, isTransportable } from '../transport/transportable';\n\n/// <summary> Interface of native object (wrapped shared_ptr<T>) that can be shared across isolates. </summary>\n/// <remarks> The counterpart of Shareable is napa::module::ShareableWrap, always extend napa::module::ShareableWrap for sharable native object. </remarks>\nexport interface Shareable extends Transportable {\n    /// <summary> Return handle of this object. </summary>\n    readonly handle: Handle;\n\n    /// <summary> Return true if handle is empty. </summary>\n    isNull(): boolean;\n\n    /// <summary> Return reference count for shared object. </summary>\n    readonly refCount: number;\n}\n\n/// <summary> Tells if a JavaScript is value or not. </summary>\nexport function isShareable(jsValue: any): boolean {\n    if (isTransportable(jsValue)) {\n        let object = <Object>jsValue;\n        return object.hasOwnProperty('handle')\n            && object.hasOwnProperty('refCount');\n    }\n    return false;\n}\n"
  },
  {
    "path": "lib/memory.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport * from './memory/allocator';\nexport * from './memory/handle';\nexport * from './memory/shareable';\n"
  },
  {
    "path": "lib/metric.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet binding = require('./binding');\n\nexport enum MetricType {\n    Number = 0,\n    Rate,\n    Percentile,\n}\n\nexport interface Metric {\n    readonly section: string;\n    readonly name: string;\n\n    set(value: number, dimensions?: string[]): void;\n    increment(dimensions?: string[]): void;\n    decrement(dimensions?: string[]): void;\n}\n\n/// <summary> A cache for metric wraps. </summary>\nvar _metricsCache: { [key: string]: Metric } = {};\n\nexport function get(section: string, name: string, type: MetricType, dimensions: string[] = []) : Metric {\n    let key: string = (section ? section : \"\") + \"\\\\\" + (name ? name : \"\");\n\n    // Check cache first\n    let metric: Metric = _metricsCache[key];\n    if (metric) {\n        return metric;\n    }\n\n    // Add to cache\n    let metricWrap: any = new binding.MetricWrap(section, name, type, dimensions);\n    metricWrap.section = section;\n    metricWrap.name = name;\n    _metricsCache[key] = metricWrap;\n\n    return metricWrap;\n}\n"
  },
  {
    "path": "lib/runtime/platform.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet binding = require('../binding');\nimport { log } from '../log';\n\n// This variable is either defined by napa runtime, or not defined (hence node runtime)\ndeclare var __in_napa: boolean;\n\n/// <summary> \n///     Describes the available platform settings.\n/// </summary>\nexport interface PlatformSettings {\n\n    /// <summary> The logging provider to use when outputting logs. </summary>\n    loggingProvider?: string;\n\n    /// <summary> The metric provider to use when creating/setting metric values. </summary>\n    metricProvider?: string;\n}\n\n/// <summary> Initialization of napa is only needed if we run in node. </summary>\nlet _initializationNeeded: boolean = (typeof __in_napa === 'undefined');\n\n/// <summary> Empty platform settings. </summary>\nlet _platformSettings: PlatformSettings = {};\n\n/// <summary> Sets the platform settings. Must be called from node before the first container is created. </summary>\nexport function setPlatformSettings(settings: PlatformSettings) {\n    if (!_initializationNeeded) {\n        // If we don't need to initialize we can't set platform settings.\n        log.err(\"Cannot set platform settings after napa was already initialized\");\n        return;\n    }\n\n    _platformSettings = settings;\n    initialize();\n}\n\nexport function initialize() {\n    if (_initializationNeeded) {\n        // Guard initialization, should only be called once.\n        binding.initialize(_platformSettings);\n        _initializationNeeded = false;\n    }\n}\n"
  },
  {
    "path": "lib/runtime.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport { \n    setPlatformSettings\n} from './runtime/platform';\n"
  },
  {
    "path": "lib/store/store-api.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { Store } from './store';\n\nlet binding = require('../binding');\n\n/// <summary> Create a store with an id. </summary>\n/// <param name=\"id\"> String identifier which can be used to get the store from all isolates. </summary>\n/// <returns> A store object or throws Error if store with this id already exists. </returns>\n/// <remarks> Store object will be destroyed when reference from all isolates are unreferenced. \n/// It's usually a best practice to keep a long-living reference in user modules or global scope. </remarks>\nexport function create(id: string): Store {\n    return binding.createStore(id);\n}\n\n/// <summary> Get a store with an id. </summary>\n/// <param name=\"id\"> String identifier which is passed to create/getOrCreate earlier. </summary>\n/// <returns> A store object if exists, otherwise undefined. </returns>\nexport function get(id: string): Store {\n    return binding.getStore(id);\n}\n\n/// <summary> Get a store with an id, or create it if not exist. </summary>\n/// <param name=\"id\"> String identifier which can be used to get the store from all isolates. </summary>\n/// <returns> A store object associated with the id. </returns>\n/// <remarks> Store object will be destroyed when reference from all isolates are unreferenced. \n/// It's usually a best practice to keep a long-living reference in user modules or global scope. </remarks>\nexport function getOrCreate(id: string): Store {\n    return binding.getOrCreateStore(id);\n}\n\n/// <summary> Returns number of stores that is alive. </summary>\nexport function count(): number {\n    return binding.getStoreCount();\n}"
  },
  {
    "path": "lib/store/store.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/// <summary> Store is a facility to share (built-in JavaScript types or Transportable subclasses) objects across isolates. </summary>\nexport interface Store {\n    /// <summary> Id of this store. </summary>\n    readonly id: string;\n\n    /// <summary> Number of keys in this store. </summary>\n    readonly size: number;\n    \n    /// <summary> Check if this store has a key. </summary>\n    /// <param name=\"key\"> Case-sensitive string key. </summary>\n    /// <returns> True if this store has the key. </returns>\n    has(key: string): boolean;\n\n    /// <summary> Get JavaScript value by key. </summary>\n    /// <param name=\"key\"> Case-sensitive string key. </summary>\n    /// <returns> Value for key, undefined if not found. </returns>\n    get(key: string): any;\n\n    /// <summary> Insert or update a JavaScript value by key. </summary>\n    /// <param name=\"key\"> Case-sensitive string key. </summary>\n    /// <param name=\"value\"> Value. Any value of built-in JavaScript types or Transportable subclasses can be accepted. </summary>\n    set(key: string, value: any): void;\n\n    /// <summary> Remove a key with its value from this store. </summary>\n    /// <param name=\"key\"> Case-sensitive string key. </summary>\n    delete(key: string): void;\n}"
  },
  {
    "path": "lib/store.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport * from './store/store';\nexport * from './store/store-api';"
  },
  {
    "path": "lib/sync/lock.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet binding = require('../binding');\nimport { cid, TransportContext, TransportableObject } from '../transport';\n\nexport interface Lock {\n    /// <summary>\n    /// Obtain the lock and input function synchronously.\n    /// or throws error if input function throws.\n    /// Lock will be released once execution finishes or an exception is thrown.\n    /// </summary>\n    /// <param name=\"func\"> The input function to run. </summary>\n    /// <param name=\"params\"> Optional. A list of parameters that passed to func. </summary>\n    /// <returns> The value that the input function returns. </returns>\n    /// <remarks> This function will obtain the lock before running the input function. It will wait until the\n    /// lock is available. If the input function throws exception, the exception will be thrown out. </remarks>\n    guardSync(func: (...params: any[]) => any, params?: any[]): any;\n}\n\nexport function createLock(): Lock {\n    return binding.createLock();\n}"
  },
  {
    "path": "lib/sync.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport * from './sync/lock';\n"
  },
  {
    "path": "lib/transport/builtin-object-transporter.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport { Shareable } from '../memory/shareable';\n\n/// <summary>\n/// ShareableWrap of SerializedData.\n/// </summary>\nexport interface SerializedData extends Shareable {\n}\n\nexport function serializeValue(jsValue: any): SerializedData {\n    return require('../binding').serializeValue(jsValue);\n}\n\nexport function deserializeValue(serializedData: SerializedData): any {\n    return require('../binding').deserializeValue(serializedData);\n}\n"
  },
  {
    "path": "lib/transport/function-transporter.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n////////////////////////////////////////////////////////////////////////\n// Module to support function transport.\n\nimport { Store } from '../store/store';\nimport * as assert from 'assert';\nimport * as path from 'path';\n\n/// <summary> Function hash to function cache. </summary>\nlet _hashToFunctionCache: {[hash: string]: (...args: any[]) => any} = {};\n\n/// <summary> Function to hash cache. </summary>\n/// <remarks> Function cannot be used as a key in TypeScript. </remarks>\nlet _functionToHashCache: any = {};\n\n/// <summary> Marshalled function body cache. </summary>\nlet _store: Store;\n\n/// <summary> Interface for function definition that will be saved in store. </summary>\ninterface FunctionDef {\n    /// <summary> From which file name the function is defined. </summary>\n    origin: string;\n\n    /// <summary> Function body. </summary>\n    body: string;\n}\n\n/// <summary> Get underlying store to save marshall function body across isolates. </summary>\nfunction getStore(): Store {\n    if (_store == null) {\n        // Lazy creation function store\n        // 1) avoid circular runtime dependency between store and transport.\n        // 2) avoid unnecessary cost when function transport is not used.\n        _store = require('../store/store-api')\n            .getOrCreate('__napajs_marshalled_functions');\n    }\n    return _store;\n}\n\n/// <summary> Save function and get a hash string to use it later. </summary>\nexport function save(func: (...args: any[]) => any): string {\n    let hash = _functionToHashCache[(<any>(func))];\n    if (hash == null) {\n        // Should happen only on first marshall of input function in current isolate.\n        let origin = (<any>func).origin || '';\n        let body = func.toString();\n        let fullContent = origin + \":\" + body;\n        hash = getFunctionHash(fullContent);\n        let def: FunctionDef = { \n            origin: origin,\n            body: body\n        };\n        getStore().set(hash, def);\n        cacheFunction(hash, func);\n    }\n    return hash;\n}\n\n/// <summary> Load a function with a hash retrieved from `save`. </summary>\nexport function load(hash: string): (...args: any[]) => any {\n    let func = _hashToFunctionCache[hash];\n    if (func == null) {\n        // Should happen only on first unmarshall of given hash in current isolate..\n        let def: FunctionDef = getStore().get(hash);\n        if (def == null) {\n            throw new Error(`Function hash cannot be found: ${hash}`);\n        }\n        func = loadFunction(def);\n        cacheFunction(hash, func);\n    }\n    return func;\n}\n\n/// <summary> Cache function with its hash in current isolate. </summary>\nfunction cacheFunction(hash: string, func: (...args: any[]) => any) {\n    _functionToHashCache[<any>(func)] = hash;\n    _hashToFunctionCache[hash] = func;\n}\n\n/// <summary> Generate hash for function definition using DJB2 algorithm. \n/// See: https://en.wikipedia.org/wiki/DJB2 \n/// </summary>\nfunction getFunctionHash(signature: string): string {\n    let hash = 5381;\n    for (let i = 0; i < signature.length; ++i) {\n        hash = (hash * 33) ^ signature.charCodeAt(i);\n    }\n\n    /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed\n    * integers. Since we want the results to be always positive, convert the\n    * signed int to an unsigned by doing an unsigned bitshift. */\n    return (hash >>> 0).toString(16);\n}\n\ndeclare var __in_napa: boolean;\n\n/// <summary> Load function from definition. </summary>\nfunction loadFunction(def: FunctionDef): (...args: any[]) => any {\n    let moduleId = def.origin;\n    let script = \"module.exports = \" + def.body + \";\";\n    let func: any = null;\n\n    if (typeof __in_napa === 'undefined') {\n        // In node, we create a sandbox using Module\n        let Module: any = null;\n        if (Module == null) {\n            Module = require('module');\n        }\n        let module = new Module(moduleId);\n        module.filename = moduleId;\n        module.paths = Module._nodeModulePaths(path.dirname(def.origin));\n        module._compile(script, moduleId);\n        func = module.exports;\n\n    } else {\n        // In napa, we create a sandbox using require(path, script);\n        func = (<any>require)(moduleId, script);\n    }\n    func.origin = def.origin;\n    return func;\n}"
  },
  {
    "path": "lib/transport/transport.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as transportable from './transportable';\nimport * as functionTransporter from './function-transporter';\nimport * as builtinObjectTransporter from './builtin-object-transporter';\nimport * as path from 'path';\n\n/// <summary> Per-isolate cid => constructor registry. </summary>\nlet _registry: Map<string, new(...args: any[]) => transportable.Transportable> \n    = new Map<string, new(...args: any[]) => transportable.Transportable>();\n\nlet _builtInTypeWhitelist = new Set();\n[\n    'ArrayBuffer',\n    'Float32Array',\n    'Float64Array',\n    'Int16Array',\n    'Int32Array',\n    'Int8Array',\n    'SharedArrayBuffer',\n    'Uint16Array',\n    'Uint32Array',\n    'Uint8Array'\n].forEach((type) => { _builtInTypeWhitelist.add(type); });\n\n/// <summary> Register a TransportableObject sub-class with a Constructor ID (cid). </summary>\nexport function register(subClass: new(...args: any[]) => any) {\n    // Check cid from constructor first, which is for TransportableObject. \n    // Thus we don't need to construct the object to get cid according to Transportable interface. \n    let cid: string = (<any>subClass)['_cid'];\n    if (cid == null) {\n        cid = new subClass().cid();\n    }\n    if (cid == null) {\n        throw new Error(`Class \"${subClass.name}\" doesn't implement cid(), did you forget put @cid decorator before class declaration?`);\n    }\n    if (_registry.has(cid)) {\n        throw new Error(`Constructor ID (cid) \"${cid}\" is already registered.`);\n    }\n    _registry.set(cid, subClass);\n}\n\n/// <summary> Marshall transform a JS value to a plain JS value that will be stringified. </summary> \nexport function marshallTransform(jsValue: any, context: transportable.TransportContext): any {\n     if (jsValue != null && typeof jsValue === 'object' && !Array.isArray(jsValue)) {\n        let constructorName = Object.getPrototypeOf(jsValue).constructor.name;\n        if (constructorName !== 'Object') {\n            if (typeof jsValue['cid'] === 'function') {\n                if (context == null) {\n                    throw new Error(`Cannot transport type \\\"${constructorName}\\\" without a transport context.`);\n                }\n                return <transportable.Transportable>(jsValue).marshall(context);\n            } else if (_builtInTypeWhitelist.has(constructorName)) {\n                let serializedData = builtinObjectTransporter.serializeValue(jsValue);\n                if (serializedData) {\n                    return { _serialized : serializedData };\n                } else {\n                    throw new Error(`Failed to serialize object with type of \\\"${constructorName}\\\".`);\n                }\n            } else {\n                throw new Error(`Object type \\\"${constructorName}\\\" is not transportable.`);\n            }\n        }\n    }\n    return jsValue;\n}\n\n/// <summary> Unmarshall transform a plain JS value to a transportable class instance. </summary>\n/// <param name=\"payload\"> Plain Javascript value. </param> \n/// <param name=\"context\"> Transport context. </param>\n/// <returns> Transported value. </returns>\nfunction unmarshallTransform(payload: any, context: transportable.TransportContext): any {\n    if (payload == null) return payload;\n    if (payload._cid !== undefined) {\n        let cid = payload._cid;\n        if (cid === 'function') {\n            return functionTransporter.load(payload.hash);\n        }\n        if (context == null) {\n            throw new Error(`Cannot transport type with cid \\\"${cid}\\\" without a transport context.`);\n        }\n        let subClass = _registry.get(cid);\n        if (subClass == null) {\n            throw new Error(`Unrecognized Constructor ID (cid) \"${cid}\". Please ensure @cid is applied on the class or transport.register is called on the class.`);\n        }\n        let object = new subClass();\n        object.unmarshall(payload, context);\n        return object;\n    } else if (payload.hasOwnProperty('_serialized')) {\n        return builtinObjectTransporter.deserializeValue(payload['_serialized']);\n    }\n    return payload;\n}\n\n/// <summary> Unmarshall from JSON string to a JavaScript value, which could contain complex/native objects. </summary>\n/// <param name=\"json\"> JSON string. </summary>\n/// <param name=\"context\"> Transport context to save shared pointers. </param>\n/// <returns> Parsed JavaScript value, which could be built-in JavaScript types or deserialized Transportable objects. </returns>\nexport function unmarshall(\n    json: string, \n    context: transportable.TransportContext): any {\n    \n    if (json === \"undefined\") {\n        return undefined;\n    }\n    return JSON.parse(json, \n        (key: any, value: any): any => {\n            return unmarshallTransform(value, context);\n        });\n}\n\n/// <summary> Marshall a JavaScript value to JSON. </summary>\n/// <param name=\"jsValue\"> JavaScript value to stringify, which maybe built-in JavaScript types or transportable objects. </param>\n/// <param name=\"context\"> Transport context to save shared pointers. </param>\n/// <returns> JSON string. </returns>\nexport function marshall(\n    jsValue: any, \n    context: transportable.TransportContext): string {\n\n    // Function is transportable only as root object. \n    // This is to avoid unexpected marshalling on member functions.\n    if (typeof jsValue === 'function') {\n        return `{\"_cid\": \"function\", \"hash\": \"${functionTransporter.save(jsValue)}\"}`;\n    }\n    return JSON.stringify(jsValue,\n        (key: string, value: any) => {\n            return marshallTransform(value, context);\n        });\n}"
  },
  {
    "path": "lib/transport/transportable.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/// <summary> In Napa.JS, transporting objects across isolates is required for multi-thread collaborations.\n/// \n/// A JavaScript value is transportable, if\n/// 1) it is a built-in JavaScript types, which includes primitive types, plain objects (whose constructor name is 'Object') and arrays.\n/// 2) or a class implements Transportable.\n/// 3) or it is a composite of #1 and #2.\n/// \n/// </summary>\n\nimport * as transport from './transport'\nimport * as v8 from '../v8';\n\nimport { Shareable } from '../memory/shareable';\nimport { Handle } from '../memory/handle';\n\nimport * as path from 'path';\n\n/// <summary> Transport context carries additional information needed to unmarshall \n/// objects, besides the payload itself. Currently, only std::shared_ptr<T> is transported via TransportContext,\n/// since their lifecycle are beyond an V8 isolate thus cannot be managed only via payload.\n/// TransportContext is a C++ add-on and only accessed from C++ thus no method is exposed to JavaScript world.\n/// </summary>\n/// <remarks> Reference: napa::binding::TransportContextWrapImpl. </remarks>\nexport interface TransportContext {\n    /// <summary> Save a shared_ptr for later load in another isolate. </summary>\n    saveShared(object: Shareable): void;\n\n    /// <summary> Load a shared_ptr from previous save in another isolate. </summary>\n    loadShared(handle: Handle): Shareable;\n\n    /// <summary> Number of shared object saved in this TransportContext. </summary> \n    readonly sharedCount: number;\n}\n\n/// <summary> Interface for transportable non-built-in JavaScript types. </summary> \nexport interface Transportable {\n    /// <summary> Get Constructor ID (cid) for transportable object. </summary>\n    cid(): string;\n\n    /// <summary> Marshall object into plain JavaScript object. </summary>\n    /// <param name='context'> Transport context for saving shared pointers, only usable for C++ addons that extends napa::module::ShareableWrap. </param>\n    /// <returns> Plain JavaScript value. </returns>\n    marshall(context: TransportContext): object;\n\n    /// <summary> Unmarshall object from payload, which is a plain JavaScript value, and a transport context. </summary>\n    /// <param name='payload'> Payload to read from, which already have inner objects transported. </param>\n    /// <param name='context'> Transport context for loading shared pointers, only needed for C++ addons that extends napa::module::ShareableWrap. </param>\n    unmarshall(payload: object, context: TransportContext): void\n}\n\n/// <summary> Abstract class for transportable objects. \n/// Subclass' obligations:\n/// 1) Constructor should accept zero parameters .\n/// 2) Implement save()/load() to marshall/unmarshall internal state.\n/// 3) Register with transport with a Constructor ID (cid) via one of following methods:\n///    - declare class decorator: @cid() use '<module-name>.<class-name>' as cid.\n///    - declare class decorator: @cid('<guid>') use the specified GUID as cid.\n/// </summary>\nexport abstract class TransportableObject implements Transportable{\n    /// <summary> Get Constructor ID (cid) for this object. </summary>\n    cid(): string {\n        return Object.getPrototypeOf(this).constructor._cid;\n    }\n\n    /// <summary> Subclass to save state to payload. </summary>\n    /// <param name='payload'> Payload to write to. \n    /// The sub-class should always serialize states into the payload \n    /// if they are required to load the sub-class instance. </param>\n    /// <param name='context'> Transport context for saving shared pointers, only usable for C++ addons that extends napa::module::ShareableWrap. </param>\n    abstract save(payload: object, context: TransportContext): void;\n\n    /// <summary> Subclass to load state from payload. </summary>\n    /// <param name='payload'> Payload to read from, which already have inner objects transported. </param>\n    /// <param name='context'> Transport context for loading shared pointers, only usable for C++ addons that extends napa::module::ShareableWrap. </param>\n    abstract load(payload: object, context: TransportContext): void;\n\n    /// <summary> Marshall object into plain JavaScript object. </summary>\n    /// <returns> Plain JavaScript value. </returns>\n    marshall(context: TransportContext): object {\n        let payload = {\n            _cid: this.cid()\n        };\n        this.save(payload, context);\n        return payload;\n    } \n\n    /// <summary> Unmarshall object from payload, which is a plain JavaScript value, and a transport context. </summary>\n    /// <param name='payload'> Payload to read from, which already have inner objects transported. </param>\n    /// <param name='context'> Transport context for looking up shared pointers. </param>\n    unmarshall(payload: object, context: TransportContext): void {\n        this.load(payload, context);\n    }\n}\n\n/// <summary> Base class for JavaScript class that is auto transportable. \n/// A JavaScript class can be auto transportable when \n/// 1) it has a default constructor.\n/// 2) members are transportable types.\n/// 3) register via class decorator @cid or transport.register.\n/// </summary>\nexport class AutoTransportable extends TransportableObject {\n    /// <summary> Automatically save own properties to payload. </summary>\n    /// <param name='payload'> Plain JS object to write to. </param>\n    /// <param name='context'> Transport context for saving shared pointers, only usable for C++ addons that extends napa::module::ShareableWrap. </param>\n    save(payload: object, context: TransportContext) {\n        for (let property of Object.getOwnPropertyNames(this)) {\n            (<any>(payload))[property] = transport.marshallTransform((<any>(this))[property], context);\n        }\n    }\n\n    /// <summary> Automatically load own properties from payload. </summary>\n    /// <param name='payload'> Payload to read from, which already have inner objects transported. </param>\n    /// <param name='context'> Transport context for loading shared pointers, only usable for C++ addons that extends napa::module::ShareableWrap. </param>\n    load(payload: object, context: TransportContext) {\n        // Members have already been unmarshalled.\n        for (let property of Object.getOwnPropertyNames(payload)) {\n            (<any>(this))[property] = (<any>(payload))[property];\n        }\n    }\n}\n\n/// <summary> Tell if a jsValue is transportable. </summary>\nexport function isTransportable(jsValue: any): boolean {\n    if (Array.isArray(jsValue)) {\n        // Traverse array.\n        for (let element of jsValue) {\n            if (!isTransportable(element)) {\n                return false;\n            }\n        }\n    } else if (typeof jsValue === 'object') {\n        let constructor = Object.getPrototypeOf(jsValue).constructor;\n        if (constructor.name === 'Object') {\n            // Traverse object.\n            for (let property in jsValue) {\n                if (!isTransportable(jsValue[property])) {\n                    return false;\n                }\n            }\n        }\n        else if (typeof jsValue['cid'] !== 'function') {\n            return false;\n        }\n    }\n    return true;\n}\n\n/// <summary> Decorator 'cid' to register a transportable class with a 'cid'. </summary>\n/// <param name=\"guid\"> If specified, use this GUID as cid. </param>\nexport function cid<T extends TransportableObject>(guid?: string) {\n    let moduleName: string = null;\n    if (!guid) {\n        moduleName = extractModuleName(v8.currentStack(2)[1].getFileName());\n    }\n\n    return (constructor: new(...args: any[]) => any ) => {\n        let cid = moduleName ? `${moduleName}.${constructor.name}` : guid;\n        (<any>constructor)['_cid'] = cid;\n        transport.register(constructor);\n    }\n}\n\nconst NODE_MODULE_PREFIX: string = 'node_modules/';\n\n/// <summary> Extract module name from module.id.</summary>\nfunction extractModuleName(moduleId: string): string {\n    moduleId = moduleId.replace('\\\\\\\\', '/');\n    if (moduleId.endsWith('.js')) {\n        moduleId = moduleId.substr(0, moduleId.length - 3);\n    }\n\n    let moduleRootStart = moduleId.lastIndexOf(NODE_MODULE_PREFIX);\n    if (moduleRootStart >= 0) {\n        // module is under node_modules.\n        return moduleId.substr(moduleRootStart + NODE_MODULE_PREFIX.length);\n    }\n    else {\n        // module is located using absolute or relative path.\n        return path.relative(process.cwd(), moduleId).replace('\\\\\\\\', '/');\n    }\n}"
  },
  {
    "path": "lib/transport.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport {\n    Transportable,\n    TransportableObject,\n    TransportContext,\n    AutoTransportable,\n    isTransportable,\n    cid\n} from './transport/transportable';\n\nexport * from './transport/transport';\n\nimport { Handle } from './memory/handle';\nimport { TransportContext } from './transport/transportable';\nimport * as functionTransporter from './transport/function-transporter';\n\nlet binding = require('./binding');\n\n/// <summary> Create a transport context. </summary>\nexport function createTransportContext(owning: boolean = true, handle : Handle = undefined): TransportContext {\n    return new binding.TransportContextWrap(owning, handle);\n}\n\nexport let saveFunction = functionTransporter.save;\nexport let loadFunction = functionTransporter.load;"
  },
  {
    "path": "lib/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": true,\n        \"sourceMap\": false,\n        \"lib\": [\"es2015\"],\n        \"declarationDir\": \"../types\"\n    }\n}"
  },
  {
    "path": "lib/v8/stack-trace.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n/// Reference: https://github.com/v8/v8/wiki/Stack-Trace-API\n\n/// <summary> Represents a stack frame. </summary>\nexport interface CallSite {\n\n    /// <summary> Returns the value of this. </summary>\n    getThis(): any;\n\n    /// <summary> \n    ///     Returns the type of this as a string. \n    ///     This is the name of the function stored in the constructor field of this, if available, \n    ///     otherwise the object's [[Class]] internal property.\n    /// </summary>\n    getTypeName(): string;\n\n    /// <summary> Returns the current function. </summary>\n    getFunction(): any;\n\n    /// <summary> \n    ///     Returns the name of the current function, typically its name property. \n    ///     If a name property is not available an attempt will be made to try to infer a name from the function's context. \n    /// </summary>\n    getFunctionName(): string;\n\n    /// <summary> Returns the name of the property of this or one of its prototypes that holds the current function. </summary>\n    getMethodName(): string;\n\n    /// <summary> If this function was defined in a script returns the name of the script. </summary>\n    getFileName(): string;\n\n    /// <summary> If this function was defined in a script returns the current line number. </summary>\n    getLineNumber(): number;\n\n    /// <summary> If this function was defined in a script returns the current column number. </summary>\n    getColumnNumber(): number;\n\n    /// <summary> If this function was created using a call to eval returns a CallSite object representing the location where eval was called. </summary>\n    getEvalOrigin(): CallSite;\n\n    /// <summary> Is this a toplevel invocation, that is, is this the global object. </summary>\n    isToplevel(): boolean;\n\n    /// <summary> Is this call in native V8 code. </summary>\n    isNative(): boolean;\n\n    /// <summary> Is this a constructor call. </summary>\n    isConstructor(): boolean;\n\n    /// <summary> Does this call take place in code defined by a call to eval. </summary>\n    isEval(): boolean;\n}\n\n/// <summary> Get current stack. </summary>\n/// <param name=\"stackTraceLimit\"> Max stack depth to trace. </param>\n/// <returns> Array of CallSite. </returns>\nexport function currentStack(stackTraceLimit: number = 0): CallSite[] {\n    let e: any = Error;\n\n    const originPrepare = e.prepareStackTrace;\n    const originLimit = e.stackTraceLimit;\n\n    if (stackTraceLimit > 0) {\n        e.stackTraceLimit = stackTraceLimit + 1;\n    }\n    \n    e.prepareStackTrace = (prepare: any, stack: any) => stack;\n    // We remove stack at top since it's always this function.\n    let stack = new e().stack.slice(1);\n    e.prepareStackTrace = originPrepare;\n\n    if (stackTraceLimit > 0) {\n        e.stackTraceLimit = originLimit;\n    }\n    return stack;\n}\n\n/// <summary> Format stack trace. </summary>\nexport function formatStackTrace(trace: CallSite[]): string {\n    let s = '';\n    for (let site of trace) {\n        s += 'at ' \n            + site.getFunctionName() \n            + '(' \n            + site.getFileName() \n            + ':' \n            + site.getLineNumber()\n            + ':'\n            + site.getColumnNumber()\n            + \")\\n\";\n    }\n    return s;\n}"
  },
  {
    "path": "lib/v8.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexport * from './v8/stack-trace';"
  },
  {
    "path": "lib/zone/function-call.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as transport from '../transport';\nimport { CallOptions } from './zone';\n\n/// <summary> Rejection type </summary>\n/// TODO: we need a better mapping between error code and result code.\nexport enum RejectionType {\n    TIMEOUT = 3,\n    APP_ERROR = 6\n}\n\n/// <summary> Interface for Call context. </summary>\nexport interface CallContext {\n\n    /// <summary> Resolve task with marshalled result. </summary>\n    resolve(result: string): void;\n\n    /// <summary> Reject task with reason. </summary>\n    reject(reason: any): void;\n\n    /// <summary> Reject task with a rejection type and reason. </summary>\n    reject(type: RejectionType, reason: any): void;\n\n    /// <summary> Returns whether task has finished (either completed or cancelled). </summary>\n    readonly finished: boolean;\n\n    /// <summary> Elapse in nano-seconds since task started. </summary>\n    readonly elapse: [number, number];\n\n    /// <summary> Module name to select function. </summary>\n    readonly module: string;\n\n    /// <summary> Function name to execute. </summary>\n    readonly function: string;\n\n    /// <summary> Marshalled arguments. </summary>\n    readonly args: string[];\n\n    /// <summary> Transport context. </summary>\n    readonly transportContext: transport.TransportContext;\n\n    /// <summary> Execute options. </summary>\n    readonly options: CallOptions;\n}\n\n/// <summary> \n///     Proxy function for __napa_zone_call__. \n///     1) calling a global function: \n///        module name: undefined or empty string\n///        function name: global function name\n///     2) calling an anonymous function at client side: \n///        module name: literal '__function' \n///        function name: hash returned from transport.saveFunction().\n///     3) calling a function from a module:\n///        module name: target module path.\n///        function name: target function name from the module.\n///\n///     function name can have multiple levels like 'foo.bar'.\n/// </summary>\nexport function call(context: CallContext): void {\n    // Cache the context since every call to context.transportContext will create a new wrap upon inner TransportContext pointer.\n    let transportContext = context.transportContext;\n    let result: any = undefined;\n    try {\n        result = callFunction(\n            context.module, \n            context.function, \n            context.args, \n            transportContext,\n            context.options);\n    }\n    catch(error) {\n        context.reject(error);\n        return;\n    }\n\n    if (result != null \n        && typeof result === 'object'\n        && typeof result['then'] === 'function') {\n        // Delay completion if return value is a promise.\n        result.then((value: any) => {\n            finishCall(context, transportContext, value);\n        })\n        .catch((error: any) => {\n            context.reject(error);\n        });\n        return;\n    }\n    finishCall(context, transportContext, result);\n}\n\n/// <summary> Call a function. </summary>\nfunction callFunction(\n    moduleName: string, \n    functionName: string, \n    marshalledArgs: string[], \n    transportContext: transport.TransportContext,\n    options: CallOptions): any {\n\n    let module: any = null;\n    let useAnonymousFunction: boolean = false;\n\n    if (moduleName == null || moduleName.length === 0 || moduleName === 'global') {\n        module = global;\n    } else if (moduleName === '__function') {\n        useAnonymousFunction = true;\n    } else {\n        module = require(moduleName);\n    }\n\n    let func = null;\n    if (useAnonymousFunction) {\n        func = transport.loadFunction(functionName);\n    } else {\n        if (module == null) {\n            throw new Error(`Cannot load module \\\"${moduleName}\\\".`);\n        }\n        func = module;\n        if (functionName != null && functionName.length != 0) {\n            var path = functionName.split('.');\n            for (let item of path) {\n                func = func[item];\n                if (func === undefined) {\n                    throw new Error(\"Cannot find function '\" + functionName + \"' in module '\" + moduleName + \"'\");\n                }\n            }\n        }\n        if (typeof func !== 'function') {\n            throw new Error(\"'\" + functionName + \"' in module '\" + moduleName + \"' is not a function\");\n        }\n    }\n\n    let args = marshalledArgs.map((arg) => { return transport.unmarshall(arg, transportContext); });\n    return func.apply(this, args);\n}\n\n/// <summary> Finish call with result. </summary>\nfunction finishCall(\n    context: CallContext, \n    transportContext: transport.TransportContext, \n    result: any) {\n\n    let payload: string = undefined;\n    try {\n        payload = transport.marshall(result, transportContext);\n    }\n    catch (error) {\n        context.reject(error);\n        return;\n    }\n    context.resolve(payload);\n}"
  },
  {
    "path": "lib/zone/zone-impl.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as path from 'path';\nimport * as zone from './zone';\nimport * as transport from '../transport';\nimport * as v8 from '../v8';\n\ninterface FunctionSpec {\n    module: string;\n    function: string;\n    arguments: any[];\n    options: zone.CallOptions;\n    transportContext: transport.TransportContext;\n}\n\nclass Result implements zone.Result{\n\n     constructor(payload: string, transportContext: transport.TransportContext) {\n          this._payload = payload;\n          this._transportContext = transportContext; \n     }\n\n     get value(): any {\n         if (this._value == null) {\n             this._value = transport.unmarshall(this._payload, this._transportContext);\n         }\n\n         return this._value;\n     }\n\n     get payload(): string {\n         return this._payload; \n     }\n\n     get transportContext(): transport.TransportContext {\n         return this._transportContext; \n     }\n\n     private _transportContext: transport.TransportContext;\n     private _payload: string;\n     private _value: any;\n};\n\ndeclare var __in_napa: boolean;\n\n/// <summary> Helper function to workaround possible delay in Promise resolve/reject when working with Node event loop.\n/// See https://github.com/audreyt/node-webworker-threads/issues/123#issuecomment-254019552\n/// </summary>\nfunction runImmediately(func : () => void) {\n    if (typeof __in_napa === 'undefined') {\n        // In node.\n        setImmediate(func);\n    } else  {\n        // In napa workers.\n        func();\n    }\n}\n\n/// <summary> Zone consists of Napa isolates. </summary>\nexport class ZoneImpl implements zone.Zone {\n    private _nativeZone: any;\n\n    constructor(nativeZone: any) {\n        this._nativeZone = nativeZone;\n    }\n\n    public get id(): string {\n        return this._nativeZone.getId();\n    }\n\n    public toJSON(): any {\n        return { id: this.id, type: this.id === 'node'? 'node': 'napa' };\n    }\n\n    public broadcast(arg1: any, arg2?: any) : Promise<void> {\n        let spec: FunctionSpec = this.createBroadcastRequest(arg1, arg2);\n\n        return new Promise<void>((resolve, reject) => {\n            this._nativeZone.broadcast(spec, (result: any) => {\n                runImmediately(() => {\n                    if (result.code === 0) {\n                        resolve();\n                    } else {\n                        reject(result.errorMessage);\n                    }\n                });\n            });\n        });\n    }\n\n    public broadcastSync(arg1: any, arg2?: any) : void {\n        let spec: FunctionSpec = this.createBroadcastRequest(arg1, arg2);\n        let result = this._nativeZone.broadcastSync(spec);\n        if (result.code !== 0) {\n            throw new Error(result.errorMessage);\n        }\n    }\n\n    public execute(arg1: any, arg2?: any, arg3?: any, arg4?: any) : Promise<zone.Result> {\n        let spec : FunctionSpec = this.createExecuteRequest(arg1, arg2, arg3, arg4);\n        \n        return new Promise<zone.Result>((resolve, reject) => {\n            this._nativeZone.execute(spec, (result: any) => {\n                runImmediately(() => {\n                    if (result.code === 0) {\n                        resolve(new Result(\n                            result.returnValue,\n                            transport.createTransportContext(true, result.contextHandle)));\n                    } else {\n                        reject(result.errorMessage);\n                    }\n                })\n            });\n        });\n    }\n\n    private createBroadcastRequest(arg1: any, arg2?: any) : FunctionSpec {\n        if (typeof arg1 === \"function\") {\n            // broadcast with function\n            if (arg1.origin == null) {\n                // We get caller stack at index 2.\n                // <caller> -> broadcast -> createBroadcastRequest\n                //   2           1               0\n                arg1.origin = v8.currentStack(3)[2].getFileName();\n            }\n            return {\n                module: \"__function\",\n                function: transport.saveFunction(arg1),\n                arguments: (arg2 == null\n                           ? []\n                           : (<Array<any>>arg2).map(arg => transport.marshall(arg, null))),\n                options: zone.DEFAULT_CALL_OPTIONS,\n                transportContext: null\n            };\n        } else {\n            // broadcast with source\n            return {\n                module: \"\",\n                function: \"eval\",\n                arguments: [JSON.stringify(arg1)],\n                options: zone.DEFAULT_CALL_OPTIONS,\n                transportContext: null\n            };\n        }\n    }\n\n    private createExecuteRequest(arg1: any, arg2: any, arg3?: any, arg4?: any) : FunctionSpec {\n\n        let moduleName: string = null;\n        let functionName: string = null;\n        let args: any[] = null;\n        let options: zone.CallOptions = undefined;\n\n        if (typeof arg1 === 'function') {\n            moduleName = \"__function\";\n            if (arg1.origin == null) {\n                // We get caller stack at index 2.\n                // <caller> -> execute -> createExecuteRequest\n                //   2           1               0\n                arg1.origin = v8.currentStack(3)[2].getFileName();\n            }\n\n            functionName = transport.saveFunction(arg1);\n            args = arg2;\n            options = arg3;\n        }\n        else {\n            moduleName = arg1;\n            // If module name is relative path, try to deduce from call site.\n            if (moduleName != null \n                && moduleName.length != 0 \n                && !path.isAbsolute(moduleName)) {\n\n                moduleName = path.resolve(\n                    path.dirname(v8.currentStack(3)[2].getFileName()), \n                    moduleName);\n            }\n            functionName = arg2;\n            args = arg3;\n            options = arg4;\n        }\n\n        if (args == null) {\n            args = [];\n        }\n\n        // Create a non-owning transport context which will be passed to execute call.\n        let transportContext: transport.TransportContext = transport.createTransportContext(false);\n        return {\n            module: moduleName,\n            function: functionName,\n            arguments: (<Array<any>>args).map(arg => transport.marshall(arg, transportContext)),\n            options: options != null? options: zone.DEFAULT_CALL_OPTIONS,\n            transportContext: transportContext\n        };\n    }\n}"
  },
  {
    "path": "lib/zone/zone.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as transport from \"../transport\";\n\n/// <summary> Describes the available settings for customizing a zone. </summary>\nexport interface ZoneSettings {\n\n    /// <summary> The number of workers that will serve zone requests. </summary>\n    workers?: number;\n}\n\n/// <summary> Default ZoneSettings </summary>\nexport let DEFAULT_SETTINGS: ZoneSettings = {\n\n    /// <summary> Set default workers to 2. </summary>\n    workers: 2\n};\n\n/// <summary> Represent option to transport arguments in zone.execute. </summary>\nexport enum TransportOption {\n\n    /// <summary> transport.marshall/unmarshall will be done by `napajs` automatically.\n    /// This is the most common way, but may not be performance optimal with objects\n    /// that will be shared in multiple zone.execute.\n    /// </summary>\n    AUTO,\n\n    /// <summary> transport.marshall/unmarshall will be done by user manually. </summary>\n    MANUAL,\n}\n\n/// <summary> Represent the options of calling a function. </summary>\nexport interface CallOptions {\n\n    /// <summary> Timeout in milliseconds. By default set to 0 if timeout is not needed. </summary>\n    timeout?: number,\n\n    /// <summary> Transport option on passing arguments. By default set to TransportOption.AUTO </summary>\n    transport?: TransportOption\n}\n\n/// <summary> Default execution options. </summary>\nexport let DEFAULT_CALL_OPTIONS: CallOptions = {\n\n    /// <summary> No timeout. </summary>\n    timeout: 0,\n\n    /// <summary> Set argument transport option to automatic. </summary>\n    transport: TransportOption.AUTO\n}\n\n/// <summary> Represent the result of an execute call. </summary>\nexport interface Result {\n\n    /// <summary> The unmarshalled result value. </summary>\n    readonly value : any;\n\n    /// <summary> A marshalled result. </summary>\n    readonly payload : string;\n\n    /// <summary> Transport context carries additional information needed to unmarshall. </summary>\n    readonly transportContext : transport.TransportContext;\n}\n\n/// <summary>\n///     Interface for Zone (for both Napa zone and Node zone)\n///     A `zone` consists of one or multiple JavaScript threads, we name each thread `worker`.\n///     Workers within a zone are symmetric, which means execute on any worker from the zone should return the same result,\n///     and the internal state of every worker should be the same from long lasting point of view.\n///\n///     There are 2 operations, designed to reinforce the symmetry of workers:\n///     1) Broadcast - run code that changes worker state on all workers, returning a promise for pending operation. \n///        Through the promise, we can only know if operation succeed or failed. Usually we use `broadcast` to bootstrap\n///        application, pre-cache objects, or change application settings.\n///     2) Execute - run code that doesn't change worker state on an arbitrary worker, returning a promise of getting the result.\n///        Execute is designed for doing the real work.\n/// \n///     Zone operations are on a basis of first-come-first-serve, while `broadcast` takes higher priority over `execute`.\n/// </summary>\nexport interface Zone {\n    \n    /// <summary> The zone id. </summary>\n    readonly id: string;\n\n    /// <summary> Compiles and run the provided source code on all zone workers. </summary>\n    /// <param name=\"source\"> A valid javascript source code. </param>\n    /// <returns> A promise which is resolved when broadcast completes, and rejected when failed. </returns>\n    /// <remarks>\n    ///     Broadcast is designed for the purpose of bootstrapping/changing internal state on all workers.\n    ///     Function broadcast returns a promise of void, telling whether the operation succeeded or failed.\n    ///     Promise will be rejected on failure from any worker, though most likely all workers will fail if one fails.\n    /// </remarks>\n    broadcast(source: string) : Promise<void>;\n\n    /// <summary> Run the function on all workers with the given arguments. </summary>\n    /// <param name=\"func\"> The JS function. </param>\n    /// <param name=\"args\"> The arguments that will pass to the function. </param>\n    /// <returns> A promise which is resolved when broadcast completes and rejected when failed. </returns>\n    /// <remarks>\n    ///     Broadcast is designed for the purpose of bootstrapping/changing internal state on all workers.\n    ///     Function broadcast returns a promise of void, telling whether the operation succeeded or failed.\n    ///     Promise will be rejected on failure from any worker, though most likely all workers will fail if one fails.\n    /// </remarks>\n    broadcast(func: (...args: any[]) => void | Promise<void>, args?: any[]) : Promise<void>;\n\n    /// <summary> Compiles and run the provided source code on all zone workers synchronously. </summary>\n    /// <param name=\"source\"> A valid javascript source code. </param>\n    /// <remarks>\n    ///     Broadcast is designed for the purpose of bootstrapping/changing internal state on all workers.\n    ///     Function broadcastSync wait for all workers to complete.\n    ///     An exception will be thrown when any worker fails.\n    /// </remarks>\n    broadcastSync(source: string) : void;\n\n    /// <summary> Run the function on all workers with the given arguments. </summary>\n    /// <param name=\"func\"> The JS function. </param>\n    /// <param name=\"args\"> The arguments that will pass to the function. </param>\n    /// <returns> A promise which is resolved when broadcast completes and rejected when failed. </returns>\n    /// <remarks>\n    ///     Broadcast is designed for the purpose of bootstrapping/changing internal state on all workers.\n    ///     Function broadcast returns a promise of void, telling whether the operation succeeded or failed.\n    ///     Promise will be rejected on failure from any worker, though most likely all workers will fail if one fails.\n    /// </remarks>\n    broadcastSync(func: (...args: any[]) => void | Promise<void>, args?: any[]) : void;\n\n    /// <summary> Executes the function on one of the zone workers. </summary>\n    /// <param name=\"module\"> The module name that contains the function to execute. </param>\n    /// <param name=\"func\"> The function name to execute. </param>\n    /// <param name=\"args\"> The arguments that will pass to the function. </param>\n    /// <param name=\"options\"> Call options, defaults to DEFAULT_CALL_OPTIONS. </param>\n    /// <returns> A promise of result which is resolved when execute completes, and rejected when failed. </returns>\n    execute(module: string, func: string, args?: any[], options?: CallOptions) : Promise<Result>;\n\n    /// <summary> Executes the function on one of the zone workers. </summary>\n    /// <param name=\"func\"> The JS function to execute. </param>\n    /// <param name=\"args\"> The arguments that will pass to the function. </param>\n    /// <param name=\"options\"> Call options, defaults to DEFAULT_CALL_OPTIONS. </param>\n    /// <returns> A promise of result which is resolved when execute completes, and rejected when failed. </returns>\n    execute(func: (...args: any[]) => any, args?: any[], options?: CallOptions) : Promise<Result>;\n}\n\n"
  },
  {
    "path": "lib/zone.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as zone from './zone/zone';\nimport * as impl from './zone/zone-impl';\n\nimport * as platform from './runtime/platform';\n\nlet binding = require('./binding');\n\n// This variable is either defined by napa runtime, or not defined (hence node runtime)\ndeclare var __in_napa: boolean;\n\n/// <summary> Creates a new zone. </summary>\n/// <summary> A unique id to identify the zone. </summary>\n/// <param name=\"settings\"> The settings of the new zone. </param>\nexport function create(id: string, settings: zone.ZoneSettings = zone.DEFAULT_SETTINGS) : zone.Zone {\n    platform.initialize();\n    return new impl.ZoneImpl(binding.createZone(id, settings));\n}\n\n/// <summary> Returns the zone associated with the provided id. </summary>\nexport function get(id: string) : zone.Zone {\n    platform.initialize();\n    return new impl.ZoneImpl(binding.getZone(id));\n}\n\n/// TODO: add function getOrCreate(id: string, settings: zone.ZoneSettings): Zone.\n\n/// <summary> Define a getter property 'current' to retrieve the current zone. </summary>\nexport declare let current: zone.Zone;\nObject.defineProperty(exports, \"current\", {\n    get: function () : zone.Zone {\n        platform.initialize();\n        return new impl.ZoneImpl(binding.getCurrentZone());\n    }\n});\n\n/// <summary> Define a getter property 'node' to retrieve node zone. </summary>\nexport declare let node: zone.Zone;\nObject.defineProperty(exports, \"node\", {\n    get: function () : zone.Zone {\n        platform.initialize();\n        return new impl.ZoneImpl(binding.getZone('node'));\n    }\n});\n\nexport * from './zone/zone';"
  },
  {
    "path": "node/CMakeLists.txt",
    "content": "# Files to compile\r\n# Note: Do not add napa core-modules cpp files that not needed in node isolation, \r\n# like timer-wrap.cpp.\r\nfile(GLOB SOURCE_FILES \r\n    \"addon.cpp\"\r\n    \"node-zone-delegates.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/platform/filesystem.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/platform/os.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/zone/call-context.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/zone/call-task.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/zone/eval-task.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/zone/terminable-task.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/allocator-debugger-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/allocator-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/call-context-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/lock-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/metric-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/napa-binding.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/shared-ptr-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/store-wrap.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/transport-context-wrap-impl.cpp\"\r\n    \"${PROJECT_SOURCE_DIR}/src/module/core-modules/napa/zone-wrap.cpp\"        \r\n    )\r\n\r\n# The addon name\r\nset(TARGET_NAME \"${PROJECT_NAME}-binding\")\r\n\r\n# The generated library\r\nadd_library(${TARGET_NAME} SHARED ${SOURCE_FILES})\r\n\r\nset_target_properties(${TARGET_NAME} PROPERTIES PREFIX \"\" SUFFIX \".node\")\r\n\r\n# Rpath definitions\r\n\r\nif (APPLE)\r\n    set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH \"@loader_path\")\r\nelse ()\r\n    set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH \"$ORIGIN/\")\r\nendif()\r\n\r\nset_target_properties(${TARGET_NAME} PROPERTIES\r\n    BUILD_WITH_INSTALL_RPATH TRUE\r\n    INSTALL_RPATH_USE_LINK_PATH FALSE)\r\n\r\n# Include directories\r\ntarget_include_directories(${TARGET_NAME} PRIVATE\r\n    ${CMAKE_JS_INC}\r\n    ${PROJECT_SOURCE_DIR}/src\r\n    ${PROJECT_SOURCE_DIR}/src/module/core-modules/napa)\r\n\r\n# Compiler definitions\r\ntarget_compile_definitions(${TARGET_NAME} PRIVATE BUILDING_NODE_EXTENSION NAPA_BINDING_EXPORTS)\r\n\r\n# Link libraries\r\ntarget_link_libraries(${TARGET_NAME} PRIVATE\r\n    ${PROJECT_NAME}\r\n    ${CMAKE_JS_LIB})\r\n"
  },
  {
    "path": "node/addon.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"napa-binding.h\"\n#include \"node-zone-delegates.h\"\n\n#include <napa/module.h>\n#include <napa/zone.h>\n\n#include <zone/node-zone.h>\n\nvoid Initialize(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n\n    if (args.Length() <= 0 || args[0]->IsUndefined()) {\n        // No settings provided.\n        napa::InitializeFromConsole(0, nullptr);\n    } else {\n        CHECK_ARG(isolate, args[0]->IsObject(), \"first argument to initialize must be an object\");\n\n        auto settingsObj = args[0]->ToObject(context).ToLocalChecked();\n\n        auto settingsMap = napa::v8_helpers::V8ObjectToMap<std::string>(isolate, settingsObj);\n\n        std::stringstream ss;\n        for (const auto& kv : settingsMap) {\n            ss << \" --\" << kv.first << \" \" << kv.second;\n        }\n\n        napa::Initialize(ss.str());\n    }\n}\n\nvoid Shutdown(const v8::FunctionCallbackInfo<v8::Value>&) {\n    napa::Shutdown();\n}\n\nvoid InitAll(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {\n    // Init node zone before initialize modules.\n    napa::zone::NodeZone::Init(napa::node_zone::Broadcast, napa::node_zone::Execute);\n\n    // Init core napa modules.\n    napa::module::binding::Init(exports, module);\n\n    // Only node addon can initialize/shutdown napa.\n    NAPA_SET_METHOD(exports, \"initialize\", Initialize);\n    NAPA_SET_METHOD(exports, \"shutdown\", Shutdown);\n}\n\nNAPA_MODULE(addon, InitAll)\n"
  },
  {
    "path": "node/node-zone-delegates.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"node-zone-delegates.h\"\n\n#include <zone/call-task.h>\n#include <zone/eval-task.h>\n\n#include <uv.h>\n\nstruct AsyncContext {\n    /// <summary> libuv request. </summary>\n    uv_async_t work;\n\n    /// <summary> Callback that will be running in Node event loop. </summary>\n    std::function<void()> callback;\n};\n\n/// <summary> Run an async work item in Node. </summary>\nvoid Run(uv_async_t* work) {\n    auto context = static_cast<AsyncContext*>(work->data);\n\n    context->callback();\n\n    uv_close(reinterpret_cast<uv_handle_t*>(work), [](auto work) {\n        auto context = static_cast<AsyncContext*>(work->data);\n        delete context;\n    });\n}\n\n/// <summary> Schedule a function in Node event loop. </summary>\nvoid ScheduleInNode(std::function<void()> callback) {\n    auto context = new AsyncContext();\n    context->work.data = context;\n    context->callback = std::move(callback);\n\n    uv_async_init(uv_default_loop(), &context->work, Run);\n    uv_async_send(&context->work);\n}\n\nvoid napa::node_zone::Broadcast(const napa::FunctionSpec& spec, napa::BroadcastCallback callback) {\n    auto requestContext = std::make_shared<napa::zone::CallContext>(spec, callback);\n    ScheduleInNode([requestContext = std::move(requestContext)]() {\n        napa::zone::CallTask task(std::move(requestContext));\n        task.Execute();\n    });\n}\n\nvoid napa::node_zone::Execute(const napa::FunctionSpec& spec, napa::ExecuteCallback callback) {\n    auto requestContext = std::make_shared<napa::zone::CallContext>(spec, callback);\n    ScheduleInNode([requestContext = std::move(requestContext)]() {\n        napa::zone::CallTask task(std::move(requestContext));\n        task.Execute();\n    });\n}\n"
  },
  {
    "path": "node/node-zone-delegates.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/types.h>\n\nnamespace napa {\nnamespace node_zone {\n\n    /// <summary> Broadcast to Node zone. </summary>\n    void Broadcast(const napa::FunctionSpec& spec, napa::BroadcastCallback callback);\n\n    /// <summary> Execute in Node zone. </summary>\n    void Execute(const napa::FunctionSpec& spec, napa::ExecuteCallback callback);\n}\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"napajs\",\n  \"description\": \"Napa.js is a multi-threaded JavaScript runtime built on V8\",\n  \"version\": \"0.2.3\",\n  \"author\": \"napajs\",\n  \"main\": \"./lib/index.js\",\n  \"types\": \"./types/index.d.ts\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Microsoft/napajs.git\"\n  },\n  \"binary\": {\n    \"module_name\": \"napa-binding\",\n    \"module_path\": \"./bin/\",\n    \"host\": \"https://github.com/Microsoft/napajs/releases/download/\",\n    \"remote_path\": \"{version}\"\n  },\n  \"dependencies\": {\n    \"node-pre-gyp\": \"^0.6.36\",\n    \"npmlog\": \"^4.1.2\",\n    \"semver\": \"^5.5.0\"\n  },\n  \"devDependencies\": {\n    \"cmake-js\": \"^3.7.3\",\n    \"node-pre-gyp-github\": \"^1.3.1\",\n    \"mocha\": \"^3.5.0\",\n    \"typescript\": \"^2.4.2\",\n    \"@types/node\": \"^8.0.22\",\n    \"@types/mocha\": \"^2.2.41\",\n    \"markdown-table\": \"^1.1.1\"\n  },\n  \"scripts\": {\n    \"benchmark\": \"node benchmark/bench.js\",\n    \"install\": \"node scripts/install.js\",\n    \"prepare\": \"tsc -p lib && tsc -p test && tsc -p benchmark\",\n    \"test\": \"mocha test -g \\\"^((?!napajs/timers).)*$\\\" --recursive && mocha test -g \\\"^napajs/timers\\\"\",\n    \"rebuild\": \"cmake-js rebuild && tsc -p lib\",\n    \"rebuildd\": \"cmake-js rebuild --debug && tsc -p lib\",\n    \"retest\": \"cmake-js rebuild -d test/module/addon && tsc -p test && mocha test --recursive\",\n    \"reunittest\": \"cmake-js rebuild -d unittest && node unittest/run.js\",\n    \"unittest\": \"cmake-js compile -d unittest && node unittest/run.js\"\n  }\n}\n"
  },
  {
    "path": "scripts/clean.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n\"use strict\";\nvar fs = require('fs');\nvar path = require(\"path\");\n\nexports.clean = function() {\n    console.log('Cleaning up build files.');\n    \n    // Remove build folder\n    var buildDir = path.join(__dirname, \"../build\");\n    console.log(`Removing ${buildDir}.`);\n    removeDirectory(buildDir);\n    \n    // Remove bin folder\n    var binDir = path.join(__dirname, \"../bin\");\n    console.log(`Removing ${binDir}.`);\n    removeDirectory(binDir);\n}\n\n// Helper function for removing all files from a directory.\nfunction removeDirectory(dirPath) {\n    if (fs.existsSync(dirPath)) {\n        fs.readdirSync(dirPath).forEach((file, index) => {\n            var currentPath = dirPath + \"/\" + file;\n            if (fs.lstatSync(currentPath).isDirectory()) {\n                // Recursive call\n                removeDirectory(currentPath);\n            } \n            else {\n                // delete a file\n                fs.unlinkSync(currentPath);\n            }\n        });\n\n        // Remove the empty directory.\n        fs.rmdirSync(dirPath);\n    }\n}\n"
  },
  {
    "path": "scripts/embedded.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n\"use strict\";\nvar childProcess = require('child_process');\nvar os = require(\"os\");\nvar path = require(\"path\");\n\nexports.build = function (buildType) {\n    var napaRoot = path.join(__dirname, \"..\");\n    var nodeVersion = \"v6.10.3\"; // Stable node version that can build as a library.\n    var nodeCloneRoot = path.join(napaRoot, \"build/node-\" + nodeVersion);\n    var archOption = \"\";\n    \n    console.log(\"\\x1b[1m\\x1b[32m\", `Building napa in embed mode (${buildType}) based on Node.JS ${nodeVersion}`,'\\x1b[0m');\n\n    // Refer to https://github.com/nodejs/node/blob/master/BUILDING.md#windows-1 for prerequisites.\n    childProcess.execSync(`git clone --branch ${nodeVersion} https://github.com/nodejs/node.git ${nodeCloneRoot}`, {\n        stdio: 'inherit'\n    });\n\n    if (os.platform() === \"win32\") {\n        console.log(\"\\x1b[1m\\x1b[32m\", \"Building Node.JS as dll.\",'\\x1b[0m');\n\n        // Build node shared library to extract intermediate v8 static libraries to build napa.dll.\n        childProcess.execSync(`vcbuild.bat x64 ${buildType} nosign dll`, {\n            cwd: nodeCloneRoot,\n            stdio: 'inherit'\n        });\n\n        archOption = \" -A x64 \";\n    }\n    else if (os.platform() === 'linux') {\n        console.log(\"\\x1b[1m\\x1b[32m\", \"Building Node.JS.\",'\\x1b[0m');\n\n        // Modify configure to add '-fPIC' cflags.\n        childProcess.execSync(\"sed -i 's/'\\\\'cflags\\\\':\\\\ \\\\\\\\[]'/'\\\\'cflags\\\\':\\\\ [\\\\'\\\\ -fPIC\\\\ \\\\']'/g' configure\", {\n            cwd: nodeCloneRoot,\n            stdio: 'inherit'\n        });\n\n        // Build node to extract intermediate v8 static libraries to build napa shared library.\n        childProcess.execSync(`./configure && make -j4`, {\n            cwd: nodeCloneRoot,\n            stdio: 'inherit'\n        });\n    }\n    else {\n        // TODO (asib): support other platforms\n        console.log(\"\\x1b[1m\\x1b[32m\", \"Napa build solution for embedded mode is not provided for \", os.platform(),'\\x1b[0m');\n\treturn;\n    }\n\n    // Create platform specific build files using cmake.\n    console.log(\"\\x1b[1m\\x1b[32m\", \"Running cmake to generate build files.\",'\\x1b[0m');\n    childProcess.execSync(`cmake ${archOption} -DNODE_ROOT=${nodeCloneRoot} -DCMAKE_BUILD_TYPE=${buildType} ..`, {\n        cwd: path.join(napaRoot, \"build\"),\n        stdio: 'inherit'\n    });\n\n    // Build.\n    console.log(\"\\x1b[1m\\x1b[32m\", \"Building napa.\",'\\x1b[0m');\n    childProcess.execSync(`cmake --build . --config ${buildType}`, {\n        cwd: path.join(napaRoot, \"build\"),\n        stdio: 'inherit'\n    });\n\n    // Install napa dependencies and compile typescript files..\n    console.log(\"\\x1b[1m\\x1b[32m\", \"Running npm install to compile typescript files.\",'\\x1b[0m');\n    childProcess.execSync(\"npm install --no-fetch --no-build\", {\n        cwd: napaRoot,\n        stdio: 'inherit'\n    });\n}\n"
  },
  {
    "path": "scripts/install.js",
    "content": "#!/usr/bin/env node\n\nvar log = require('npmlog');\nvar fileExistsSync = require('fs').existsSync;\nvar path = require('path');\nvar execSync = require('child_process').execSync;\n\n// Default command\nvar fetchCommand = 'node-pre-gyp install --fallback-to-build=false';\nvar buildCommand = 'cmake-js compile';\n\n// ==== Determine install options ====\n// Skip the fetch stage. '--no-fetch', or '--fetch=false'\nvar skipFetch = process.env.hasOwnProperty('npm_config_fetch') && !process.env['npm_config_fetch'];\n// Skip the build stage. '--no-build', or '--build=false'\nvar skipBuild = process.env.hasOwnProperty('npm_config_build') && !process.env['npm_config_build'];\n// Skip the prepare stage. '--no-prepare', or '--prepare=false'\nvar skipPrepare = process.env.hasOwnProperty('npm_config_prepare') && !process.env['npm_config_prepare'];\n\n// Use debug build\nif (process.env.hasOwnProperty('npm_config_debug') && process.env['npm_config_debug']) {\n    buildCommand += \" --debug\";\n}\n\nlog.info('NAPA_INSTALL', 'installing napajs...');\n\nvar errorCode = 0;\n\n// ==== Try to fetch the pre-build binaries ====\nif (!skipFetch) {\n    try {\n        log.info('NAPA_INSTALL', 'downloading the pre-build binaries...');\n        execSync(fetchCommand, { 'stdio': 'inherit' });\n\n        log.info('NAPA_INSTALL', 'completed successfully by download.');\n        skipBuild = true;\n    }\n    catch (e) {\n        errorCode = e.status;\n\n        log.warn('NAPA_INSTALL', 'failed to download the pre-build binaries.');\n        if (!skipBuild) {\n            log.warn('NAPA_INSTALL', 'will fallback to build stage.');\n        }\n    }\n}\n\n// ==== Try to build from sources ====\nif (!skipBuild) {\n    errorCode = 0;\n\n    try {\n        log.info('NAPA_INSTALL', 'building from sources...');\n        execSync(buildCommand, { 'stdio': 'inherit' });\n\n        log.info('NAPA_INSTALL', 'completed successfully by build.');\n    }\n    catch (e) {\n        errorCode = e.status;\n\n        log.warn('NAPA_INSTALL', 'failed to build from sources.');\n    }\n}\n\n// ==== Running \"npm run prepare\" explicitly ====\n//\n// NOTE: Napa.js has the \"prepare\" script, which is supposed to run by NPM\n//       after a \"npm install\" command without parameters.\n//       However, NPM below 4.x does not recognize script \"prepare\".\n//       We have to run it explicitly in this case.\nif (!skipPrepare && errorCode == 0) {\n    var npmVersion = execSync('npm --version').toString().trim();\n    log.info('NAPA_INSTALL', `current NPM version=${npmVersion}.`);\n\n    var npmMajorVersion = npmVersion.split('.')[0];\n    var npmMajorVersionNumber = parseInt(npmMajorVersion);\n    if (npmMajorVersionNumber < 4) {\n        log.info('NAPA_INSTALL', 'NPM below 4.x does not recognize script \"prepare\". We need to run it explicitly.');\n\n        // Skip this step if we already have the TypeScripts compiled.\n        var mainFilePath = path.join(__dirname, '..', process.env['npm_package_main']);\n        if (fileExistsSync(mainFilePath) ) {\n            log.info('NAPA_INSTALL', 'already have compiled typescripts. skip running \"npm run prepare\".');\n        }\n        else {\n            log.info('NAPA_INSTALL', 'running \"npm run prepare\"...');\n\n            try {\n                execSync('npm run prepare', { 'stdio': 'inherit' });\n            }\n            catch (e) {\n                errorCode = e.status;\n            }\n        }\n    }\n}\n\nif (errorCode != 0) {\n    log.error('NAPA_INSTALL', 'failed to install napajs.');\n}\n\nprocess.exit(errorCode);\n"
  },
  {
    "path": "scripts/paths.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nlet path = require('path');\n\nObject.defineProperty(exports, 'root', {\n    get: function() {\n        let rootPath = path.resolve(__dirname, '..');\n        // Output the path to stdout for cmake/gyp commands.\n        process.stdout.write(rootPath);\n        return rootPath;\n    }\n});\n\nObject.defineProperty(exports, 'lib', {\n    get: function() {\n        let libPath = path.resolve(__dirname, '../bin/' + getLibraryName('napa'));\n        // Output the path to stdout for cmake/gyp commands.\n        process.stdout.write(libPath);\n        return libPath;\n    }\n});\n\nObject.defineProperty(exports, 'inc', {\n    get: function() {\n        let incPath = path.resolve(__dirname, '../inc');\n        // Output the path to stdout for cmake/gyp commands.\n        process.stdout.write(incPath);\n        return incPath;\n    }\n});\n\n// Resolve library name according to platform type.\nfunction getLibraryName(originalName) {\n    if (process.platform === \"win32\") {\n        return originalName + '.lib';\n    } else if (process.platform === 'darwin') {\n        return 'lib' + originalName + '.dylib';\n    } else if (process.platform === 'linux') {\n        return 'lib' + originalName + '.so';\n    } else {\n        throw new Error(\n            'Failed to resolve the library name of \"' + originalName +\n            '\" because your platform type \"' + process.platform +\n            '\"is not supported by require(\\'napajs/build\\').paths');\n    }\n}\n"
  },
  {
    "path": "src/CMakeLists.txt",
    "content": "set(CMAKE_CXX_FLAGS_ORG ${CMAKE_CXX_FLAGS})\n\n# Use -fno-rtti and -fPIC to build v8-extensions as a static library for compatibility with node and v8.\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-rtti -fPIC\")\nadd_subdirectory(v8-extensions)\n\n# Restore CMAKE_CXX_FLAGS from CMAKE_CXX_FLAGS_ORG.\nset(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_ORG})\n\n# Files to compile\nfile(GLOB SOURCE_FILES_0 ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)\nfile(GLOB_RECURSE SOURCE_FILES_1\n    ${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/memory/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/module/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/platform/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/providers/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/settings/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/store/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/zone/*.cpp\n)\nset(SOURCE_FILES ${SOURCE_FILES_0} ${SOURCE_FILES_1})\n\n# The target name\nset(TARGET_NAME ${PROJECT_NAME})\n\n# The generated library\nadd_library(${TARGET_NAME} SHARED ${SOURCE_FILES})\n\n# Include directories\ntarget_include_directories(${TARGET_NAME}\n    PRIVATE\n    ${CMAKE_CURRENT_SOURCE_DIR}\n    ${PROJECT_SOURCE_DIR}/third-party\n    PUBLIC\n    ${PROJECT_SOURCE_DIR}/inc)\n\n# Compiler definitions\ntarget_compile_definitions(${TARGET_NAME} PRIVATE NAPA_EXPORTS NAPA_BINDING_EXPORTS BUILDING_NAPA_EXTENSION)\n\n# Link libraries\ntarget_link_libraries(${TARGET_NAME} PRIVATE \"v8-extensions\")\n\nif(CMAKE_JS_VERSION)\n    # Building Napa as an npm package for node usage (using exported v8 from node.exe)\n\n    target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_JS_INC})\n    target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_JS_LIB})\n\n    # Using the V8 functions exported from node.exe\n    target_compile_definitions(${TARGET_NAME} PRIVATE USING_V8_SHARED)\nelse()\n    # Building Napa for embed scenarios (static linking with v8)\n    if (NOT DEFINED NODE_ROOT)\n        message(FATAL_ERROR \"NODE_ROOT must be set to the node sources root directory\")\n    endif()\n\n    set(NODE_BUILD_TYPE \"Release\")\n    if ((DEFINED CMAKE_BUILD_TYPE) AND (CMAKE_BUILD_TYPE STREQUAL \"debug\"))\n        set(NODE_BUILD_TYPE \"Debug\")\n    endif()\n\n    # V8 header files\n    target_include_directories(${TARGET_NAME} PRIVATE ${NODE_ROOT}/deps/v8/include)\n\n    if(WIN32)\n        find_library(V8_BASE_0_LIBRARY NAMES v8_base_0 PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_BASE_1_LIBRARY NAMES v8_base_1 PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_BASE_2_LIBRARY NAMES v8_base_2 PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_BASE_3_LIBRARY NAMES v8_base_3 PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_LIBBASE_LIBRARY NAMES v8_libbase PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_LIBPLATFORM_LIBRARY NAMES v8_libplatform PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n        find_library(V8_NOSNAPSHOT_LIBRARY NAMES v8_nosnapshot PATHS ${NODE_ROOT}/build/${NODE_BUILD_TYPE}/lib)\n\n        find_library(ICUI18N_LIBRARY NAMES icui18n PATHS ${NODE_ROOT}/${NODE_BUILD_TYPE}/lib)\n        find_library(ICUSTUBDATA_LIBRARY NAMES icustubdata PATHS ${NODE_ROOT}/${NODE_BUILD_TYPE}/lib)\n        find_library(ICUUCX_LIBRARY NAMES icuucx PATHS ${NODE_ROOT}/${NODE_BUILD_TYPE}/lib)\n\n        set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS \"/LTCG\")\n\n        # V8 static libraries\n        target_link_libraries(${TARGET_NAME} PRIVATE\n            ${V8_BASE_0_LIBRARY}\n            ${V8_BASE_1_LIBRARY}\n            ${V8_BASE_2_LIBRARY}\n            ${V8_BASE_3_LIBRARY}\n            ${V8_LIBBASE_LIBRARY}\n            ${V8_LIBPLATFORM_LIBRARY}\n            ${V8_NOSNAPSHOT_LIBRARY}\n            ${ICUI18N_LIBRARY}\n            ${ICUSTUBDATA_LIBRARY}\n            ${ICUUCX_LIBRARY})\n\n    elseif(\"${CMAKE_SYSTEM}\" MATCHES \"Linux\")\n        find_library(V8_BASE_LIBRARY NAMES v8_base PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/deps/v8/tools/gyp)\n        find_library(V8_LIBBASE_LIBRARY NAMES v8_libbase PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/deps/v8/tools/gyp)\n        find_library(V8_LIBPLATFORM_LIBRARY NAMES v8_libplatform PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/deps/v8/tools/gyp)\n        find_library(V8_NOSNAPSHOT_LIBRARY NAMES v8_nosnapshot PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/deps/v8/tools/gyp)\n\n        find_library(ICUI18N_LIBRARY NAMES icui18n PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/tools/icu)\n        find_library(ICUSTUBDATA_LIBRARY NAMES icustubdata PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/tools/icu)\n        find_library(ICUUCX_LIBRARY NAMES icuucx PATHS ${NODE_ROOT}/out/${NODE_BUILD_TYPE}/obj.target/tools/icu)\n\n        # V8 static libraries\n        target_link_libraries(${TARGET_NAME} PRIVATE\n            ${V8_BASE_LIBRARY}\n            ${V8_LIBBASE_LIBRARY}\n            ${V8_LIBPLATFORM_LIBRARY}\n            ${V8_NOSNAPSHOT_LIBRARY}\n            ${ICUI18N_LIBRARY}\n            ${ICUSTUBDATA_LIBRARY}\n            ${ICUUCX_LIBRARY})\n\n    else()\n        message(FATAL_ERROR \"Node build solution for embed mode is not provided for ${CMAKE_SYSTEM}\")\n    endif()\n\nendif()\n\nif(WIN32)\n    target_link_libraries(${TARGET_NAME} PRIVATE winmm.lib)\nendif()\n"
  },
  {
    "path": "src/api/capi.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/capi.h>\n\n#include <providers/providers.h>\n#include <settings/settings-parser.h>\n#include <v8-extensions/v8-common.h>\n#include <zone/napa-zone.h>\n#include <zone/node-zone.h>\n#include <zone/worker-context.h>\n\n#include <napa/log.h>\n\n#include <atomic>\n#include <fstream>\n#include <sstream>\n#include <thread>\n#include <unordered_map>\n#include <vector>\n\n\nusing namespace napa;\n\nstatic std::atomic<bool> _initialized(false);\nstatic settings::PlatformSettings _platformSettings;\n\n/// <summary> A simple wrapper around Zone for managing lifetime using shared_ptr. </summary>\nstruct napa_zone {\n    std::string id;\n    std::shared_ptr<zone::Zone> zone;\n};\n\nnapa_zone_handle napa_zone_create(napa_string_ref id) {\n    NAPA_ASSERT(_initialized, \"Napa wasn't initialized\");\n\n    // The actual zone is created upon initialization.\n    return new napa_zone { NAPA_STRING_REF_TO_STD_STRING(id), nullptr };\n}\n\nnapa_zone_handle napa_zone_get(napa_string_ref id) {\n    NAPA_ASSERT(_initialized, \"Napa wasn't initialized\");\n\n    auto zoneId = NAPA_STRING_REF_TO_STD_STRING(id);\n    std::shared_ptr<zone::Zone> zone;\n    if (zoneId == \"node\") {\n        zone = zone::NodeZone::Get();\n    } else {\n        zone = zone::NapaZone::Get(zoneId);\n    }\n\n    if (!zone) {\n        return nullptr;\n    }\n\n    return new napa_zone { std::move(zoneId), std::move(zone) };\n}\n\nnapa_zone_handle napa_zone_get_current() {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n\n    auto zone = reinterpret_cast<zone::Zone*>(zone::WorkerContext::Get(zone::WorkerContextItem::ZONE));\n    if (zone == nullptr) {\n        LOG_WARNING(\"Api\", \"Trying to get current zone from a thread that is not associated with a zone\");\n        return nullptr;\n    }\n\n    return napa_zone_get(STD_STRING_TO_NAPA_STRING_REF(zone->GetId()));\n}\n\nnapa_result_code napa_zone_init(napa_zone_handle handle, napa_string_ref settings) {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n    NAPA_ASSERT(handle, \"Zone handle is null\");\n\n    settings::ZoneSettings zoneSettings;\n    if (!napa::settings::ParseFromString(NAPA_STRING_REF_TO_STD_STRING(settings), zoneSettings)) {\n        NAPA_DEBUG(\"Api\", \"Failed to parse zone settings: %s\", settings.data);\n        return NAPA_RESULT_SETTINGS_PARSER_ERROR;\n    }\n\n    zoneSettings.id = handle->id;\n\n    // Create the actual zone.\n    handle->zone = zone::NapaZone::Create(zoneSettings);\n    if (handle->zone == nullptr) {\n        NAPA_DEBUG(\"Api\", \"Failed to create Napa zone '%s' with settings: %s\", handle->id.c_str(), settings.data);\n        return NAPA_RESULT_ZONE_INIT_ERROR;\n    }\n\n    NAPA_DEBUG(\"Api\", \"Napa zone '%s' created with settings: %s\", handle->id.c_str(), settings.data);\n\n    return NAPA_RESULT_SUCCESS;\n}\n\nnapa_result_code napa_zone_release(napa_zone_handle handle) {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n    NAPA_ASSERT(handle, \"Zone handle is null\");\n\n    handle->zone = nullptr;\n    delete handle;\n\n    return NAPA_RESULT_SUCCESS;\n}\n\nnapa_string_ref napa_zone_get_id(napa_zone_handle handle) {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n    NAPA_ASSERT(handle, \"Zone handle is null\");\n\n    return STD_STRING_TO_NAPA_STRING_REF(handle->id);\n}\n\nvoid napa_zone_broadcast(napa_zone_handle handle,\n                         napa_zone_function_spec spec,\n                         napa_zone_broadcast_callback callback,\n                         void* context) {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n    NAPA_ASSERT(handle, \"Zone handle is null\");\n    NAPA_ASSERT(handle->zone, \"Zone handle wasn't initialized\");\n\n    FunctionSpec req;\n    req.module = spec.module;\n    req.function = spec.function;\n\n    req.arguments.reserve(spec.arguments_count);\n    for (size_t i = 0; i < spec.arguments_count; i++) {\n        req.arguments.emplace_back(spec.arguments[i]);\n    }\n\n    req.options = spec.options;\n\n    // Assume ownership of transport context\n    req.transportContext.reset(reinterpret_cast<napa::transport::TransportContext*>(spec.transport_context));\n\n\n    handle->zone->Broadcast(req, [callback, context](Result result) {\n        napa_zone_result res;\n        res.code = result.code;\n        res.error_message = STD_STRING_TO_NAPA_STRING_REF(result.errorMessage);\n        res.return_value = STD_STRING_TO_NAPA_STRING_REF(result.returnValue);\n\n        // Release ownership of transport context\n        res.transport_context = reinterpret_cast<void*>(result.transportContext.release());\n\n        callback(res, context);\n    });\n}\n\nvoid napa_zone_execute(napa_zone_handle handle,\n                       napa_zone_function_spec spec,\n                       napa_zone_execute_callback callback,\n                       void* context) {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n    NAPA_ASSERT(handle, \"Zone handle is null\");\n    NAPA_ASSERT(handle->zone, \"Zone handle wasn't initialized\");\n\n    FunctionSpec req;\n    req.module = spec.module;\n    req.function = spec.function;\n\n    req.arguments.reserve(spec.arguments_count);\n    for (size_t i = 0; i < spec.arguments_count; i++) {\n        req.arguments.emplace_back(spec.arguments[i]);\n    }\n\n    req.options = spec.options;\n\n    // Assume ownership of transport context\n    req.transportContext.reset(reinterpret_cast<napa::transport::TransportContext*>(spec.transport_context));\n\n    handle->zone->Execute(req, [callback, context](Result result) {\n        napa_zone_result res;\n        res.code = result.code;\n        res.error_message = STD_STRING_TO_NAPA_STRING_REF(result.errorMessage);\n        res.return_value = STD_STRING_TO_NAPA_STRING_REF(result.returnValue);\n\n        // Release ownership of transport context\n        res.transport_context = reinterpret_cast<void*>(result.transportContext.release());\n\n        callback(res, context);\n    });\n}\n\nstatic napa_result_code napa_initialize_common() {\n    if (!napa::providers::Initialize(_platformSettings)) {\n        return NAPA_RESULT_PROVIDERS_INIT_ERROR;\n    }\n\n    if (!napa::v8_common::Initialize()) {\n        return NAPA_RESULT_V8_INIT_ERROR;\n    }\n\n    _initialized = true;\n\n    NAPA_DEBUG(\"Api\", \"Napa platform initialized successfully\");\n\n    return NAPA_RESULT_SUCCESS;\n}\n\nnapa_result_code napa_initialize(napa_string_ref settings) {\n    NAPA_ASSERT(!_initialized, \"Napa platform was already initialized\");\n\n    if (!napa::settings::ParseFromString(NAPA_STRING_REF_TO_STD_STRING(settings), _platformSettings)) {\n        return NAPA_RESULT_SETTINGS_PARSER_ERROR;\n    }\n\n    return napa_initialize_common();\n}\n\nnapa_result_code napa_initialize_from_console(int argc, const char* argv[]) {\n    NAPA_ASSERT(!_initialized, \"Napa platform was already initialized\");\n\n    if (!napa::settings::ParseFromConsole(argc, argv, _platformSettings)) {\n        return NAPA_RESULT_SETTINGS_PARSER_ERROR;\n    }\n\n    return napa_initialize_common();\n}\n\nnapa_result_code napa_shutdown() {\n    NAPA_ASSERT(_initialized, \"Napa platform wasn't initialized\");\n\n    napa::providers::Shutdown();\n    napa::v8_common::Shutdown();\n\n    LOG_INFO(\"Api\", \"Napa platform shutdown successfully\");\n\n    return NAPA_RESULT_SUCCESS;\n}\n\n\n#define NAPA_RESULT_CODE_DEF(symbol, string_rep) string_rep\n\nstatic const char* NAPA_REPONSE_CODE_STRINGS[] = {\n#include \"napa/result-codes.inc\"\n};\n\n#undef NAPA_RESULT_CODE_DEF\n\ntemplate<class T, size_t N>\nconstexpr size_t size(T(&)[N]) { return N; }\n\nconst char* napa_result_code_to_string(napa_result_code code) {\n    NAPA_ASSERT(code >= 0, \"result code out of range (%d)\", code);\n    NAPA_ASSERT(static_cast<size_t>(code) < size(NAPA_REPONSE_CODE_STRINGS), \"result code out of range (%d)\", code);\n\n    return NAPA_REPONSE_CODE_STRINGS[code];\n}\n\n\n///////////////////////////////////////////////////////////////\n/// Implementation of napa.memory C API\n\nvoid* napa_malloc(size_t size) {\n    return ::malloc(size);\n}\n\nvoid napa_free(void* pointer, size_t /*size_hint*/) {\n    ::free(pointer);\n}\n\nnamespace {\n    napa_allocate_callback _global_allocate = napa_malloc;\n    napa_deallocate_callback _global_deallocate = napa_free;\n} // namespace\n\nvoid napa_allocator_set(\n    napa_allocate_callback allocate_callback,\n    napa_deallocate_callback deallocate_callback) {\n\n    NAPA_ASSERT(allocate_callback != nullptr, \"'allocate_callback' should be a valid function.\");\n    NAPA_ASSERT(deallocate_callback != nullptr, \"'deallocate_callback' should be a valid function.\");\n\n    _global_allocate = allocate_callback;\n    _global_deallocate = deallocate_callback;\n}\n\nvoid* napa_allocate(size_t size) {\n    return _global_allocate(size);\n}\n\nvoid napa_deallocate(void* pointer, size_t size_hint) {\n    _global_deallocate(pointer, size_hint);\n}\n"
  },
  {
    "path": "src/memory/built-in-allocators.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/memory.h>\n#include <napa/capi.h>\n#include <cstring>\n\n/// <summary> C runtime allocator from napa.dll. </summary>\nclass CrtAllocator: public napa::memory::Allocator {\npublic:\n    /// <summary> Allocate memory of given size. </summary>\n    /// <param name=\"size\"> Requested size. </summary>\n    /// <returns> Allocated memory. May throw if error happens. </returns>\n    void* Allocate(size_t size) override {\n        return ::napa_malloc(size);\n    }\n\n    /// <summary> Deallocate memory allocated from this allocator. </summary>\n    /// <param name=\"memory\"> Pointer to the memory. </summary>\n    /// <param name=\"sizeHint\"> Hint of size to delete. 0 if not available from caller. </summary>\n    /// <returns> None. May throw if error happens. </returns>\n    void Deallocate(void* memory, size_t sizeHint) override {\n        ::napa_free(memory, sizeHint);\n    }\n\n    /// <summary> Get allocator type for better debuggability. </summary>\n    const char* GetType() const override {\n        return \"CrtAllocator\";\n    }\n\n    /// <summary> Tell if another allocator equals to this allocator. </summary>\n    bool operator==(const Allocator& other) const override {\n        return std::strcmp(other.GetType(), GetType()) == 0;\n    }\n};\n\n/// <summary> Allocator that uses napa_allocate and napa_deallocate. </summary>\nclass DefaultAllocator: public napa::memory::Allocator {\npublic:\n    /// <summary> Allocate memory of given size. </summary>\n    /// <param name=\"size\"> Requested size. </summary>\n    /// <returns> Allocated memory. May throw if error happens. </returns>\n    void* Allocate(size_t size) override {\n        return ::napa_allocate(size);\n    }\n\n    /// <summary> Deallocate memory allocated from this allocator. </summary>\n    /// <param name=\"memory\"> Pointer to the memory. </summary>\n    /// <param name=\"sizeHint\"> Hint of size to delete. 0 if not available from caller. </summary>\n    /// <returns> None. May throw if error happens. </returns>\n    void Deallocate(void* memory, size_t sizeHint) override {\n        return ::napa_deallocate(memory, sizeHint);\n    }\n\n    /// <summary> Get allocator type for better debuggability. </summary>\n    const char* GetType() const override {\n        return \"DefaultAllocator\";\n    }\n\n    /// <summary> Tell if another allocator equals to this allocator. </summary>\n    bool operator==(const Allocator& other) const override {\n        return std::strcmp(other.GetType(), GetType()) == 0;\n    }\n};\n\nnamespace napa {\nnamespace memory {\n\n    namespace {\n        // Never destory to ensure they live longer than all consumers.\n        auto _crtAllocator = new CrtAllocator();\n        auto _defaultAllocator = new DefaultAllocator();\n    }\n\n    Allocator& GetCrtAllocator() {\n        return *_crtAllocator;\n    }\n\n    Allocator& GetDefaultAllocator() {\n        return *_defaultAllocator;\n    }\n} // namespace memory\n} // namespace napa"
  },
  {
    "path": "src/module/core-modules/core-modules.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"napa/napa-binding.h\"\n\n#include \"node/console.h\"\n#include \"node/file-system.h\"\n#include \"node/os.h\"\n#include \"node/path.h\"\n#include \"node/process.h\"\n#include \"node/tty-wrap.h\"\n\n\n#define INITIALIZE_CORE_MODULE(registerer, name, built_in, init)                                        \\\n    do {                                                                                                \\\n        napa::module::ModuleInitializer initializer = [](auto exports, auto module) {                   \\\n            return reinterpret_cast<napa::module::ModuleInitializer>(init)(exports, module);            \\\n        };                                                                                              \\\n        registerer(name, built_in, initializer);                                                        \\\n    } while (false)\n\n// <remarks> napa-binding needs to be put at bottom since it may access other core modules. </remarks>\n// macro arguments: registerer, core module name, is built-in, core module initialization function.\n#define INITIALIZE_CORE_MODULES(registerer)                                                     \\\n    INITIALIZE_CORE_MODULE(registerer, \"console\", true, console::Init);                         \\\n    INITIALIZE_CORE_MODULE(registerer, \"fs\", false, file_system::Init);                         \\\n    INITIALIZE_CORE_MODULE(registerer, \"os\", false, os::Init);                                  \\\n    INITIALIZE_CORE_MODULE(registerer, \"path\", false, path::Init);                              \\\n    INITIALIZE_CORE_MODULE(registerer, \"process\", true, process::Init);                         \\\n    INITIALIZE_CORE_MODULE(registerer, \"tty_wrap\", false, tty_wrap::Init);                      \\\n    INITIALIZE_CORE_MODULE(registerer, \"napa-binding\", false, binding::Init);\n"
  },
  {
    "path": "src/module/core-modules/napa/allocator-debugger-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"allocator-debugger-wrap.h\"\n\n#include <napa/memory.h>\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(AllocatorDebuggerWrap);\n\nAllocatorDebuggerWrap::AllocatorDebuggerWrap(std::shared_ptr<napa::memory::AllocatorDebugger> allocatorDebugger) {\n    this->_object = std::move(allocatorDebugger);\n}\n\nvoid AllocatorDebuggerWrap::Init(){\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, ConstructorCallback);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    InitConstructorTemplate<AllocatorDebuggerWrap>(constructorTemplate);\n\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"allocate\", AllocatorWrap::AllocateCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"deallocate\", AllocatorWrap::DeallocateCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"getDebugInfo\", GetDebugInfoCallback);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"type\", AllocatorWrap::GetTypeCallback, nullptr);\n\n    auto constructor = constructorTemplate->GetFunction();\n    InitConstructor(\"<AllocatorDebugger>\", constructor);\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructor);\n}\n\nvoid AllocatorDebuggerWrap::ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    JS_ENSURE(isolate, args.IsConstructCall(), \"Class \\\"AllocatorDebuggerWrap\\\" allows constructor call only.\");\n    CHECK_ARG(isolate, args.Length() <= 1, \"Class \\\"AllocatorDebuggerWrap\\\" requires 1 argument of \\\"allocator\\\" in constructor.'\");\n\n    std::shared_ptr<napa::memory::Allocator> allocator;\n    if (args.Length() == 0) {\n        allocator = std::shared_ptr<napa::memory::Allocator>(\n            &napa::memory::GetDefaultAllocator(),\n            [](napa::memory::Allocator*){});\n    } \n    else {\n        CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"allocator\\\" should be \\\"AllocatorWrap\\\" type.'\");\n        auto allocatorWrap = NAPA_OBJECTWRAP::Unwrap<AllocatorWrap>(v8::Local<v8::Object>::Cast(args[0]));\n        JS_ENSURE(isolate, allocatorWrap != nullptr,  \"argument \\\"allocator\\\" must be of type \\\"AllocatorWrap\\\".\");\n        allocator = allocatorWrap->Get();\n    }\n\n    // It's deleted when its Javascript object is garbage collected by V8's GC.\n    auto wrap = new AllocatorDebuggerWrap(NAPA_MAKE_SHARED<napa::memory::SimpleAllocatorDebugger>(allocator));\n    wrap->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n}\n\nvoid AllocatorDebuggerWrap::GetDebugInfoCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(args.Holder());\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, thisObject->Get<napa::memory::AllocatorDebugger>()->GetDebugInfo()));\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/allocator-debugger-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"allocator-wrap.h\"\n\n#include <napa/module.h>\n#include <napa/memory/allocator-debugger.h>\n\nnamespace napa {\nnamespace module {\n    \n    /// <summary> It wraps napa::memory::AllocatorDebugger. </summary>\n    /// <remarks> Reference: napajs/lib/memory/allocator.ts#AllocatorDebugger </remarks>\n    class AllocatorDebuggerWrap: public AllocatorWrap {\n    public:\n        /// <summary> Init this wrap. </summary>\n        static void Init();\n\n        /// <summary> Declare constructor in public, so we can export class constructor to JavaScript world. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"AllocatorDebuggerWrap\";\n\n    private:\n        /// <summary> Constructor. </summary>\n        explicit AllocatorDebuggerWrap(std::shared_ptr<napa::memory::AllocatorDebugger> allocatorDebugger);\n\n        /// <summary> No copy allowed. </summary>\n        AllocatorDebuggerWrap(const AllocatorDebuggerWrap&) = delete;\n        AllocatorDebuggerWrap& operator=(const AllocatorDebuggerWrap&) = delete;\n\n        /// <summary> AllocatorDebuggerWrap.constructor </summary>\n        static void ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements AllocatorDebugger.debugInfo </summary>\n        static void GetDebugInfoCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n    };\n}\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/allocator-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"allocator-wrap.h\"\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(AllocatorWrap);\n\nvoid AllocatorWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<AllocatorWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    InitConstructorTemplate<AllocatorWrap>(constructorTemplate);\n    \n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"allocate\", AllocateCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"deallocate\", DeallocateCallback);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"type\", GetTypeCallback, nullptr);\n\n    auto constructor = constructorTemplate->GetFunction();\n    InitConstructor(\"<AllocatorWrap>\", constructor);\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructor);\n}\n\nstd::shared_ptr<napa::memory::Allocator> AllocatorWrap::Get() {\n    return ShareableWrap::Get<napa::memory::Allocator>();\n}\n\nvoid AllocatorWrap::AllocateCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument of 'size' is required for \\\"allocate\\\".\");\n    CHECK_ARG(isolate, args[0]->IsUint32(), \"Argument \\\"size\\\" must be a unsigned integer.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<AllocatorWrap>(args.Holder());\n    auto allocator = thisObject->Get();\n    JS_ENSURE(isolate, allocator != nullptr, \"AllocatorWrap is not attached with any C++ allocator.\");\n\n    auto handle = v8_helpers::PtrToV8Uint32Array(isolate, allocator->Allocate(args[0]->Uint32Value()));\n    args.GetReturnValue().Set(handle);\n}\n\nvoid AllocatorWrap::DeallocateCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 2, \"2 arguments is required for \\\"deallocate\\\".\");\n    auto result = v8_helpers::V8ValueToUintptr(isolate, args[0]);\n    JS_ENSURE(isolate, result.second, \"Unable to cast \\\"handle\\\" to pointer. Please check if it's in valid handle format.\");\n    \n    CHECK_ARG(isolate, args[1]->IsUint32(), \"Argument \\\"sizeHint\\\" must be a 32-bit unsigned integer.\");\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<AllocatorWrap>(args.Holder());\n    auto allocator = thisObject->Get();\n    JS_ENSURE(isolate, allocator != nullptr, \"AllocatorWrap is not attached with any C++ allocator.\");\n    \n    allocator->Deallocate(reinterpret_cast<void*>(result.first), args[1]->Uint32Value());\n}\n\nvoid AllocatorWrap::GetTypeCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args){\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<AllocatorWrap>(args.Holder());\n    auto allocator = thisObject->Get();\n    args.GetReturnValue().Set(\n        v8_helpers::MakeV8String(\n            isolate, \n            allocator != nullptr ? allocator->GetType() : \"<unloaded>\"));\n}"
  },
  {
    "path": "src/module/core-modules/napa/allocator-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/memory/allocator.h>\n#include <napa/module.h>\n#include <napa/module/shareable-wrap.h>\n\nnamespace napa {\nnamespace module {\n    /// <summary> Interface for AllocatorWrap. </summary>\n    class AllocatorWrap: public ShareableWrap {\n    public:\n        /// <summary> It creates a persistent constructor for AllocatorWrap instance. </summary>\n        static void Init();\n\n        /// <summary> Get transport context. </summary>\n        std::shared_ptr<napa::memory::Allocator> Get();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"AllocatorWrap\";\n\n        /// <summary> Declare constructor in public, so we can export class constructor in JavaScript world. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n    protected:\n        /// <summary> It implements Allocator.allocate(size: number): napajs.memory.Handle </summary>\n        static void AllocateCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Allocator.allocate(size: number): napajs.memory.Handle </summary>\n        static void DeallocateCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements readonly Allocator.type: string </summary>\n        static void GetTypeCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n    };\n}\n}\n    "
  },
  {
    "path": "src/module/core-modules/napa/call-context-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"call-context-wrap.h\"\n#include \"transport-context-wrap-impl.h\"\n\n#include <napa/transport.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(CallContextWrap);\n\nvoid CallContextWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<CallContextWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    InitConstructorTemplate<CallContextWrap>(constructorTemplate);\n    \n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"resolve\", ResolveCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"reject\", RejectCallback);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"finished\", IsFinishedCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"elapse\", GetElapseCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"module\", GetModuleCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"function\", GetFunctionCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"args\", GetArgumentsCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"transportContext\", GetTransportContextCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"options\", GetOptionsCallback, nullptr);\n\n    auto constructor = constructorTemplate->GetFunction();\n    InitConstructor(\"<CallContextWrap>\", constructor);\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructor);\n}\n\nv8::Local<v8::Object> CallContextWrap::NewInstance(std::shared_ptr<zone::CallContext> call) {\n    return ShareableWrap::NewInstance<CallContextWrap>(call);\n}\n\nzone::CallContext& CallContextWrap::GetRef() {\n    return ShareableWrap::GetRef<zone::CallContext>();\n}\n\nvoid CallContextWrap::ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument of 'result' is required for \\\"resolve\\\".\");\n    \n    v8::String::Utf8Value result(args[0]);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    auto success = thisObject->GetRef().Resolve(std::string(*result, result.length()));\n\n    JS_ENSURE(isolate, success, \"Resolve call failed: Already finished.\");\n}\n\nvoid CallContextWrap::RejectCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1 || args.Length() == 2, \"at least 1 argument of 'reason' is required for \\\"reject\\\".\");\n\n    napa::ResultCode code = NAPA_RESULT_EXECUTE_FUNC_ERROR;\n    v8::Local<v8::Value> reason;\n\n    if (args.Length() == 1) {\n        reason = args[0];\n    } else {\n        CHECK_ARG(isolate, args[0]->IsUint32(), \"arg 'resultCode' should be a number type.\");\n        code = static_cast<napa::ResultCode>(args[0]->Uint32Value());\n\n        reason = args[1];\n    }\n    \n    v8::String::Utf8Value reasonStr(reason);\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    auto success = thisObject->GetRef().Reject(code, std::string(*reasonStr, reasonStr.length()));\n    JS_ENSURE(isolate, success, \"Reject call failed: Already finished.\");\n}\n\nvoid CallContextWrap::IsFinishedCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args){\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    args.GetReturnValue().Set(thisObject->GetRef().IsFinished());\n}\n\nvoid CallContextWrap::GetElapseCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args){\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    args.GetReturnValue().Set(v8_helpers::HrtimeToV8Uint32Array(isolate, thisObject->GetRef().GetElapse().count()));\n}\n\nvoid CallContextWrap::GetModuleCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, thisObject->GetRef().GetModule()));\n}\n\nvoid CallContextWrap::GetFunctionCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, thisObject->GetRef().GetFunction()));\n}\n\nvoid CallContextWrap::GetArgumentsCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n\n    auto& cppArgs = thisObject->GetRef().GetArguments();\n    auto jsArgs = v8::Array::New(isolate, static_cast<int>(cppArgs.size()));\n    for (size_t i = 0; i < cppArgs.size(); ++i) {\n        // TODO: Switch to 2-bytes external string.\n        (void)jsArgs->CreateDataProperty(context, static_cast<uint32_t>(i), v8_helpers::MakeV8String(isolate, cppArgs[i]));\n    }\n    args.GetReturnValue().Set(jsArgs);\n}\n\nvoid CallContextWrap::GetTransportContextCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<CallContextWrap>(args.Holder());\n\n    auto& transportContext = thisObject->GetRef().GetTransportContext();\n    // Create a non-owning transport context wrap, since transport context is always owned by call context. \n    auto wrap = TransportContextWrapImpl::NewInstance(false, &transportContext);\n    args.GetReturnValue().Set(wrap);\n}\n\nvoid CallContextWrap::GetOptionsCallback(v8::Local<v8::String> /*propertyName*/, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    // Prepare execute options.\n    // NOTE: export necessary fields from CallContext.GetOptions to jsOptions object here. Now it's empty.\n    auto jsOptions = v8::Object::New(isolate);\n\n    args.GetReturnValue().Set(jsOptions);\n}\n\n"
  },
  {
    "path": "src/module/core-modules/napa/call-context-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/module/shareable-wrap.h>\n\n#include <zone/call-context.h>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> \n    ///     Class that wraps zone::CallContext, which enables JavaScript world to \n    ///     resolve or reject a function call.\n    /// </summary>\n    class CallContextWrap: public ShareableWrap {\n    public:\n        /// <summary> It creates a persistent constructor for CallContextWrap instance. </summary>\n        static void Init();\n\n        /// <summary> Create a new instance of wrap associating with specific call context. </summary>\n        static v8::Local<v8::Object> NewInstance(std::shared_ptr<zone::CallContext> call);\n\n        /// <summary> Get call context. </summary>\n        zone::CallContext& GetRef();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"CallContextWrap\";\n\n        /// <summary> Declare constructor in public, so we can export class constructor in JavaScript world. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n    protected:\n        /// <summary> It implements CallContext.resolve(result: any): void </summary>\n        static void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.reject(reason: string): void </summary>\n        static void RejectCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.finished: boolean </summary>\n        static void IsFinishedCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.module: string </summary>\n        static void GetModuleCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.function: string </summary>\n        static void GetFunctionCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.args: string[] </summary>\n        static void GetArgumentsCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.transportContext: TransportContext </summary>\n        static void GetTransportContextCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.options: CallOptions </summary>\n        static void GetOptionsCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements CallContext.elapse: [number, number] (precision in nano-second) </summary>\n        static void GetElapseCallback(v8::Local<v8::String> propertyName, const v8::PropertyCallbackInfo<v8::Value>& args);\n    };\n}\n}\n    "
  },
  {
    "path": "src/module/core-modules/napa/lock-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"lock-wrap.h\"\n\n#include <napa/module/binding/wraps.h>\n\n#include <memory>\n#include <mutex>\n#include <vector>\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(napa::module::LockWrap);\n\nvoid LockWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<LockWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    InitConstructorTemplate<LockWrap>(constructorTemplate);\n\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"guardSync\", GuardSyncCallback);\n\n    auto constructor = constructorTemplate->GetFunction();\n    InitConstructor(\"<LockWrap>\", constructor);\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructor);\n}\n\nv8::Local<v8::Object> LockWrap::NewInstance() {\n    return binding::CreateShareableWrap(std::make_shared<std::mutex>(), exportName);\n}\n\nvoid LockWrap::GuardSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() >= 1, \"1 argument is required for calling 'guardSync'.\");\n    CHECK_ARG(isolate, args[0]->IsFunction(), \"Argument \\\"func\\\" shall be 'Function' type.\");\n    CHECK_ARG(isolate, args.Length() < 2 || args[1]->IsArray(), \"Argument \\\"params\\\" shall be a valid array.\");\n\n    auto context = isolate->GetCurrentContext();\n    auto holder = args.Holder();\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<LockWrap>(args.Holder());\n\n    v8::TryCatch tryCatch(isolate);\n    try {\n        auto mutex = thisObject->Get<std::mutex>();\n        std::lock_guard<std::mutex> guard(*mutex);\n\n        std::vector<v8::Local<v8::Value>> params;\n\n        if (args.Length() >= 2) {\n            auto paramsArray = v8::Local<v8::Array>::Cast(args[1]);\n            int paramsLength = paramsArray->Length();\n            params.reserve(paramsLength);\n\n            for (int i = 0; i < paramsLength; i++) {\n                auto item = paramsArray->Get(context, i).ToLocalChecked();\n                params.emplace_back(item);\n            }\n        }\n\n        auto result = v8::Local<v8::Function>::Cast(args[0])->Call(\n            context,\n            holder,\n            static_cast<int>(params.size()),\n            params.empty() ? nullptr : params.data());\n\n        if (result.IsEmpty() || tryCatch.HasCaught()) {\n            tryCatch.ReThrow();\n        } else {\n            args.GetReturnValue().Set(result.ToLocalChecked());\n        }\n    } catch (const std::system_error& ex) {\n        isolate->ThrowException(v8::Exception::Error(v8_helpers::MakeV8String(isolate, ex.what())));\n    }\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/lock-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/module/shareable-wrap.h>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> An object wrap to expose lock APIs. </summary>\n    class LockWrap : public ShareableWrap {\n    public:\n\n        /// <summary> Initializes the wrap. </summary>\n        static void Init();\n\n        /// <summary> Creates a new instance of LockWrap. </summary>\n        static v8::Local<v8::Object> NewInstance();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"LockWrap\";\n\n        /// <summary> Declare persistent constructor to create Lock Javascript wrapper instance. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n    private:\n\n        // LockWrap methods\n        static void GuardSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n    };\n}\n}"
  },
  {
    "path": "src/module/core-modules/napa/metric-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"metric-wrap.h\"\n\nusing namespace napa::module;\nusing namespace napa::v8_helpers;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(MetricWrap);\n\nvoid MetricWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    // Prepare constructor template.\n    auto functionTemplate = v8::FunctionTemplate::New(isolate, ConstructorCallback);\n    functionTemplate->SetClassName(MakeV8String(isolate, _exportName));\n    functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    // Prototypes.\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"set\", Set);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"increment\", Increment);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"decrement\", Decrement);\n\n    // Set persistent constructor into V8.\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(_exportName, functionTemplate->GetFunction());\n}\n\nMetricWrap::MetricWrap(napa::providers::Metric* metric, uint32_t dimensions) :\n    _metric(metric), _dimensions(dimensions) {\n}\n\nvoid MetricWrap::ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    JS_ENSURE(isolate, args.IsConstructCall(), \"class \\\"MetricWrap\\\" allows constructor call only.\");\n\n    CHECK_ARG(isolate, args.Length() == 4,\n        \"class \\\"MetricWrap\\\" accepts exactly 4 arguments (section, name, type, dimensions)\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"'section' must be a valid string\");\n    CHECK_ARG(isolate, args[1]->IsString(), \"'name' must be a valid string\");\n    CHECK_ARG(isolate, args[2]->IsUint32(), \"'type' must be a uint32 type that represents the native enum\");\n    CHECK_ARG(isolate, args[3]->IsArray(), \"'dimensions' must be a valid array\");\n\n    auto section = V8ValueTo<Utf8String>(args[0]);\n    auto name = V8ValueTo<Utf8String>(args[1]);\n    auto type = static_cast<napa::providers::MetricType>(args[2]->Uint32Value());\n\n    // Holds te dimensions strings on the stack for the GetMetric call.\n    auto dimensionsStringsHolder = V8ArrayToVector<Utf8String>(isolate, v8::Local<v8::Array>::Cast(args[3]));\n\n    std::vector<const char*> dimensions;\n    dimensions.reserve(dimensionsStringsHolder.size());\n    for (const auto& dimension : dimensionsStringsHolder) {\n        dimensions.emplace_back(dimension.Data());\n    }\n\n    auto& metricProvider = napa::providers::GetMetricProvider();\n    auto metric = metricProvider.GetMetric(section.Data(), name.Data(), type, dimensions.size(), dimensions.data());\n\n    auto wrap = new MetricWrap(metric, static_cast<uint32_t>(dimensions.size()));\n\n    wrap->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n}\n\nvoid MetricWrap::Set(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args[0]->IsUint32(), \"'value' argument must be a valid Uint32\");\n    auto value = args[0]->Uint32Value();\n\n    InvokeWithDimensions(args, 1, [value](napa::providers::Metric* metric, std::vector<const char*>& dimensions) {\n        metric->Set(value, dimensions.size(), dimensions.data());\n    });\n}\n\nvoid MetricWrap::Increment(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    InvokeWithDimensions(args, 0, [](napa::providers::Metric* metric, std::vector<const char*>& dimensions) {\n        metric->Increment(1, dimensions.size(), dimensions.data());\n    });\n}\n\nvoid MetricWrap::Decrement(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    InvokeWithDimensions(args, 0, [](napa::providers::Metric* metric, std::vector<const char*>& dimensions) {\n        metric->Decrement(1, dimensions.size(), dimensions.data());\n    });\n}\n\ntemplate <typename Func>\nvoid MetricWrap::InvokeWithDimensions(const v8::FunctionCallbackInfo<v8::Value>& args, uint32_t index, Func&& func) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto dimensionsArg = args[index];\n    CHECK_ARG(isolate, dimensionsArg->IsArray() || dimensionsArg->IsUndefined(), \"'dimensions' must be an array or undefined\");\n\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<MetricWrap>(args.Holder());\n\n    // Holds the dimensions strings on the stack for so it exists during the call to func.\n    std::vector<napa::v8_helpers::Utf8String> dimensionsStringsHolder;\n\n    std::vector<const char*> dimensions;\n    if (dimensionsArg->IsArray() && wrap->_dimensions > 0) {\n        auto arr = v8::Local<v8::Array>::Cast(dimensionsArg);\n        JS_ENSURE(\n            isolate,\n            wrap->_dimensions == arr->Length(),\n            \"the dimensions count does not match. expected: %d, received: %d\",\n            wrap->_dimensions,\n            arr->Length());\n\n        dimensionsStringsHolder = napa::v8_helpers::V8ArrayToVector<napa::v8_helpers::Utf8String>(isolate, arr);\n\n        dimensions.reserve(dimensionsStringsHolder.size());\n        for (const auto& dimension : dimensionsStringsHolder) {\n            dimensions.emplace_back(dimension.Data());\n        }\n    } else {\n        JS_ENSURE(isolate, wrap->_dimensions == 0, \"expected %s dimensions but received 0\", wrap->_dimensions);\n    }\n\n    func(wrap->_metric, dimensions);\n}"
  },
  {
    "path": "src/module/core-modules/napa/metric-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/providers/metric.h>\n\n#include <memory>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> An object wrap to expose metric APIs. </summary>\n    class MetricWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> Initializes the wrap. </summary>\n        static void Init();\n\n        /// <summary> Create a new MetricWrap instance that wraps the provided metric. </summary>\n        static v8::Local<v8::Object> NewInstance(napa::providers::Metric* metric, uint32_t dimensions);\n\n        /// <summary> Declare persistent constructor to create Metric Javascript wrapper instance. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n    private:\n\n        /// <summary> The underlying metric. </summary>\n        napa::providers::Metric* _metric;\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* _exportName = \"MetricWrap\";\n\n        /// <summary> Number of dimensions this metric expects. </summary>\n        uint32_t _dimensions;\n\n        /// <summary> Constructor. </summary>\n        MetricWrap(napa::providers::Metric* metric, uint32_t dimensions);\n\n        /// <summary> MetricWrap.constructor </summary>\n        static void ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        // MetricWrap getters\n        static void NameGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args);\n        static void SectionGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        // MetricWrap methods\n        static void Set(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void Increment(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void Decrement(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary>\n        ///     Helper method that extracts the dimensions and metric from args and calls the func \n        ///     with these arguments.\n        /// </summary>\n        template <typename Func>\n        static void InvokeWithDimensions(const v8::FunctionCallbackInfo<v8::Value>& args, uint32_t index, Func&& func);\n    };\n}\n}"
  },
  {
    "path": "src/module/core-modules/napa/napa-binding.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"napa-binding.h\"\n\n#include \"allocator-debugger-wrap.h\"\n#include \"allocator-wrap.h\"\n#include \"call-context-wrap.h\"\n#include \"lock-wrap.h\"\n#include \"metric-wrap.h\"\n#include \"shared-ptr-wrap.h\"\n#include \"store-wrap.h\"\n#include \"timer-wrap.h\"\n#include \"transport-context-wrap-impl.h\"\n#include \"zone-wrap.h\"\n\n#include <zone/worker-context.h>\n\n#include <napa/zone.h>\n#include <napa/memory.h>\n#include <napa/module/binding.h>\n#include <napa/module/binding/wraps.h>\n#include <napa/providers/logging.h>\n#include <napa/providers/metric.h>\n\n#include <v8-extensions/v8-extensions-macros.h>\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n    #include <v8-extensions/v8-extensions.h>\n#endif\n\nusing namespace napa;\nusing namespace napa::module;\n\nstatic void RegisterBinding(v8::Local<v8::Object> module) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto persistentModule = new v8::Persistent<v8::Object>(isolate, module);\n    zone::WorkerContext::Set(zone::WorkerContextItem::NAPA_BINDING, persistentModule);\n}\n\nv8::Local<v8::Object> napa::module::binding::GetModule() {\n    auto persistentModule = \n        reinterpret_cast<v8::Persistent<v8::Object>*>(\n            zone::WorkerContext::Get(zone::WorkerContextItem::NAPA_BINDING));\n    \n    NAPA_ASSERT(persistentModule != nullptr, \"\\\"napajs\\\" must be required before napa::module::binding::GetModule() can be called from C++.\");\n    return v8::Local<v8::Object>::New(v8::Isolate::GetCurrent(), *persistentModule);\n}\n\nstatic void CreateZone(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n\n    CHECK_ARG(isolate, args[0]->IsString(), \"first argument to createZone must be a string\");\n    v8::String::Utf8Value zoneId(args[0]->ToString());\n\n    std::stringstream ss;\n    if ((args.Length() > 1) && (!args[1]->IsUndefined())) {\n        CHECK_ARG(isolate, args[1]->IsObject(), \"second argument to createZone must be an object\");\n        auto settingsObj = args[1]->ToObject(context).ToLocalChecked();\n\n        auto settingsMap = napa::v8_helpers::V8ObjectToMap<std::string>(isolate, settingsObj);\n\n        for (const auto& kv : settingsMap) {\n            ss << \" --\" << kv.first << \" \" << kv.second;\n        }\n    }\n\n    try {\n        auto zoneProxy = std::make_unique<napa::Zone>(*zoneId, ss.str());\n        args.GetReturnValue().Set(ZoneWrap::NewInstance(std::move(zoneProxy)));\n    } catch (const std::runtime_error& ex) {\n        JS_FAIL(isolate, ex.what());\n    } catch (...) {\n        JS_FAIL(isolate, \"Failed to initialize zone with id \", *zoneId);\n    }\n}\n\nstatic void GetZone(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args[0]->IsString(), \"first argument to getZone must be a string\");\n    v8::String::Utf8Value zoneId(args[0]->ToString());\n\n    try {\n        auto zoneProxy = napa::Zone::Get(*zoneId);\n        args.GetReturnValue().Set(ZoneWrap::NewInstance(std::move(zoneProxy)));\n    }\n    catch (const std::runtime_error &ex) {\n        JS_FAIL(isolate, ex.what());\n    } catch (...) {\n        JS_FAIL(isolate, \"No zone exists with id \", *zoneId);\n    }\n}\n\nstatic void GetCurrentZone(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(ZoneWrap::NewInstance(napa::Zone::GetCurrent()));\n}\n\n/////////////////////////////////////////////////////////////////////\n/// Store APIs\n\nstatic void CreateStore(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument of 'id' is required.\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'id' must be string.\");\n\n    auto id = napa::v8_helpers::V8ValueTo<std::string>(args[0]);\n    auto store = napa::store::CreateStore(id.c_str());\n\n    JS_ENSURE(isolate, store != nullptr, \"Store with id \\\"%s\\\" already exists.\", id.c_str());\n\n    args.GetReturnValue().Set(StoreWrap::NewInstance(store));\n}\n\nstatic void GetOrCreateStore(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument of 'id' is required.\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'id' must be string.\");\n\n    auto id = napa::v8_helpers::V8ValueTo<std::string>(args[0]);\n    auto store = napa::store::GetOrCreateStore(id.c_str());\n\n    args.GetReturnValue().Set(StoreWrap::NewInstance(store));\n}\n\nstatic void GetStore(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument of 'id' is required.\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'id' must be string.\");\n\n    auto id = napa::v8_helpers::V8ValueTo<std::string>(args[0]);\n    auto store = napa::store::GetStore(id.c_str());\n\n    if (store != nullptr) {\n        args.GetReturnValue().Set(StoreWrap::NewInstance(store));\n    }\n}\n\nstatic void GetStoreCount(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    args.GetReturnValue().Set(static_cast<uint32_t>(napa::store::GetStoreCount()));\n}\n\n/////////////////////////////////////////////////////////////////////\n/// Sync APIs\n\nstatic void CreateLock(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(LockWrap::NewInstance());\n}\n\nstatic void GetCrtAllocator(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    args.GetReturnValue().Set(binding::CreateAllocatorWrap(\n        std::shared_ptr<napa::memory::Allocator>(\n            &napa::memory::GetCrtAllocator(),\n            [](napa::memory::Allocator*){})));\n}\n\nstatic void GetDefaultAllocator(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    args.GetReturnValue().Set(binding::CreateAllocatorWrap(\n        std::shared_ptr<napa::memory::Allocator>(\n            &napa::memory::GetDefaultAllocator(),\n            [](napa::memory::Allocator*){})));\n}\n\nstatic void Log(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 4, \"log accepts exactly 4 arguments (level, section, traceId, message)\");\n    CHECK_ARG(isolate, args[0]->IsUint32(), \"'level' must be a uint32 type that represents the native enum\");\n    CHECK_ARG(isolate, args[1]->IsString() || args[1]->IsUndefined(), \"'section' must be a valid string or undefined\");\n\n    auto level = static_cast<napa::providers::LoggingProvider::Verboseness>(args[0]->Uint32Value());\n\n    napa::v8_helpers::Utf8String sectionValue;\n    const char* section = \"\";\n    if (!args[1]->IsUndefined()) {\n        sectionValue = napa::v8_helpers::V8ValueTo<napa::v8_helpers::Utf8String>(args[1]);\n        section = sectionValue.Length() > 0 ? sectionValue.Data() : \"\";\n    }\n\n    auto& logger = napa::providers::GetLoggingProvider();\n\n    // If log is not enabled we can return early.\n    if (!logger.IsLogEnabled(section, level)) {\n        return;\n    }\n\n    CHECK_ARG(isolate, args[2]->IsString() || args[2]->IsUndefined(), \"'traceId' must be a valid string or undefined\");\n    CHECK_ARG(isolate, args[3]->IsString(), \"'message' must be a valid string\");\n\n    napa::v8_helpers::Utf8String traceIdValue;\n    const char* traceId = \"\";\n    if (!args[2]->IsUndefined()) {\n        traceIdValue = napa::v8_helpers::V8ValueTo<napa::v8_helpers::Utf8String>(args[2]);\n        traceId = traceIdValue.Length() > 0 ? traceIdValue.Data() : \"\";\n    }\n\n    v8::String::Utf8Value message(args[3]->ToString());\n\n    // Get the first frame in user code.\n    // The first 2 frames are part of the log.js file.\n    auto stackFrame = v8::StackTrace::CurrentStackTrace(isolate, 3)->GetFrame(2);\n\n    v8::String::Utf8Value file(stackFrame->GetScriptName());\n    int line = stackFrame->GetLineNumber();\n\n    logger.LogMessage(section, level, traceId, *file, line, *message);\n}\n\nvoid SerializeValue(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    #if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument is required for \\\"serializeValue\\\".\");\n\n    auto serializedData = v8_extensions::Utils::SerializeValue(isolate, args[0]);\n    if (serializedData) {\n        args.GetReturnValue().Set(binding::CreateShareableWrap(serializedData));\n    }\n\n    #else\n\n    isolate->ThrowException(v8::Exception::TypeError(napa::v8_helpers::MakeV8String(\n        isolate,\n        \"It requires v8 newer than 6.2.x to transport builtin types. \\\n        If run in node mode, please make sure the node version is v9.0.0 or above.\")));\n\n    #endif\n}\n\nvoid DeserializeValue(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    #if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument is required for \\\"deserializeValue\\\".\");\n    CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"object\\\" shall be 'SharedPtrWrap' type.\");\n    auto shareableWrap = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(v8::Local<v8::Object>::Cast(args[0]));\n    auto serializedData = shareableWrap->Get<v8_extensions::SerializedData>();\n\n    v8::Local<v8::Value> value;\n    if (v8_extensions::Utils::DeserializeValue(isolate, serializedData).ToLocal(&value)) {\n        args.GetReturnValue().Set(value);\n    }\n\n    #else\n\n    isolate->ThrowException(v8::Exception::TypeError(napa::v8_helpers::MakeV8String(\n        isolate,\n        \"It requires v8 newer than 6.2.x to transport builtin types. \\\n        If run in node mode, please make sure the node version is v9.0.0 or above.\")));\n\n    #endif\n}\n\n/////////////////////////////////////////////////////////////////////\n/// Timers APIs, these APIs only valid in non-node isolation, i.e., \n/// they are not needed when building the napa_binding.node\n\n#ifdef BUILDING_NAPA_EXTENSION\nstatic void SetImmediate(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    TimerWrap::SetImmediateCallback(args);\n}\n\n// Set Timeout or Set Interval\nstatic void SetTimers(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    TimerWrap::SetTimersCallback(args);\n}\n#endif\n\n\nstatic void InitNapaOnlyBindings(v8::Local<v8::Object> exports) {\n#ifdef BUILDING_NAPA_EXTENSION \n    TimerWrap::Init();\n\n    NAPA_SET_METHOD(exports, \"setImmediate\", SetImmediate);\n    NAPA_SET_METHOD(exports, \"setTimers\", SetTimers);\n#endif\n}\n\nvoid binding::Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {\n    // Register napa binding in worker context.\n    RegisterBinding(module);\n\n    AllocatorDebuggerWrap::Init();\n    AllocatorWrap::Init();\n    CallContextWrap::Init();\n    LockWrap::Init();\n    MetricWrap::Init();\n    SharedPtrWrap::Init();\n    StoreWrap::Init();\n    TransportContextWrapImpl::Init();\n    ZoneWrap::Init();\n\n    NAPA_EXPORT_OBJECTWRAP(exports, \"AllocatorDebuggerWrap\", AllocatorDebuggerWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"AllocatorWrap\", AllocatorWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"CallContextWrap\", CallContextWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"LockWrap\", LockWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"MetricWrap\", MetricWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"SharedPtrWrap\", SharedPtrWrap);\n    NAPA_EXPORT_OBJECTWRAP(exports, \"TransportContextWrap\", TransportContextWrapImpl);\n\n    NAPA_SET_METHOD(exports, \"createZone\", CreateZone);\n    NAPA_SET_METHOD(exports, \"getZone\", GetZone);\n    NAPA_SET_METHOD(exports, \"getCurrentZone\", GetCurrentZone);\n\n    NAPA_SET_METHOD(exports, \"createStore\", CreateStore);\n    NAPA_SET_METHOD(exports, \"getOrCreateStore\", GetOrCreateStore);\n    NAPA_SET_METHOD(exports, \"getStore\", GetStore);\n    NAPA_SET_METHOD(exports, \"getStoreCount\", GetStoreCount);\n\n    NAPA_SET_METHOD(exports, \"createLock\", CreateLock);\n    \n    NAPA_SET_METHOD(exports, \"getCrtAllocator\", GetCrtAllocator);\n    NAPA_SET_METHOD(exports, \"getDefaultAllocator\", GetDefaultAllocator);\n\n    NAPA_SET_METHOD(exports, \"log\", Log);\n\n    NAPA_SET_METHOD(exports, \"serializeValue\", SerializeValue);\n    NAPA_SET_METHOD(exports, \"deserializeValue\", DeserializeValue);\n\n    InitNapaOnlyBindings(exports);\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/napa-binding.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n\nnamespace napa {\nnamespace module {\nnamespace binding {\n\n    /// <summary> Initialize and export napa related functions and object wraps. </summary>\n    void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module);\n}\n}\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/shared-ptr-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"shared-ptr-wrap.h\"\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(napa::module::SharedPtrWrap);\n\nvoid SharedPtrWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<SharedPtrWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, SharedPtrWrap::exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    InitConstructorTemplate<SharedPtrWrap>(constructorTemplate);\n    auto constructor = constructorTemplate->GetFunction();\n    InitConstructor(\"<SharedPtrWrap>\", constructor);\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructor);\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/shared-ptr-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/module/shareable-wrap.h>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> It wraps C++ std::shared_ptr<T> and allow it be shared across isolates. </summary>\n    /// <remarks> see napajs/lib/memory/shared-ptr-wrap.d.ts#SharedPtrWrap </remarks>\n    class SharedPtrWrap : public ShareableWrap {\n    public:\n        /// <summary> Init SharedPtrWrap. </summary>\n        static void Init();\n\n        /// <summary> Declare constructor in public, so we can export class constructor in JavaScript world. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"SharedPtrWrap\";\n    };\n}\n}"
  },
  {
    "path": "src/module/core-modules/napa/store-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"store-wrap.h\"\n#include <napa/transport.h>\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(StoreWrap);\n    \nvoid StoreWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<StoreWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"set\", SetCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"get\", GetCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"has\", HasCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"delete\", DeleteCallback);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"id\", GetIdCallback, nullptr);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"size\", GetSizeCallback, nullptr);\n\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructorTemplate->GetFunction());\n}\n\nv8::Local<v8::Object> StoreWrap::NewInstance(std::shared_ptr<napa::store::Store> store) {\n    auto object = napa::module::NewInstance<StoreWrap>().ToLocalChecked();\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(object);\n    wrap->_store = std::move(store);\n    return object;\n}\n\nnapa::store::Store& StoreWrap::Get() {\n    return *_store;\n}\n\nvoid StoreWrap::SetCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    CHECK_ARG(isolate, args.Length() == 2, \"2 arguments are required for \\\"set\\\".\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument \\\"key\\\" must be string.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    // Marshall value object into payload.\n    napa::transport::TransportContext transportContext;\n    auto payload = napa::transport::Marshall(args[1], &transportContext);\n    \n    RETURN_ON_PENDING_EXCEPTION(payload);\n    \n    store.Set(\n        v8_helpers::V8ValueTo<std::string>(args[0]).c_str(),\n        std::make_shared<napa::store::Store::ValueType>(napa::store::Store::ValueType {\n            v8_helpers::V8ValueTo<std::u16string>(payload.ToLocalChecked()),\n            std::move(transportContext)\n        }));\n}\n\nvoid StoreWrap::GetCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument are required for \\\"get\\\".\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'key' must be string.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    // Marshall value object into payload.\n    auto key = v8_helpers::V8ValueTo<std::string>(args[0]);\n    auto storeValue = store.Get(key.c_str());\n    if (storeValue != nullptr) {\n        auto value = napa::transport::Unmarshall(\n            v8_helpers::MakeExternalV8String(isolate, storeValue->payload), \n            &(storeValue->transportContext));\n\n        RETURN_ON_PENDING_EXCEPTION(value);\n        args.GetReturnValue().Set(value.ToLocalChecked());\n    }\n}\n\nvoid StoreWrap::HasCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument are required for \\\"has\\\".\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'key' must be string.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    args.GetReturnValue().Set(store.Has(v8_helpers::V8ValueTo<std::string>(args[0]).c_str()));\n}\n\nvoid StoreWrap::DeleteCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument are required for \\\"delete\\\".\");\n    CHECK_ARG(isolate, args[0]->IsString(), \"Argument 'key' must be string.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    store.Delete(v8_helpers::V8ValueTo<std::string>(args[0]).c_str());\n}\n\nvoid StoreWrap::GetIdCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, store.GetId()));\n}\n\nvoid StoreWrap::GetSizeCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    \n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<StoreWrap>(args.Holder());\n    auto& store = thisObject->Get();\n\n    args.GetReturnValue().Set(static_cast<uint32_t>(store.Size()));\n}\n\n"
  },
  {
    "path": "src/module/core-modules/napa/store-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n\n#include <store/store.h>\n\nnamespace napa {\nnamespace module {\n    \n    /// <summary> It wraps napa::store::Store. </summary>\n    /// <remarks> Reference: napajs/lib/store.ts#Store </remarks>\n    class StoreWrap: public NAPA_OBJECTWRAP {\n    public:\n        /// <summary> Init this wrap. </summary>\n        static void Init();\n\n        /// <summary> It creates an instance of StoreWrap with a napa::store::Store pointer. </summary>\n        static v8::Local<v8::Object> NewInstance(std::shared_ptr<napa::store::Store> store);\n\n        /// <summary> Get napa::store::Store from wrap. </summary>\n        napa::store::Store& Get();\n\n    private:\n        /// <summary> Default constructor. </summary>\n        StoreWrap() = default;\n\n        /// <summary> No copy allowed. </summary>\n        StoreWrap(const StoreWrap&) = delete;\n        StoreWrap& operator=(const StoreWrap&) = delete;\n\n        /// <summary> It implements Store.set(key: string, value: any): void </summary>\n        static void SetCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Store.get(key: string): any </summary>\n        static void GetCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Store.has(key: string): boolean </summary>\n        static void HasCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Store.delete(key: string): void </summary>\n        static void DeleteCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Store.id </summary>\n        static void GetIdCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements Store.size </summary>\n        static void GetSizeCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args);\n        \n        /// <summary> Friend default constructor callback. </summary>\n        template <typename T>\n        friend void napa::module::DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n        template <typename T>\n        friend v8::MaybeLocal<v8::Object> napa::module::NewInstance(int argc, v8::Local<v8::Value> argv[]);\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"StoreWrap\";\n\n        /// <summary> Hid constructor from public access. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        /// <summary> Store. </summary>\n        std::shared_ptr<napa::store::Store> _store;\n    };\n}\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/timer-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// See: https://groups.google.com/forum/#!topic/nodejs/onA0S01INtw\n#ifdef BUILDING_NODE_EXTENSION\n#include <node.h>\n#endif\n\n#include <vector>\n#include <memory>\n#include <functional>\n\n#include \"timer-wrap.h\"\n\n#include <napa/zone.h>\n#include <zone/worker.h>\n#include <zone/scheduler.h>\n#include <zone/worker-context.h>\n#include <zone/async-context.h>\n#include <zone/task.h>\n\n\nusing napa::zone::WorkerId;\nusing napa::zone::WorkerContext;\nusing napa::zone::WorkerContextItem;\nusing napa::zone::NapaZone;\nusing napa::zone::SchedulePhase;\n\nusing v8::Array;\nusing v8::Boolean;\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Global;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> A task to run a C++ callback task without cross isolation. </summary>\n    class CallbackTask : public Task {\n    public:\n        typedef std::function<void(void)> Callback;    \n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"context\"> Structure containing asynchronous work's context. </param>\n        CallbackTask(Callback callback) \n            : _callback(std::move(callback)) \n        {\n        }\n\n        /// <summary> Overrides Task.Execute to define running execution logic. </summary>\n        virtual void Execute()\n        {\n            _callback();\n        }\n\n    private:\n        Callback _callback;\n    };\n\n}\n}\n\nusing namespace napa::module;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(TimerWrap);\n\nvoid TimerWrap::Init() {\n    auto isolate = Isolate::GetCurrent();\n    auto constructorTemplate = FunctionTemplate::New(isolate, DefaultConstructorCallback<TimerWrap>);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructorTemplate->GetFunction());\n}\n\nLocal<Object> TimerWrap::NewInstance(std::shared_ptr<napa::zone::Timer> timer) {\n    auto object = napa::module::NewInstance<TimerWrap>().ToLocalChecked();\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<TimerWrap>(object);\n    wrap->_timer = std::move(timer);\n    return object;\n}\n\nvoid TimerWrap::Reset() {\n    _timer.reset();\n}\n\nnapa::zone::Timer& TimerWrap::Get() {\n    return *_timer;\n}\n\n// This is created as SetWeak(void) is not exists in v8 used in NodeJS 6.\nstatic void EmptyWeakCallback(const v8::WeakCallbackInfo<int>& data) {\n}\n\nstd::shared_ptr<napa::zone::CallbackTask> buildTimeoutTask(\n        std::shared_ptr<Persistent<Object>> sharedTimeout,\n        std::shared_ptr<Persistent<Context>> sharedContext)\n{\n    return std::make_shared<napa::zone::CallbackTask>(\n        [sharedTimeout, sharedContext]() {\n            auto isolate = Isolate::GetCurrent();\n            HandleScope handleScope(isolate);\n            auto context = Local<Context>::New(isolate, *sharedContext);\n            Context::Scope contextScope(context);\n\n            auto timeout = Local<Object>::New(isolate, *sharedTimeout);\n\n            bool needDestroy = true;\n            Local<Boolean> active = Local<Boolean>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_active\")));\n            if (active->Value()) {\n                Local<Function> cb = Local<Function>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_callback\")));\n                Local<Array> args = Local<Array>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_args\")));\n                \n                std::vector<Local<Value>> parameters;\n                parameters.reserve(args->Length());\n                for (int i = 0; i < static_cast<int>(args->Length()); ++i) {\n                    Local<Value> v = args->Get(context, i).ToLocalChecked();\n                    parameters.emplace_back(v);\n                }\n                cb->Call(context, context->Global(), static_cast<int>(parameters.size()), parameters.data());\n\n                Local<Number> interval = Local<Number>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_repeat\")));\n                bool isInterval = (interval->Value() >= 1);\n                if (isInterval) {\n                    auto jsTimer = NAPA_OBJECTWRAP::Unwrap<TimerWrap>(\n                        Local<Object>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_timer\"))));\n\n                    //Re-arm the interval timer in napa's timer schedule thread.\n                    jsTimer->Get().Start();\n\n                    // If not interval timer, global v8 handle for Timeout and Context will be SetWeak.\n                    // Otherwise keep holding the hanle as they will be used some time later.\n                    needDestroy = false;\n                }\n            }\n\n            if (needDestroy) {\n                if (!sharedTimeout->IsEmpty()) {\n                    sharedTimeout->SetWeak((int*)nullptr, EmptyWeakCallback, v8::WeakCallbackType::kParameter);\n                    sharedTimeout->Reset();\n                }\n                if (!sharedContext->IsEmpty()) {\n                    sharedContext->SetWeak((int*)nullptr, EmptyWeakCallback, v8::WeakCallbackType::kParameter);\n                    sharedContext->Reset();\n                }\n            }\n        }\n    );\n}\n\nvoid TimerWrap::SetImmediateCallback(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = Isolate::GetCurrent();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument is required for calling 'SetImmediateCallback'.\");\n    CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"timeout\\\" shall be 'Timeout' type.\");\n\n    auto zone = reinterpret_cast<NapaZone*>(WorkerContext::Get(WorkerContextItem::ZONE));\n    if (zone == nullptr) {\n        throw new std::runtime_error(\"Null zone encountered!\");\n    }\n    auto scheduler = zone->GetScheduler().get();\n    if (scheduler == nullptr) {\n        throw new std::runtime_error(\"Null scheduler encountered!\");\n    }\n\n    Local<Object> timeout = Local<Object>::Cast(args[0]);\n    auto sharedTimeout = std::make_shared<Persistent<Object>>(isolate, timeout);\n\n    auto context = isolate->GetCurrentContext();\n    auto sharedContext = std::make_shared<Persistent<Context>>(isolate, context);\n\n    auto immediateCallbackTask = buildTimeoutTask(sharedTimeout, sharedContext);\n\n    auto workerId = static_cast<WorkerId>(\n        reinterpret_cast<uintptr_t>(WorkerContext::Get(WorkerContextItem::WORKER_ID)));\n    scheduler->ScheduleOnWorker(workerId, immediateCallbackTask, SchedulePhase::ImmediatePhase);\n}\n\n\nvoid TimerWrap::SetTimersCallback(const FunctionCallbackInfo<Value>& args) {\n    auto isolate = Isolate::GetCurrent();\n    HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 argument is required for calling 'SetTimersCallback'.\");\n    CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"timeout\\\" shall be 'Timeout' type.\");\n\n    auto zone = reinterpret_cast<NapaZone*>(WorkerContext::Get(WorkerContextItem::ZONE));\n    if (zone == nullptr) {\n        throw new std::runtime_error(\"Null zone encountered!\");\n    }\n    auto scheduler = zone->GetScheduler().get();\n    if (scheduler == nullptr) {\n        throw new std::runtime_error(\"Null scheduler encountered!\");\n    }\n    auto workerId = static_cast<WorkerId>(\n        reinterpret_cast<uintptr_t>(WorkerContext::Get(WorkerContextItem::WORKER_ID)));\n\n    Local<Object> timeout = Local<Object>::Cast(args[0]);\n    auto sharedTimeout = std::make_shared<Persistent<Object>>(isolate, timeout);\n\n    auto context = isolate->GetCurrentContext();\n    auto sharedContext = std::make_shared<Persistent<Context>>(isolate, context);\n\n    Local<Number> after = Local<Number>::Cast(timeout->Get(String::NewFromUtf8(isolate, \"_after\")));\n    std::chrono::milliseconds msAfter{static_cast<int>(after->Value())};\n    auto sharedTimer = std::make_shared<napa::zone::Timer>(\n        [sharedTimeout, sharedContext, scheduler, workerId]() {\n            auto timerCallbackTask = buildTimeoutTask(sharedTimeout, sharedContext);\n            scheduler->ScheduleOnWorker(workerId, timerCallbackTask, SchedulePhase::DefaultPhase);\n        }, msAfter);\n\n    auto jsTimer = TimerWrap::NewInstance(sharedTimer);\n    timeout->Set(String::NewFromUtf8(isolate, \"_timer\"), jsTimer);\n    sharedTimer->Start();\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/timer-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <zone/timer.h>\n\nnamespace napa {\nnamespace module {\n    \n    /// <summary> It wraps napa::zone::Timer. </summary>\n    /// <remarks> Reference: napajs/lib/timer.ts#Timer </remarks>\n    class TimerWrap: public NAPA_OBJECTWRAP {\n    public:\n        /// <summary> Init this wrap. </summary>\n        static void Init();\n\n        /// <summary> It creates an instance of TimerWrap with a napa::zone::Timer pointer. </summary>\n        static v8::Local<v8::Object> NewInstance(std::shared_ptr<napa::zone::Timer> timer);\n\n        napa::zone::Timer& Get();\n\n        void Reset();\n\n        static void SetImmediateCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        static void SetTimersCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    private:\n        /// <summary> Default constructor. </summary>\n        TimerWrap() = default;\n    \n        /// <summary> No copy allowed. </summary>\n        TimerWrap(const TimerWrap&) = delete;\n        TimerWrap& operator=(const TimerWrap&) = delete;\n\n\n        /// <summary> Friend default constructor callback. </summary>\n        template <typename T>\n        friend void napa::module::DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n        template <typename T>\n        friend v8::MaybeLocal<v8::Object> napa::module::NewInstance(int argc, v8::Local<v8::Value> argv[]);\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"TimerWrap\";\n\n        /// <summary> Hid constructor from public access. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        std::shared_ptr<napa::zone::Timer> _timer;\n    };\n}\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/transport-context-wrap-impl.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"transport-context-wrap-impl.h\"\n\n#include <napa/module/shareable-wrap.h>\n#include <napa/module/binding/wraps.h>\n\nusing namespace napa;\nusing namespace napa::transport;\nusing namespace napa::module;\n\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(TransportContextWrapImpl);\n\nTransportContextWrapImpl::TransportContextWrapImpl(TransportContext* context, bool owning) : \n    _context(context), _owning(owning) {\n}\n\nv8::Local<v8::Object> TransportContextWrapImpl::NewInstance(bool owning, napa::transport::TransportContext* context) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    v8::Local<v8::Value> argv[] = { v8::Boolean::New(isolate, owning), v8_helpers::PtrToV8Uint32Array(isolate, context) };\n    auto object = napa::module::NewInstance<TransportContextWrapImpl>(sizeof(argv) / sizeof(v8::Local<v8::Value>), argv);\n    RETURN_VALUE_ON_PENDING_EXCEPTION(object, v8::Local<v8::Object>());\n    \n    return scope.Escape(object.ToLocalChecked());\n}\n\nTransportContextWrapImpl::~TransportContextWrapImpl() {\n    if (_owning) {\n        delete _context;\n    }\n}\n\nTransportContext* TransportContextWrapImpl::Get() {\n    return _context;\n}\n\nvoid TransportContextWrapImpl::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto constructorTemplate = v8::FunctionTemplate::New(isolate, TransportContextWrapImpl::ConstructorCallback);\n    constructorTemplate->SetClassName(v8_helpers::MakeV8String(isolate, exportName));\n    constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"saveShared\", SaveSharedCallback);\n    NAPA_SET_PROTOTYPE_METHOD(constructorTemplate, \"loadShared\", LoadSharedCallback);\n    NAPA_SET_ACCESSOR(constructorTemplate, \"sharedCount\", GetSharedCountCallback, nullptr);\n\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, constructorTemplate->GetFunction());\n}\n\nvoid TransportContextWrapImpl::GetSharedCountCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args){\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<TransportContextWrapImpl>(args.Holder());\n    JS_ENSURE(isolate, thisObject != nullptr, \"Invalid object to get property \\\"sharedCount\\\".\");\n\n    args.GetReturnValue().Set(thisObject->_context->GetSharedCount());\n}\n\nvoid TransportContextWrapImpl::ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    JS_ENSURE(isolate, args.IsConstructCall(), \n        \"class \\\"TransportContextWrap\\\" allows constructor call only.\");\n\n    CHECK_ARG(isolate, args.Length() == 1 || args.Length() == 2, \n        \"class \\\"TransportContextWrap\\\" accept a required boolean argument 'owning' and an optional argument 'handle' of Handle type.\");\n\n    CHECK_ARG(isolate, args[0]->IsBoolean(), \"Argument \\\"owning\\\" must be boolean.\");\n    bool owning = args[0]->BooleanValue();\n\n    // It's deleted when its Javascript object is garbage collected by V8's GC.\n    TransportContext* context = nullptr;\n    \n    if (args.Length() == 1 || args[1]->IsUndefined()) {\n        context = new TransportContext();\n    } else {\n        auto result = v8_helpers::V8ValueToPtr<TransportContext>(isolate, args[1]);\n        JS_ENSURE(isolate, result.second, \n            \"argument 'handle' must be of type [number, number].\");\n\n        context = result.first;\n    }\n    auto wrap = new TransportContextWrapImpl(context, owning);\n    wrap->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n}\n\nvoid TransportContextWrapImpl::SaveSharedCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 arguments are required for \\\"saveShared\\\".\");\n    CHECK_ARG(isolate, args[0]->IsObject(), \"Argument \\\"object\\\" shall be 'ShareableWrap' type.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<TransportContextWrap>(args.Holder());\n    auto sharedWrap = NAPA_OBJECTWRAP::Unwrap<ShareableWrap>(v8::Local<v8::Object>::Cast(args[0]));\n    thisObject->Get()->SaveShared(sharedWrap->Get<void>());\n}\n\nvoid TransportContextWrapImpl::LoadSharedCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1, \"1 arguments are required for \\\"saveShared\\\".\");\n\n    auto result = v8_helpers::V8ValueToUintptr(isolate, args[0]);\n    JS_ENSURE(isolate, result.second, \"Unable to cast \\\"handle\\\" to pointer. Please check if it's in valid format.\");\n\n    auto thisObject = NAPA_OBJECTWRAP::Unwrap<TransportContextWrap>(args.Holder());\n    auto object = thisObject->Get()->LoadShared<void>(result.first);\n\n    args.GetReturnValue().Set(binding::CreateShareableWrap(object));\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/transport-context-wrap-impl.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n#include <napa/module/transport-context-wrap.h>\n\nnamespace napa {\nnamespace module {\n    \n    /// <summary> It implements napa::module::TransportContextWrap. </summary>\n    /// <remarks> Reference: napajs/lib/transport/transportable.ts#TransportContext </remarks>\n    class TransportContextWrapImpl: public napa::module::TransportContextWrap {\n    public:\n        /// <summary> Init this wrap. </summary>\n        static void Init();\n\n        /// <summary> Create a non-owning transport context wrap. </summary>\n        static v8::Local<v8::Object> NewInstance(bool owning = true, napa::transport::TransportContext* context = nullptr);\n\n        /// <summary> Destructor. </summary>\n        ~TransportContextWrapImpl(); \n\n        /// <summary> Get transport context. </summary>\n        napa::transport::TransportContext* Get() override;\n\n        /// <summary> Declare constructor in public, so we can export class constructor to JavaScript world. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"TransportContextWrap\";\n\n    private:\n        /// <summary> Constructor. </summary>\n        TransportContextWrapImpl(napa::transport::TransportContext* context, bool owning);\n\n        /// <summary> No copy allowed. </summary>\n        TransportContextWrapImpl(const TransportContextWrapImpl&) = delete;\n        TransportContextWrapImpl& operator=(const TransportContextWrapImpl&) = delete;\n\n        /// <summary> TransportContextWrap.constructor </summary>\n        static void ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements TransportContext.sharedCount </summary>\n        static void GetSharedCountCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements TransportContext.saveShared(handle: Handle, object: napajs.memory.ShareableWrap) </summary>\n        static void SaveSharedCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> It implements TransportContext.loadShared(handle: Handle): napajs.memory.ShareableWrap) </summary>\n        static void LoadSharedCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Transport context. </summary>\n        napa::transport::TransportContext* _context;\n\n        /// <summary> Own context or not. </summary>\n        bool _owning;\n    };\n}\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/zone-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"zone-wrap.h\"\n\n#include \"transport-context-wrap-impl.h\"\n\n#include <napa/zone.h>\n#include <napa/assert.h>\n#include <napa/async.h>\n#include <napa/v8-helpers.h>\n\n#include <sstream>\n#include <vector>\n\nusing namespace napa::module;\nusing namespace napa::v8_helpers;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(ZoneWrap);\n\n// Forward declaration.\nstatic v8::Local<v8::Object> CreateResponseObject(const napa::Result& result);\ntemplate <typename Func>\nstatic void CreateRequestAndExecute(v8::Local<v8::Object> obj, Func&& func);\n\nvoid ZoneWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    // Prepare constructor template.\n    auto functionTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<ZoneWrap>);\n    functionTemplate->SetClassName(MakeV8String(isolate, exportName));\n    functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    // Prototypes.\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"getId\", GetId);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"broadcast\", Broadcast);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"broadcastSync\", BroadcastSync);\n    NODE_SET_PROTOTYPE_METHOD(functionTemplate, \"execute\", Execute);\n    NODE_SET_PROTOTYPE_METHOD(functionTemplate, \"executeSync\", ExecuteSync);\n\n    // Set persistent constructor into V8.\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, functionTemplate->GetFunction());\n}\n\nv8::Local<v8::Object> ZoneWrap::NewInstance(std::unique_ptr<napa::Zone> zoneProxy) {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto context = isolate->GetCurrentContext();\n\n    auto constructor = NAPA_GET_PERSISTENT_CONSTRUCTOR(exportName, ZoneWrap);\n    auto object = constructor->NewInstance(context).ToLocalChecked();\n    auto wrap = NAPA_OBJECTWRAP::Unwrap<ZoneWrap>(object);\n\n    wrap->_zoneProxy = std::move(zoneProxy);\n    return object;\n}\n\nvoid ZoneWrap::GetId(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    auto wrap = ObjectWrap::Unwrap<ZoneWrap>(args.Holder());\n\n    args.GetReturnValue().Set(MakeV8String(isolate, wrap->_zoneProxy->GetId()));\n}\n\nvoid ZoneWrap::Broadcast(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args[0]->IsObject(), \"first argument to zone.broadcast must be the function spec object\");\n    CHECK_ARG(isolate, args[1]->IsFunction(), \"second argument to zone.broadcast must be the callback\");\n    \n    v8::String::Utf8Value source(args[0]->ToString());\n\n    napa::zone::DoAsyncWork(v8::Local<v8::Function>::Cast(args[1]),\n        [&args](std::function<void(void*)> complete) {\n            CreateRequestAndExecute(args[0]->ToObject(), [&args, &complete](const napa::FunctionSpec& spec) {\n                auto wrap = ObjectWrap::Unwrap<ZoneWrap>(args.Holder());\n\n                wrap->_zoneProxy->Broadcast(spec, [complete = std::move(complete)](napa::Result result) {\n                    complete(new napa::Result(std::move(result)));\n                });\n            });\n        },\n        [](auto jsCallback, void* res) {\n            auto isolate = v8::Isolate::GetCurrent();\n            auto context = isolate->GetCurrentContext();\n\n            auto result = static_cast<napa::Result*>(res);\n\n            v8::HandleScope scope(isolate);\n\n            std::vector<v8::Local<v8::Value>> argv;\n            argv.emplace_back(CreateResponseObject(*result));\n\n            (void)jsCallback->Call(context, context->Global(), static_cast<int>(argv.size()), argv.data());\n\n            delete result;\n        }\n    );\n}\n\nvoid ZoneWrap::BroadcastSync(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args[0]->IsObject(), \"first argument to zone.broadcastSync must be the function spec object\");\n\n    CreateRequestAndExecute(args[0]->ToObject(), [&args](const napa::FunctionSpec& spec) {\n        auto wrap = ObjectWrap::Unwrap<ZoneWrap>(args.Holder());\n\n        napa::Result result = wrap->_zoneProxy->BroadcastSync(spec);\n        args.GetReturnValue().Set(CreateResponseObject(result));\n    });\n}\n\nvoid ZoneWrap::Execute(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args[0]->IsObject(), \"first argument to zone.execute must be the function spec object\");\n    CHECK_ARG(isolate, args[1]->IsFunction(), \"second argument to zone.execute must be the callback\");\n\n    napa::zone::DoAsyncWork(v8::Local<v8::Function>::Cast(args[1]),\n        [&args](std::function<void(void*)> complete) {\n            CreateRequestAndExecute(args[0]->ToObject(), [&args, &complete](const napa::FunctionSpec& spec) {\n                auto wrap = ObjectWrap::Unwrap<ZoneWrap>(args.Holder());\n\n                wrap->_zoneProxy->Execute(spec, [complete = std::move(complete)](napa::Result result) {\n                    complete(new napa::Result(std::move(result)));\n                });\n            });\n        },\n        [](auto jsCallback, void* res) {\n            auto isolate = v8::Isolate::GetCurrent();\n            auto context = isolate->GetCurrentContext();\n\n            auto result = static_cast<napa::Result*>(res);\n\n            v8::HandleScope scope(isolate);\n\n            std::vector<v8::Local<v8::Value>> argv;\n            argv.emplace_back(CreateResponseObject(*result));\n\n            (void)jsCallback->Call(context, context->Global(), static_cast<int>(argv.size()), argv.data());\n\n            delete result;\n        }\n    );\n}\n\nvoid ZoneWrap::ExecuteSync(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args[0]->IsObject(), \"first argument to zone.execute must be the function spec object\");\n\n    CreateRequestAndExecute(args[0]->ToObject(), [&args](const napa::FunctionSpec& spec) {\n        auto wrap = ObjectWrap::Unwrap<ZoneWrap>(args.Holder());\n\n        napa::Result result = wrap->_zoneProxy->ExecuteSync(spec);\n        args.GetReturnValue().Set(CreateResponseObject(result));\n    });\n}\n\nstatic v8::Local<v8::Object> CreateResponseObject(const napa::Result& result) {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto context = isolate->GetCurrentContext();\n\n    auto responseObject = v8::Object::New(isolate);\n\n    (void)responseObject->CreateDataProperty(\n        context,\n        MakeV8String(isolate, \"code\"),\n        v8::Uint32::NewFromUnsigned(isolate, result.code));\n\n    (void)responseObject->CreateDataProperty(\n        context,\n        MakeV8String(isolate, \"errorMessage\"),\n        MakeV8String(isolate, result.errorMessage));\n\n    (void)responseObject->CreateDataProperty(\n        context,\n        MakeV8String(isolate, \"returnValue\"),\n        MakeV8String(isolate, result.returnValue));\n\n    // Transport context handle\n    v8::Local<v8::Value> contextHandleValue;\n    auto transportContext = result.transportContext.release();\n    if (transportContext == nullptr) {\n        contextHandleValue = v8::Null(isolate);\n    } else {\n        contextHandleValue = PtrToV8Uint32Array(isolate, transportContext);\n    }\n    (void)responseObject->CreateDataProperty(\n        context,\n        MakeV8String(isolate, \"contextHandle\"),\n        contextHandleValue);\n\n    return responseObject;\n}\n\ntemplate <typename Func>\nstatic void CreateRequestAndExecute(v8::Local<v8::Object> obj, Func&& func) {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto context = isolate->GetCurrentContext();\n\n    napa::FunctionSpec spec;\n    \n    // module property is optional in a spec\n    Utf8String module;\n    auto maybe = obj->Get(context, MakeV8String(isolate, \"module\"));\n    if (!maybe.IsEmpty()) {\n        module = Utf8String(maybe.ToLocalChecked());\n        spec.module = NAPA_STRING_REF_WITH_SIZE(module.Data(), module.Length());\n    }\n\n    // function property is mandatory in a spec\n    maybe = obj->Get(context, MakeV8String(isolate, \"function\"));\n    CHECK_ARG(isolate, !maybe.IsEmpty(), \"function property is missing in function spec object\");\n\n    auto functionValue = maybe.ToLocalChecked();\n    CHECK_ARG(isolate, functionValue->IsString(), \"function property in function spec object must be a string\");\n\n    v8::String::Utf8Value function(functionValue->ToString());\n    spec.function = NAPA_STRING_REF_WITH_SIZE(*function, static_cast<size_t>(function.length()));\n\n    // arguments are optional in a spec\n    maybe = obj->Get(context, MakeV8String(isolate, \"arguments\"));\n    std::vector<Utf8String> arguments;\n    if (!maybe.IsEmpty()) {\n        arguments = V8ArrayToVector<Utf8String>(isolate, v8::Local<v8::Array>::Cast(maybe.ToLocalChecked()));\n\n        spec.arguments.reserve(arguments.size());\n        for (const auto& arg : arguments) {\n            spec.arguments.emplace_back(NAPA_STRING_REF_WITH_SIZE(arg.Data(), arg.Length()));\n        }\n    }\n\n    // options argument is optional.\n    maybe = obj->Get(context, MakeV8String(isolate, \"options\"));\n    if (!maybe.IsEmpty()) {\n        auto optionsValue = maybe.ToLocalChecked();\n        JS_ENSURE(isolate, optionsValue->IsObject(), \"argument 'options' must be an object.\");\n        auto options = v8::Local<v8::Object>::Cast(optionsValue);\n\n        // timeout is optional.\n        maybe = options->Get(context, MakeV8String(isolate, \"timeout\"));\n        if (!maybe.IsEmpty()) {\n            spec.options.timeout = maybe.ToLocalChecked()->Uint32Value(context).FromJust();\n        }\n\n        // transport option is optional.\n        maybe = options->Get(context, MakeV8String(isolate, \"transport\"));\n        if (!maybe.IsEmpty()) {\n            spec.options.transport = static_cast<napa::TransportOption>(maybe.ToLocalChecked()->Uint32Value(context).FromJust());\n        }\n    }\n\n    // transportContext property is mandatory in a spec\n    maybe = obj->Get(context, MakeV8String(isolate, \"transportContext\"));\n    CHECK_ARG(isolate, !maybe.IsEmpty(), \"transportContext property is missing in function spec object\");\n\n    // for broadcast(), we are not creating transportContext. The value of the property is set to null\n    // otherwise it should be an object.\n    auto transportContextValue = maybe.ToLocalChecked();\n    if (!transportContextValue->IsNull()) {\n        CHECK_ARG(isolate, transportContextValue->IsObject(), \"transportContext must be null or an object.\");\n        auto transportContextWrap = NAPA_OBJECTWRAP::Unwrap<TransportContextWrapImpl>(transportContextValue->ToObject());\n        spec.transportContext.reset(transportContextWrap->Get());\n    }\n\n    // Execute\n    func(spec);\n}\n"
  },
  {
    "path": "src/module/core-modules/napa/zone-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module.h>\n\n#include <memory>\n\n// Forward declare zone.\nnamespace napa {\n    class Zone;\n}\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> An object wrap to expose zone APIs. </summary>\n    class ZoneWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"ZoneWrap\";\n\n        /// <summary> Initializes the wrap. </summary>\n        static void Init();\n\n        /// <summary> Create a new ZoneWrap instance that wraps the provided proxy. </summary>\n        static v8::Local<v8::Object> NewInstance(std::unique_ptr<napa::Zone> zoneProxy);\n\n    private:\n\n        /// <summary> Declare persistent constructor to create Zone Javascript wrapper instance. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        std::unique_ptr<napa::Zone> _zoneProxy;\n\n        // ZoneWrap methods\n        static void GetId(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void Broadcast(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void BroadcastSync(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void Execute(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void ExecuteSync(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Friend default constructor callback. </summary>\n        template <typename WrapType>\n        friend void napa::module::DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n    };\n}\n}"
  },
  {
    "path": "src/module/core-modules/node/console.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"console.h\"\n\n#include <napa/module.h>\n\n#include <iostream>\n#include <sstream>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary> Log a message to console. </summary>\n    /// <param name=\"args\"> All arguments are converted to string and printed out to console. </param>\n    void LogCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n}   // End of anonymous namespace.\n\nvoid console::Init(v8::Local<v8::Object> exports) {\n    NAPA_SET_METHOD(exports, \"log\", LogCallback);\n}\n\nnamespace {\n\n    void LogCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        std::ostringstream oss;\n        for (int i = 0; i < args.Length(); ++i) {\n            v8::String::Utf8Value argument(args[i]->ToString());\n            oss << *argument << \" \";\n        }\n\n        std::string message = oss.str();\n        if (!message.empty()) {\n            message.pop_back();\n        }\n\n        std::cout << message << std::endl;\n\n        args.GetReturnValue().Set(args.Holder());\n    }\n\n}   // End of anonymous namespace."
  },
  {
    "path": "src/module/core-modules/node/console.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon to print a message to console. </summary>\nnamespace console {\n\n    /// <summary> Set console object as global variable of given context. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace console\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/core-modules/node/file-system-helpers.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#ifdef _MSC_VER\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n#include \"file-system-helpers.h\"\n#include <platform/filesystem.h>\n\n#include <algorithm>\n#include <functional>\n#include <memory>\n#include <sstream>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    std::string GetFileFullPath(const std::string& file) {\n        return filesystem::Path(file).Absolute().Normalize().String();\n    }\n\n}   // End of anonymous namespace.\n\nstd::string file_system_helpers::ReadFileSync(const std::string& filename) {\n    std::string fileFullPath = GetFileFullPath(filename);\n\n    FILE* source = fopen(fileFullPath.c_str(), \"rb\");\n    if (source == nullptr) {\n        std::ostringstream oss;\n        oss << \"Can't open for read \" << fileFullPath;\n        throw std::runtime_error(oss.str());\n    }\n\n    std::unique_ptr<FILE, std::function<void(FILE*)>> deferred(source, [](auto file) {\n        fclose(file);\n    });\n\n    fseek(source, 0, SEEK_END);\n    auto size = static_cast<size_t>(ftell(source));\n    rewind(source);\n\n    std::string content;\n    content.resize(size);\n\n    for (size_t i = 0; i < size; ) {\n        i += fread(&content[i], 1, size - i, source);\n        if (ferror(source) != 0) {\n            std::ostringstream oss;\n            oss << \"Can't read \" << fileFullPath;\n            throw std::runtime_error(oss.str());\n        }\n    }\n\n    return content;\n}\n\nvoid file_system_helpers::WriteFileSync(const std::string& filename, const char* data, size_t length) {\n    auto fileFullPath = GetFileFullPath(filename);\n    \n    FILE* target = fopen(fileFullPath.c_str(), \"wb\");\n    if (target == nullptr) {\n        std::ostringstream oss;\n        oss << \"Can't open for write \" << fileFullPath;\n        throw std::runtime_error(oss.str());\n    }\n\n    std::unique_ptr<FILE, std::function<void(FILE*)>> deferred(target, [](auto file) {\n        fclose(file);\n    });\n\n    for (size_t written = 0; written < length; ) {\n        written += fwrite(data + written, 1, length - written, target);\n        if (ferror(target) != 0) {\n            std::ostringstream oss;\n            oss << \"Can't write \" << fileFullPath;\n            throw std::runtime_error(oss.str());\n        }\n    }\n}\n\nvoid file_system_helpers::MkdirSync(const std::string& directory) {\n    filesystem::Path path(GetFileFullPath(directory));\n    if (!filesystem::IsDirectory(path) && !filesystem::MakeDirectory(path))\n    {\n        std::ostringstream oss;\n        oss << \"The directory: \" << directory << \" doesn't exist, and can't be created.\";\n        throw std::runtime_error(oss.str());\n    }\n}\n\nbool file_system_helpers::ExistsSync(const std::string& path) {\n    return filesystem::Exists(GetFileFullPath(path));\n}\n\nstd::vector<std::string> file_system_helpers::ReadDirectorySync(const std::string& directory) {\n    std::vector<std::string> names;\n    filesystem::PathIterator iterator(GetFileFullPath(directory));\n    while (iterator.Next()) {\n        names.emplace_back(iterator->Filename().String());\n    }\n    return names;\n}"
  },
  {
    "path": "src/module/core-modules/node/file-system-helpers.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <string>\n#include <vector>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Helper APIs for file system operations. </summary>\nnamespace file_system_helpers {\n\n    /// <summary> Read file synchronously. </summary>\n    /// <param name=\"filename\"> Filename to read. </param>\n    std::string ReadFileSync(const std::string& filename);\n\n    /// <summary> Write file synchronously. </summary>\n    /// <param name=\"filename\"> Filename to write. </param>\n    /// <param name=\"data\"> Buffer of data to write. </param>\n    /// <param name=\"length\"> Length of data to write. </param>\n    void WriteFileSync(const std::string& filename, const char* data, size_t length);\n\n    /// <summary> Make directory synchronously. </summary>\n    /// <param name=\"directory\"> Directory to make. </param>\n    void MkdirSync(const std::string& directory);\n\n    /// <summary> Check if a path exits synchronously. </summary>\n    /// <param name=\"path\"> Path to check. </param>\n    /// <returns> True if path exists. </returns>\n    bool ExistsSync(const std::string& path);\n\n    /// <summary> Read a directory synchronously. </summary>\n    /// <param name=\"directory\"> Directory to read. </param>\n    /// <returns> File and directory names except '.' and '..'. </returns>\n    std::vector<std::string> ReadDirectorySync(const std::string& directory);\n\n}   // End of namespace file_system_helpers\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/core-modules/node/file-system.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"file-system.h\"\n#include \"file-system-helpers.h\"\n\n#include <napa/module.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary> Read file synchronously. </summary>\n    /// <param name=\"args\"> It holds filename. </param>\n    void ReadFileSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Write file synchronously. </summary>\n    /// <param name=\"args\"> It holds filename and string to write. </param>\n    void WriteFileSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Make directory synchronously. </summary>\n    /// <param name=\"args\"> It holds directory to make. </param>\n    void MkdirSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Check if a path exits synchronously. </summary>\n    /// <param name=\"args\"> A string argument of path. </param>\n    void ExistsSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Read a directory synchronously. </summary>\n    /// <param name=\"args\"> A string argument of path. </param>\n    void ReaddirSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n}   // End of anonymous namespace.\n\nvoid file_system::Init(v8::Local<v8::Object> exports) {\n    NAPA_SET_METHOD(exports, \"readFileSync\", ReadFileSyncCallback);\n    NAPA_SET_METHOD(exports, \"writeFileSync\", WriteFileSyncCallback);\n    NAPA_SET_METHOD(exports, \"mkdirSync\", MkdirSyncCallback);\n    NAPA_SET_METHOD(exports, \"existsSync\", ExistsSyncCallback);\n    NAPA_SET_METHOD(exports, \"readdirSync\", ReaddirSyncCallback);\n}\n\nnamespace {\n\n    void ReadFileSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() > 0,\n            \"fs.readFileSync requires at least 1 argument.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsString(),\n            \"fs.readFileSync requires a string of file path as the 1st argument.\");\n\n        v8::String::Utf8Value filename(args[0]);\n\n        try {\n            auto content = file_system_helpers::ReadFileSync(*filename);\n            args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, content));\n        } catch (const std::exception& ex) {\n            isolate->ThrowException(v8::Exception::Error(v8_helpers::MakeV8String(isolate, ex.what())));\n            args.GetReturnValue().SetUndefined();\n        }\n    }\n\n    void WriteFileSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() >= 2,\n            \"fs.writeFileSync requires 2 parameters.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsString(),\n            \"fs.writeFileSync requires a string as the 1st parameter for file name.\");\n\n        CHECK_ARG(isolate,\n            args[1]->IsString(),\n            \"fs.writeFileSync require a string as the 2nd parameter for data to write.\");\n            \n        v8::String::Utf8Value fileName(args[0]);\n        v8::String::Utf8Value content(args[1]);\n\n        try {\n            file_system_helpers::WriteFileSync(std::string(*fileName), *content, static_cast<size_t>(content.length()));\n        } catch (const std::exception& ex) {\n            isolate->ThrowException(v8::Exception::Error(v8_helpers::MakeV8String(isolate, ex.what())));\n        }\n    }\n\n    void MkdirSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() >= 1,\n            \"fs.mkdirFileSync requires 1 parameters.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsString(),\n            \"fs.mkdirFileSync requires a string as the 1st parameter for the directory.\");\n            \n        v8::String::Utf8Value directory(args[0]);\n\n        try {\n            file_system_helpers::MkdirSync(std::string(*directory));\n        } catch (const std::exception& ex) {\n            isolate->ThrowException(v8::Exception::Error(v8_helpers::MakeV8String(isolate, ex.what())));\n        }\n    }\n\n    void ExistsSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() >= 1,\n            \"fs.existsSync requires 1 parameters.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsString(),\n            \"fs.existsSync requires a string as the 1st parameter for the path to check.\");\n            \n        v8::String::Utf8Value path(args[0]);\n        auto exists = file_system_helpers::ExistsSync(std::string(*path));\n\n        args.GetReturnValue().Set(exists);\n    }\n\n    void ReaddirSyncCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() >= 1,\n            \"fs.readdirSync requires 1 parameters.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsString(),\n            \"fs.readdirSync requires a string as the 1st parameter for the path to check.\");\n\n        v8::String::Utf8Value directory(args[0]);\n        auto names = file_system_helpers::ReadDirectorySync(std::string(*directory));\n\n        auto context = isolate->GetCurrentContext();\n        auto count = static_cast<uint32_t>(names.size());\n        auto result = v8::Array::New(isolate, count);\n\n        for (uint32_t i = 0; i < count; ++i) {\n            (void)result->CreateDataProperty(context, i, v8_helpers::MakeV8String(isolate, names[i]));\n        }\n            \n        args.GetReturnValue().Set(result);\n    }\n\n}   // End of anonymous namespace."
  },
  {
    "path": "src/module/core-modules/node/file-system.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <string>\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon for file system operations. </summary>\nnamespace file_system {\n\n    /// <summary> Set file system object. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace file_system\n}   // End of namespace module\n}   // End of namespace napa"
  },
  {
    "path": "src/module/core-modules/node/os.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"os.h\"\n\n#include <napa/module.h>\n#include <platform/os.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nvoid TypeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, platform::GetOSType()));\n}\n\nvoid os::Init(v8::Local<v8::Object> exports) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto context = isolate->GetCurrentContext();\n\n    NAPA_SET_METHOD(exports, \"type\", TypeCallback);\n}"
  },
  {
    "path": "src/module/core-modules/node/os.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon for operating system. </summary>\nnamespace os {\n\n    /// <summary> Set os object. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace os\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/core-modules/node/path.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"path.h\"\n\n#include <napa/module.h>\n#include <platform/filesystem.h>\n#include <platform/os.h>\n\n#include <string>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary>\n    /// Normalize a path by removing '.' and '..' and use preferred separator. (windows in \\\\ and posix in /).\n    /// Example:\n    /// path.normalize('c:/foo\\\\bar/.././baz/.')\n    /// // returns 'c:\\\\foo\\\\baz'.\n    /// </summary>\n    /// <param name=\"args\"> A sequence of paths to resolve. </param>\n    void NormalizeCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Resolve a sequence of paths to one absolute path.\n    /// Example:\n    /// path.resolve('c:/foo\\\\bar', '.\\\\baz')\n    /// // returns 'c:\\\\foo\\\\bar\\\\baz'.\n    ///\n    /// path.resolve('c:\\\\foo/bar', 'd:/tmp/file/')\n    /// // returns 'd:\\\\tmp\\\\file'.\n    ///\n    /// path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')\n    /// // if the current working directory is c:\\\\home\\\\myself\\\\node,\n    /// // this returns 'c:\\\\home\\\\myself\\\\node\\\\wwwroot\\\\static_files\\\\gif\\\\image.gif'.\n    /// </summary>\n    /// <param name=\"args\"> A sequence of paths to resolve. </param>\n    void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Join a sequence of paths to one.\n    /// Example:\n    /// path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')\n    /// // returns '/foo/bar/baz/asdf'\n    /// </summary>\n    /// <param name=\"args\"> A sequence of paths to join. </param>\n    void JoinCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Parent directory name of a file name.\n    /// Example:\n    /// path.dirname('c:/foo\\\\bar\\\\baz/asdf\\\\quux')\n    /// // returns 'c:\\\\foo\\\\bar\\\\baz\\\\asdf'.\n    /// // even quux is a directory. The behavior is the same with Node.JS.\n    /// </summary>\n    /// <param name=\"args\">1 Argument of file path. </param>\n    void DirnameCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Base name of a file path.\n    /// Example:\n    /// path.basename('c:\\\\foo/bar/baz/asdf\\\\quux.html')\n    /// // returns 'quux.html'.\n    /// path.basename('c:/foo\\\\bar/baz/asdf/quux.html', '.html')\n    /// // returns 'quux'.\n    /// </summary>\n    /// <param name=\"args\"> 1 required argument of file path and another optional argument of extension. </param>\n    void BasenameCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Extension of a file path.\n    /// Example:\n    /// path.extname('index.html')\n    /// // returns '.html'.\n    ///\n    /// path.extname('index.coffee.md')\n    /// // returns '.md'.\n    ///\n    /// path.extname('index.')\n    /// // returns '.'.\n    ///\n    /// path.extname('index')\n    /// // returns ''.\n    /// </summary>\n    /// <param name=\"args\"> 1 argument of file path. </param>\n    void ExtnameCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Check if a path is an absolute path or not.\n    /// Example:\n    /// path.isAbsolute('c:/foo/bar') // returns true.\n    /// path.isAbsolute('c:\\\\baz/..')  // returns true.\n    /// path.isAbsolute('qux/')     // returns false.\n    /// path.isAbsolute('.')        // returns false.\n    /// </summary>\n    /// <param name=\"args\"> 1 argument of file path. </param>\n    void IsAbsoluteCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary>\n    /// Get relative path from the first path to the second.\n    /// Example:\n    /// path.relative('c:/foo\\\\bar', 'c:/foo/abc.txt')\n    /// // returns '..\\\\abc.txt'.\n    ///\n    /// path.relative('c:/foo\\\\../bar', 'c:/bar')\n    /// // returns '.'.\n    ///\n    /// path.relative('c:\\\\foo', 'c:/')\n    /// // returns '..'.\n    ///\n    /// path.relative('c:\\\\foo', 'd:\\\\bar')\n    /// // returns 'd:\\\\bar'.\n    /// </summary>\n    /// <param name=\"args\"> 2 strings represent from-path and to-path. </param>\n    void RelativeCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n}   // End of anonymous namespace.\n\nvoid path::Init(v8::Local<v8::Object> exports) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto context = isolate->GetCurrentContext();\n\n    NAPA_SET_METHOD(exports, \"normalize\", NormalizeCallback);\n    NAPA_SET_METHOD(exports, \"resolve\", ResolveCallback);\n    NAPA_SET_METHOD(exports, \"join\", JoinCallback);\n    NAPA_SET_METHOD(exports, \"dirname\", DirnameCallback);\n    NAPA_SET_METHOD(exports, \"basename\", BasenameCallback);\n    NAPA_SET_METHOD(exports, \"extname\", ExtnameCallback);\n    NAPA_SET_METHOD(exports, \"isAbsolute\", IsAbsoluteCallback);\n    NAPA_SET_METHOD(exports, \"relative\", RelativeCallback);\n\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"sep\"),\n                                      v8_helpers::MakeV8String(isolate, platform::DIR_SEPARATOR));\n}\n\nnamespace {\n\n    void NormalizeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsString() ,\n            \"path.normalize requires 1 string parameter of file path.\");\n        \n        v8::String::Utf8Value utf8Path(args[0]);\n        auto path = filesystem::Path(*utf8Path).Normalize();\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, path.String()));\n    }\n\n    void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() > 0,\n            \"path.resolve requires at least one string parameters.\");\n\n        auto path = filesystem::CurrentDirectory();\n\n        for (int i = 0; i < args.Length(); ++i) {\n            CHECK_ARG(isolate,\n                args[i]->IsString(),\n                \"path.resolve doesn't accept non-string argument.\");\n            \n            v8::String::Utf8Value nextPath(args[i]);\n            path /= *nextPath;\n        }\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, path.Absolute().Normalize().String()));\n    }\n\n    void JoinCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() > 0 && args[0]->IsString(),\n            \"path.join requires at least one string parameters.\");\n\n        v8::String::Utf8Value basePath(args[0]);\n        auto path = filesystem::Path(*basePath);\n\n        for (int i = 1; i < args.Length(); ++i) {\n            CHECK_ARG(isolate,\n                args[i]->IsString(),\n                \"path.join doesn't accept non-string argument.\");\n            \n            v8::String::Utf8Value nextPath(args[i]);\n            path /= *nextPath;\n        }\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, path.Normalize().String()));\n    }\n\n    void DirnameCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsString(),\n            \"path.dirname requires 1 string parameter of file path.\");\n        \n        v8::String::Utf8Value utf8Path(args[0]);\n        auto path = filesystem::Path(*utf8Path);\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, path.Dirname().String()));\n    }\n\n    void BasenameCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 || args.Length() == 2,\n            \"path.basename takes 1 required argument of file path and 1 optional argument of extension\");\n        \n        CHECK_ARG(isolate,\n            args[0]->IsString() ,\n            \"path.basename requires a string parameter of file path.\");\n        \n        v8::String::Utf8Value utf8Path(args[0]);\n        auto fileName = filesystem::Path(*utf8Path).Filename().String();\n        if (args.Length() == 2) {\n            CHECK_ARG(isolate,\n                args[1]->IsString() ,\n                \"path.basename requires a string as 2nd parameter of extension.\");\n\n            v8::String::Utf8Value extension(args[1]);\n            auto pos = fileName.find(*extension);\n            if (pos != std::string::npos) {\n                fileName = fileName.substr(0, pos);\n            }\n        }\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, fileName));\n    }\n\n    void ExtnameCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsString(),\n            \"path.extname requires 1 string parameter of file path.\");\n        \n        v8::String::Utf8Value utf8Path(args[0]);\n        auto path = filesystem::Path(*utf8Path);\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, path.Extension().String()));\n    }\n\n    void IsAbsoluteCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsString() ,\n            \"path.isAbsolute requires 1 string parameter of file path.\");\n        \n        v8::String::Utf8Value utf8Path(args[0]);\n        auto path = filesystem::Path(*utf8Path);\n        args.GetReturnValue().Set(path.IsAbsolute());\n    }\n\n    void RelativeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 2 && args[0]->IsString() && args[1]->IsString(),\n            \"path.relative requires 2 arguments of string type.\");\n\n        v8::String::Utf8Value from(args[0]);\n        v8::String::Utf8Value to(args[1]);\n\n        auto relativePath = filesystem::Path(*to).Relative(*from);\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, relativePath.String()));\n    }\n\n}   // End of anonymous namespace."
  },
  {
    "path": "src/module/core-modules/node/path.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon for path operations. </summary>\nnamespace path {\n\n    /// <summary> Set path object. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace path\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/core-modules/node/process.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"process.h\"\n\n#include <napa/module.h>\n#include <platform/filesystem.h>\n#include <platform/os.h>\n#include <platform/process.h>\n\n#include <chrono>\n#include <iostream>\n#include <sstream>\n\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary> Callback to cwd(). </summary>\n    void CwdCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Callback to chdir(). </summary>\n    void ChdirCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Callback to exit process. </summary>\n    void ExitCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Callback to hrtime. </summary>\n    void HrtimeCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Callback to umask. </summary>\n    void UmaskCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Environment variable getter. </summary>\n    void EnvGetterCallback(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>&);\n\n    /// <summary> Environment variable setter. </summary>\n    void EnvSetterCallback(v8::Local<v8::String>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<v8::Value>&);\n\n}   // End of anonymous namespace.\n\nvoid process::Init(v8::Local<v8::Object> exports) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto context = isolate->GetCurrentContext();\n\n    NAPA_SET_METHOD(exports, \"cwd\", CwdCallback);\n    NAPA_SET_METHOD(exports, \"chdir\", ChdirCallback);\n    NAPA_SET_METHOD(exports, \"exit\", ExitCallback);\n    NAPA_SET_METHOD(exports, \"hrtime\", HrtimeCallback);\n    NAPA_SET_METHOD(exports, \"umask\", UmaskCallback);\n\n    auto argc = platform::GetArgc();\n    auto argv = platform::GetArgv();\n    auto arguments = v8::Array::New(isolate, argc);\n    for (int i = 0; i < argc; ++i) {\n        (void)arguments->CreateDataProperty(context, i, v8_helpers::MakeV8String(isolate, argv[i]));\n    }\n    (void)exports->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"argv\"), arguments);\n\n    auto envObjectTemplate = v8::ObjectTemplate::New(isolate);\n    envObjectTemplate->SetNamedPropertyHandler(EnvGetterCallback, EnvSetterCallback);\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"env\"),\n                                      envObjectTemplate->NewInstance());\n\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"platform\"),\n                                      v8_helpers::MakeV8String(isolate, platform::PLATFORM));\n\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"version\"),\n                                      v8_helpers::MakeV8String(isolate, std::to_string(MODULE_VERSION)));\n\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"execPath\"),\n                                      v8_helpers::MakeV8String(isolate, filesystem::ProgramPath().String()));\n\n    (void)exports->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"pid\"),\n                                      v8::Integer::New(isolate, platform::Getpid()));\n}\n\nnamespace {\n\n    void CwdCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, \n            filesystem::CurrentDirectory().String()));\n    }\n\n    void ChdirCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsString(),\n            \"process.chdir requires a string parameter.\");\n\n        v8::String::Utf8Value dirname(args[0]);\n        filesystem::Path dir(*dirname);\n        JS_ENSURE(isolate, filesystem::IsDirectory(dir), \"Directory \\\"%s\\\" doesn't exist\", dir.c_str());\n\n        filesystem::SetCurrentDirectory(dir);\n\n        args.GetReturnValue().SetUndefined();\n    }\n\n    void ExitCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1,\n            \"process.exit requires 1 int32 parameter as exit code.\");\n\n        CHECK_ARG(isolate,\n            args[0]->IsInt32(),\n            \"Exit code must be integer.\");\n\n        std::exit(args[0]->Int32Value());\n    }\n\n    void HrtimeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n        auto context = isolate->GetCurrentContext();\n\n        // Returns the current time in nanoseconds\n        uint64_t time = std::chrono::high_resolution_clock::now().time_since_epoch().count();\n\n        if (args.Length() == 1) {\n            auto result = v8_helpers::V8Uint32ArrayToHrtime(isolate, args[0]);\n            JS_ENSURE(isolate, result.second, \"The 1st argument of hrtime must be a two-element uint32 array.\");\n\n            // Calculate the delta\n            time -= result.first;\n        }\n        args.GetReturnValue().Set(v8_helpers::HrtimeToV8Uint32Array(isolate, time));\n    }\n\n    void UmaskCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        if (args.Length() == 0 || args[0]->IsUndefined()) {\n            auto old = platform::Umask(0);\n            platform::Umask(old);\n            args.GetReturnValue().Set(old);\n            return;\n        }\n        \n        CHECK_ARG(isolate,\n            args[0]->IsInt32() || args[0]->IsString(),\n            \"Argument must be an integer or octal string\");\n\n        int32_t value = 0;\n        if (args[0]->IsInt32()) {\n            // Integer.\n            value = args[0]->Int32Value();\n        } else {\n            // Octal string.\n            v8::String::Utf8Value arg(args[0]);\n            value = std::strtol(*arg, nullptr, 8);\n        }\n\n        auto old = platform::Umask(value);\n        args.GetReturnValue().Set(old);\n    }\n\n    void EnvGetterCallback(v8::Local<v8::String> propertyKey, const v8::PropertyCallbackInfo<v8::Value>& info) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        v8::String::Utf8Value key(propertyKey);\n        auto value = platform::GetEnv(*key);\n\n        if (value.empty()) {\n            info.GetReturnValue().SetUndefined();\n        } else {\n            info.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, value));\n        }\n    }\n\n    void EnvSetterCallback(v8::Local<v8::String> propertyKey,\n                           v8::Local<v8::Value> propertyValue,\n                           const v8::PropertyCallbackInfo<v8::Value>& info) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        v8::String::Utf8Value key(propertyKey);\n        v8::String::Utf8Value value(propertyValue);\n        platform::SetEnv(*key, *value);\n\n        info.GetReturnValue().Set(propertyValue);\n    }\n\n}   // End of anonymous namespace."
  },
  {
    "path": "src/module/core-modules/node/process.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon to provide helper APIs for process. </summary>\nnamespace process {\n\n    /// <summary> Set process object as global variable of given context. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace process\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/core-modules/node/tty-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"tty-wrap.h\"\n\n#include <napa/module.h>\n#include <platform/process.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary> Callback to isTTY(). </summary>\n    void IsTTYCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n    /// <summary> Callback to guessHandleType(). </summary>\n    void GuessHandleTypeCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n\n}   // End of anonymous namespace.\n\nvoid tty_wrap::Init(v8::Local<v8::Object> exports) {\n    NAPA_SET_METHOD(exports, \"isTTY\", IsTTYCallback);\n    NAPA_SET_METHOD(exports, \"guessHandleType\", GuessHandleTypeCallback);\n}\n\nnamespace {\n\n    void IsTTYCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsInt32(),\n            \"tty_wrap.isTTY requires a file descriptor\");\n\n        int32_t fd = args[0]->Int32Value();\n        CHECK_ARG(isolate, fd >= 0, \"Invalid file descriptor\");\n\n        args.GetReturnValue().Set(platform::Isatty(fd) > 0);\n    }\n\n    void GuessHandleTypeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        CHECK_ARG(isolate,\n            args.Length() == 1 && args[0]->IsInt32(),\n            \"tty_wrap.getHandleType requires a integer parameter\");\n\n        int32_t fd = args[0]->Int32Value();\n        CHECK_ARG(isolate, fd >= 0, \"Invalid file descriptor\");\n\n        // Napa doesn't have any information about handle type, so return as unknown handle.\n        args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, \"UNKNOWN\"));\n    }\n\n}   // End of anonymous namespace."
  },
  {
    "path": "src/module/core-modules/node/tty-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace module {\n\n/// <summary> Napa built-in addon to provide helper APIs for text terminal. </summary>\nnamespace tty_wrap {\n\n    /// <summary> Set tty object as global variable of given context. </summary>\n    /// <param name=\"exports\"> Object to set module. </param>\n    void Init(v8::Local<v8::Object> exports);\n\n}   // End of namespace tty_wrap\n}   // End of namespace module\n}   // End of namespace napa\n"
  },
  {
    "path": "src/module/loader/binary-module-loader.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"binary-module-loader.h\"\n#include \"module-loader-helpers.h\"\n\n#include <napa/v8-helpers.h>\n\n#include <platform/dll.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nBinaryModuleLoader::BinaryModuleLoader(BuiltInModulesSetter builtInModulesSetter)\n    : _builtInModulesSetter(std::move(builtInModulesSetter)) {}\n\nbool BinaryModuleLoader::TryGet(const std::string& path, v8::Local<v8::Value> /*arg*/, v8::Local<v8::Object>& module) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    auto library = std::make_shared<dll::SharedLibrary>(path);\n    auto napaModule = library->Import<NapaModule>(napa::module::NAPA_MODULE_EXPORT);\n\n    JS_ENSURE_WITH_RETURN(isolate,\n                          napaModule != nullptr,\n                          false,\n                          \"Can't import napa module: \\\"%s\\\"\", \n                          path.c_str());\n\n    JS_ENSURE_WITH_RETURN(isolate,\n                          napaModule->version == MODULE_VERSION,\n                          false,\n                          \"Module version is not compatible: \\\"%s\\\"\",\n                          path.c_str());\n\n    _modules.push_back(library);\n\n    auto context = isolate->GetCurrentContext();\n\n    auto moduleContext = v8::Context::New(isolate);\n    JS_ENSURE_WITH_RETURN(isolate, !moduleContext.IsEmpty(), false, \"Can't create module context for \\\"%s\\\"\", path.c_str());\n\n    // We set an empty security token so callee can access caller's context.\n    moduleContext->SetSecurityToken(v8::Undefined(isolate));\n    v8::Context::Scope contextScope(moduleContext);\n\n    module_loader_helpers::SetupModuleContext(context, moduleContext, path);\n\n    _builtInModulesSetter(moduleContext);\n\n    module = scope.Escape(module_loader_helpers::ExportModule(moduleContext->Global(), napaModule->initializer));\n    return true;\n}"
  },
  {
    "path": "src/module/loader/binary-module-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"module-file-loader.h\"\n#include \"platform/dll.h\"\n\n#include <memory>\n#include <string>\n#include <vector>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> It loads a module from binary file. </summary>\n    class BinaryModuleLoader : public ModuleFileLoader {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"builtInSetter\"> Built-in modules registerer. </param>\n        BinaryModuleLoader(BuiltInModulesSetter builtInModulesSetter);\n\n        /// <summary> It loads a module from binary file. </summary>\n        /// <param name=\"path\"> Module path called by require(). </param>\n        /// <param name=\"arg\"> Argument for loading the file. Passed through as arg1 from require. </param>\n        /// <param name=\"module\"> Loaded binary module if successful. </param>\n        /// <returns> True if binary module is loaded, false otherwise. </returns>\n        bool TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) override;\n\n    private:\n\n        /// Built-in modules registerer.\n        BuiltInModulesSetter _builtInModulesSetter;\n\n        /// <summary> It keeps binary modules loaded. </summary>\n        std::vector<std::shared_ptr<dll::SharedLibrary>> _modules;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/core-module-loader.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"core-module-loader.h\"\n#include \"javascript-module-loader.h\"\n#include \"module-cache.h\"\n#include \"module-loader-helpers.h\"\n\n#include <platform/filesystem.h>\n\n#include <sstream>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    const std::string CORE_MODULE_EXTENSION = \".js\";\n    const std::string CORE_MODULE_DIRECTORY = \"lib\\\\core\";\n\n}   // End of anonymous namespace.\n\nCoreModuleLoader::CoreModuleLoader(BuiltInModulesSetter builtInModulesSetter,\n                                   ModuleCache& moduleCache,\n                                   ModuleCache& bindingCache)\n    : JavascriptModuleLoader(std::move(builtInModulesSetter), moduleCache), _bindingCache(bindingCache) {}\n                                \nbool CoreModuleLoader::TryGet(const std::string& name, v8::Local<v8::Value> /*arg*/, v8::Local<v8::Object>& module) {\n    filesystem::Path basePath(module_loader_helpers::GetNapaRuntimeDirectory());\n    auto fileName = name + CORE_MODULE_EXTENSION;\n\n    // Check ./lib or ../lib directory only\n    auto fullPath = basePath / CORE_MODULE_DIRECTORY / fileName;\n    if (filesystem::IsRegularFile(fullPath)) {\n        // Load javascript core module from a file at ./lib directory.\n        return JavascriptModuleLoader::TryGet(fullPath.String(), v8::Local<v8::Value>(), module);\n    }\n\n    fullPath = (basePath.Parent() / CORE_MODULE_DIRECTORY / fileName).Normalize();\n    if (filesystem::IsRegularFile(fullPath)) {\n        // Load javascript core module from a file at ../lib directory.\n        return JavascriptModuleLoader::TryGet(fullPath.String(), v8::Local<v8::Value>(), module);\n    }\n\n    // Return binary core module if exists.\n    return _bindingCache.TryGet(name, module);\n}"
  },
  {
    "path": "src/module/loader/core-module-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"javascript-module-loader.h\"\n\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> It loads a core module. </summary>\n    class CoreModuleLoader : public JavascriptModuleLoader {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"builtInSetter\"> Built-in modules registerer. </param>\n        /// <param name=\"moduleCache\"> Cache for all modules. </param>\n        /// <param name=\"bindingCache\"> Cache for binding core binary modules. </param>\n        CoreModuleLoader(BuiltInModulesSetter builtInModulesSetter,\n                         ModuleCache& moduleCache,\n                         ModuleCache& bindingCache);\n\n        /// <summary> It loads a core module. </summary>\n        /// <param name=\"name\"> Core module name. </param>\n        /// <param name=\"arg\"> Argument for loading the file. Passed through as arg1 from require. </param>\n        /// <param name=\"module\"> Loaded core module if successful. </param>\n        /// <returns> True if core module is loaded, false otherwise. </returns>\n        bool TryGet(const std::string& name, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) override;\n\n    private:\n\n        /// Cache instance for binding binary core modules.\n        ModuleCache& _bindingCache;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/javascript-module-loader.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"javascript-module-loader.h\"\n#include \"module-cache.h\"\n#include \"module-loader-helpers.h\"\n\n#include <napa/v8-helpers.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nJavascriptModuleLoader::JavascriptModuleLoader(BuiltInModulesSetter builtInModulesSetter, ModuleCache& moduleCache)\n    : _builtInModulesSetter(std::move(builtInModulesSetter)) , _moduleCache(moduleCache) {}\n\nbool JavascriptModuleLoader::TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    bool fromContent = !arg.IsEmpty();\n    v8::Local<v8::String> source;\n\n    if (!fromContent) {\n        source = module_loader_helpers::ReadModuleFile(path);\n        JS_ENSURE_WITH_RETURN(isolate, !source.IsEmpty(), false, \"Can't read Javascript module: \\\"%s\\\"\", path.c_str());\n    } else {\n        JS_ENSURE_WITH_RETURN(isolate, arg->IsString(), false, \"The 2nd argument of 'require' must be content of string type.\");\n        source = v8::Local<v8::String>::Cast(arg);\n    }\n\n    auto context = isolate->GetCurrentContext();\n\n    auto moduleContext = v8::Context::New(isolate);\n    JS_ENSURE_WITH_RETURN(isolate, !moduleContext.IsEmpty(), false, \"Can't create module context for: \\\"%s\\\"\", path.c_str());\n\n    // We set an empty security token so callee can access caller's context.\n    moduleContext->SetSecurityToken(v8::Undefined(isolate));\n    v8::Context::Scope contextScope(moduleContext);\n\n    module_loader_helpers::SetupModuleContext(context, moduleContext, path);\n\n    _builtInModulesSetter(moduleContext);\n\n    // To prevent cycle, cache unloaded module first.\n    if (!fromContent) {\n        _moduleCache.Upsert(path, module_loader_helpers::ExportModule(moduleContext->Global(), nullptr));\n    }\n\n    v8::TryCatch tryCatch(isolate);\n    {\n        auto origin = v8::ScriptOrigin(v8_helpers::MakeV8String(isolate, path));\n\n        // The wrapper set 'this' reference to module.exports in module's top level code\n        v8::Local<v8::String> wrappedSource = v8::String::Concat(\n            v8_helpers::MakeV8String(isolate, \"(function(){\"),\n            v8::String::Concat(\n                source,\n                v8_helpers::MakeV8String(isolate, \"}).apply(module.exports);\")\n            )\n        );\n        auto script = v8::Script::Compile(wrappedSource, &origin);\n        if (script.IsEmpty() || tryCatch.HasCaught()) {\n            tryCatch.ReThrow();\n            return false;\n        }\n\n        auto run = script->Run();\n        if (run.IsEmpty() || tryCatch.HasCaught()) {\n            tryCatch.ReThrow();\n            return false;\n        }\n    }\n\n    // Export a loaded module.\n    module = scope.Escape(module_loader_helpers::ExportModule(moduleContext->Global(), nullptr));\n    return true;\n}"
  },
  {
    "path": "src/module/loader/javascript-module-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"module-file-loader.h\"\n\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    // forward declaration.\n    class ModuleCache;\n\n    /// <summary> It loads a module from javascript file or content from arg. </summary>\n    class JavascriptModuleLoader : public ModuleFileLoader {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"builtInSetter\"> Built-in modules registerer. </param>\n        /// <param name=\"moduleCache\"> Cache for all modules. </param>\n        JavascriptModuleLoader(BuiltInModulesSetter builtInModulesSetter, ModuleCache& moduleCache);\n\n        /// <summary> It loads a module from javascript file. </summary>\n        /// <param name=\"path\"> Module path called by require(). </param>\n        /// <param name=\"arg\"> Argument for loading the file. Passed through as arg1 from require. </param>\n        /// <param name=\"module\"> Loaded javascript module if successful. </param>\n        /// <returns> True if the javascript module is loaded, false otherwise. </returns>\n        bool TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) override;\n\n    private:\n\n        /// Built-in modules registerer.\n        BuiltInModulesSetter _builtInModulesSetter;\n\n        /// Module cache instance.\n        ModuleCache& _moduleCache;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/json-module-loader.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"json-module-loader.h\"\n#include \"module-loader-helpers.h\"\n\n#include <napa/v8-helpers.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nbool JsonModuleLoader::TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    auto source = module_loader_helpers::ReadModuleFile(path);\n    JS_ENSURE_WITH_RETURN(isolate, !source.IsEmpty(), false, \"Can't read JSON module: \\\"%s\\\"\", path.c_str());\n\n    auto json = v8::JSON::Parse(isolate, source).ToLocalChecked();\n    JS_ENSURE_WITH_RETURN(isolate, !json.IsEmpty(), false, \"Can't parse JSON from \\\"%s\\\"\", path.c_str());\n\n    module = scope.Escape(json->ToObject(isolate->GetCurrentContext()).ToLocalChecked());\n    return true;\n}\n"
  },
  {
    "path": "src/module/loader/json-module-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"module-file-loader.h\"\n\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> It loads an object from json file. </summary>\n    class JsonModuleLoader : public ModuleFileLoader {\n    public:\n\n        /// <summary> It loads an object from json file. </summary>\n        /// <param name=\"path\"> Module path called by require(). </param>\n        /// <param name=\"arg\"> Argument for loading the file. Passed through as arg1 from require. </param>\n        /// <param name=\"module\"> Loaded object if successful. </param>\n        /// <returns> True if the object is loaded, false otherwise. </returns>\n        bool TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) override;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/module-cache.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"module-cache.h\"\n\n#include <unordered_map>\n\nusing namespace napa;\nusing namespace napa::module;\n\nusing PersistentModule = v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>;\nusing PersistentModuleCache = std::unordered_map<std::string, PersistentModule>;\n\nstruct ModuleCache::ModuleCacheImpl {\n    /// <summary> Module cache to avoid module loading overhead. </summary>\n    PersistentModuleCache moduleCache;\n};\n\nModuleCache::ModuleCache() : _impl(std::make_unique<ModuleCache::ModuleCacheImpl>()) {}\n\nModuleCache::~ModuleCache() = default;\n\nstd::string NormalizeCacheKey(const std::string& path) {\n    #ifdef _WIN32\n    // Remove UNC prefix if present.\n    if (path.substr(0, 4) == \"\\\\\\\\?\\\\\") {\n        return path.substr(4);\n    }\n    #endif\n    return path;\n}\n\nvoid ModuleCache::Upsert(const std::string& path, v8::Local<v8::Object> module) {\n    if (module.IsEmpty()) {\n        return;\n    }\n\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto key = NormalizeCacheKey(path);\n    auto iter = _impl->moduleCache.find(key);\n    if (iter != _impl->moduleCache.end()) {\n        // If exists, reset it and override with new module.\n        iter->second.Reset();\n        iter->second = PersistentModule(isolate, module);\n    } else {\n        _impl->moduleCache.emplace(std::piecewise_construct,\n                                   std::forward_as_tuple(key),\n                                   std::forward_as_tuple(isolate, module));\n    }\n}\n\nbool ModuleCache::TryGet(const std::string& path, v8::Local<v8::Object>& module) const {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    auto key = NormalizeCacheKey(path);\n    auto iter = _impl->moduleCache.find(key);\n    if (iter == _impl->moduleCache.end()) {\n        return false;\n    }\n\n    module = v8::Local<v8::Object>::New(isolate, iter->second);\n    return true;\n}"
  },
  {
    "path": "src/module/loader/module-cache.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/module-internal.h>\n\n#include <memory>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary> Module cache to avoid module loading overhead. </summary>\n    class ModuleCache {\n    public:\n\n        /// <summary> Constructor. </summary>\n        ModuleCache();\n\n        /// <summary> Default destructor. </summary>\n        ~ModuleCache();\n\n        /// <summary> Non-copyable. </summary>\n        ModuleCache(const ModuleCache&) = delete;\n        ModuleCache& operator=(const ModuleCache&) = delete;\n\n        /// <summary> Movable. </summary>\n        ModuleCache(ModuleCache&&) = default;\n        ModuleCache& operator=(ModuleCache&&) = default;\n\n        /// <summary> It inserts or updates a module into cache using path as a key. </summary>\n        /// <param name=\"path\"> The module name path. </param>\n        /// <param name=\"module\"> V8 representative javascript object to be cached. </param>\n        void Upsert(const std::string& path, v8::Local<v8::Object> module);\n\n        /// <summary> A helper to load a module from cache. </summary>\n        /// <param name=\"path\"> Full path of javascript or napa module. </param>\n        /// <param name=\"module\"> Cached module if successful. </param>\n        /// <returns> True if it finds successfully. False, otherwise. </returns>\n        bool TryGet(const std::string& path, v8::Local<v8::Object>& module) const;\n\n    private:\n\n        /// <summary> Implementation of module cache. </summary>\n        struct ModuleCacheImpl;\n        std::unique_ptr<ModuleCacheImpl> _impl;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/module-file-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/module-internal.h>\n\n#include <functional>\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    using BuiltInModulesSetter = std::function<void (v8::Local<v8::Context> context)>;\n\n    /// <summary> Interface to load a module from file. </summary>\n    class ModuleFileLoader {\n    public:\n\n        virtual ~ModuleFileLoader() = default;\n\n        /// <summary> It loads a module from file. </summary>\n        /// <param name=\"path\"> Module path called by require(). </param>\n        /// <param name=\"arg\"> Optional argument for loading module file. Passed through as arg1 from require. </param>\n        /// <param name=\"module\"> Loaded module if successful. </param>\n        /// <returns> True if the module was loaded, false otherwise. </returns>\n        virtual bool TryGet(const std::string& path, v8::Local<v8::Value> arg, v8::Local<v8::Object>& module) = 0;\n    };\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/loader/module-loader-helpers.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"module-loader-helpers.h\" \n\n#include <module/core-modules/node/file-system-helpers.h>\n#include <platform/dll.h>\n#include <platform/filesystem.h>\n\n#include <napa/log.h>\n#include <napa/v8-helpers.h>\n\n#include <rapidjson/document.h>\n#include <rapidjson/error/en.h>\n#include <rapidjson/istreamwrapper.h>\n\n#include <fstream>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    /// <summary> Set up __dirname and __filename at V8 context. </summary>\n    /// <param name=\"exports\"> Object to set module paths. </param>\n    /// <param name=\"dirname\"> Module directory name. </param>\n    /// <param name=\"filename\"> Module file name. </param>\n    void SetupModulePath(v8::Local<v8::Object> exports, const std::string& dirname, const std::string& filename);\n\n    /// <summary> Set up module objects at V8 context. </summary>\n    /// <param name=\"parentContext\"> Parent context. </param>\n    /// <param name=\"exports\"> Object to set module objects. </param>\n    /// <param name=\"id\"> Module id. </param>\n    void SetupModuleObjects(v8::Local<v8::Context> parentContext, v8::Local<v8::Object> exports, const std::string& id);\n\n}   // End of anonymous namespace.\n\nv8::Local<v8::Object> module_loader_helpers::ExportModule(v8::Local<v8::Object> object,\n                                                          const napa::module::ModuleInitializer& initializer) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    auto module = object->Get(v8_helpers::MakeV8String(isolate, \"module\"))->ToObject();\n    auto exports = module->Get(v8_helpers::MakeV8String(isolate, \"exports\"))->ToObject();\n    if (initializer != nullptr) {\n        initializer(exports, module);\n    }\n\n    return scope.Escape(exports);\n}\n\nstd::string module_loader_helpers::GetCurrentContextDirectory() {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto context = isolate->GetCurrentContext();\n    auto contextObject = context->Global();\n    auto dirPropertyName = v8_helpers::MakeV8String(isolate, \"__dirname\");\n\n    if (contextObject.IsEmpty() \n        || contextObject->IsNull()\n        || !contextObject->Has(dirPropertyName)) {\n        return GetCurrentWorkingDirectory();\n    }\n\n    v8::String::Utf8Value callingPath(contextObject->Get(dirPropertyName));\n    return std::string(*callingPath);\n}\n\nstd::string module_loader_helpers::GetModuleDirectory(v8::Local<v8::Object> module) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto filename = module->Get(v8_helpers::MakeV8String(isolate, \"filename\"));\n    if (filename.IsEmpty() || !filename->IsString()) {\n        return \"\";\n    }\n\n    filesystem::Path moduleFile(v8_helpers::V8ValueTo<std::string>(filename));\n    return moduleFile.Parent().Normalize().String();\n}\n\nconst std::string& module_loader_helpers::GetNapaDllPath() {\n    static std::string dllPath = dll::ThisLineLocation();\n    return dllPath;\n}\n\nconst std::string& module_loader_helpers::GetNapaRuntimeDirectory() {\n    static std::string runtimeDirectory = filesystem::Path(GetNapaDllPath()).Parent().Normalize().String();\n    return runtimeDirectory;\n}\n\nconst std::string& module_loader_helpers::GetCurrentWorkingDirectory() {\n    static std::string currentWorkingDirectory = filesystem::CurrentDirectory().String();\n    return currentWorkingDirectory;\n}\n\nconst std::string& module_loader_helpers::GetLibDirectory() {\n    static std::string libDirectory = (filesystem::Path(GetNapaDllPath()).Parent().Parent() / \"lib\").Normalize().String();\n    return libDirectory;\n}\n\nvoid module_loader_helpers::SetupTopLevelContext() {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto exports = isolate->GetCurrentContext()->Global();\n\n    SetupModulePath(exports, GetCurrentWorkingDirectory(), std::string());\n    SetupModuleObjects(v8::Local<v8::Context>(), exports, \".\");\n\n    // Set 'global' variable shared by top-level context and module contexts.\n    (void)exports->Set(v8_helpers::MakeV8String(isolate, \"global\"), exports);\n}\n\nvoid module_loader_helpers::SetupModuleContext(v8::Local<v8::Context> parentContext,\n                                               v8::Local<v8::Context> moduleContext,\n                                               const std::string& path) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto exports = moduleContext->Global();\n\n    SetupModuleObjects(parentContext, exports, path);\n    if (path.empty()) {\n        SetupModulePath(exports, GetCurrentWorkingDirectory(), std::string());\n    } else {\n        filesystem::Path current(path);\n        SetupModulePath(exports, current.Parent().Normalize().String(), path);\n    }\n\n    auto global = parentContext->Global()->Get(parentContext, v8_helpers::MakeV8String(isolate, \"global\")).ToLocalChecked()->ToObject();\n    (void)exports->Set(v8_helpers::MakeV8String(isolate, \"global\"), global);\n}\n\nstd::vector<module_loader_helpers::CoreModuleInfo> module_loader_helpers::ReadCoreModulesJson() {\n    static const std::string CORE_MODULES_JSON_PATH =\n        (filesystem::Path(GetLibDirectory()) / \"core\" / \"core-modules.json\").String();\n\n    NAPA_ASSERT(filesystem::IsRegularFile(CORE_MODULES_JSON_PATH), \"Core module JSON file \\\"%s\\\" does not exist.\", CORE_MODULES_JSON_PATH.c_str());\n\n    std::vector<CoreModuleInfo> coreModuleInfos;\n\n    // Reserve capacity to help avoiding too frequent allocation.\n    coreModuleInfos.reserve(16);\n\n    rapidjson::Document document;\n    try {\n        std::ifstream ifs(CORE_MODULES_JSON_PATH);\n        rapidjson::IStreamWrapper isw(ifs);\n        if (document.ParseStream(isw).HasParseError()) {\n            throw std::runtime_error(rapidjson::GetParseError_En(document.GetParseError()));\n        }\n\n        for (const auto& obj : document.GetArray()) {\n            auto moduleName = obj[\"name\"].GetString();\n            auto isBuiltIn = (obj[\"type\"] == \"builtin\");\n\n            coreModuleInfos.emplace_back(moduleName, isBuiltIn);\n        }\n    } catch (const std::exception& ex) {\n        NAPA_ASSERT(false, \"Reading core-modules.json failed: %s\", ex.what());\n    }\n\n    return coreModuleInfos;\n}\n\nv8::Local<v8::String> module_loader_helpers::ReadModuleFile(const std::string& path) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    std::string content;\n    try {\n        content = file_system_helpers::ReadFileSync(path);\n    } catch (const std::exception& ex) {\n        isolate->ThrowException(v8::Exception::Error(v8_helpers::MakeV8String(isolate, ex.what())));\n        return scope.Escape(v8::Local<v8::String>());\n    }\n\n    JS_ENSURE_WITH_RETURN(isolate,\n                          !content.empty(),\n                          scope.Escape(v8::Local<v8::String>()),\n                          \"\\\"%s\\\" is empty\",\n                          path.c_str());\n\n    return scope.Escape(v8_helpers::MakeV8String(isolate, content));\n}\n\nnamespace {\n\n    void SetupModulePath(v8::Local<v8::Object> exports, const std::string& dirname, const std::string& filename) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        (void)exports->Set(v8_helpers::MakeV8String(isolate, \"__dirname\"), v8_helpers::MakeV8String(isolate, dirname));\n        if (filename.empty()) {\n            (void)exports->Set(v8_helpers::MakeV8String(isolate, \"__filename\"), v8::Null(isolate));\n        } else {\n            (void)exports->Set(v8_helpers::MakeV8String(isolate, \"__filename\"), v8_helpers::MakeV8String(isolate, filename));\n        }\n    }\n\n    void SetupModuleObjects(v8::Local<v8::Context> parentContext, v8::Local<v8::Object> exports, const std::string& id) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = isolate->GetCurrentContext();\n\n        auto module = v8::Object::New(isolate);\n        (void)module->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"exports\"), v8::Object::New(isolate));\n        (void)module->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"paths\"), v8::Array::New(isolate));\n        (void)module->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"id\"), v8_helpers::MakeV8String(isolate, id));\n        (void)module->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"filename\"), v8_helpers::MakeV8String(isolate, id));\n\n        // Setup 'module.require'.\n        if (!parentContext.IsEmpty()) {\n            auto requireKey = v8_helpers::MakeV8String(isolate, \"require\");\n            (void)module->CreateDataProperty(context, requireKey, parentContext->Global()->Get(requireKey));\n        }\n\n        (void)exports->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"module\"), module);\n        (void)exports->CreateDataProperty(context, v8_helpers::MakeV8String(isolate, \"exports\"),\n            module->Get(v8_helpers::MakeV8String(isolate, \"exports\"))->ToObject());\n\n        // Set '__in_napa' variable in all modules context to distinguish node and napa runtime.\n        (void)exports->Set(v8_helpers::MakeV8String(isolate, \"__in_napa\"), v8::Boolean::New(isolate, true));\n\n#ifndef USING_V8_SHARED\n\n        // Set '__in_embed' variable in all modules context to distinguish between napa running in node and embedded mode.\n        (void)exports->Set(v8_helpers::MakeV8String(isolate, \"__in_embed\"), v8::Boolean::New(isolate, true));\n#endif\n    }\n}   // End of anonymous namespace.\n"
  },
  {
    "path": "src/module/loader/module-loader-helpers.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/module/module-internal.h>\n#include <vector>\n\n#include <vector>\n\nnamespace napa {\nnamespace module {\nnamespace module_loader_helpers {\n\n    /// <summary> Core module information from 'core-modules.json'. </summary>\n    struct CoreModuleInfo {\n        /// <summary> Core module name. </summary>\n        std::string name;\n\n        /// <summary> True if it's a built-in module. False, otherwise. </summary>\n        bool isBuiltIn;\n\n        /// <summary> Constructor. </summary>\n        CoreModuleInfo(std::string name, bool isBuiltIn)\n            : name(std::move(name)), isBuiltIn(isBuiltIn) {}\n    };\n\n    /// <summary> It exports loaded module. </summary>\n    /// <param name=\"object\"> Loaded javascript object. </param>\n    /// <param name=\"initializer\"> Callback function to initialize a module. </param>\n    /// <returns> Exported javascript object. </returns>\n    v8::Local<v8::Object> ExportModule(v8::Local<v8::Object> object,\n                                       const napa::module::ModuleInitializer& initializer);\n\n    /// <summary> It returns directory of a JavaScript context. </summary>\n    /// <returns> Directory of context. If called from external string, module root directory will be returned. </returns>\n    std::string GetCurrentContextDirectory();\n\n    /// <summary> It returns parent directory of module.filename. </summary>\n    /// <returns> Parent directory of module.filename. </summary>\n    std::string GetModuleDirectory(v8::Local<v8::Object> module);\n\n    /// <summary> It returns the directory of napa runtime. </summary>\n    /// <returns> Directory of napa runtime. </returns>\n    const std::string& GetNapaRuntimeDirectory();\n\n    /// <summary> It returns napa.dll path. </summary>\n    /// <returns> Path of napa.dll. </summary>\n    const std::string& GetNapaDllPath();\n\n    /// <summary> It returns the process current working directory. </summary>\n    const std::string& GetCurrentWorkingDirectory();\n\n    /// <summary> It returns the root directory of napa lib files. </summary>\n    const std::string& GetLibDirectory();\n\n    /// <summary> It sets globals and the root module path of global context as the script path. </summary>\n    void SetupTopLevelContext();\n\n    /// <summary> It sets up a module context. </summary>\n    /// <param name=\"parentContext\"> Parent context. </param>\n    /// <param name=\"moduleContext\"> Module context. </param>\n    /// <param name=\"path\"> Module path called by require(). </param>\n    /// <returns> V8 context object. </returns>\n    void SetupModuleContext(v8::Local<v8::Context> parentContext,\n                            v8::Local<v8::Context> moduleContext,\n                            const std::string& path);\n\n    /// <summary> It reads javascript core module information. </summary>\n    std::vector<CoreModuleInfo> ReadCoreModulesJson();\n\n    /// <summary> It reads a module file to javascript string. </summary>\n    /// <param name=\"path\"> File path to read. </param>\n    /// <returns> V8 string containing file content. </returns>\n    v8::Local<v8::String> ReadModuleFile(const std::string& path);\n\n}   // End of namespace module_loader_helpers.\n}   // End of namespace module\n}   // End of namespace napa"
  },
  {
    "path": "src/module/loader/module-loader.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"module-loader.h\"\n\n#include \"binary-module-loader.h\"\n#include \"core-module-loader.h\"\n#include \"javascript-module-loader.h\"\n#include \"json-module-loader.h\"\n#include \"module-cache.h\"\n#include \"module-loader-helpers.h\"\n#include \"module-resolver.h\"\n\n#include <module/core-modules/core-modules.h>\n#include <platform/filesystem.h>\n\n// TODO: decouple dependencies between module-loader and zone.\n#include <zone/worker-context.h>\n\n#include <napa/log.h>\n#include <napa/module.h>\n\n#include <unordered_set>\n\nusing namespace napa;\nusing namespace napa::module;\n\n/// <summary> Implementation of module loader. </summary>\n/// <remarks>\n/// It has three kinds of core modules.\n/// Built-in module:\n///     It can be accessed with/without require() such as console, process, but can't be with process.binding().\n///     It's cached at both binding and module cache.\n///     If javascript core file exists, it overrides binary core module.\n/// Binary core module:\n///     It can be accessed with only process.binding(), not with require().\n///     It's cached at only binding cache.\n/// Javascript core module:\n///     It exists as Javascript file at './lib' or '../lib' directory.\n///     It can be accessed with only require() and cached at only module cache.\n///     If javascript core file exists, it overrides binary core module.\n/// </remarks>\nclass ModuleLoader::ModuleLoaderImpl {\npublic:\n\n    /// <summary> Constructor. </summary>\n    ModuleLoaderImpl();\n\n    /// <summary> Bootstrap core modules into module loader. </summary>\n    /// <remarks>\n    /// Bootstraping must be done after module loader is created and registered into isolate data\n    /// because Javascript core modules may call 'require'.\n    /// </remarks>\n    void Bootstrap();\n\nprivate:\n\n    /// <summary> Global callback function for require(). </summary>\n    /// <param name=\"args\"> V8 argument to return module object. </param>\n    static void RequireCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Callback to resolve a given module path. </summary>\n    /// <param name=\"args\"> Module name. </param>\n    static void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> Callback to bind core binary module. </summary>\n    /// <param name=\"args\"> Module name. </param>\n    static void BindingCallback(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> It loads a module. </summary>\n    /// <param name=\"path\"> Module path called by require(). </param>\n    /// <param name=\"args\"> V8 argument to return module object. </param>\n    void RequireModule(const char* path,\n                       const v8::FunctionCallbackInfo<v8::Value>& args);\n\n    /// <summary> It registers a binary core module. </summary>\n    /// <param name=\"name\"> Module name. </param>\n    /// <param name=\"isBuiltInModule\"> True if it's a built-in module, which doesn't need require() to call. </param>\n    /// <param name=\"initializer\"> Module initialization function. </param>\n    void LoadBinaryCoreModule(const char* name,\n                              bool isBuiltInModule,\n                              const napa::module::ModuleInitializer& initializer);\n\n    /// <summary> It sets up built-in modules at each module's' context. </summary>\n    /// <param name=\"context\"> V8 context. </param>\n    void SetupBuiltInModules(v8::Local<v8::Context> context);\n\n    /// <summary> It sets up require function. </summary>\n    /// <param name=\"context\"> V8 context. </param>\n    void SetupRequire(v8::Local<v8::Context> context);\n\n    /// <summary> It adds the extra functions, which access module loader's function, into built-in modules. <summary>\n    /// <param name=\"context\"> V8 context. </param>\n    /// <remarks> It assumes that calling built-in modules are already loaded into a context. </remarks>\n    void DecorateBuiltInModules(v8::Local<v8::Context> context);\n\n    /// <summary> Module cache to avoid module loading overhead. </summary>\n    ModuleCache _moduleCache;\n\n    /// <summary> Cache for core binary modules, which can be accessed by process.binding(). </summary>\n    ModuleCache _bindingCache;\n\n    /// <summary> Module resolver to resolve module path. </summary>\n    ModuleResolver _resolver;\n\n    /// <summary> Built-in module list. </summary>\n    std::unordered_set<std::string> _builtInNames;\n\n    /// <summary> Module loaders. </summary>\n    std::array<std::unique_ptr<ModuleFileLoader>, static_cast<size_t>(ModuleType::END_OF_MODULE_TYPE)> _loaders;\n};\n\nvoid ModuleLoader::CreateModuleLoader() {\n    auto moduleLoader = reinterpret_cast<ModuleLoader*>(zone::WorkerContext::Get(zone::WorkerContextItem::MODULE_LOADER));\n    if (moduleLoader == nullptr) {\n        moduleLoader = new ModuleLoader();\n        zone::WorkerContext::Set(zone::WorkerContextItem::MODULE_LOADER, moduleLoader);\n\n        // Now, Javascript core module's 'require' can find module loader instance correctly.\n        moduleLoader->_impl->Bootstrap();\n    }\n    NAPA_DEBUG(\"ModuleLoader\", \"Module loader is created successfully.\");\n}\n\nModuleLoader::ModuleLoader() : _impl(std::make_unique<ModuleLoader::ModuleLoaderImpl>()) {}\n\nModuleLoader::~ModuleLoader() = default;\n\nModuleLoader::ModuleLoaderImpl::ModuleLoaderImpl() {\n    auto builtInModulesSetter = [this](v8::Local<v8::Context> context) {\n        SetupRequire(context);\n        SetupBuiltInModules(context);\n    };\n\n    // Set up module loaders for each module type.\n    _loaders = {{\n        nullptr,\n        std::make_unique<CoreModuleLoader>(builtInModulesSetter, _moduleCache, _bindingCache),\n        std::make_unique<JavascriptModuleLoader>(builtInModulesSetter, _moduleCache),\n        std::make_unique<JsonModuleLoader>(),\n        std::make_unique<BinaryModuleLoader>(builtInModulesSetter)\n    }};\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::Bootstrap() {\n    // Set up top-level context.\n    module_loader_helpers::SetupTopLevelContext();\n\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n\n    // 'require' needs to be available in top-level context before core-module is loaded.\n    SetupRequire(context);\n\n    // Initialize core modules listed in core-modules.h.\n    INITIALIZE_CORE_MODULES(LoadBinaryCoreModule)\n    NAPA_DEBUG(\"ModuleLoader\", \"Binary core modules are loaded.\");\n\n    // Set up built-in modules from binaries.\n    SetupBuiltInModules(context);\n\n    // Load core module information from 'core-modules.json'.\n    auto coreModuleInfos = module_loader_helpers::ReadCoreModulesJson();\n    for (auto& info : coreModuleInfos) {\n        _resolver.SetAsCoreModule(info.name.c_str());\n\n        if (info.isBuiltIn) {\n            _builtInNames.emplace(std::move(info.name));\n        }\n    }\n\n    auto& coreModuleLoader = _loaders[static_cast<size_t>(ModuleType::CORE)];\n\n    // Override built-in modules with javascript file if exists.\n    for (const auto& name : _builtInNames) {\n        v8::Local<v8::Object> module;\n        if (coreModuleLoader->TryGet(name, v8::Local<v8::Value>(), module)) {\n            // If javascript core module exists, replace the existing one.\n            _moduleCache.Upsert(name, module);\n            (void)context->Global()->Set(context,\n                                         v8_helpers::MakeV8String(isolate, name),\n                                         module);\n        }\n    }\n    NAPA_DEBUG(\"ModuleLoader\", \"JavaScript core modules are loaded.\");\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::RequireCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate,\n        args.Length() == 1 || args.Length() == 2 || args[0]->IsString(),\n        \"Invalid arguments\");\n\n    auto moduleLoader = reinterpret_cast<ModuleLoader*>(zone::WorkerContext::Get(zone::WorkerContextItem::MODULE_LOADER));\n    JS_ENSURE(isolate, moduleLoader != nullptr, \"Module loader is not initialized\");\n\n    v8::String::Utf8Value path(args[0]);\n    moduleLoader->_impl->RequireModule(*path, args);\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1 && args[0]->IsString(), \"Invalid arguments\");\n\n    auto moduleLoader = reinterpret_cast<ModuleLoader*>(zone::WorkerContext::Get(zone::WorkerContextItem::MODULE_LOADER));\n    JS_ENSURE(isolate, moduleLoader != nullptr, \"Module loader is not initialized\");\n\n    v8::String::Utf8Value path(args[0]);\n    auto contextDir = module_loader_helpers::GetCurrentContextDirectory();\n\n    auto moduleInfo = moduleLoader->_impl->_resolver.Resolve(*path, contextDir.c_str());\n    JS_ENSURE(isolate, moduleInfo.type != ModuleType::NONE, \"Cannot find module \\\"%s\\\"\", *path);\n\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, moduleInfo.fullPath));\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::BindingCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    CHECK_ARG(isolate, args.Length() == 1 && args[0]->IsString(), \"Invalid arguments\");\n\n    auto moduleLoader = reinterpret_cast<ModuleLoader*>(zone::WorkerContext::Get(zone::WorkerContextItem::MODULE_LOADER));\n    JS_ENSURE(isolate, moduleLoader != nullptr, \"Module loader is not initialized\");\n\n    v8::String::Utf8Value name(args[0]);\n    v8::Local<v8::Object> module;\n\n    if (moduleLoader->_impl->_bindingCache.TryGet(*name, module)) {\n        args.GetReturnValue().Set(module);\n        return;\n    }\n\n    LOG_WARNING(\"ModuleLoader\", \"process.binding for \\\"%s\\\" does not exist.\", *name);\n    args.GetReturnValue().SetUndefined();\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::RequireModule(const char* path, const v8::FunctionCallbackInfo<v8::Value>& args) {\n    if (path == nullptr) {\n        args.GetReturnValue().SetUndefined();\n        return;\n    }\n\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    // Set optional argument for module file loader.\n    auto arg = args.Length() == 1 ? v8::Local<v8::Value>() : args[1]; \n    bool fromContent = !arg.IsEmpty() && arg->IsString();\n\n    // If require is called with a module receiver, use module.filename to deduce context directory.\n    std::string contextDir;\n    if (!args.Holder().IsEmpty()) {\n        contextDir = module_loader_helpers::GetModuleDirectory(args.Holder());\n    }\n\n    if (contextDir.empty()) {\n        contextDir = module_loader_helpers::GetCurrentContextDirectory();\n    }\n\n    ModuleInfo moduleInfo;\n    if (fromContent) {\n        moduleInfo = ModuleInfo { \n            ModuleType::JAVASCRIPT, \n            (filesystem::Path(contextDir) / path).Normalize().String(),    // Module id\n            \"\"                                                             // No package.json\n        };\n    } else {\n        moduleInfo = _resolver.Resolve(path, contextDir.c_str());\n        JS_ENSURE(isolate, moduleInfo.type != ModuleType::NONE, \"Cannot resolve module path \\\"%s\\\"\", path);\n    }\n\n    v8::Local<v8::Object> module;\n\n    // Module from content script is not cached.\n    if (!fromContent) {\n        if (_moduleCache.TryGet(moduleInfo.fullPath, module)) {\n            NAPA_DEBUG(\"ModuleLoader\", \"Retrieved module from cache: \\\"%s\\\".\", path);\n            args.GetReturnValue().Set(module);\n            return;\n        }\n    }\n\n    auto& loader = _loaders[static_cast<size_t>(moduleInfo.type)];\n    JS_ENSURE(isolate, loader != nullptr, \"No proper module loader is defined\");\n\n    auto succeeded = loader->TryGet(moduleInfo.fullPath, arg, module);\n    if (!succeeded) {\n        NAPA_DEBUG(\"ModuleLoader\", \"Cannot load module \\\"%s\\\".\", path);\n        // Exception has already been thrown upon loader failure.\n        args.GetReturnValue().SetUndefined();\n        return;\n    }\n\n    NAPA_DEBUG(\"ModuleLoader\", \"Loaded module from file (first time): \\\"%s\\\".\", path);\n\n    if (!fromContent) {\n        _moduleCache.Upsert(moduleInfo.fullPath, module);\n    }\n    args.GetReturnValue().Set(module);\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::LoadBinaryCoreModule(\n        const char* name,\n        bool isBuiltInModule,\n        const napa::module::ModuleInitializer& initializer) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto context = isolate->GetCurrentContext();\n\n    auto moduleContext = v8::Context::New(isolate);\n    NAPA_ASSERT(!moduleContext.IsEmpty(), \"Can't set up context for core modules\");\n\n    // We set an empty security token so callee can access caller's context.\n    moduleContext->SetSecurityToken(v8::Undefined(isolate));\n    v8::Context::Scope contextScope(moduleContext);\n\n    module_loader_helpers::SetupModuleContext(context, moduleContext, module_loader_helpers::GetNapaDllPath());\n\n    // Put it into module resolver to prevent from resolving as user module.\n    _resolver.SetAsCoreModule(name);\n\n    auto module = module_loader_helpers::ExportModule(moduleContext->Global(), initializer);\n\n    if (isBuiltInModule) {\n        _builtInNames.emplace(name);\n\n        // Put core module into cache.\n        // This makes the same behavior with node.js, i.e. it must be loaded by 'require'.\n        _moduleCache.Upsert(name, module);\n    } else {\n        // Put into binding cache.\n        // It must be accessed by process.binding(), not by require().\n        _bindingCache.Upsert(name, module);\n    }\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::SetupBuiltInModules(v8::Local<v8::Context> context) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    // Assume that built-in modules are already cached.\n    for (const auto& name : _builtInNames) {\n        v8::Local<v8::Object> module;\n        if (_moduleCache.TryGet(name, module)) {\n            (void)context->Global()->CreateDataProperty(context,\n                                                        v8_helpers::MakeV8String(isolate, name),\n                                                        module);\n        }\n    }\n\n    // Can decorate a context after loading up built-in modules.\n    DecorateBuiltInModules(context);\n}\n\nvoid ModuleLoader::ModuleLoaderImpl::SetupRequire(v8::Local<v8::Context> context) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    // Set up require().\n    auto requireFunctionTemplate = v8::FunctionTemplate::New(isolate, RequireCallback);\n    (void)context->Global()->CreateDataProperty(context,\n                                                v8_helpers::MakeV8String(isolate, \"require\"),\n                                                requireFunctionTemplate->GetFunction());\n\n    // Set up require.resolve().\n    auto require = context->Global()->Get(context,\n                                          v8_helpers::MakeV8String(isolate, \"require\")).ToLocalChecked()->ToObject();\n    auto resolveFunctionTemplate = v8::FunctionTemplate::New(isolate, ResolveCallback);\n    (void)require->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"resolve\"),\n                                      resolveFunctionTemplate->GetFunction());\n}\n\n// If we have more decorations, move them out from this class.\nvoid ModuleLoader::ModuleLoaderImpl::DecorateBuiltInModules(v8::Local<v8::Context> context) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    // Add process.binding()\n    auto process = context->Global()->Get(context,\n                                          v8_helpers::MakeV8String(isolate, \"process\")).ToLocalChecked()->ToObject();\n    JS_ENSURE(isolate, !process.IsEmpty(), \"Process built-in module doesn't exist\");\n\n    auto bindingFunctionTemplate = v8::FunctionTemplate::New(isolate, BindingCallback);\n    (void)process->CreateDataProperty(context,\n                                      v8_helpers::MakeV8String(isolate, \"binding\"),\n                                      bindingFunctionTemplate->GetFunction());\n}\n"
  },
  {
    "path": "src/module/loader/module-loader.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <memory>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary>\n    /// It follows node.js's module resolution algorithm, https://nodejs.org/api/modules.html#modules_all_together except,\n    /// - Napa module is created in thread-safe way.\n    /// - Napa native module uses '.napa' extension instead of '.node'.\n    /// </summary>\n    class ModuleLoader {\n    public:\n\n        /// <summary> It creates a module loader. One thread can have only one module loader. </summary>\n        static void CreateModuleLoader();\n\n        /// <summary>\n        /// A helper macro to create a module loader instance at current thread.\n        /// This must be called before calling 'require'.\n        /// </summary>\n        #define CREATE_MODULE_LOADER napa::module::ModuleLoader::CreateModuleLoader\n\n        /// <summary> Non-copyable and Non-movable. </summary>\n        ModuleLoader(const ModuleLoader&) = delete;\n        ModuleLoader& operator=(const ModuleLoader&) = delete;\n        ModuleLoader(ModuleLoader&&) = delete;\n        ModuleLoader& operator=(ModuleLoader&&) = delete;\n\n    private:\n\n        /// <summary> Constructor. </summary>\n        ModuleLoader();\n\n        /// <summary> Default destructor. </summary>\n        ~ModuleLoader();\n\n        class ModuleLoaderImpl;\n        std::unique_ptr<ModuleLoaderImpl> _impl;\n    };\n\n}\n}"
  },
  {
    "path": "src/module/loader/module-resolver-cache.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"module-resolver-cache.h\"\n\n#include <mutex>\n#include <unordered_map>\n\nusing namespace napa;\nusing namespace napa::module;\n\nstruct ModuleResolverCacheKey {\n    std::string _name;\n    std::string _path;\n\n    bool operator==(const ModuleResolverCacheKey& other) const {\n        return _name == other._name && _path == other._path;\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<ModuleResolverCacheKey> {\n        std::size_t operator()(ModuleResolverCacheKey key) const {\n            return std::hash<std::string>{}(key._name) ^ std::hash<std::string>{}(key._path);\n        }\n    };\n}\n\nclass ModuleResolverCache::ModuleResolverCacheImpl {\npublic:\n    ModuleInfo Lookup(const char* name, const char* path);\n    void Insert(const char* name, const char* path, const ModuleInfo& moduleInfo);\nprivate:\n    std::mutex _lock;\n    std::unordered_map<ModuleResolverCacheKey, ModuleInfo> _resolvedModules;\n};\n\nModuleResolverCache::ModuleResolverCache() : _impl(std::make_unique<ModuleResolverCache::ModuleResolverCacheImpl>()) {}\n\nModuleResolverCache::~ModuleResolverCache() = default;\n\nModuleInfo ModuleResolverCache::Lookup(const char* name, const char* path) {\n    return _impl->Lookup(name, path);\n}\n\nvoid ModuleResolverCache::Insert(const char* name, const char* path, const ModuleInfo& moduleInfo) {\n    _impl->Insert(name, path, moduleInfo);\n}\n\nModuleInfo ModuleResolverCache::ModuleResolverCacheImpl::Lookup(const char* name, const char* path) {\n    ModuleResolverCacheKey key{name, path};\n\n    std::lock_guard<std::mutex> lock(_lock);\n\n    auto result = _resolvedModules.find(key);\n    if (result != _resolvedModules.end()) {\n        return result->second;\n    }\n\n    return ModuleInfo{ModuleType::NONE, name, path};\n}\n\nvoid ModuleResolverCache::ModuleResolverCacheImpl::Insert(const char* name, const char* path, const ModuleInfo& moduleInfo) {\n    ModuleResolverCacheKey key{name, path};\n    \n    std::lock_guard<std::mutex> lock(_lock);\n\n    _resolvedModules.emplace(std::make_pair(key, moduleInfo));\n}\n"
  },
  {
    "path": "src/module/loader/module-resolver-cache.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"module-resolver.h\"\n\n#include <memory>\n\nnamespace napa {\nnamespace module {\n\n    /// <summary>\n    /// The Module resolver cache helps to reduce the overhead when ModuleResolver\n    /// is trying to traversal the file system.\n    /// </summary>\n    class ModuleResolverCache {\n    public:\n\n        /// <summary> Constructor. </summary>\n        ModuleResolverCache();\n\n        /// <summary> Default destructor. </summary>\n        ~ModuleResolverCache();\n\n        /// <summary> Non-copyable. </summary>\n        ModuleResolverCache(const ModuleResolverCache&) = delete;\n        ModuleResolverCache& operator=(const ModuleResolverCache&) = delete;\n\n        /// <summary> Movable. </summary>\n        ModuleResolverCache(ModuleResolverCache&&) = default;\n        ModuleResolverCache& operator=(ModuleResolverCache&&) = default;\n\n        /// <summary> Lookup the module info. </summary>\n        /// <param name=\"name\"> Module name or path. </param>\n        /// <param name=\"path\"> Current context path. If nullptr, it'll be current path. </param>\n        /// <returns> Module resolution information. </returns>\n        ModuleInfo Lookup(const char* name, const char* path);\n\n        /// <summary> Insert the specific module info into the cache. </summary>\n        /// <param name=\"name\"> Module name or path. </param>\n        /// <param name=\"path\"> Current context path. If nullptr, it'll be current path. </param>\n        void Insert(const char* name, const char* path, const ModuleInfo& moduleInfo);\n\n    private:\n        class ModuleResolverCacheImpl;\n        std::unique_ptr<ModuleResolverCacheImpl> _impl;\n    };\n    \n}   // End of namespace module.\n}   // End of namespace napa.\n"
  },
  {
    "path": "src/module/loader/module-resolver.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"module-resolver.h\"\n#include \"module-resolver-cache.h\"\n\n#include <platform/filesystem.h>\n#include <platform/os.h>\n#include <platform/process.h>\n\n#include <utils/string.h>\n\n#include <rapidjson/document.h>\n#include <rapidjson/error/en.h>\n#include <rapidjson/istreamwrapper.h>\n\n#include <fstream>\n#include <sstream>\n#include <unordered_set>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n\n    const std::string NAPA_MODULE_EXTENSION = \".napa\";\n    const std::string JAVASCRIPT_MODULE_EXTENSION = \".js\";\n    const std::string JSON_OBJECT_EXTENSION = \".json\";\n\n}   // End of anonymous namespace.\n\nclass ModuleResolver::ModuleResolverImpl {\npublic:\n\n    /// <summary> Constructor. </summary>\n    ModuleResolverImpl();\n\n    /// <summary> It resolves a full module path from a given argument of require(). </summary>\n    /// <param name=\"name\"> Module name or path. </param>\n    /// <param name=\"path\"> Current context path. </param>\n    /// <returns> Module resolution details. </returns>\n    /// <remarks> It also searches NODE_PATH directories. </remarks>\n    ModuleInfo Resolve(const char* name, const char* path);\n\n    /// <summary> It registers core modules, so they are resolved first. </summary>\n    /// <param name=\"name\"> Module name. </param>\n    /// <returns>\n    /// True if it successfully adds a module.\n    /// If it fails or there is a duplication, return false.\n    /// </returns>\n    bool SetAsCoreModule(const char* name);\n\nprivate:\n\n    /// <summary> It resolves a full module path from a given argument of require(). </summary>\n    /// <param name=\"name\"> Module name or path. </param>\n    /// <param name=\"path\"> Base path. </param>\n    /// <returns> Module resolution details. </returns>\n    ModuleInfo ResolveFromPath(const filesystem::Path& name, const filesystem::Path& path);\n\n    /// <summary> It resolves a full module path from 'NODE_PATH'. </summary>\n    /// <param name=\"name\"> Module name or path. </param>\n    /// <param name=\"path\"> Base path. </param>\n    /// <returns> Module resolution details. </returns>\n    ModuleInfo ResolveFromEnv(const filesystem::Path& name, const filesystem::Path& path);\n\n    /// <summary> It checks whether a module exists or not. </summary>\n    /// <param name=\"name\"> Module name. </param>\n    /// <returns> True if a module exists at registry. </summary>\n    bool IsCoreModule(const std::string& module);\n\n    /// <summary> It loads module as a file. </summary>\n    /// <param name=\"name\"> Module name. </param>\n    /// <param name=\"path\"> Base path. </param>\n    /// <param name=\"package\"> Path to package.json. </param>\n    /// <returns> Module resolution details. </returns>\n    ModuleInfo LoadAsFile(const filesystem::Path& name, const filesystem::Path& path);\n\n    /// <summary> It loads module as a directory. </summary>\n    /// <param name=\"name\"> Module path. </param>\n    /// <param name=\"path\"> Base path. </param>\n    /// <returns> Module resolution details. </returns>\n    ModuleInfo LoadAsDirectory(const filesystem::Path& name, const filesystem::Path& path);\n\n    /// <summary> It loads module from node_modules directories. </summary>\n    /// <param name=\"name\"> Module name or path. </param>\n    /// <param name=\"path\"> Base path. </param>\n    /// <returns> Module resolution details. </returns>\n    ModuleInfo LoadNodeModules(const filesystem::Path& name, const filesystem::Path& path);\n\n    /// <summary> It returns all possible node module paths. </summary>\n    /// <param name=\"path\"> Base path. </param>\n    /// <returns> List of possible node_modules paths. </summary>\n    std::vector<std::string> GetNodeModulesPaths(const filesystem::Path& path);\n\n    /// <summary> It tries the extension candidates. </summary>\n    /// <param name=\"path\"> Possible module path. </param>\n    /// <returns> Module resolution details. </returns>\n    /// <remarks> \"path\" argument is changed. </remarks>\n    ModuleInfo TryExtensions(const filesystem::Path& path);\n\n    /// <summary> It checks whether a path is relative. </summary>\n    /// <param name=\"path\"> Path. </param>\n    /// <returns> True if a path is relative. </summary>\n    bool IsExplicitRelativePath(const filesystem::Path& path) const;\n\n    /// <summary> Registered modules. </summary>\n    std::unordered_set<std::string> _coreModules;\n\n    /// <summary> Paths in 'NODE_PATH' environment variable. </summary>\n    std::vector<std::string> _nodePaths;\n\n    /// <summary> Module info cache for all loaded modules. </summary>\n    ModuleResolverCache _cache;\n};\n\nModuleResolver::ModuleResolver() : _impl(std::make_unique<ModuleResolver::ModuleResolverImpl>()) {}\n\nModuleResolver::~ModuleResolver() = default;\n\nModuleInfo ModuleResolver::Resolve(const char* name, const char* path) {\n    return _impl->Resolve(name, path);\n}\n\nbool ModuleResolver::SetAsCoreModule(const char* name) {\n    return _impl->SetAsCoreModule(name);\n}\n\nModuleResolver::ModuleResolverImpl::ModuleResolverImpl() {\n    auto envPath = platform::GetEnv(\"NODE_PATH\");\n    if (!envPath.empty()) {\n        std::vector<std::string> nodePaths;\n        utils::string::Split(envPath, nodePaths, std::string(platform::ENV_DELIMITER));\n\n        for (auto& nodePath : nodePaths) {\n            if (filesystem::IsDirectory(nodePath)) {\n                _nodePaths.emplace_back(std::move(nodePath));\n            }\n        }\n    }\n}\n\n#define RETURN_IF_NOT_EMPTY(run)                    \\\n    do {                                            \\\n        auto result = run;                          \\\n        if (result.type != ModuleType::NONE) {      \\\n            return result;                          \\\n        }                                           \\\n    } while (false);\n\nModuleInfo ModuleResolver::ModuleResolverImpl::Resolve(const char* name, const char* path) {\n    // If name is a core modules, return it.\n    if (IsCoreModule(name)) {\n        return ModuleInfo{ModuleType::CORE, std::string(name), std::string()};\n    }\n\n    // Normalize module context path.\n    filesystem::Path basePath =\n        (path == nullptr) ? filesystem::CurrentDirectory() : filesystem::Path(path);\n\n    // Lookup for module info cache.\n    RETURN_IF_NOT_EMPTY(_cache.Lookup(name, basePath.c_str()));\n    \n        // Look up from the given path.\n    ModuleInfo moduleInfo = ResolveFromPath(name, basePath);\n    if (moduleInfo.type != ModuleType::NONE) {\n        _cache.Insert(name, basePath.c_str(), moduleInfo);\n        return moduleInfo;\n    }\n\n    // Look up NODE_PATH\n    moduleInfo = ResolveFromEnv(name, basePath);\n    if (moduleInfo.type != ModuleType::NONE) {\n        _cache.Insert(name, basePath.c_str(), moduleInfo);\n    }\n    return moduleInfo;\n}\n\nbool ModuleResolver::ModuleResolverImpl::SetAsCoreModule(const char* name) {\n    auto result = _coreModules.emplace(name);\n    return result.second;\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::ResolveFromPath(const filesystem::Path& name,\n                                                               const filesystem::Path& path) {\n    // If name begins with './' or '/' or '../',\n    if (IsExplicitRelativePath(name) || name.IsAbsolute()) {\n        // Load as a file (path + name).\n        RETURN_IF_NOT_EMPTY(LoadAsFile(name, path));\n\n        // Load as a directory (path + name)\n        RETURN_IF_NOT_EMPTY(LoadAsDirectory(name, path));\n    }\n\n    // Load node_modules.\n    return LoadNodeModules(name, path);\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::ResolveFromEnv(const filesystem::Path& name,\n                                                              const filesystem::Path& path) {\n    for (const auto& nodePath : _nodePaths) {\n        if (nodePath == path.String()) {\n            continue;\n        }\n\n        RETURN_IF_NOT_EMPTY(ResolveFromPath(name, nodePath.c_str()));\n    }\n\n    return ModuleInfo{ModuleType::NONE, std::string(), std::string()};\n}\n\nbool ModuleResolver::ModuleResolverImpl::IsCoreModule(const std::string& module) {\n    return _coreModules.find(module) != _coreModules.end();\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::LoadAsFile(const filesystem::Path& name,\n                                                          const filesystem::Path& path) {\n    auto fullPath = (path / name).Normalize();\n\n    if (filesystem::IsRegularFile(fullPath)) {\n        ModuleType type = ModuleType::JAVASCRIPT;\n\n        auto extension = fullPath.Extension().String();\n        if (extension == JSON_OBJECT_EXTENSION) {\n            type = ModuleType::JSON;\n        } else if (extension == NAPA_MODULE_EXTENSION) {\n            type = ModuleType::NAPA;\n        }\n\n        return ModuleInfo{type, fullPath.String(), std::string()};\n    }\n\n    return TryExtensions(fullPath);\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::LoadAsDirectory(const filesystem::Path& name,\n                                                               const filesystem::Path& path) {\n    auto fullPath = (path / name).Normalize();\n\n    auto packageJson = fullPath / \"package.json\";\n    if (filesystem::IsRegularFile(packageJson)) {\n        rapidjson::Document package;\n        try {\n            std::ifstream ifs(packageJson.String());\n            rapidjson::IStreamWrapper isw(ifs);\n            if (package.ParseStream(isw).HasParseError()) {\n                throw std::runtime_error(rapidjson::GetParseError_En(package.GetParseError()));\n            }\n\n            if (package.HasMember(\"main\")) {\n                filesystem::Path mainPath(package[\"main\"].GetString());\n                mainPath.Normalize();\n\n                auto moduleInfo = LoadAsFile(mainPath, fullPath);\n                if (moduleInfo.type != ModuleType::NONE) {\n                    moduleInfo.packageJsonPath = packageJson.String();\n                    return moduleInfo;\n                }\n            }\n        } catch (...) {}    // ignore exception and continue.\n    }\n\n    fullPath = fullPath / \"index\";\n    return TryExtensions(fullPath);\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::LoadNodeModules(const filesystem::Path& name,\n                                                               const filesystem::Path& path) {\n    auto modulePaths = GetNodeModulesPaths(path);\n    for (const auto& modulePath :modulePaths) {\n        // Load as a file (path + name).\n        RETURN_IF_NOT_EMPTY(LoadAsFile(name, modulePath));\n\n        // Load as a directory (path + name)\n        RETURN_IF_NOT_EMPTY(LoadAsDirectory(name, modulePath));\n    }\n\n    return ModuleInfo{ModuleType::NONE, std::string(), std::string()};\n}\n\nstd::vector<std::string> ModuleResolver::ModuleResolverImpl::GetNodeModulesPaths(const filesystem::Path& path) {\n    std::vector<std::string> subpaths;\n    subpaths.reserve(256);\n\n    for (filesystem::Path subpath(path); !subpath.IsEmpty(); subpath = subpath.Parent().Normalize()) {\n        if (subpath.Filename().String() == \"node_modules\") {\n            continue;\n        }\n\n        auto modulePath = subpath / \"node_modules\";\n        if (filesystem::IsDirectory(modulePath)) {\n            subpaths.emplace_back(modulePath.String());\n        }\n    }\n\n    return subpaths;\n}\n\nModuleInfo ModuleResolver::ModuleResolverImpl::TryExtensions(const filesystem::Path& path) {\n    std::ostringstream oss;\n    oss << path.String() << JAVASCRIPT_MODULE_EXTENSION;\n\n    auto modulePath = filesystem::Path(oss.str());\n    if (filesystem::IsRegularFile(modulePath)) {\n        return ModuleInfo{ModuleType::JAVASCRIPT, modulePath.String(), std::string()};\n    }\n\n    modulePath.ReplaceExtension(JSON_OBJECT_EXTENSION);\n    if (filesystem::IsRegularFile(modulePath)) {\n        return ModuleInfo{ModuleType::JSON, modulePath.String(), std::string()};\n    }\n\n    modulePath.ReplaceExtension(NAPA_MODULE_EXTENSION);\n    if (filesystem::IsRegularFile(modulePath)) {\n        return ModuleInfo{ModuleType::NAPA, modulePath.String(), std::string()};\n    }\n\n    return ModuleInfo{ModuleType::NONE, std::string(), std::string()};\n}\n\nbool ModuleResolver::ModuleResolverImpl::IsExplicitRelativePath(const filesystem::Path& path) const {\n    // Start with \".\" or \"..\"\n    return !path.IsEmpty() && path.String()[0] == '.';\n}\n"
  },
  {
    "path": "src/module/loader/module-resolver.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <memory>\n#include <string>\n\nnamespace napa {\nnamespace module {\n\n    enum class ModuleType : size_t {\n        /// <summary> Module is not resolved correctly. </summary>\n        NONE,\n\n        /// <summary> Built-in or core module. </summary>\n        CORE,\n\n        /// <summary> Javascript module. </summary>\n        JAVASCRIPT,\n\n        /// <summary> Module with json object. </summary>\n        JSON,\n\n        /// <summary> Binary module. </summary>\n        NAPA,\n\n        /// <summary> End of module type. </summary>\n        END_OF_MODULE_TYPE\n    };\n\n    /// <summary> Module's detail information acquired at path resolution. </summary>\n    struct ModuleInfo {\n        /// <summary> Module type. </summary>\n        ModuleType type;\n\n        /// <summary> Full path. </summary>\n        std::string fullPath;\n\n        /// <summary> Package.json path. </summary>\n        std::string packageJsonPath;\n    };\n\n    /// <summary>\n    /// It resolves a module path by the algorithm described at\n    /// https://nodejs.org/api/modules.html#modules_all_together.\n    /// One module loader has one module resolver, so each thread has its own instance of this class.\n    /// </summary>\n    class ModuleResolver {\n    public:\n\n        /// <summary> Constructor. </summary>\n        ModuleResolver();\n\n        /// <summary> Default destructor. </summary>\n        ~ModuleResolver();\n\n        /// <summary> Non-copyable. </summary>\n        ModuleResolver(const ModuleResolver&) = delete;\n        ModuleResolver& operator=(const ModuleResolver&) = delete;\n\n        /// <summary> Movable. </summary>\n        ModuleResolver(ModuleResolver&&) = default;\n        ModuleResolver& operator=(ModuleResolver&&) = default;\n\n        /// <summary> It resolves a full module path from a given argument of require(). </summary>\n        /// <param name=\"name\"> Module name or path. </param>\n        /// <param name=\"path\"> Current context path. If nullptr, it'll be current path. </param>\n        /// <returns> Module resolution information. </returns>\n        ModuleInfo Resolve(const char* name, const char* path = nullptr);\n\n        /// <summary> It registers built-in or core modules, so they are resolved first. </summary>\n        /// <param name=\"name\"> Module name. </param>\n        /// <returns>\n        /// True if it successfully adds a module.\n        /// If it fails or there is a duplication, return false.\n        /// </returns>\n        bool SetAsCoreModule(const char* name);\n\n    private:\n\n        /// <summary> Implementation of module resolver. </summary>\n        class ModuleResolverImpl;\n        std::unique_ptr<ModuleResolverImpl> _impl;\n    };\n\n}   // End of namespace module.\n}   // End of namespace napa."
  },
  {
    "path": "src/module/module.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/module/module-internal.h>\n#include <napa/v8-helpers.h>\n\n#include <zone/worker-context.h>\n\n#include <napa/log.h>\n\nusing namespace napa;\n\n/// <summary>\n/// Map from module's class name to persistent constructor object.\n/// To suppport multiple isolates, let each isolate has its own persistent constructor at thread local storage.\n/// </summary>\ntypedef v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>> PersistentConstructor;\nstruct ConstructorInfo {\n    std::unordered_map<std::string, PersistentConstructor> constructorMap;\n};\n\n/// <summary> It sets the persistent constructor at the current V8 isolate. </summary>\n/// <param name=\"name\"> Unique constructor name. It's recommended to use the same name as module. </param>\n/// <param name=\"constructor\"> V8 persistent function to constructor V8 object. </param>\nvoid napa::module::SetPersistentConstructor(const char* name,\n                                     v8::Local<v8::Function> constructor) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto constructorInfo =\n        static_cast<ConstructorInfo*>(zone::WorkerContext::Get(zone::WorkerContextItem::CONSTRUCTOR));\n    if (constructorInfo == nullptr) {\n        constructorInfo = new ConstructorInfo();\n        zone::WorkerContext::Set(zone::WorkerContextItem::CONSTRUCTOR, constructorInfo);\n    }\n\n    constructorInfo->constructorMap.emplace(std::piecewise_construct,\n                                            std::forward_as_tuple(name),\n                                            std::forward_as_tuple(isolate, constructor));\n}\n\n/// <summary> It gets the given persistent constructor from the current V8 isolate. </summary>\n/// <param name=\"name\"> Unique constructor name given at SetPersistentConstructor() call. </param>\n/// <returns> V8 local function object. </returns>\nv8::Local<v8::Function> napa::module::GetPersistentConstructor(const char* name) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::EscapableHandleScope scope(isolate);\n\n    auto constructorInfo =\n        static_cast<ConstructorInfo*>(zone::WorkerContext::Get(zone::WorkerContextItem::CONSTRUCTOR));\n    if (constructorInfo == nullptr) {\n        return scope.Escape(v8::Local<v8::Function>());\n    }\n\n    auto iter = constructorInfo->constructorMap.find(name);\n    if (iter != constructorInfo->constructorMap.end()) {\n        auto constructor = v8::Local<v8::Function>::New(isolate, iter->second);\n        return scope.Escape(constructor);\n    } else {\n        return scope.Escape(v8::Local<v8::Function>());\n    }\n}\n"
  },
  {
    "path": "src/platform/dll.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <platform/dll.h>\n#include <platform/filesystem.h>\n#include <platform/platform.h>\n\n#ifdef SUPPORT_POSIX\n\n#include <dlfcn.h>\n\n#else\n\n#pragma push_macro(\"NOMINMAX\")\n#define NOMINMAX\n#include <windows.h>\n#pragma pop_macro(\"NOMINMAX\")\n\n#endif\n\n#include <stdexcept>\n\nnamespace napa {\nnamespace dll {\n\nSharedLibrary::SharedLibrary(const std::string& dllFileName) {\n#ifdef SUPPORT_POSIX\n    _module = dlopen(dllFileName.c_str(), RTLD_LAZY);\n#else\n    _module = ::LoadLibraryA(dllFileName.c_str());\n#endif\n    if (_module == nullptr) {\n        throw std::runtime_error(dllFileName + \" cannot be loaded.\");\n    }\n}\n\nSharedLibrary::~SharedLibrary() {\n#ifdef SUPPORT_POSIX\n    dlclose(_module);\n#else\n    ::FreeLibrary(static_cast<HMODULE>(_module));\n#endif\n}\n\nvoid* SharedLibrary::ImportImpl(const std::string& symbolName) {\n#ifdef SUPPORT_POSIX\n    return reinterpret_cast<void*>(dlsym(_module, symbolName.c_str()));\n#else\n    return reinterpret_cast<void*>(::GetProcAddress(static_cast<HMODULE>(_module), symbolName.c_str()));\n#endif\n}\n\nstd::string ThisLineLocation() {\n    void* symbolAddress = reinterpret_cast<void*>(&ThisLineLocation);\n\n#ifdef SUPPORT_POSIX\n    Dl_info info;\n    auto result = dladdr(symbolAddress, &info);\n    if (result == 0) {\n        return \"\";\n    }\n    return info.dli_fname;\n#else\n    MEMORY_BASIC_INFORMATION mbi;\n    auto size = ::VirtualQuery(symbolAddress, &mbi, sizeof(mbi));\n    if (size == 0) {\n        return \"\";\n    }\n\n    static constexpr size_t DEFAULT_PATH_SIZE = 1024;\n    char path[DEFAULT_PATH_SIZE];\n    auto len = ::GetModuleFileNameA(reinterpret_cast<HMODULE>(mbi.AllocationBase), path, sizeof(path));\n    if (len == 0) {\n        return \"\";\n    }\n\n    // Currently we do not fully support UNC prefix in Napa.js.\n    //\n    // The following is a workaround to fix inconsistency of __dirname and __filename\n    // between Napa.js and Node.js\n    //\n    // https://github.com/Microsoft/napajs/issues/131\n    // Should remove this code when fixing Issue #131.\n    if (len > 4 && filesystem::Path(path).HasUncPrefix()) {\n        return path + 4;\n    }\n\n    return path;\n#endif\n}\n\n}\n}\n"
  },
  {
    "path": "src/platform/dll.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <string>\n\nnamespace napa {\nnamespace dll {\n\n    /// <summary> Cross-platform shared library access. </summary>\n    class SharedLibrary {\n    public:\n        SharedLibrary(const std::string& dllFileName);\n        virtual ~SharedLibrary();\n\n        template <typename T>\n        T* Import(const std::string& symbolName) {\n            return reinterpret_cast<T*>(ImportImpl(symbolName));\n        }\n\n    private:\n        void* ImportImpl(const std::string& symbolName);\n\n        void* _module;\n    };\n\n    /// <summary> Returns the path of the dll including this line of code. </summary>\n    std::string ThisLineLocation();\n}\n}"
  },
  {
    "path": "src/platform/filesystem.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <platform/filesystem.h>\n#include <platform/platform.h>\n\n#include \"utils/string.h\"\n\n#include <algorithm>\n#include <cstdio>\n#include <deque>\n#include <sstream>\n#include <iostream>\n#include <vector>\n\n#ifdef OS_MAC\n#include <mach-o/dyld.h>\n#endif\n\nnamespace napa {\nnamespace filesystem {\nusing CharType = Path::CharType;\nusing StringType = Path::StringType;\n\nnamespace {\n\n    /// <summary> Tell if a character is path separator. </summary>\n    bool IsSeparator(char ch) {\n#ifdef SUPPORT_POSIX\n        return ch == '/';\n#else\n        return ch == '/' || ch == '\\\\';\n#endif\n    }\n\n    /// <summary> Tell if a character is a letter. </summary>\n    bool IsLetter(char ch) {\n        return (ch >= 'A' && ch <= 'Z')\n            || (ch >= 'a' && ch <= 'z');\n    }\n\n    /// <summary> Tell if it's a root of Windows path. </summary>\n    bool IsWindowsRootSegment(const StringType& segment) {\n        return segment.size() == 2 && IsLetter(segment[0]) && segment[1] == ':';\n    }\n\n    /// <summary> Has UNC prefix \"\\\\\\\\?\" in windows. </summary>\n    bool ParseUncPrefix(const std::string& path) {\n        if (path.size() < 4) {\n            return false;\n        }\n        return path[0] == '\\\\' \n            && path[1] == '\\\\' \n            && path[2] == '?'\n            && path[3] == '\\\\';\n    }\n\n    /// <summary> Parse driver spec. </summary>\n    std::string ParseDriveSpec(const std::string& path, bool* hasUncPrefix = nullptr) {\n        StringType::size_type driveSpecStart = 0;\n        auto unc = ParseUncPrefix(path);\n\n        if (unc) {\n            driveSpecStart = 4;\n        }\n        if (path.size() < driveSpecStart + 2 ||\n            !IsLetter(path[driveSpecStart]) ||\n            path[driveSpecStart + 1] != ':') {\n            return \"\";\n        }\n        if (hasUncPrefix != nullptr) {\n            *hasUncPrefix = unc;\n        }\n        return path.substr(driveSpecStart, 2);\n    }\n\n    /// <summary> Resolve path string into segments. </summary>\n    void Parse(\n        const StringType& path,\n        bool* hasUncPrefix,\n        StringType* driveSpec,\n        bool* isAbsolute,\n        std::vector<StringType>* segments) {\n\n        StringType::size_type pathStart = 0;\n        bool unc = false;\n        auto drive = ParseDriveSpec(path, &unc);\n\n        if (unc) {\n            pathStart += 4;\n        }\n\n        if (!drive.empty()) {\n            pathStart += 2;\n        }\n\n        auto absolute = path.size() > pathStart && IsSeparator(path[pathStart]);\n\n        if (pathStart < path.size() && segments != nullptr) {\n            std::vector<StringType> segs;\n            std::deque<StringType> resolved;\n            utils::string::Split(path.begin() + pathStart, path.end(), segs, StringType(\"\\\\/\"), true);\n\n            for (auto it = segs.begin(); it < segs.end(); ++it) {\n                auto& seg = *it;\n                if (seg == \"..\") {\n                    // Backtrace '..'.\n                    if (resolved.empty() || resolved.back() == \"..\") {\n                        resolved.push_back(seg);\n                    }\n                    else {\n                        resolved.pop_back();\n                    }\n                }\n                else if (seg != \".\") {\n                    // Skip '.'\n                    resolved.push_back(seg);\n                }\n            }\n            segments->reserve(resolved.size());\n            for (auto it = resolved.begin(); it != resolved.end(); ++it) {\n                segments->emplace_back(std::move(*it));\n            }\n        }\n\n        if (hasUncPrefix != nullptr) {\n            *hasUncPrefix = unc;\n        }\n\n        if (driveSpec != nullptr) {\n            *driveSpec = drive;\n        }\n\n        if (isAbsolute != nullptr) {\n            *isAbsolute = absolute;\n        }\n    }\n\n    /// <summary> Format path name from path meta-data. </summary>\n    std::string FormatPathString(\n        bool hasUncPrefix,\n        const std::string& driveSpec,\n        bool isAbsolute,\n        const std::vector<StringType>& segments,\n        const CharType* seperator = platform::DIR_SEPARATOR) {\n\n        // Output normalized string.\n        std::stringstream ss;\n\n        if (hasUncPrefix) {\n            ss << \"\\\\\\\\?\\\\\";\n        }\n\n        // Drive spec could be empty.\n        ss << driveSpec;\n\n        if (isAbsolute) {\n            ss << platform::DIR_SEPARATOR;\n        }\n\n        for (auto it = segments.begin(); it != segments.end(); ++it) {\n            if (it != segments.begin()) {\n                ss << seperator;\n            }\n            ss << *it;\n        }\n        auto path = ss.str();\n        if (path.size() == 0) {\n            return \".\";\n        }\n        return path;\n    }\n\n}\n\nPath& Path::operator=(const CharType* path) {\n    _pathname = path;\n    return *this;\n}\n\nPath& Path::operator=(const StringType& path) {\n    _pathname = path;\n    return *this;\n}\n\nPath& Path::operator=(const Path& path) {\n    _pathname = path._pathname;\n    return *this;\n}\n\nPath& Path::operator=(StringType&& path) {\n    _pathname = std::move(path);\n    return *this;\n}\n\nPath& Path::operator=(Path&& path) {\n    _pathname = std::move(path._pathname);\n    return *this;\n}\n\nPath& Path::operator/=(const Path& path) {\n    return Append(path);\n}\n\nPath Path::operator/(const Path& path) const {\n    Path tmp(*this);\n    tmp /= path;\n    return tmp;\n}\n\nint Path::Compare(const Path& path) const {\n    return _pathname.compare(path._pathname);\n}\n\n/// <summary> Get unnormalized path string. </summary>\n/// <remarks> Use GenericForm() to always use '/' as delimiter. </summary>\nconst std::string& Path::String() const {\n    return _pathname;\n}\n\n/// <summary> Get unnormalized path string buffer. </summary>\nconst CharType* Path::c_str() const {\n    return _pathname.c_str();\n}\n\nPath& Path::Append(const Path& path) {\n    if (path.IsAbsolute()) {\n#ifdef _WIN32\n        auto drive = path.DriveSpec();\n        auto baseDrive = DriveSpec();\n\n        if (!path.HasUncPrefix() && drive.IsEmpty()) {\n            _pathname = baseDrive.String() + path._pathname;\n            return *this;\n        }\n#endif\n        _pathname = path._pathname;\n    }\n    else {\n        if (!path._pathname.empty()) {\n            if (!IsSeparator(path._pathname[0])) {\n                _pathname += platform::DIR_SEPARATOR;\n            }\n            _pathname += path._pathname;\n        }\n    }\n    return *this;\n}\n\nPath& Path::Normalize() {\n    if (!_pathname.empty()) {\n        std::string driveSpec;\n        bool hasUncPrefix = false;\n        bool isAbsolute = false;\n        std::vector<StringType> segs;\n\n        Parse(_pathname, &hasUncPrefix, &driveSpec, &isAbsolute, &segs);\n\n        // No parent path.\n        if (isAbsolute && segs.size() > 0 && segs[0] == \"..\") {\n            _pathname = \"\";\n        }\n        else {\n            _pathname = FormatPathString(hasUncPrefix, driveSpec, isAbsolute, segs, platform::DIR_SEPARATOR);\n        }\n    }\n    return *this;\n}\n\nPath& Path::ReplaceExtension(const std::string& extension) {\n    auto pos = _pathname.find_last_of(\"./\\\\\");\n    if (pos != StringType::npos && pos != _pathname.size() - 1 && _pathname[pos] == '.') {\n        _pathname.replace(pos, _pathname.size(), extension);\n    }\n    return *this;\n}\n\nPath Path::GenericForm() const {\n    if (HasUncPrefix()) {\n        return *this;\n    }\n\n    Path path(*this);\n    path.Normalize();\n\n#ifdef _WIN32\n    std::replace(path._pathname.begin(), path._pathname.end(), '\\\\', '/');\n#endif\n    return path;\n}\n\nPath Path::DriveSpec() const {\n    return Path(ParseDriveSpec(_pathname));\n}\n\nPath Path::Parent() const {\n    if (IsEmpty()) {\n        return Path();\n    }\n    return *this / \"..\";\n}\n\nPath Path::Dirname() const {\n    if (IsEmpty()) {\n        return Path(\".\");\n    }\n\n    auto pos = _pathname.find_last_of(\"/\\\\\");\n    if (pos == StringType::npos) {\n        // relative path, return '.' as directory name.\n        return Path(\".\");\n    }\n    return Path(_pathname.substr(0, pos));\n}\n\nPath Path::Extension() const {\n    auto pos = _pathname.find_last_of(\"./\\\\\");\n    if (pos == StringType::npos || pos == _pathname.size() - 1 || _pathname[pos] != '.') {\n        return Path();\n    }\n    return Path(_pathname.substr(pos));\n}\n\nPath Path::Basename() const {\n    if (IsEmpty() || IsFilenameDot() || IsFilenameDotDot()) {\n        return Path();\n    }\n    auto fileStart = _pathname.find_last_of(\"/\\\\\");\n    if (fileStart == StringType::npos) {\n        fileStart = 0;\n    }\n    auto dotStart = _pathname.find_last_of(\".\");\n    if (dotStart == StringType::npos || dotStart < fileStart) {\n        return Path(_pathname.substr(fileStart + 1));\n    }\n    return Path(_pathname.substr(fileStart + 1, dotStart - fileStart - 1));\n}\n\nPath Path::Filename() const {\n    if (IsEmpty()) {\n        return Path();\n    }\n\n    auto pos = _pathname.find_last_of(\"/\\\\\");\n    if (pos == StringType::npos) {\n        // relative path, return the whole path as filename.\n        return *this;\n    }\n    return Path(_pathname.substr(pos + 1));\n}\n\nbool Path::HasUncPrefix() const {\n    return ParseUncPrefix(_pathname);\n}\n\nbool Path::IsAbsolute() const {\n    if (IsEmpty()) {\n        return false;\n    }\n\n    StringType::size_type pathStart = 0;\n    if (HasUncPrefix()) {\n        pathStart += 4;\n    }\n\n    bool hasDriveSpec = HasDriveSpec();\n    if (hasDriveSpec) {\n        pathStart += 2;\n    }\n\n    if (pathStart >= _pathname.size()) {\n        return false;\n    }\n\n    return IsSeparator(_pathname[pathStart]);\n}\n\nPath Path::Relative(const Path& base) const {\n    Path current = Absolute().Normalize();\n    Path other = base.Absolute().Normalize();\n\n    if (current.IsEmpty() || other.IsEmpty()) {\n        return Path();\n    }\n\n    std::string driveSpecCurrent;\n    std::string driveSpecOther;\n\n    std::vector<StringType> segsCurrent;\n    std::vector<StringType> segsOther;\n\n    Parse(current._pathname, nullptr, &driveSpecCurrent, nullptr, &segsCurrent);\n    Parse(other._pathname, nullptr, &driveSpecOther, nullptr, &segsOther);\n\n    // Return current path if base is from different drive spec.\n    if (utils::string::ToLowerCopy(driveSpecCurrent) != utils::string::ToLowerCopy(driveSpecOther)) {\n        return current;\n    }\n\n    StringType::size_type same = 0;\n    for (; same < segsCurrent.size() && same < segsOther.size(); ++same) {\n        if (utils::string::ToLowerCopy(segsCurrent[same]) != utils::string::ToLowerCopy(segsOther[same])) {\n            break;\n        }\n    }\n\n    std::stringstream ss;\n    for (size_t i = 0; i < segsOther.size() - same; ++i) {\n        ss << \"..\" << platform::DIR_SEPARATOR;\n    }\n\n    for (size_t i = same; i < segsCurrent.size(); ++i) {\n        ss << segsCurrent[i];\n        if (i != segsCurrent.size() - 1) {\n            ss << platform::DIR_SEPARATOR;\n        }\n    }\n    return Path(ss.str()).RemoveTrailingSeparator();\n}\n\nPath Path::Absolute() const {\n    if (IsEmpty()) {\n        return Path();\n    }\n    return CurrentDirectory() / *this;\n}\n\nPath& Path::RemoveTrailingSeparator() {\n    if (_pathname.size() > 0 && IsSeparator(_pathname[_pathname.size() - 1])) {\n        _pathname.erase(_pathname.size() - 1);\n    }\n    return *this;\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Path& path) {\n    stream << path.String();\n    return stream;\n}\n\nbool operator==(const Path& lhs, const Path& rhs) {\n    return lhs.Compare(rhs) == 0;\n}\n\nbool operator!=(const Path& lhs, const Path& rhs) {\n    return lhs.Compare(rhs) != 0;\n}\n\nbool operator<(const Path& lhs, const Path& rhs) {\n    return lhs.Compare(rhs) < 0;\n}\n\nPath CurrentDirectory() {\n    static constexpr size_t DEFAULT_PATH_SIZE = 1024;\n    char path[DEFAULT_PATH_SIZE];\n\n#ifdef SUPPORT_POSIX\n    auto result = getcwd(path, sizeof(path));\n    if (result == nullptr) {\n        return Path();\n    }\n#else\n    DWORD result = ::GetCurrentDirectoryA(sizeof(path), path);\n    if (result == 0) {\n        return Path();\n    }\n#endif\n    return Path(path);\n}\n\nbool SetCurrentDirectory(const Path& path) {\n#ifdef SUPPORT_POSIX\n    return ::chdir(path.c_str()) == 0;\n#else\n    return ::SetCurrentDirectoryA(path.c_str()) == TRUE;\n#endif\n}\n\nPath ProgramPath() {\n    static constexpr size_t DEFAULT_PATH_SIZE = 1024;\n    char path[DEFAULT_PATH_SIZE] = { '\\0' };\n\n#if defined(OS_MAC)\n    uint32_t size = sizeof(path);\n    if (_NSGetExecutablePath(path, &size) == 0) {\n        return path;\n    }\n#elif defined(OS_WINDOWS)\n    if (::GetModuleFileNameA(NULL, path, sizeof(path)) > 0) {\n        return path;\n    }\n#elif defined(SUPPORT_POSIX)\n    if (::readlink(\"/proc/self/exe\", path, sizeof(path)) > 0\n        || ::readlink(\"/proc/curproc/file\", path, sizeof(path)) > 0\n        || ::readlink(\"/proc/self/path/a.out\", path, sizeof(path))) {\n        return path;\n    }\n#else\n    static_assert(false, \"Unsupported OS\";)\n#endif\n    return Path();\n}\n\nbool Exists(const Path& path) {\n#ifdef SUPPORT_POSIX\n    struct stat st;\n    return ::stat(path.c_str(), &st) == 0;\n#else\n    auto attribute = GetFileAttributesA(path.c_str());\n    return attribute != INVALID_FILE_ATTRIBUTES;\n#endif\n}\n\nbool IsRegularFile(const Path& path) {\n#ifdef SUPPORT_POSIX\n    struct stat st;\n    return ::stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode);\n#else\n    // We don't deal with symlink for now.\n    auto attribute = GetFileAttributesA(path.c_str());\n    return attribute != INVALID_FILE_ATTRIBUTES && !(attribute & FILE_ATTRIBUTE_DIRECTORY);\n#endif\n}\n\nbool IsDirectory(const Path& path) {\n#ifdef SUPPORT_POSIX\n    struct stat st;\n    return ::stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode);\n#else\n    // We don't deal with symlink for now.\n    auto attribute = GetFileAttributesA(path.c_str());\n    return attribute != INVALID_FILE_ATTRIBUTES && attribute & FILE_ATTRIBUTE_DIRECTORY;\n#endif\n}\n\nbool MakeDirectory(const Path& path) {\n#ifdef SUPPORT_POSIX\n    return ::mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0 || errno == EEXIST;\n#else\n    return ::CreateDirectoryA(path.c_str(), 0) == TRUE || ::GetLastError() == ERROR_ALREADY_EXISTS;\n#endif\n}\n\nbool MakeDirectories(const Path& path) {\n    if (path.IsEmpty()) {\n        return false;\n    }\n    if (IsDirectory(path)) {\n        return true;\n    }\n    auto parent = path.Parent().Normalize();\n    if (!IsDirectory(parent) && !MakeDirectories(parent)) {\n        return false;\n    }\n    return MakeDirectory(path);\n}\n\nPathIterator::PathIterator(Path path)\n    : _base(std::move(path)) {\n#ifdef SUPPORT_POSIX\n    _dir = ::opendir(_base.c_str());\n#else\n    _first = true;\n    WIN32_FIND_DATAA findData;\n    std::string pattern = _base.String() + \"\\\\*\";\n    _findHandle = ::FindFirstFileA(pattern.c_str(), &findData);\n\n    if (_findHandle != INVALID_HANDLE_VALUE) {\n        _currentPath = _base / findData.cFileName;\n    }\n#endif\n}\n\nPathIterator::~PathIterator() {\n#ifdef SUPPORT_POSIX\n    if (_dir != nullptr) {\n        (void)closedir(_dir);\n    }\n#else\n    if (_findHandle != INVALID_HANDLE_VALUE) {\n        (void)::FindClose(_findHandle);\n    }\n#endif\n}\n\nconst Path& PathIterator::operator*() const {\n    return _currentPath;\n}\n\nconst Path* PathIterator::operator->() const {\n    return &_currentPath;\n}\n\nbool PathIterator::Next() {\n#ifdef SUPPORT_POSIX\n    if (_dir == nullptr) {\n        return false;\n    }\n    struct dirent *dp;\n    dp = ::readdir(_dir);\n    if (dp == nullptr) {\n        return false;\n    }\n    _currentPath = _base / dp->d_name;\n#else\n    if (_findHandle == INVALID_HANDLE_VALUE) {\n        return false;\n    }\n\n    if (_first) {\n        _first = false;\n    }\n    else {\n        WIN32_FIND_DATAA findData;\n        if (::FindNextFileA(_findHandle, &findData) == FALSE) {\n            return false;\n        }\n        _currentPath = _base / findData.cFileName;\n    }\n#endif\n\n    if (_currentPath.IsFilenameDot() || _currentPath.IsFilenameDotDot()) {\n        // Don't include '.' or '..' as files in a directory.\n        return Next();\n    }\n\n    return true;\n}\n\n}\n}\n"
  },
  {
    "path": "src/platform/filesystem.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n#include <platform/platform.h>\n#include <platform/os.h>\n\n#include <string>\n\n#ifdef SUPPORT_POSIX\n\n#include <dirent.h>\n#include <errno.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#else\n\n#pragma push_macro(\"NOMINMAX\")\n#define NOMINMAX\n#include <windows.h>\n#pragma pop_macro(\"NOMINMAX\")\n\n#endif\n\nnamespace napa {\nnamespace filesystem {\n\n    /// <summary> Helper class for path manipulation. </summary>\n    class Path {\n    public:\n\n        // We only support ANSI path for now.\n        // TODO: consider use wchar_t for Windows.\n        typedef char CharType;\n\n        typedef std::basic_string<CharType> StringType;\n\n        Path() {}\n\n        Path(const CharType* path) : _pathname(path) {}\n        Path(const StringType& path) : _pathname(path) {}\n        Path(StringType&& path) : _pathname(std::move(path)) {}\n\n        Path(const Path& path) : _pathname(path._pathname) {}\n        Path(Path&& path) : _pathname(std::move(path._pathname)) {}\n\n        Path& operator=(const CharType* path);\n        Path& operator=(const StringType& path);\n        Path& operator=(const Path& path);\n        Path& operator=(StringType&& path);\n        Path& operator=(Path&& path);\n\n        /// <summary> Operator to append a relative path. </summary>\n        Path& operator/=(const Path& path);\n\n        /// <summary> Operator to append a relative path. </summary>\n        Path operator/(const Path& path) const;\n\n        /// <summary> Compare two paths. </summary>\n        int Compare(const Path& path) const;\n\n        /// <summary> Get unnormalized path string. </summary>\n        /// <remarks> Use GenericForm() to always use '/' as delimiter. </summary>\n        const std::string& String() const;\n\n        /// <summary> Get unnormalized path string buffer. </summary>\n        const CharType* c_str() const;\n\n        /// <summary> \n        ///     Append a path to current path\n        ///     Or return the path if it's absolute.\n        /// </summary>\n        Path& Append(const Path& path);\n\n        /// <summary> Normalize current path. </summary>\n        Path& Normalize();\n\n        /// <summary> Replace extension. </summary>\n        Path& ReplaceExtension(const std::string& extension);\n\n        /// <summary> Get normalized generic form of path string. using '/' as separator. </summary>\n        Path GenericForm() const;\n\n        /// <summary> Drive spec. </summary>\n        Path DriveSpec() const;\n\n        /// <summary> Get parent path. (normalized) </summary>\n        Path Parent() const;\n\n        /// <summary> Return directory name. </summary>\n        Path Dirname() const;\n\n        /// <summary> Return file extension of current path. </summary>\n        Path Extension() const;\n\n        /// <summary> Return base file name without extension. </summary>\n        Path Basename() const;\n\n        /// <summary> Return file name of current path. </summary>\n        Path Filename() const;\n\n        /// <summary> Has UNC prefix \\\\? (Windows). </summary>\n        bool HasUncPrefix() const;\n\n        /// <summary> Has drive specification like c: (Windows). </summary>\n        bool HasDriveSpec() const {\n            return !DriveSpec().IsEmpty();\n        }\n\n        /// <summary> Tell if path has file name. </summary>\n        bool HasFilename() const {\n            return !Filename().IsEmpty();\n        }\n\n        /// <summary> Tell if path has extension. </summary>\n        bool HasExtension() const {\n            return !Extension().IsEmpty();\n        }\n\n        /// <summary> Tell if current path is empty. </summary>\n        bool IsEmpty() const {\n            return _pathname.empty();\n        }\n\n        /// <summary> Tell if current path is an absolute path. </summary>\n        bool IsAbsolute() const;\n\n        /// <summary> Tell if current path is relative or not. </summary>\n        bool IsRelative() const {\n            return !IsAbsolute();\n        }\n\n        /// <summary> Tell if current file name is '.'. </summary>\n        bool IsFilenameDot() const {\n            return Filename().String() == \".\";\n        }\n\n        /// <summary> Tell if current file name is '..'. </summary>\n        bool IsFilenameDotDot() const {\n            return Filename().String() == \"..\";\n        }\n\n        /// <summary> Get relative path to a base. </summary>\n        Path Relative(const Path& base) const;\n\n        /// <summary> Get normalized absolute path. </summary>\n        Path Absolute() const;\n\n    private:\n        /// <summary> Remove one trailing separator. </summary>\n        Path& RemoveTrailingSeparator();\n\n        /// <summary> Unnormalized path. </summary>\n        StringType _pathname;\n    };\n\n    /// <summary> Support outputing to ostream. </summary>\n    std::ostream& operator<<(std::ostream& stream, const Path& path);\n\n    bool operator==(const Path& lhs, const Path& rhs);\n    bool operator!=(const Path& lhs, const Path& rhs);\n    bool operator<(const Path& lhs, const Path& rhs);\n\n    /// <summary> Get current working directory. </summary>\n    Path CurrentDirectory();\n\n    /// <summary> Set current working directory. </summary>\n    bool SetCurrentDirectory(const Path& path);\n\n    /// <summary> Get path of current process. </summary>\n    Path ProgramPath();\n\n    /// <summary> Tell if a path exists (either a regular file or directory). </summary>\n    bool Exists(const Path& path);\n\n    /// <summary> Tell if a path is a regular file. </summary>\n    bool IsRegularFile(const Path& path);\n\n    /// <summary> Tell if a path is a directory. </summary>\n    bool IsDirectory(const Path& path);\n\n    /// <summary> Make a directory. </summary>\n    /// <returns> True if succeed or directory already exists, false if operation failed. </returns>\n    bool MakeDirectory(const Path& path);\n\n    /// <summary> Make directories recursively. </summary>\n    bool MakeDirectories(const Path& path);\n\n    /// <summary> Path iterator </summary>\n    class PathIterator {\n    public:\n        PathIterator(Path path);\n        ~PathIterator();\n\n        /// <summary> Operator to get the path reference. </summary>\n        const Path& operator*() const;\n\n        /// <summary> Operator to get the path pointer. </summary>\n        const Path* operator->() const;\n\n        /// <summary> Move to next file, or return false. </summary>\n        /// <remarks> Always call Next() after construction. </remarks>\n        bool Next();\n\n    private:\n\n#ifdef SUPPORT_POSIX\n        DIR* _dir;\n#else\n        HANDLE _findHandle;\n        bool _first;\n#endif\n        Path _base;\n        Path _currentPath;\n    };\n}\n}"
  },
  {
    "path": "src/platform/os.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <platform/os.h>\n#include <platform/platform.h>\n\n#ifdef SUPPORT_POSIX\n#include <sys/utsname.h>\n#endif\n\n#include <stdexcept>\n\nnamespace napa {\nnamespace platform {\n\nconst char* GetOSType() {\n#ifdef SUPPORT_POSIX\n    static struct utsname info;\n    if (uname(&info) < 0) {\n        throw std::runtime_error(\"Error getting uname\");\n    }\n    return info.sysname;\n#else\n    return \"Windows_NT\";\n#endif\n}\n\n\n#ifdef SUPPORT_POSIX\n    const char* ENV_DELIMITER = \":\";\n#else\n    const char* ENV_DELIMITER = \";\";\n#endif\n\n#ifdef SUPPORT_POSIX\n    const char* DIR_SEPARATOR = \"/\";\n#else\n    const char* DIR_SEPARATOR = \"\\\\\";\n#endif\n\n}\n}\n"
  },
  {
    "path": "src/platform/os.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\nnamespace napa {\nnamespace platform {\n    /// <summary> Get OS type. </summary>\n    const char* GetOSType();\n\n    /// <summary> Environment variables delimiter. </summary>\n    extern const char* ENV_DELIMITER;\n\n    /// <summary> Directory separator. </summary>\n    extern const char* DIR_SEPARATOR;\n}\n}\n"
  },
  {
    "path": "src/platform/platform.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)\n\n#ifndef SUPPORT_WINDOWS\n#define SUPPORT_WINDOWS\n#endif\n\n#else\n\n#ifndef SUPPORT_POSIX\n#define SUPPORT_POSIX\n#endif\n\n#endif\n\n#if defined(__linux) || defined(__linux__) || defined(linux)\n#define OS_LINUX\n#elif defined(__APPLE__)\n#define OS_MAC\n#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)\n#define OS_WINDOWS\n#elif defined(__FreeBSD__) || defined(__FreeBSD)\n#define OS_FREEBSD\n#else\n// Unknown OS\n#endif\n\nnamespace napa {\nnamespace platform {\n    /// <summary> Platform. </summary>\n#if defined(OS_LINUX)\n    constexpr const char* PLATFORM = \"linux\";\n#elif defined(OS_MAC)\n    constexpr const char* PLATFORM = \"darwin\";\n#elif defined(OS_WINDOWS)\n    constexpr const char* PLATFORM = \"win32\";\n#elif defined(OS_FREEBSD)\n    constexpr const char* PLATFORM = \"freebsd\";\n#else\n    constexpr const char* PLATFORM = \"unknown\";\n#endif\n}   // End of namespce platform.\n}   // End of namespce napa.\n"
  },
  {
    "path": "src/platform/process.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <platform/process.h>\n#include <platform/platform.h>\n\n#ifdef SUPPORT_POSIX\n\n#include <unistd.h>\n#include <limits.h>\n#include <sys/syscall.h>\n\n#else\n\n#include <windows.h>\n\n#include <io.h>\n#include <process.h>\n\n#endif\n\n#include <sys/stat.h>\n\n#include <functional>\n#include <memory>\n#include <sstream>\n#include <string>\n#include <vector>\n\nnamespace napa {\nnamespace platform {\n\nnamespace {\n#ifdef SUPPORT_POSIX\n    static size_t ReadBuffer(const char* filename, char* buffer, size_t length) {\n        FILE* source = fopen(filename, \"rb\");\n        if (source == nullptr) {\n            return 0;\n        }\n\n        std::unique_ptr<FILE, std::function<void(FILE*)>> deferred(source, [](auto file) {\n            fclose(file);\n        });\n\n        return fread(buffer, 1, length, source);\n    }\n\n    struct CommandLineArgs {\n        int argc;\n        std::vector<char*> argv;\n\n        CommandLineArgs() {\n            size_t length = ReadBuffer(\"/proc/self/cmdline\", commandLine, PATH_MAX);\n            commandLine[length] = '\\0';\n\n            ParseCommandLine(length);\n        }\n\n    private:\n        void ParseCommandLine(size_t length) {\n            argc = 0;\n            argv.clear();\n\n            bool start = true;\n            for (size_t i = 0; i < length; i++) {\n                if (start && commandLine[i] != '\\0') {\n                    start = false;\n                    argv.push_back(commandLine + i);\n                    argc++;\n                }\n                else if (commandLine[i] == '\\0') {\n                    start = true;\n                }\n            }\n        }\n\n        char commandLine[PATH_MAX + 1];\n    };\n\n    static const CommandLineArgs& GetCommandLineArgs() {\n        static CommandLineArgs commandLineArgs;\n        return commandLineArgs;\n    }\n#endif\n}\n\nint GetArgc() {\n#ifdef SUPPORT_POSIX\n    return GetCommandLineArgs().argc;\n#else\n    return __argc;\n#endif\n}\n\n/// <summary> Get the process arguments. </summary>\nchar** GetArgv() {\n#ifdef SUPPORT_POSIX\n    return const_cast<char**>(&GetCommandLineArgs().argv[0]);\n#else\n    return __argv;\n#endif\n}\n\nbool SetEnv(const char* name, const char* value) {\n#ifdef SUPPORT_POSIX\n    return 0 == setenv(name, value, 1);\n#else\n    std::ostringstream oss;\n    oss << name << \"=\" << value;\n    return _putenv(oss.str().c_str()) == 0;\n#endif\n}\n\nstd::string GetEnv(const char* name) {\n#ifdef SUPPORT_POSIX\n    std::string value;\n\n    char* buffer = getenv(name);\n    if (buffer != nullptr) {\n        value.assign(buffer);\n    }\n\n    return value;\n#else\n    std::string value;\n\n    char* buffer = nullptr;\n    size_t size = 0;\n    if (_dupenv_s(&buffer, &size, name) == 0 && buffer != nullptr) {\n        value.assign(buffer, size - 1);\n        free(buffer);\n    }\n\n    return value;\n#endif\n}\n\nint32_t Umask(int32_t mode) {\n#ifdef SUPPORT_POSIX\n    return static_cast<int32_t>(umask(mode));\n#else\n    int32_t oldMask;\n    if (_umask_s(mode, &oldMask)) {\n        throw std::runtime_error(\"Error setting umask\");\n    }\n    return oldMask;\n#endif\n}\n\nint32_t Getpid() {\n#ifdef SUPPORT_POSIX\n    return static_cast<int32_t>(getpid());\n#else\n    return _getpid();\n#endif\n}\n\nint32_t Gettid() {\n#ifdef SUPPORT_POSIX\n    return static_cast<int32_t>(syscall(SYS_gettid));\n#else\n    return static_cast<int32_t>(GetCurrentThreadId());\n#endif\n}\n\nint32_t Isatty(int32_t fd) {\n#ifdef SUPPORT_POSIX\n    return static_cast<int32_t>(isatty(fd));\n#else\n    return _isatty(fd);\n#endif\n}\n\n}\n}\n"
  },
  {
    "path": "src/platform/process.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <cstdint>\n#include <string>\n\nnamespace napa {\nnamespace platform {\n\n    /// <summary> Get the number of process arguments. </summary>\n    int GetArgc();\n\n    /// <summary> Get the process arguments. </summary>\n    char** GetArgv();\n\n    /// <summary> Set environment variable. </summary>\n    bool SetEnv(const char* name, const char* value);\n\n    /// <summary> Get environment variable. </summary>\n    std::string GetEnv(const char* name);\n\n    /// <summary> Set file permission mask at the current process. </summary>\n    int32_t Umask(int32_t mode);\n\n    /// <summary> Return pid. </summary>\n    int32_t Getpid();\n\n    /// <summary> Return tid. </summary>\n    int32_t Gettid();\n\n    /// <summary> Return nonzero value if a descriptor is associated with a character device. </summary>\n    /// <param name=\"fd\"> File descriptor. </param>\n    int32_t Isatty(int32_t fd);\n\n}\n}"
  },
  {
    "path": "src/platform/thread-local.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n#pragma once\n\n#include <napa/assert.h>\n#include <platform/platform.h>\n\n#ifdef SUPPORT_POSIX\n\n#include <pthread.h>\n\n#else\n\n#include <windows.h>\n\n#endif\n\nnamespace napa {\nnamespace tls {\n\n    /// <summary> Cross platform implementation for Tls. </summary>\n    /// <remarks> Use thread_local once major clang versions supports it. </remarks>\n    template <typename T>\n    class ThreadLocal {\n    public:\n        ThreadLocal() {\n#ifdef SUPPORT_POSIX\n            auto result = pthread_key_create(&_key, nullptr);\n            NAPA_ASSERT(result == 0, \"Failed to create key for TLS\");\n#else\n            _key = TlsAlloc();\n            NAPA_ASSERT(_key != TLS_OUT_OF_INDEXES, \"Failed to create key for TLS\");\n#endif\n        }\n\n        ~ThreadLocal() {\n            auto object = TlsGet();\n            if (object != nullptr) {\n                delete object;\n            }\n\n#ifdef SUPPORT_POSIX\n            auto result = pthread_key_delete(_key);\n            NAPA_ASSERT(result == 0, \"Failed to delete key for TLS\");\n#else\n            auto result = TlsFree(_key);\n            NAPA_ASSERT(result == TRUE, \"Failed to delete key \");\n#endif\n        }\n\n        /// <summary> Per-thread install object of T.  </summary>\n        template <typename... Args>\n        void Install(Args&&... args) {\n            auto object = new T(std::forward<Args>(args)...);\n            TlsSet(object);\n        }\n\n        T& operator*() {\n            return *TlsGet();\n        }\n\n        T* operator->() {\n            return TlsGet();\n        }\n\n        const T& operator*() const {\n            return *TlsGet();\n        }\n\n        const T* operator->() const {\n            return TlsGet();\n        }\n\n        /// <summary> Reset current Tls slot with another pointer. </summary>\n        void Reset(T* object) {\n            T* old = TlsGet();\n            if (old != nullptr) {\n                delete old;\n            }\n            TlsSet(object);\n        }\n\n    private:\n        /// <summary> Get const pointer of T in current Tls slot.  </summary>\n        T* TlsGet() const {\n#ifdef SUPPORT_POSIX\n            return reinterpret_cast<T*>(pthread_getspecific(_key));\n#else\n            return reinterpret_cast<T*>(TlsGetValue(_key));\n#endif\n        }\n\n        /// <summary> Set value for current Tls slot. </summary>\n        void TlsSet(const void* object) {\n#ifdef SUPPORT_POSIX\n            auto result = pthread_setspecific(_key, object);\n            NAPA_ASSERT(result == 0, \"Failed to set value in Tls\");\n#else\n            auto result = TlsSetValue(_key, (LPVOID)object);\n            NAPA_ASSERT(result == TRUE, \"Failed to set value in Tls\");\n#endif\n        }\n\n#ifdef SUPPORT_POSIX\n        pthread_key_t _key;\n#else\n        DWORD _key;\n#endif\n    };\n}\n}"
  },
  {
    "path": "src/providers/console-logging-provider.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/providers/logging.h>\n\n#include <stdio.h>\n\nnamespace napa {\nnamespace providers {\n\n    /// <summary> A logging provider that logs to the standard console. </summary>\n    class ConsoleLoggingProvider : public LoggingProvider {\n    public:\n\n        virtual void LogMessage(\n            const char* section,\n            Verboseness level,\n            const char* traceId,\n            const char* file,\n            int line,\n            const char* message) override {\n            if (section == nullptr || section[0] == '\\0') {\n                printf(\"%s [%s:%d]\\n\", message, file, line);\n            } else {\n                printf(\"[%s] %s [%s:%d]\\n\", section, message, file, line);\n            }\n        }\n\n        virtual bool IsLogEnabled(const char* section, Verboseness level) override {\n            return true;\n        }\n\n        virtual void Destroy() override {\n            // Don't actually delete. We're a lifetime process object.\n        }\n    };\n\n}\n}\n"
  },
  {
    "path": "src/providers/nop-logging-provider.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/providers/logging.h>\n\n\nnamespace napa {\nnamespace providers {\n\n    /// <summary> A logging provider that does nothing. </summary>\n    class NopLoggingProvider : public LoggingProvider {\n    public:\n\n        virtual void LogMessage(\n            const char* section,\n            Verboseness level,\n            const char* traceId,\n            const char* file,\n            int line,\n            const char* message) override {}\n\n        virtual bool IsLogEnabled(const char* section, Verboseness level) override {\n            return false;\n        }\n\n        virtual void Destroy() override {\n            // Don't actually delete. We're a lifetime process object.\n        }\n\n    };\n\n}\n}\n"
  },
  {
    "path": "src/providers/nop-metric-provider.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/providers/metric.h>\n\nnamespace napa {\nnamespace providers {\n\n    ///<summary> A no-operation instance of a Metric. </summary>\n    class NopMetric : public Metric {\n    public:\n\n        bool Set(int64_t, size_t, const char*[]) override {\n            return true;\n        }\n\n        bool Increment(uint64_t, size_t, const char*[]) override {\n            return true;\n        }\n\n        bool Decrement(uint64_t, size_t, const char*[]) override {\n            return true;\n        }\n\n        void Destroy() override {\n            // Don't actually delete. We're a lifetime process object.\n        }\n    };\n\n    ///<summary> A no-operation instance of a MetricProvider.</summary>\n    class NopMetricProvider : public MetricProvider\n    {\n    public:\n\n        NopMetricProvider() : _defaultMetric(new NopMetric()) {}\n\n        Metric* GetMetric(const char*, const char*, MetricType, size_t, const char**) override {\n            return _defaultMetric;\n        }\n\n        virtual void Destroy() override {\n            // Don't actually delete. We're a lifetime process object.\n        }\n\n    private:\n        Metric* _defaultMetric;\n    };\n}\n}\n\n"
  },
  {
    "path": "src/providers/providers.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"providers.h\"\n\n#include \"console-logging-provider.h\"\n#include \"nop-logging-provider.h\"\n#include \"nop-metric-provider.h\"\n\n#include <module/loader/module-resolver.h>\n#include <platform/dll.h>\n#include <platform/filesystem.h>\n\n#include <napa/log.h>\n\n#include <rapidjson/document.h>\n#include <rapidjson/error/en.h>\n#include <rapidjson/istreamwrapper.h>\n\n#include <fstream>\n#include <string>\n\nusing namespace napa;\nusing namespace napa::providers;\n\n// Forward declarations.\nstatic LoggingProvider* LoadLoggingProvider(const std::string& providerName);\nstatic MetricProvider* LoadMetricProvider(const std::string& providerName);\n\n// Providers - Initially assigned to defaults.\nstatic LoggingProvider* _loggingProvider = LoadLoggingProvider(\"\");\nstatic MetricProvider* _metricProvider = LoadMetricProvider(\"\");\n\n\nbool napa::providers::Initialize(const settings::PlatformSettings& settings) {\n    _loggingProvider = LoadLoggingProvider(settings.loggingProvider);\n    _metricProvider = LoadMetricProvider(settings.metricProvider);\n\n    return true;\n}\n\nvoid napa::providers::Shutdown() {\n    if (_loggingProvider != nullptr) {\n        _loggingProvider->Destroy();\n    }\n    \n    if (_metricProvider != nullptr) {\n        _metricProvider->Destroy();\n    }\n}\n\nLoggingProvider& napa::providers::GetLoggingProvider() {\n    return *_loggingProvider;\n}\n\nMetricProvider& napa::providers::GetMetricProvider() {\n    return *_metricProvider;\n}\n\ntemplate <typename ProviderType>\nstatic ProviderType* LoadProvider(\n    const std::string& providerName,\n    const std::string& jsonPropertyPath,\n    const std::string& functionName) {\n\n    napa::module::ModuleResolver moduleResolver;\n\n    // Resolve the provider module information\n    auto moduleInfo = moduleResolver.Resolve(providerName.c_str());\n    NAPA_ASSERT(!moduleInfo.packageJsonPath.empty(), \"missing package.json in provider '%s'\", providerName.c_str());\n\n    // Full path to the root of the provider module\n    auto modulePath = filesystem::Path(moduleInfo.packageJsonPath).Parent().Normalize();\n\n    // Extract relative path to provider dll from package.json\n    rapidjson::Document package;\n    std::ifstream ifs(moduleInfo.packageJsonPath);\n    rapidjson::IStreamWrapper isw(ifs);\n    NAPA_ASSERT(!package.ParseStream(isw).HasParseError(), rapidjson::GetParseError_En(package.GetParseError()));\n\n    NAPA_ASSERT(package.HasMember(jsonPropertyPath.c_str()),\n                \"missing property '%s' in '%s'\",\n                jsonPropertyPath.c_str(),\n                moduleInfo.packageJsonPath.c_str());\n\n    auto providerRelativePath = package[jsonPropertyPath.c_str()].GetString();\n\n    // Full path to provider dll\n    auto providerPath = (modulePath / providerRelativePath).Normalize();\n\n    // Keep a static instance for each provider type (each template type will have its own static variable).\n    static dll::SharedLibrary library(providerPath.String());\n    auto createProviderFunc = library.Import<ProviderType*()>(functionName);\n    return createProviderFunc();\n}\n\nstatic LoggingProvider* LoadLoggingProvider(const std::string& providerName) {\n    if (providerName.empty() || providerName == \"console\") {\n        static auto consoleLoggingProvider = std::make_unique<ConsoleLoggingProvider>();\n        return consoleLoggingProvider.get();\n    }\n\n    if (providerName == \"nop\") {\n        static auto nopLoggingProvider = std::make_unique<NopLoggingProvider>();\n        return nopLoggingProvider.get();\n    }\n\n    return LoadProvider<LoggingProvider>(providerName, \"providers.logging\", \"CreateLoggingProvider\");\n}\n\nstatic MetricProvider* LoadMetricProvider(const std::string& providerName) {\n    if (providerName.empty()) {\n        static auto nopMetricProvider = std::make_unique<NopMetricProvider>();\n        return nopMetricProvider.get();\n    }\n\n    return LoadProvider<MetricProvider>(providerName, \"providers.metric\", \"CreateMetricProvider\");;\n}\n"
  },
  {
    "path": "src/providers/providers.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/providers/logging.h>\n#include <napa/providers/metric.h>\n\n#include \"settings/settings.h\"\n\n\nnamespace napa {\nnamespace providers {\n\n    /// <summary> Initializes and loads all providers based on the provided settings. </summary>\n    bool Initialize(const settings::PlatformSettings& settings);\n\n    /// <summary> Clean up and destroy all loaded providers. </summary>\n    void Shutdown();\n}\n}\n"
  },
  {
    "path": "src/settings/settings-parser.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"settings-parser.h\"\n\n#include <napa/log.h>\n\n// Open source header only library for argument parsing.\n// https://github.com/Taywee/args\n#include <args/args.hxx>\n\nusing namespace napa;\nusing namespace napa::settings;\n\n\nbool settings::Parse(const std::vector<std::string>& args, PlatformSettings& settings) {\n    args::ArgumentParser parser(\"platform settings parser\");\n\n    args::ValueFlag<std::string> loggingProvider(parser, \"loggingProvider\", \"logging provider\", { \"loggingProvider\" });\n    args::ValueFlag<std::string> metricProvider(parser, \"metricProvider\", \"metric provider\", { \"metricProvider\" });\n\n    try {\n        parser.ParseArgs(args);\n    }\n    catch (const std::exception& ex) {\n        LOG_ERROR(\"Settings\", \"Failed to parse platform settings. Error: %s\", ex.what());\n        return false;\n    }\n\n    if (loggingProvider) {\n        settings.loggingProvider = loggingProvider.Get();\n    }\n\n    if (metricProvider) {\n        settings.metricProvider = metricProvider.Get();\n    }\n\n    return true;\n}\n\nbool settings::Parse(const std::vector<std::string>& args, ZoneSettings& settings) {\n    args::ArgumentParser parser(\"zone settings parser\");\n\n    args::ValueFlag<uint32_t> workers(parser, \"workers\", \"number of zone workers\", { \"workers\" });\n    args::ValueFlag<uint32_t> maxOldSpaceSize(parser, \"maxOldSpaceSize\", \"max old space size in MB\", { \"maxOldSpaceSize\" });\n    args::ValueFlag<uint32_t> maxSemiSpaceSize(parser, \"maxSemiSpaceSize\", \"max semi space size in MB\", { \"maxSemiSpaceSize\" });\n    args::ValueFlag<uint32_t> maxExecutableSize(parser, \"maxExecutableSize\", \"max executable size in MB\", { \"maxExecutableSize\" });\n    args::ValueFlag<uint32_t> maxStackSize(parser, \"maxStackSize\", \"max isolate stack size in bytes\", { \"maxStackSize\" });\n\n    try {\n        parser.ParseArgs(args);\n    }\n    catch (const std::exception& ex) {\n        LOG_ERROR(\"Settings\", \"Failed to parse zone settings. Error: %s\", ex.what());\n        return false;\n    }\n\n    if (workers) {\n        NAPA_ASSERT(workers.Get() > 0, \"The number of workers must be greater than 0\");\n        settings.workers = workers.Get();\n    }\n\n    if (maxOldSpaceSize) {\n        settings.maxOldSpaceSize = maxOldSpaceSize.Get();\n    }\n\n    if (maxSemiSpaceSize) {\n        settings.maxSemiSpaceSize = maxSemiSpaceSize.Get();\n    }\n\n    if (maxExecutableSize) {\n        settings.maxExecutableSize = maxExecutableSize.Get();\n    }\n\n    if (maxStackSize) {\n        NAPA_ASSERT(maxStackSize.Get() > 0, \"The maximum allowed stack size must be greater than 0\");\n        settings.maxStackSize = maxStackSize.Get();\n    }\n\n    return true;\n}"
  },
  {
    "path": "src/settings/settings-parser.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"settings.h\"\n#include <utils/string.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n\nnamespace napa {\nnamespace settings {\n\n    /// <summary> Parses napa settings from a vector of arguments. </summary>\n    /// <param name=\"str\"> The arguments holding the settings. </param>\n    /// <param name=\"settings\">\n    ///     A setting out parameter that is filled with parsed settings.\n    ///     Settings that do not appear in the settings string will not be changed.\n    /// </param>\n    /// <returns> True if parsing succeeded, false otherwise. </returns>\n    bool Parse(const std::vector<std::string>& args, ZoneSettings& settings);\n    bool Parse(const std::vector<std::string>& args, PlatformSettings& settings);\n\n    /// <summary> Parses napa settings from string. </summary>\n    /// <param name=\"str\"> The settings string that will be parsed. </param>\n    /// <param name=\"settings\">\n    ///     A setting out parameter that is filled with parsed settings.\n    ///     Settings that do not appear in the settings string will not be changed.\n    /// </param>\n    /// <returns> True if parsing succeeded, false otherwise. </returns>\n    template <typename SettingsType>\n    bool ParseFromString(const std::string& str, SettingsType& settings) {\n        auto strCopy = utils::string::TrimCopy(str);\n        if (strCopy.empty()) {\n            return true;\n        }\n\n        std::vector<std::string> args;\n        try {\n            utils::string::Split(strCopy, args, \"\\t \", true);\n        }\n        catch (std::exception& ex) {\n            std::cerr << \"Failed to split input string [\" << strCopy << \"] error: \" << ex.what() << std::endl;\n            return false;\n        }\n\n        return Parse(args, settings);\n    }\n\n    /// <summary> Parses napa settings console args. </summary>\n    /// <param name=\"argc\"> Number of arguments. </param>\n    /// <param name=\"argv\"> The arguments. </param>\n    /// <param name=\"settings\">\n    ///     A setting out parameter that is filled with parsed settings.\n    ///     Settings that do not appear in the settings string will not be changed.\n    /// </param>\n    /// <returns> True if parsing succeeded, false otherwise. </returns>\n    template <typename SettingsType>\n    bool ParseFromConsole(int argc, const char* argv[], SettingsType& settings) {\n        std::vector<std::string> args;\n\n        // Skip first parameter (program name)\n        args.reserve(argc - 1);\n        for (auto i = 1; i < argc; i++) {\n            args.emplace_back(argv[i]);\n        }\n\n        return Parse(args, settings);\n    }\n}\n}"
  },
  {
    "path": "src/settings/settings.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <algorithm>\n#include <string>\n#include <vector>\n\nnamespace napa {\nnamespace settings {\n\n    /// <summary> Platform settings - setting that affect all zones. </summary>\n    struct PlatformSettings {\n\n        /// <summary> The logging provider. </summary>\n        std::string loggingProvider = \"console\";\n\n        /// <summary> The metric provider. </summary>\n        std::string metricProvider;\n    };\n\n    /// <summary> Zone specific settings. </summary>\n    struct ZoneSettings {\n\n        /// <summary> The zone id. </summary>\n        std::string id;\n\n        /// <summary> The number of zone workers. </summary>\n        uint32_t workers = 2;\n\n        /// <summary> Isolate memory constraint - The maximum old space size in megabytes. </summary>\n        uint32_t maxOldSpaceSize = 0u;\n\n        /// <summary> Isolate memory constraint - The maximum semi space size in megabytes. </summary>\n        uint32_t maxSemiSpaceSize = 0u;\n\n        /// <summary> Isolate memory constraint - The maximum executable size in megabytes. </summary>\n        uint32_t maxExecutableSize = 0u;\n\n        /// <summary> The maximum size that the isolate stack is allowed to grow in bytes. </summary>\n        uint32_t maxStackSize = 500 * 1024;\n    };\n}\n}"
  },
  {
    "path": "src/store/store.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"store.h\"\n\n#include <napa/memory.h>\n\n#include <mutex>\n#include <unordered_map>\n\nusing namespace napa::store;\n\nclass StoreImpl: public Store {\npublic:\n    /// <summary> Constructor. </summary>\n    explicit StoreImpl(const char* id)\n        : _id(id) {\n    }\n\n    /// <summary> Get ID of this store. </summary>\n    const char* GetId() const override {\n        return _id.c_str();\n    }\n\n    /// <summary> Set value with a key. </summary>\n    /// <param name=\"key\"> Case-sensitive key to set. </param>\n    /// <param name=\"value\"> A shared pointer of ValueType,\n    /// which is composed by a pair of payload and transport context. </returns>\n    void Set(const char* key, std::shared_ptr<Store::ValueType> value) override {\n        std::lock_guard<std::mutex> lock(_storeAccess);\n        auto it = _valueMap.find(key);\n        if (it != _valueMap.end()) {\n            it->second = std::move(value);\n        } else {\n            _valueMap.emplace(std::string(key), std::move(value));\n        }\n    }\n\n    /// <summary> Get value by a key. </summary>\n    /// <param name=\"key\"> Case-sensitive key to get. </param>\n    /// <returns> A ValueType shared pointer, empty if not found. </returns>\n    std::shared_ptr<ValueType> Get(const char* key) const override {\n        std::lock_guard<std::mutex> lock(_storeAccess);\n        auto it = _valueMap.find(key);\n        if (it != _valueMap.end()) {\n            return it->second;\n        }\n        return nullptr;\n    }\n\n    /// <summary> Check if this store has a key. </summary>\n    /// <param name=\"key\"> Case-sensitive key. </param>\n    /// <returns> True if the key exists in store. </returns>\n    bool Has(const char* key) const override {\n        std::lock_guard<std::mutex> lock(_storeAccess);\n        return _valueMap.find(key) != _valueMap.end();\n    }\n\n    /// <summary> Delete a key. No-op if key is not found in store. </summary>\n    void Delete(const char* key) override {\n        std::lock_guard<std::mutex> lock(_storeAccess);\n        _valueMap.erase(key);\n    }\n\n    /// <summary> Return size of the store. </summary>\n    size_t Size() const override {\n        std::lock_guard<std::mutex> lock(_storeAccess);\n        return _valueMap.size();\n    }\n\nprivate:\n    /// <summary> ID. Case sensitive. </summary>\n    std::string _id;\n\n    /// <summary> Key to value map. </summary>\n    std::unordered_map<std::string, std::shared_ptr<Store::ValueType>> _valueMap;\n\n    /// <summary> Mutex to value map access. (use std::shared_mutex when it's public) </summary>\n    mutable std::mutex _storeAccess;\n};\n\nnamespace napa {\nnamespace store {\n\n    namespace {\n        std::unordered_map<std::string, std::weak_ptr<Store>> _storeRegistry;\n        std::mutex _registryAccess;\n    } // namespace\n\n    std::shared_ptr<Store> CreateStore(const char* id) {\n        std::lock_guard<std::mutex> lockWrite(_registryAccess);\n        \n        std::shared_ptr<Store> store;\n        auto it = _storeRegistry.find(id);\n        if (it == _storeRegistry.end()) {\n            store = std::make_shared<StoreImpl>(id);\n            _storeRegistry.insert(std::make_pair(std::string(id), store));\n        }\n        return store;\n    }\n\n    std::shared_ptr<Store> GetOrCreateStore(const char* id) {\n        auto store = GetStore(id);\n        if (store == nullptr) {\n            store = CreateStore(id);\n            if (store == nullptr) {\n                // Already created just now. Lookup again.\n                store = GetStore(id);\n            }\n        }\n        return store;\n    }\n\n    std::shared_ptr<Store> GetStore(const char* id) {\n        std::lock_guard<std::mutex> lockRead(_registryAccess);\n        auto it = _storeRegistry.find(id);\n        if (it != _storeRegistry.end()) {\n            return it->second.lock();\n        }\n        return std::shared_ptr<Store>();\n    }\n\n    size_t GetStoreCount() {\n        std::lock_guard<std::mutex> lockWrite(_registryAccess);\n        for (auto it = _storeRegistry.begin(); it != _storeRegistry.end(); ) {\n            if (it->second.use_count() == 0) {\n                _storeRegistry.erase(it++);\n            } else {\n                ++it;\n            }\n        }\n        return _storeRegistry.size();\n    }\n} // namespace store\n} // namespace napa\n"
  },
  {
    "path": "src/store/store.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n#include <napa/transport/transport-context.h>\n\n#include <string>\n#include <memory>\n\nnamespace napa {\nnamespace store {\n\n    /// <summary> Class for memory store, which stores transportable JS objects across isolates. </summary>\n    /// <remarks> Store is intended to be used by StoreWrap. \n    /// We expose Store in napa.dll instead of napa-binding for sharing memory between Napa and Node.JS. </remarks>\n    class Store {\n    public:\n        /// Meta-data that is necessary to marshall/unmarshall JS values.\n        struct ValueType {\n            /// <summary> JSON string from marshalled JS value. </summary>\n            std::u16string payload;\n\n            /// <summary> TransportContext that is needed to unmarshall the JS value. </summary>\n            napa::transport::TransportContext transportContext;\n        };\n\n        /// <summary> Get ID of this store. </summary>\n        virtual const char* GetId() const = 0;\n\n        /// <summary> Set value with a key. </summary>\n        /// <param name=\"key\"> Case-sensitive key to set. </param>\n        /// <param name=\"value\"> A shared pointer of ValueType,\n        /// which is composed by a pair of payload and transport context. </returns>\n        virtual void Set(const char* key, std::shared_ptr<ValueType> value) = 0;\n\n        /// <summary> Get value by a key. </summary>\n        /// <param name=\"key\"> Case-sensitive key to get. </param>\n        /// <returns> A ValueType shared pointer, empty if not found. </returns>\n        virtual std::shared_ptr<ValueType> Get(const char* key) const = 0;\n\n        /// <summary> Check if this store has a key. </summary>\n        /// <param name=\"key\"> Case-sensitive key. </param>\n        /// <returns> True if the key exists in store. </returns>\n        virtual bool Has(const char* key) const = 0;\n\n        /// <summary> Delete a key. No-op if key is not found in store. </summary>\n        virtual void Delete(const char* key) = 0;\n\n        /// <summary> Return size of the store. </summary>\n        virtual size_t Size() const = 0;\n\n        /// <summary> Destructor. </summary>\n        virtual ~Store() = default;\n    };\n\n    /// <summary> Create a store by id. </summary>\n    /// <param name=\"id\"> Case-sensitive id. </summary>\n    /// <returns> Newly created store, or nullptr if store associated with id already exists. </summary>\n    NAPA_API std::shared_ptr<Store> CreateStore(const char* id);\n\n    /// <summary> Get or create a store by id. </summary>\n    /// <param name=\"id\"> Case-sensitive id. </summary>\n    /// <returns> Existing or newly created store. Should never be nullptr. </summary>\n    NAPA_API std::shared_ptr<Store> GetOrCreateStore(const char* id);\n\n    /// <summary> Get a store by id. </summary>\n    /// <param name=\"id\"> Case-sensitive id. </summary>\n    /// <returns> Existing store or nullptr if not found. </summary>\n    NAPA_API std::shared_ptr<Store> GetStore(const char* id);\n\n    /// <summary> Get store count currently in use. </summary>\n    NAPA_API size_t GetStoreCount();\n}\n}"
  },
  {
    "path": "src/utils/string.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <algorithm>\n#include <cctype>\n#include <cstddef>\n#include <string>\n#include <vector>\n\n\nnamespace napa {\nnamespace utils {\nnamespace string {\n\n    /// <summary> Replace all matches in a string. </summary>\n    inline void ReplaceAll(std::string& str, const std::string& match, const std::string& replacement) {\n        for (size_t pos = str.find(match); pos != std::string::npos; pos = str.find(match, pos)) {\n            str.replace(pos, match.size(), replacement);\n            pos += replacement.size();\n        }\n    }\n\n    /// <summary> Return a copy of string with all matches replaced. </summary>\n    inline std::string ReplaceAllCopy(const std::string& str, const std::string& match, const std::string& replacement) {\n        std::string copy(str);\n        ReplaceAll(copy, match, replacement);\n        return copy;\n    }\n\n    /// <summary> Split a string range into a list with a set of delimiters. </summary>\n    inline void Split(\n        std::string::const_iterator begin,\n        std::string::const_iterator end,\n        std::vector<std::string>& outputList,\n        const std::vector<char>& delimiters,\n        bool compress = false) {\n\n        outputList.clear();\n        auto start = begin;\n\n        for (auto it = begin; it != end; ++it) {\n            for (auto j = delimiters.begin(); j < delimiters.end(); ++j) {\n                if (*it == *j) {\n                    if (it != start || !compress) {\n                        outputList.push_back(std::string(start, it));\n                    }\n                    start = it + 1;\n                    break;\n                }\n            }\n        }\n        if (start != end || !compress) {\n            outputList.push_back(std::string(start, end));\n        }\n    }\n\n    /// <summary> Split a string range into a list with a set of delimiters passed in as a string. </summary>\n    inline void Split(\n        std::string::const_iterator begin,\n        std::string::const_iterator end,\n        std::vector<std::string>& outputList,\n        const std::string& anyCharAsDelimiter,\n        bool compress = false) {\n\n        std::vector<char> delimiters(anyCharAsDelimiter.begin(), anyCharAsDelimiter.end());\n        Split(begin, end, outputList, delimiters, compress);\n    }\n\n    /// <summary> Split a string into a list with a set of delimiters. </summary>\n    inline void Split(\n        const std::string& str,\n        std::vector<std::string>& outputList,\n        const std::string& delimiters,\n        bool compress = false) {\n\n        return Split(str.begin(), str.end(), outputList, delimiters, compress);\n    }\n\n    /// <summary> Trim the provided string. </summary>\n    inline void Trim(std::string &str) {\n        // Left trim\n        str.erase(0, str.find_first_not_of(\" \\n\\r\\t\"));\n\n        // Right trim\n        str.erase(str.find_last_not_of(\" \\n\\r\\t\") + 1);\n    }\n\n    /// <summary> Return a trimmed copy of the string. </summary>\n    inline std::string TrimCopy(const std::string &str) {\n        std::string copy = str;\n        Trim(copy);\n        return copy;\n    }\n\n    /// <summary> In-place convert a string to lower case. </summary>\n    inline void ToLower(std::string& str) {\n        std::transform(str.begin(), str.end(), str.begin(), (int (*)(int))std::tolower);\n    }\n\n    /// <summary> Return a copy of a string of lower case. </summary>\n    inline std::string ToLowerCopy(const std::string& str) {\n        std::string copy(str);\n        ToLower(copy);\n        return copy;\n    }\n\n    /// <summary> In-place convert a string to upper case. </summary>\n    inline void ToUpper(std::string& str) {\n        std::transform(str.begin(), str.end(), str.begin(), (int (*)(int))std::toupper);\n    }\n\n    /// <summary> Return a copy of a string of upper case. </summary>\n    inline std::string ToUpperCopy(const std::string& str) {\n        std::string copy(str);\n        ToUpper(copy);\n        return copy;\n    }\n\n    /// <summary> Case insensitive compare. </summary>\n    inline int CaseInsensitiveCompare(const std::string& left, const std::string& right) {\n        for (size_t i = 0; i < left.size(); ++i) {\n            if (i == right.size()) {\n                return 1;\n            }\n            auto l = std::tolower(left[i]);\n            auto r = std::tolower(right[i]);\n\n            if (l != r) {\n                return l - r;\n            }\n        }\n        return 0;\n    }\n\n    /// <summary> Case insensitive equals. </summary>\n    inline bool CaseInsensitiveEquals(const std::string& left, const std::string& right) {\n        return CaseInsensitiveCompare(left, right) == 0;\n    }\n}\n}\n}"
  },
  {
    "path": "src/v8-extensions/CMakeLists.txt",
    "content": "# Files to compile\nfile(GLOB SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)\n\n# The target name\nset(TARGET_NAME \"v8-extensions\")\n\n# The generated library\nadd_library(${TARGET_NAME} STATIC ${SOURCE_FILES})\n\n# Include directories\ntarget_include_directories(${TARGET_NAME}\n    PRIVATE\n    ${CMAKE_CURRENT_SOURCE_DIR}\n    ${PROJECT_SOURCE_DIR}/inc)\n\n# Compiler definitions\ntarget_compile_definitions(${TARGET_NAME} PRIVATE NAPA_EXPORTS NAPA_BINDING_EXPORTS BUILDING_NAPA_EXTENSION)\n\nif(CMAKE_JS_VERSION)\n    # Building Napa as an npm package for node usage (using exported v8 from node.exe)\n\n    target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_JS_INC})\n    target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_JS_LIB})\n\n    # Using the V8 functions exported from node.exe\n    target_compile_definitions(${TARGET_NAME} PRIVATE USING_V8_SHARED)\nelse()\n    # Building Napa for embed scenarios (static linking with v8)\n    if (NOT DEFINED NODE_ROOT)\n        message(FATAL_ERROR \"NODE_ROOT must be set to the node sources root directory\")\n    endif()\n\n    set(NODE_BUILD_TYPE \"Release\")\n    if ((DEFINED CMAKE_BUILD_TYPE) AND (CMAKE_BUILD_TYPE STREQUAL \"debug\"))\n        set(NODE_BUILD_TYPE \"Debug\")\n    endif()\n\n    # V8 header files\n    target_include_directories(${TARGET_NAME} PRIVATE ${NODE_ROOT}/deps/v8/include)\n\nendif()\n"
  },
  {
    "path": "src/v8-extensions/array-buffer-allocator.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if !(V8_VERSION_CHECK_FOR_ARRAY_BUFFER_ALLOCATOR)\n\n#include \"array-buffer-allocator.h\"\n\n#include <cstring>\n#include <stdlib.h>\n#include <v8.h>\n\nusing namespace napa::v8_extensions;\n\nvoid* ArrayBufferAllocator::Allocate(size_t length) {\n    void* data = AllocateUninitialized(length);\n    return std::memset(data, 0, length);\n}\n\nvoid* ArrayBufferAllocator::AllocateUninitialized(size_t length) {\n    return malloc(length);\n}\n\nvoid ArrayBufferAllocator::Free(void* data, size_t length) {\n    free(data);\n}\n\n#endif"
  },
  {
    "path": "src/v8-extensions/array-buffer-allocator.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_extensions {\n\n    ///<summary> Allocator that V8 uses to allocate |ArrayBuffer|'s memory. </summary>\n    class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {\n    public:\n\n        /// <see> v8::ArrayBuffer::Allocator::Allocate </see>\n        virtual void* Allocate(size_t length) override;\n\n        /// <see> v8::ArrayBuffer::Allocator::AllocateUninitialized </see>\n        virtual void* AllocateUninitialized(size_t length) override;\n\n        /// <see> v8::ArrayBuffer::Allocator::Free </see>\n        virtual void Free(void* data, size_t length) override;\n    };\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/deserializer.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n#include \"deserializer.h\"\n\n#include <napa/module/binding/basic-wraps.h>\n\nusing namespace napa::v8_extensions;\nusing namespace v8;\n\nDeserializer::Deserializer(Isolate* isolate, std::shared_ptr<SerializedData> data) :\n    _isolate(isolate),\n    _deserializer(isolate, data->GetData(), data->GetSize(), this),\n    _data(std::move(data)) {\n    _deserializer.SetSupportsLegacyWireFormat(true);\n}\n\nMaybeLocal<Value> Deserializer::ReadValue() {\n    bool readHeader = false;\n    Local<Context> context = _isolate->GetCurrentContext();\n    if (!_deserializer.ReadHeader(context).To(&readHeader)) {\n        return MaybeLocal<Value>();\n    }\n\n#if !V8_VERSION_EQUALS_TO_OR_NEWER_THAN(6, 6)\n\n    uint32_t index = 0;\n    Local<String> key = v8_helpers::MakeV8String(_isolate, \"_externalized\");\n    for (const auto& contents : _data->GetExternalizedSharedArrayBufferContents()) {\n        Local<SharedArrayBuffer> sharedArrayBuffers = SharedArrayBuffer::New(\n            _isolate, contents.first.Data(), contents.first.ByteLength());\n        auto shareableWrap = napa::module::binding::CreateShareableWrap(contents.second);\n\n        // After deserialization of a SharedArrayBuffer from its SerializedData,\n        // set its '_externalized' property to a ShareableWrap of its ExternalizedContents.\n        // This extends the lifecycle of the ExternalizedContents by the lifetime of the restored SharedArrayBuffer object.\n        sharedArrayBuffers->CreateDataProperty(context, key, shareableWrap);\n        _deserializer.TransferSharedArrayBuffer(index++, sharedArrayBuffers);\n    }\n\n#endif\n\n    return _deserializer.ReadValue(context);\n}\n\n#if V8_VERSION_EQUALS_TO_OR_NEWER_THAN(6, 6)\n\nMaybeLocal<SharedArrayBuffer> Deserializer::GetSharedArrayBufferFromId(\n    Isolate* isolate, uint32_t cloneId) {\n    if (_data && cloneId < _data->GetExternalizedSharedArrayBufferContents().size()) {\n        auto externalizedSharedArrayBufferContents = _data->GetExternalizedSharedArrayBufferContents().at(cloneId);\n        SharedArrayBuffer::Contents contents = externalizedSharedArrayBufferContents.first;\n        auto sharedArrayBuffer = SharedArrayBuffer::New(isolate, contents.Data(), contents.ByteLength());\n\n        // After deserialization of a SharedArrayBuffer from its SerializedData,\n        // set its '_externalized' property to a ShareableWrap of its ExternalizedContents.\n        // This extends the lifecycle of the ExternalizedContents\n        // by the lifetime of the restored SharedArrayBuffer object.\n        Local<Context> context = _isolate->GetCurrentContext();\n        Local<String> key = v8_helpers::MakeV8String(_isolate, \"_externalized\");\n        auto shareableWrap = napa::module::binding::CreateShareableWrap(externalizedSharedArrayBufferContents.second);\n        sharedArrayBuffer->CreateDataProperty(context, key, shareableWrap);\n        return sharedArrayBuffer;\n    }\n    else {\n        return MaybeLocal<SharedArrayBuffer>();\n    }\n}\n\n#endif\n\nDeserializer* Deserializer::NewDeserializer(Isolate* isolate, std::shared_ptr<SerializedData> data) {\n    return new Deserializer(isolate, data);\n}\n\n#endif\n"
  },
  {
    "path": "src/v8-extensions/deserializer.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"serialized-data.h\"\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_extensions {\n\n    /// <summary>\n    /// Deserializer is used to deserialize a SerializedData instance to a JavaScript object.\n    /// It is derived from v8::ValueDeserializer::Delegate, whose interface is implemented\n    /// to handle ShardArrayBuffer specially as below.\n    ///   For each of the SharedArrayBuffer in the input SerializedData, \n    ///   1). create a SharedArrayBuffer instance from its SharedArrayBuffer::Contents stored in SerializedData.\n    ///   2). generate a ShareableWrap of ExternalizedContents, and attach it to the SharedArrayBuffer instance.\n    /// </summary>\n    class Deserializer : public v8::ValueDeserializer::Delegate {\n    public:\n        Deserializer(v8::Isolate* isolate, std::shared_ptr<SerializedData> data);\n\n        v8::MaybeLocal<v8::Value> ReadValue();\n\n#if V8_VERSION_EQUALS_TO_OR_NEWER_THAN(6, 6)\n\n        v8::MaybeLocal<v8::SharedArrayBuffer> GetSharedArrayBufferFromId(\n            v8::Isolate* isolate, uint32_t cloneId) override;\n\n#endif\n\n        static Deserializer* NewDeserializer(\n            v8::Isolate* isolate, std::shared_ptr<SerializedData> data);\n\n    private:\n        v8::Isolate* _isolate;\n        v8::ValueDeserializer _deserializer;\n        std::shared_ptr<SerializedData> _data;\n\n        Deserializer(const Deserializer&) = delete;\n        Deserializer& operator=(const Deserializer&) = delete;\n    };\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/externalized-contents.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n#include \"externalized-contents.h\"\n\n#include <stdlib.h>\n\nusing namespace napa::v8_extensions;\nusing namespace v8;\n\nExternalizedContents::ExternalizedContents(const SharedArrayBuffer::Contents& contents) :\n    _data(contents.Data()),\n    _size(contents.ByteLength()) {}\n\nExternalizedContents::ExternalizedContents(ExternalizedContents&& other) :\n    _data(other._data),\n    _size(other._size) {\n    other._data = nullptr;\n    other._size = 0;\n}\n\nExternalizedContents& ExternalizedContents::operator=(ExternalizedContents&& other) {\n    if (this != &other) {\n        _data = other._data;\n        _size = other._size;\n        other._data = nullptr;\n        other._size = 0;\n    }\n    return *this;\n}\n\nExternalizedContents::~ExternalizedContents() {\n    // TODO #146: Get array_buffer_allocator to free ExternalizedContents.\n    free(_data);\n}\n\n#endif\n"
  },
  {
    "path": "src/v8-extensions/externalized-contents.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_extensions {\n\n    /// <summary> \n    /// 1. ExternalizedContents holds the externalized memory of a SharedArrayBuffer once it is serialized.\n    /// 2. Only 1 instance of ExternalizedContents would be generated for each SharedArrayBuffer.\n    ///    If a SharedArrayBuffer had been externalized, it will reuse the ExternalizedContents instance\n    ///    created before in napa::v8_extensions::Utils::SerializeValue().\n    /// </summary>\n    class ExternalizedContents {\n    public:\n        explicit ExternalizedContents(const v8::SharedArrayBuffer::Contents& contents);\n\n        ExternalizedContents(ExternalizedContents&& other);\n\n        ExternalizedContents& operator=(ExternalizedContents&& other);\n\n        ~ExternalizedContents();\n\n    private:\n        void* _data;\n        size_t _size;\n\n        ExternalizedContents(const ExternalizedContents&) = delete;\n        ExternalizedContents& operator=(const ExternalizedContents&) = delete;\n    };\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/serialized-data.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n#include \"serialized-data.h\"\n\n#include <stdlib.h>\n\nusing namespace napa::v8_extensions;\nusing namespace v8;\n\nSerializedData::SerializedData() : _size(0) {}\n\nconst uint8_t* SerializedData::GetData() const { return _data.get(); }\n\nsize_t SerializedData::GetSize() const { return _size; }\n\nconst std::vector<ExternalizedSharedArrayBufferContents>&\nSerializedData::GetExternalizedSharedArrayBufferContents() const {\n    return _externalizedSharedArrayBufferContents;\n}\n\nvoid SerializedData::DataDeleter::operator()(uint8_t* p) const { free(p); }\n\n#endif\n"
  },
  {
    "path": "src/v8-extensions/serialized-data.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"externalized-contents.h\"\n\nnamespace napa {\nnamespace v8_extensions {\n\n    using namespace v8;\n\n    typedef std::pair<SharedArrayBuffer::Contents, std::shared_ptr<ExternalizedContents>> ExternalizedSharedArrayBufferContents;\n\n    /// <summary>\n    /// SerializedData holds the serialized data of a JavaScript object, and it is required during its deserialization.\n    /// If the JavaScript object has properties or elements of SharedArrayBuffer or types based on SharedArrayBuffer, \n    /// like DataView and TypedArray, their ExternalizedContents will be stored in _externalizedSharedArrayBufferContents.\n    /// </summary>\n    class SerializedData {\n    public:\n        SerializedData();\n\n        const uint8_t* GetData() const;\n\n        size_t GetSize() const;\n\n        const std::vector<ExternalizedSharedArrayBufferContents>& GetExternalizedSharedArrayBufferContents() const;\n\n    private:\n        struct DataDeleter {\n            void operator()(uint8_t* p) const;\n        };\n\n        std::unique_ptr<uint8_t, DataDeleter> _data;\n        size_t _size;\n        std::vector<ExternalizedSharedArrayBufferContents> _externalizedSharedArrayBufferContents;\n\n    private:\n        friend class Serializer;\n\n        SerializedData(const SerializedData&) = delete;\n        SerializedData& operator=(const SerializedData&) = delete;\n    };\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/serializer.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n#include \"serializer.h\"\n\n#include <napa/module/binding/basic-wraps.h>\n#include <stdlib.h>\n\nusing namespace napa::v8_extensions;\nusing namespace v8;\n\nSerializer::Serializer(Isolate* isolate) :\n    _isolate(isolate),\n    _serializer(isolate, this) {}\n\nMaybe<bool> Serializer::WriteValue(Local<Value> value) {\n    bool ok = false;\n    _data.reset(new SerializedData);\n    _serializer.WriteHeader();\n\n    Local<Context> context = _isolate->GetCurrentContext();\n    if (!_serializer.WriteValue(context, value).To(&ok)) {\n        _data.reset();\n        return Nothing<bool>();\n    }\n\n    if (!FinalizeTransfer().To(&ok)) {\n        return Nothing<bool>();\n    }\n\n    std::pair<uint8_t*, size_t> pair = _serializer.Release();\n    _data->_data.reset(pair.first);\n    _data->_size = pair.second;\n    return Just(true);\n}\n\nstd::shared_ptr<SerializedData> Serializer::Release() {\n    return _data;\n}\n\nvoid Serializer::ThrowDataCloneError(Local<String> message) {\n    _isolate->ThrowException(Exception::Error(message));\n}\n\nMaybe<uint32_t> Serializer::GetSharedArrayBufferId(\n    Isolate* isolate,\n    Local<SharedArrayBuffer> sharedArrayBuffer\n) {\n    for (size_t index = 0; index < _sharedArrayBuffers.size(); ++index) {\n        if (_sharedArrayBuffers[index] == sharedArrayBuffer) {\n            return Just<uint32_t>(static_cast<uint32_t>(index));\n        }\n    }\n\n    size_t index = _sharedArrayBuffers.size();\n    _sharedArrayBuffers.emplace_back(_isolate, sharedArrayBuffer);\n    return Just<uint32_t>(static_cast<uint32_t>(index));\n}\n\nvoid* Serializer::ReallocateBufferMemory(void* oldBuffer, size_t size, size_t* actualSize) {\n    void* result = realloc(oldBuffer, size);\n    *actualSize = result ? size : 0;\n    return result;\n}\n\nvoid Serializer::FreeBufferMemory(void* buffer) { free(buffer); }\n\nExternalizedSharedArrayBufferContents\nSerializer::MaybeExternalize(Local<SharedArrayBuffer> sharedArrayBuffer) {\n    Local<Context> context = _isolate->GetCurrentContext();\n    Local<String> key = v8_helpers::MakeV8String(_isolate, \"_externalized\");\n    bool ok = false;\n    if (sharedArrayBuffer->IsExternal()\n        && sharedArrayBuffer->Has(context, key).To(&ok)) {\n        Local<Value> value;\n        // If the SharedArrayBuffer has been externalized, just get its Contents without externalizing it again,\n        // and get its ExternalizedContents which has been stored in the '_externalized' property of the SharedArrayBuffer.\n        if (sharedArrayBuffer->Get(context, key).ToLocal(&value)) {\n            auto shareableWrap = NAPA_OBJECTWRAP::Unwrap<napa::module::ShareableWrap>(Local<Object>::Cast(value));\n            auto externalizedContents = shareableWrap->Get<ExternalizedContents>();\n            return std::make_pair(sharedArrayBuffer->GetContents(), externalizedContents);\n        }\n        return std::make_pair(sharedArrayBuffer->GetContents(), nullptr);\n    } else {\n        // If the SharedArrayBuffer has not been externalized,\n        // externalize it and get its Contents and ExternalizedContents at first,\n        // then store its ExternalizedContents in the '_externalized' property of the original SharedArrayBuffer.\n        auto contents = sharedArrayBuffer->Externalize();\n        auto externalizedContents = std::make_shared<ExternalizedContents>(contents);\n        auto shareableWrap = napa::module::binding::CreateShareableWrap(externalizedContents);\n        sharedArrayBuffer->CreateDataProperty(context, key, shareableWrap);\n        return std::make_pair(contents, externalizedContents);\n    }\n}\n\nMaybe<bool> Serializer::FinalizeTransfer() {\n    for (const auto& globalSharedArrayBuffer : _sharedArrayBuffers) {\n        Local<SharedArrayBuffer> sharedArrayBuffer =\n            Local<SharedArrayBuffer>::New(_isolate, globalSharedArrayBuffer);\n        // Externalize the SharedArrayBuffer if it hasn't been done before,\n        // and store it's ExternalizedContents which will be used when deserializing it in deserializer.\n        _data->_externalizedSharedArrayBufferContents.push_back(MaybeExternalize(sharedArrayBuffer));\n    }\n\n    return Just(true);\n}\n\n#endif\n"
  },
  {
    "path": "src/v8-extensions/serializer.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"serialized-data.h\"\n\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_extensions {\n\n    /// <summary>\n    /// Serializer is used to serialize a JavaScript object to a SerializedData instance.\n    /// It is derived from v8::ValueSerializer::Delegate, whose interface is implemented\n    /// to handle ShardArrayBuffer specially as below.\n    ///   If a SharedArrayBuffer is being serialized for the first time, \n    ///   1). it will be externlized and the ExternalizedContents will be attached to its SerializedData.\n    ///   2). a ShareableWrap of the ExternalizedContents will be set to the input SharedArrayBuffer.\n    ///   If a SharedArrayBuffer has been serialized, the externalization will be skipped, and its ExternalizedContents\n    ///   will be retrieved from the input SharedArrayBuffer and attached to its SerializedData.\n    /// </summary>\n    class Serializer : public v8::ValueSerializer::Delegate {\n    public:\n        explicit Serializer(v8::Isolate* isolate);\n\n        v8::Maybe<bool> WriteValue(v8::Local<v8::Value> value);\n\n        std::shared_ptr<SerializedData> Release();\n\n    protected:\n        void ThrowDataCloneError(v8::Local<v8::String> message) override;\n\n        v8::Maybe<uint32_t> GetSharedArrayBufferId(\n            v8::Isolate* isolate,\n            v8::Local<v8::SharedArrayBuffer> sharedArrayBuffer\n        ) override;\n\n        void* ReallocateBufferMemory(void* oldBuffer, size_t size, size_t* actualSize) override;\n\n        void FreeBufferMemory(void* buffer) override;\n\n    private:\n        ExternalizedSharedArrayBufferContents MaybeExternalize(v8::Local<v8::SharedArrayBuffer> sharedArrayBuffer);\n\n        v8::Maybe<bool> FinalizeTransfer();\n\n        v8::Isolate* _isolate;\n        v8::ValueSerializer _serializer;\n        std::shared_ptr<SerializedData> _data;\n        std::vector<v8::Global<v8::SharedArrayBuffer>> _sharedArrayBuffers;\n\n        Serializer(const Serializer&) = delete;\n        Serializer& operator=(const Serializer&) = delete;\n    };\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/v8-common.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-common.h\"\n\n#ifdef USING_V8_SHARED\n\n// Empty stubs when using shared v8\nbool napa::v8_common::Initialize() { return true; }\nvoid napa::v8_common::Shutdown() {}\n\n#else\n\n#include <napa/log.h>\n\n// V8 libraries\n#include <libplatform/libplatform.h>\n#include <v8.h>\n\nstatic v8::Platform* _platform = nullptr;\n\n\nbool napa::v8_common::Initialize() {\n    NAPA_ASSERT(!_platform, \"V8 was already initialized\");\n\n    _platform = v8::platform::CreateDefaultPlatform();\n    v8::V8::InitializePlatform(_platform);\n    v8::V8::Initialize();\n\n    return true;\n}\n\nvoid napa::v8_common::Shutdown() {\n    NAPA_ASSERT(_platform, \"V8 wasn't initialized\");\n\n    v8::V8::Dispose();\n    v8::V8::ShutdownPlatform();\n\n    delete _platform;\n    _platform = nullptr;\n}\n#endif"
  },
  {
    "path": "src/v8-extensions/v8-common.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\nnamespace napa {\nnamespace v8_common {\n\n    /// <summary> Performs v8 global initialization. </summary>\n    bool Initialize();\n\n    /// <summary> Shutdown and clean v8 global resources. </summary>\n    void Shutdown();\n}\n}\n"
  },
  {
    "path": "src/v8-extensions/v8-extensions-macros.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <v8.h>\n\n#define V8_VERSION_EQUALS_TO_OR_NEWER_THAN(MAJOR, MINOR) \\\n    (V8_MAJOR_VERSION == (MAJOR) && V8_MINOR_VERSION >= (MINOR) || V8_MAJOR_VERSION > (MAJOR))\n    \n#define V8_VERSION_CHECK_FOR_ARRAY_BUFFER_ALLOCATOR \\\n    V8_VERSION_EQUALS_TO_OR_NEWER_THAN(5, 5)\n\n#define V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER \\\n    V8_VERSION_EQUALS_TO_OR_NEWER_THAN(6, 2)\n"
  },
  {
    "path": "src/v8-extensions/v8-extensions.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"v8-extensions-macros.h\"\n\n#if V8_VERSION_CHECK_FOR_BUILT_IN_TYPE_TRANSPORTER\n\n#include \"deserializer.h\"\n#include \"serializer.h\"\n#include \"v8-extensions.h\"\n\nusing namespace napa;\nusing namespace v8;\n\nstd::shared_ptr<v8_extensions::SerializedData>\nv8_extensions::Utils::SerializeValue(Isolate* isolate, Local<Value> value) {\n    bool ok = false;\n    Serializer serializer(isolate);\n    if (serializer.WriteValue(value).To(&ok)) {\n        return serializer.Release();\n    }\n    return nullptr;\n}\n\nMaybeLocal<Value>\nv8_extensions::Utils::DeserializeValue(Isolate* isolate, std::shared_ptr<v8_extensions::SerializedData>& data) {\n    Local<Value> value;\n    Deserializer deserializer(isolate, data);\n    return deserializer.ReadValue();\n}\n\n#endif\n"
  },
  {
    "path": "src/v8-extensions/v8-extensions.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n#include <v8.h>\n\nnamespace napa {\nnamespace v8_extensions {\n\n    class SerializedData;\n\n    class NAPA_API Utils {\n        public:\n        static std::shared_ptr<SerializedData>\n        SerializeValue(v8::Isolate* isolate, v8::Local<v8::Value> value);\n        \n        static v8::MaybeLocal<v8::Value>\n        DeserializeValue(v8::Isolate* isolate, std::shared_ptr<SerializedData>& data);\n    };\n}\n}\n"
  },
  {
    "path": "src/zone/async-complete-task.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"async-complete-task.h\"\n\n#include <v8.h>\n\nusing namespace napa::zone;\n\nAsyncCompleteTask::AsyncCompleteTask(std::shared_ptr<AsyncContext> context) : _context(std::move(context)) {}\n\nvoid AsyncCompleteTask::Execute() {\n    // If asyncWork is empty, don't need to wait for async result. It just posts a completion only.\n    if (_context->asyncWork != nullptr) {\n        _context->future.wait();\n    }\n\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    auto jsCallback = v8::Local<v8::Function>::New(isolate, _context->jsCallback);\n    _context->asyncCompleteCallback(jsCallback, _context->result);\n\n    _context->jsCallback.Reset();\n}"
  },
  {
    "path": "src/zone/async-complete-task.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"async-context.h\"\n\n#include <zone/task.h>\n\n#include <memory>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> A task to run Javascript callback after asynchronous callback completes. </summary>\n    class AsyncCompleteTask : public Task {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"context\"> Structure containing asynchronous work's context. </param>\n        AsyncCompleteTask(std::shared_ptr<AsyncContext> context);\n\n        /// <summary> Overrides Task.Execute to define running execution logic. </summary>\n        virtual void Execute() override;\n\n    private:\n\n        std::shared_ptr<AsyncContext> _context;\n    };\n\n}\n}"
  },
  {
    "path": "src/zone/async-context.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/zone/napa-async-runner.h>\n\n#include <zone/worker.h>\n#include <zone/napa-zone.h>\n\n#include <v8.h>\n\n#include <future>\n\nnamespace napa {\nnamespace zone {\n    \n    /// <summary> Class holding asynchronous callbacks. </summary>\n    struct AsyncContext {\n        /// <summary> Zone instance issueing asynchronous work. </summary>\n        NapaZone* zone = nullptr;\n\n        /// <summary> Keep scheduler instance referenced until async work completes. </summary>\n        std::shared_ptr<zone::Scheduler> scheduler;\n\n        /// <summary> Worker Id issueing asynchronous work. </summary>\n        zone::WorkerId workerId;\n\n        /// <summary> Future to wait async callback. </summary>\n        std::future<void> future;\n\n        /// <summary> Javascript callback. </summary>\n        v8::Persistent<v8::Function> jsCallback;\n\n        /// <summary> Function to run asynchronously in separate thread. </summary>\n        AsyncWork asyncWork;\n\n        /// <summary> Return value from asynchronous work. </summary>\n        void* result = nullptr;\n\n        /// <summary> Callback running in V8 isolate after asynchronous callback completes. </summary>\n        AsyncCompleteCallback asyncCompleteCallback;\n    };\n\n}   // End of namespace zone.\n}   // End of namespace napa.\n"
  },
  {
    "path": "src/zone/async-runner.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/zone/napa-async-runner.h>\n\n#include <zone/async-complete-task.h>\n#include <zone/worker-context.h>\n#include <zone/napa-zone.h>\n\nusing namespace napa;\nusing namespace napa::zone;\n\nnamespace {\n\n    /// <summary> Prepare asynchronous work. </summary>\n    /// <param name=\"jsCallback\"> Javascript callback. </summary>\n    /// <param name=\"asyncWork\"> Function to run asynchronously in separate thread. </param>\n    /// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous callback completes. </param>\n    /// <returns> AsyncContext instance. </summary>\n    std::shared_ptr<AsyncContext> PrepareAsyncWork(v8::Local<v8::Function> jsCallback,\n                                                   AsyncWork asyncWork,\n                                                   AsyncCompleteCallback asyncCompleteCallback);\n\n}   // End of anonymous namespace.\n\n/// <summary> It runs a synchronous function in the separate thread and posts a completion into the current V8 execution loop. </summary>\n/// <param name=\"jsCallback\"> Javascript callback. </summary>\n/// <param name=\"asyncWork\"> Function to run asynchronously in separate thread. </param>\n/// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous callback completes. </param>\nvoid napa::zone::PostAsyncWork(v8::Local<v8::Function> jsCallback,\n                               AsyncWork asyncWork,\n                               AsyncCompleteCallback asyncCompleteCallback) {\n    auto context = PrepareAsyncWork(jsCallback, std::move(asyncWork), std::move(asyncCompleteCallback));\n    if (context == nullptr) {\n        return;\n    }\n\n    context->future = std::async(std::launch::async, [context]() {\n        context->result = context->asyncWork();\n\n        auto asyncCompleteTask = std::make_shared<AsyncCompleteTask>(context);\n        context->zone->GetScheduler()->ScheduleOnWorker(context->workerId, asyncCompleteTask);\n    });\n}\n\n/// <summary> It runs an asynchronous function and post a completion into the current V8 execution loop. </summary>\n/// <param name=\"jsCallback\"> Javascript callback. </summary>\n/// <param name=\"asyncWork\"> Function to wrap async-supporting function. </param>\n/// <param name=\"asyncCompleteCallback\"> Callback running in V8 isolate after asynchronous function completes. </param>\nvoid napa::zone::DoAsyncWork(v8::Local<v8::Function> jsCallback,\n                             const CompletionWork& asyncWork,\n                             AsyncCompleteCallback asyncCompleteCallback) {\n    auto context = PrepareAsyncWork(jsCallback, nullptr, std::move(asyncCompleteCallback));\n    if (context == nullptr) {\n        return;\n    }\n\n    asyncWork([context](void* result) {\n        context->result = result;\n\n        auto asyncCompleteTask = std::make_shared<AsyncCompleteTask>(context);\n        context->zone->GetScheduler()->ScheduleOnWorker(context->workerId, asyncCompleteTask);\n    });\n}\n\nnamespace {\n\n    std::shared_ptr<AsyncContext> PrepareAsyncWork(v8::Local<v8::Function> jsCallback,\n                                                   AsyncWork asyncWork,\n                                                   AsyncCompleteCallback asyncCompleteCallback) {\n        auto isolate = v8::Isolate::GetCurrent();\n        v8::HandleScope scope(isolate);\n\n        auto context = std::make_shared<zone::AsyncContext>();\n\n        context->zone = reinterpret_cast<NapaZone*>(WorkerContext::Get(WorkerContextItem::ZONE));\n        if (context->zone == nullptr) {\n            return nullptr;\n        }\n\n        context->scheduler = context->zone->GetScheduler();\n        context->workerId = static_cast<WorkerId>(\n            reinterpret_cast<uintptr_t>(WorkerContext::Get(WorkerContextItem::WORKER_ID)));\n\n        context->jsCallback.Reset(isolate, jsCallback);\n        context->asyncWork = std::move(asyncWork);\n        context->asyncCompleteCallback = std::move(asyncCompleteCallback);\n\n        return context;\n    }\n\n}   // End of anonymous namespace.\n"
  },
  {
    "path": "src/zone/call-context.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// See: https://groups.google.com/forum/#!topic/nodejs/onA0S01INtw\n#ifdef BUILDING_NODE_EXTENSION\n#include <node.h>\n#endif\n\n#include \"call-context.h\"\n\n#include <napa/log.h>\n#include <napa/v8-helpers.h>\n\n#include <stdint.h>\n\nusing namespace napa::zone;\n\nCallContext::CallContext(const napa::FunctionSpec& spec, napa::ExecuteCallback callback) : \n    _module(NAPA_STRING_REF_TO_STD_STRING(spec.module)),\n    _function(NAPA_STRING_REF_TO_STD_STRING(spec.function)),\n    _callback(callback),\n    _finished(false) {\n\n    // Audit start time.\n    _startTime = std::chrono::high_resolution_clock::now();\n    \n    _arguments.reserve(spec.arguments.size());\n    for (auto& arg : spec.arguments) {\n        _arguments.emplace_back(NAPA_STRING_REF_TO_STD_STRING(arg));\n    }\n    _options = spec.options;\n\n    // Pass ownership of the transport context.\n    _transportContext = std::move(spec.transportContext);\n}\n\nbool CallContext::Resolve(std::string marshalledResult) {\n    auto expected = false;\n    if (!_finished.compare_exchange_strong(expected, true)) {\n        return false;\n    }\n\n    NAPA_DEBUG(\"CallTask\", \"Call to \\\"%s.%s\\\" is resolved successfully.\", _module.c_str(), _function.c_str());\n\n    _callback({ \n        NAPA_RESULT_SUCCESS, \n        \"\", \n        std::move(marshalledResult),\n        std::move(_transportContext) \n    });\n    return true;\n}\n\nbool CallContext::Reject(napa::ResultCode code, std::string reason) {\n    auto expected = false;\n    if (!_finished.compare_exchange_strong(expected, true)) {\n        return false;\n    }\n\n    NAPA_DEBUG(\"CallTask\", \"Call to \\\"%s.%s\\\" was rejected: %s.\", _module.c_str(), _function.c_str(), reason.c_str());\n\n    _callback({ code, reason, \"\", std::move(_transportContext) });\n    return true;\n}\n\nbool CallContext::IsFinished() const {\n    return _finished;\n}\n\nconst std::string& CallContext::GetModule() const {\n    return _module;\n}\n\nconst std::string& CallContext::GetFunction() const {\n    return _function;\n}\n\nconst std::vector<std::string>& CallContext::GetArguments() const {\n    return _arguments;\n}\n\nnapa::transport::TransportContext& CallContext::GetTransportContext() {\n    return *_transportContext.get();\n}\n\nconst napa::CallOptions& CallContext::GetOptions() const {\n    return _options;\n}\n\nstd::chrono::nanoseconds CallContext::GetElapse() const {\n    return std::chrono::high_resolution_clock::now() - _startTime;\n}"
  },
  {
    "path": "src/zone/call-context.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/types.h>\n#include <v8.h>\n\n#include <atomic>\n#include <chrono>\n#include <memory>\n#include <vector>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Context of calling a JavaScript function. </summary>\n    class CallContext {\n\n    public:\n        /// <summary> Construct spec from external FunctionSpec. </summary>\n        explicit CallContext(const napa::FunctionSpec& spec, napa::ExecuteCallback callback);\n\n        /// <summary> Resolve current spec. </summary>\n        /// <param name=\"result\"> marshalled return value. </param>\n        /// <returns> True if operation is successful, otherwise if task is already finished before. </returns>\n        //bool Resolve(v8::Local<v8::Value> result);\n        bool Resolve(std::string result);\n\n        /// <summary> Reject current spec. </summary>\n        /// <param name=\"resultCode\"> Response code to return to user. </summary>\n        /// <param name=\"reason\"> Reason of cancellation. </summary>\n        /// <returns> True if operation is successful, otherwise if task is already finished before. </returns>\n        bool Reject(napa::ResultCode code, std::string reason);\n\n        /// <summary> Returns whether current job is completed or cancelled. </summary>\n        bool IsFinished() const;\n\n        /// <summary> Get module name to load function. </summary>\n        const std::string& GetModule() const;\n\n        /// <summary> Get function name to execute. </summary>\n        const std::string& GetFunction() const;\n\n        /// <summary> Get marshalled arguments. </summary>\n        const std::vector<std::string>& GetArguments() const;\n\n        /// <summary> Get transport context. </summary>\n        napa::transport::TransportContext& GetTransportContext();\n\n        /// <summary> Get options. </summary>\n        const napa::CallOptions& GetOptions() const;\n\n        /// <summary> Get elapse since task start in nano-second. </summary>\n        std::chrono::nanoseconds GetElapse() const;\n\n    private:\n        /// <summary> Module name. </summary>\n        std::string _module;\n\n        /// <summary> Function name. </summary>\n        std::string _function;\n\n        /// <summary> Arguments. </summary>\n        std::vector<std::string> _arguments;\n\n        /// <summary> Execute options. </summary>\n        napa::CallOptions _options;\n\n        /// <summary> Transport context. </summary>\n        std::unique_ptr<napa::transport::TransportContext> _transportContext;\n\n         /// <summary> Callback when task completes. </summary>\n        napa::ExecuteCallback _callback;\n\n        /// <summary> Whether this task is finished. </summary>\n        std::atomic<bool> _finished;\n\n        /// <summary> Call start time. </summary>\n        std::chrono::high_resolution_clock::time_point _startTime;\n    };\n}\n}"
  },
  {
    "path": "src/zone/call-task.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// See: https://groups.google.com/forum/#!topic/nodejs/onA0S01INtw\n#ifdef BUILDING_NODE_EXTENSION\n#include <node.h>\n#endif\n\n#include \"call-task.h\"\n\n#include <module/core-modules/napa/call-context-wrap.h>\n\n#include <napa/log.h>\n\nusing namespace napa::zone;\nusing namespace napa::v8_helpers;\n\nnapa::zone::CallTask::CallTask(std::shared_ptr<CallContext> context) : \n    _context(std::move(context)) {\n}\n\nvoid CallTask::Execute() {\n    NAPA_DEBUG(\"CallTask\", \"Begin executing function (%s.%s).\", _context->GetModule().c_str(), _context->GetFunction().c_str());\n\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n\n    // Get the module based main function from global scope.\n    auto executeFunction = context->Global()->Get(MakeExternalV8String(isolate, \"__napa_zone_call__\"));\n    JS_ENSURE(isolate, executeFunction->IsFunction(), \"__napa_zone_call__ function must exist in global scope\");\n\n    // Create task wrap.\n    auto contextWrap = napa::module::CallContextWrap::NewInstance(_context);\n    v8::Local<v8::Value> argv[] = { contextWrap };\n\n    // Execute the function.\n    v8::TryCatch tryCatch(isolate);\n    auto res = v8::Local<v8::Function>::Cast(executeFunction)->Call(\n        isolate->GetCurrentContext(),\n        context->Global(),\n        1,\n        argv);\n\n    // Terminating an isolate may occur from a different thread, i.e. from timeout service.\n    // If the function call already finished successfully when the isolate is terminated it may lead\n    // to one the following:\n    //      1. Terminate was called before tryCatch.HasTerminated(), the user gets an error code.\n    //      2. Terminate was called after tryCatch.HasTerminated(), the user gets a success code.\n    //\n    //  In both cases the isolate is being restored since this happens before each task executes.\n    if (tryCatch.HasTerminated()) {\n        if (_terminationReason == TerminationReason::TIMEOUT) {\n            (void)_context->Reject(NAPA_RESULT_TIMEOUT, \"Terminated due to timeout\");\n        } else {\n            (void)_context->Reject(NAPA_RESULT_INTERNAL_ERROR, \"Terminated with unknown reason\");\n        }\n        return;\n    }\n\n    NAPA_ASSERT(!tryCatch.HasCaught(), \"__napa_zone_call__ should catch all user exceptions and reject task.\");\n}\n"
  },
  {
    "path": "src/zone/call-task.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"call-context.h\"\n#include \"terminable-task.h\"\n\n#include <memory>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> A task for executing pre-loaded javascript functions. </summary>\n    class CallTask : public TerminableTask {\n    public:\n        /// <summary> Constructor. </summary>\n        /// <param name=\"context\"> Call context. </param>\n        CallTask(std::shared_ptr<CallContext> context);\n\n        /// <summary> Overrides Task.Execute to define execution logic. </summary>\n        virtual void Execute() override;\n\n    private:\n        /// <summary> Call context. </summary>\n        std::shared_ptr<CallContext> _context;\n    };\n}\n}\n"
  },
  {
    "path": "src/zone/eval-task.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// See: https://groups.google.com/forum/#!topic/nodejs/onA0S01INtw\n#ifdef BUILDING_NODE_EXTENSION\n#include <node.h>\n#endif\n\n#include \"eval-task.h\"\n\n#include <platform/filesystem.h>\n\n#include <napa/log.h>\n#include <napa/v8-helpers.h>\n\n#include <v8.h>\n\nusing namespace napa;\nusing namespace napa::zone;\n\nEvalTask::EvalTask(std::string source, std::string sourceOrigin, BroadcastCallback callback) :\n    _source(std::move(source)),\n    _sourceOrigin(std::move(sourceOrigin)),\n    _callback(std::move(callback)) {}\n\nvoid EvalTask::Execute() {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n    auto context = isolate->GetCurrentContext();\n\n    NAPA_DEBUG(\"EvalTask\", \"Begin executing script:\\\"%s\\\"\", _source.c_str());\n\n    auto filename = v8_helpers::MakeV8String(isolate, _sourceOrigin);\n    filesystem::Path originPath(_sourceOrigin);\n    if (originPath.IsAbsolute()) {\n        auto global = context->Global();\n\n        auto dirname = v8_helpers::MakeV8String(isolate, originPath.Parent().Normalize().String());\n        (void)global->Set(context, v8_helpers::MakeV8String(isolate, \"__dirname\"), dirname);\n        (void)global->Set(context, v8_helpers::MakeV8String(isolate, \"__filename\"), filename);\n    }\n\n    auto source = napa::v8_helpers::MakeV8String(isolate, _source);\n    auto sourceOrigin = v8::ScriptOrigin(filename);\n\n    // Compile the source code.\n    v8::MaybeLocal<v8::Script> compileResult;\n    {\n        v8::TryCatch tryCatch(isolate);\n        compileResult = v8::Script::Compile(context, source, &sourceOrigin);\n        if (tryCatch.HasCaught()) {\n            auto exception = tryCatch.Exception();\n            v8::String::Utf8Value exceptionStr(exception);\n\n            std::stringstream ss;\n            ss << \"Compilation failed: \" << *exceptionStr;\n            std::string reason = ss.str();\n            NAPA_DEBUG(\"EvalTask\", reason.c_str());\n\n            _callback({ NAPA_RESULT_BROADCAST_SCRIPT_ERROR, reason.c_str(), \"\", nullptr });\n            return;\n        }\n    }\n    \n    NAPA_DEBUG(\"EvalTask\", \"Script compiled successfully\");\n    auto script = compileResult.ToLocalChecked();\n\n    // Run the source code.\n    {\n        v8::TryCatch tryCatch(isolate);\n        (void)script->Run(context);\n        if (tryCatch.HasCaught()) {\n            auto exception = tryCatch.Exception();\n            v8::String::Utf8Value exceptionStr(exception);\n            auto stackTrace = tryCatch.StackTrace();\n            v8::String::Utf8Value stackTraceStr(stackTrace);\n\n            std::stringstream ss;\n            ss << \"Eval failed: \" << *exceptionStr << \" - \" << *stackTraceStr;\n            std::string reason = ss.str();\n            NAPA_DEBUG(\"EvalTask\", reason.c_str());\n\n            _callback({ NAPA_RESULT_BROADCAST_SCRIPT_ERROR, reason.c_str(), \"\", nullptr });\n            return;\n        }\n    }\n\n    NAPA_DEBUG(\"EvalTask\", \"Eval script completed with success\");\n    _callback({ NAPA_RESULT_SUCCESS, \"\", \"\", nullptr });\n}\n"
  },
  {
    "path": "src/zone/eval-task.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"task.h\"\n\n#include \"napa/types.h\"\n\n#include <functional>\n#include <string>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> A task for evaluating javascript source code. </summary>\n    class EvalTask : public Task {\n    public:\n        /// <summary> Constructor. </summary>\n        /// <param name=\"source\"> The JS source code to load on the isolate the runs this task. </param>\n        /// <param name=\"sourceOrigin\"> The origin of the source code. </param>\n        /// <param name=\"callback\"> A callback that is triggered when the task execution completed. </param>\n        EvalTask(std::string source,\n            std::string sourceOrigin = \"\",\n            BroadcastCallback callback = [](Result) {});\n\n        /// <summary> Overrides Task.Execute to define loading execution logic. </summary>\n        virtual void Execute() override;\n\n    private:\n        std::string _source;\n        std::string _sourceOrigin;\n        BroadcastCallback _callback;\n    };\n}\n}\n"
  },
  {
    "path": "src/zone/napa-zone.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"napa-zone.h\"\n\n#include <module/loader/module-loader.h>\n#include <platform/dll.h>\n#include <platform/filesystem.h>\n#include <utils/string.h>\n#include <zone/eval-task.h>\n#include <zone/call-task.h>\n#include <zone/call-context.h>\n#include <zone/task-decorators.h>\n#include <zone/worker-context.h>\n\n#include <napa/log.h>\n\n#include <future>\n\nusing namespace napa;\nusing namespace napa::zone;\n\n// Static members initialization\nstd::mutex NapaZone::_mutex;\nstd::unordered_map<std::string, std::weak_ptr<NapaZone>> NapaZone::_zones;\n\n/// <summary> Load 'napajs' module during bootstrap. We use relative path to decouple from how module will be published.  </summary>\nstatic const std::string NAPAJS_MODULE_PATH = filesystem::Path(dll::ThisLineLocation()).Parent().Parent().Normalize().String();\nstatic const std::string BOOTSTRAP_SOURCE = \"require('\" + utils::string::ReplaceAllCopy(NAPAJS_MODULE_PATH, \"\\\\\", \"\\\\\\\\\") + \"');\";\n\nstd::shared_ptr<NapaZone> NapaZone::Create(const settings::ZoneSettings& settings) {\n    std::lock_guard<std::mutex> lock(_mutex);\n\n    auto iter = _zones.find(settings.id);\n    if (iter != _zones.end() && !iter->second.expired()) {\n        NAPA_DEBUG(\"Zone\", \"Failed to create zone '%s': a zone with this name already exists.\", settings.id.c_str());\n        return nullptr;\n    }\n\n    // An helper class to enable make_shared of NapaZone\n    struct MakeSharedEnabler : public NapaZone {\n        MakeSharedEnabler(const settings::ZoneSettings& settings) : NapaZone(settings) {}\n    };\n\n    // Fail to create Napa zone is not expected, will always trigger crash.\n    auto zone = std::make_shared<MakeSharedEnabler>(settings);\n    _zones[settings.id] = zone;\n\n    NAPA_DEBUG(\"Zone\", \"Napa zone \\\"%s\\\" created.\", settings.id.c_str());\n\n    return zone;\n}\n\nstd::shared_ptr<NapaZone> NapaZone::Get(const std::string& id) {\n    std::lock_guard<std::mutex> lock(_mutex);\n\n    auto iter = _zones.find(id);\n    if (iter == _zones.end()) {\n        NAPA_DEBUG(\"Zone\", \"Get zone \\\"%s\\\" failed due to not found.\", id.c_str());\n        return nullptr;\n    }\n\n    auto zone = iter->second.lock();\n    if (zone == nullptr) {\n        LOG_WARNING(\"Zone\", \"Zone '%s' was already deleted.\", id.c_str());\n\n        // Use this chance to clean up the map\n        _zones.erase(id);\n    }\n    \n    NAPA_DEBUG(\"Zone\", \"Get zone \\\"%s\\\" succeeded.\", id.c_str());\n    return zone;\n}\n\nNapaZone::NapaZone(const settings::ZoneSettings& settings) : \n    _settings(settings) {\n\n    // Create the zone's scheduler.\n    _scheduler = std::make_unique<Scheduler>(_settings, [this](WorkerId id) {\n        // Initialize the worker context TLS data\n        INIT_WORKER_CONTEXT();\n\n        // Zone instance into TLS.\n        WorkerContext::Set(WorkerContextItem::ZONE, reinterpret_cast<void*>(this));\n\n        // Worker Id into TLS.\n        WorkerContext::Set(WorkerContextItem::WORKER_ID, reinterpret_cast<void*>(static_cast<uintptr_t>(id)));\n\n        // Load module loader and built-in modules of require, console and etc.\n        CREATE_MODULE_LOADER();\n    });\n\n    // Bootstrap after zone is created.\n    std::promise<ResultCode> promise;\n    auto future = promise.get_future();\n\n    // Makes sure the callback is only called once, after all workers finished running the broadcast task.\n    auto counter = std::make_shared<std::atomic<uint32_t>>(_settings.workers);\n    auto callOnce = [&promise, counter](Result result) {\n        if (--(*counter) == 0) {\n            promise.set_value(result.code);\n        }\n    };\n\n    auto bootstrapTask = std::make_shared<EvalTask>(BOOTSTRAP_SOURCE, \"\", std::move(callOnce));\n\n    _scheduler->ScheduleOnAllWorkers(std::move(bootstrapTask));\n    NAPA_DEBUG(\"Zone\", \"Scheduling bootstrap script \\\"%s\\\" to zone \\\"%s\\\"\", BOOTSTRAP_SOURCE.c_str(), _settings.id.c_str());\n\n    NAPA_ASSERT(future.get() == NAPA_RESULT_SUCCESS, \"Bootstrap Napa zone failed.\");\n}\n\nconst std::string& NapaZone::GetId() const {\n    return _settings.id;\n}\n\nvoid NapaZone::Broadcast(const FunctionSpec& spec, BroadcastCallback callback) {\n    // Makes sure the callback is only called once, after all workers finished running the broadcast task.\n    auto counter = std::make_shared<std::atomic<uint32_t>>(_settings.workers);\n    auto callOnce = [this, callback = std::move(callback), counter](Result result) {\n        if (--(*counter) == 0) {\n            callback(std::move(result));\n        }\n    };\n\n    for (WorkerId id = 0; id < _settings.workers; id++) {\n        std::shared_ptr<Task> task;\n\n        if (spec.options.timeout > 0) {\n            task = std::make_shared<TimeoutTaskDecorator<CallTask>>(\n                std::chrono::milliseconds(spec.options.timeout),\n                std::make_shared<CallContext>(spec, callOnce));\n        } else {\n            task = std::make_shared<CallTask>(std::make_shared<CallContext>(spec, callOnce));\n        }\n\n        _scheduler->ScheduleOnWorker(id, std::move(task));\n    }\n\n    NAPA_DEBUG(\"Zone\", \"Broadcast function \\\"%s.%s\\\" on zone \\\"%s\\\"\", spec.module.data, spec.function.data, _settings.id.c_str());\n}\n\nvoid NapaZone::Execute(const FunctionSpec& spec, ExecuteCallback callback) {\n    std::shared_ptr<Task> task;\n\n    if (spec.options.timeout > 0) {\n        task = std::make_shared<TimeoutTaskDecorator<CallTask>>(\n            std::chrono::milliseconds(spec.options.timeout),\n            std::make_shared<CallContext>(spec, std::move(callback)));\n    } else {\n        task = std::make_shared<CallTask>(std::make_shared<CallContext>(spec, std::move(callback)));\n    }\n    \n    NAPA_DEBUG(\"Zone\", \"Execute function \\\"%s.%s\\\" on zone \\\"%s\\\"\", spec.module.data, spec.function.data, _settings.id.c_str());\n    _scheduler->Schedule(std::move(task));\n}\n\nconst settings::ZoneSettings& NapaZone::GetSettings() const {\n    return _settings;\n}\n\nstd::shared_ptr<Scheduler> NapaZone::GetScheduler() {\n    return _scheduler;\n}\n"
  },
  {
    "path": "src/zone/napa-zone.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"zone.h\"\n\n#include \"zone/scheduler.h\"\n#include \"settings/settings.h\"\n\n#include <memory>\n#include <string>\n#include <unordered_map>\n\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Concrete implementation of a Napa zone. </summary>\n    class NapaZone : public Zone {\n    public:\n\n        /// <summary> Creates a new zone with the provided id and settings. </summary>\n        static std::shared_ptr<NapaZone> Create(const settings::ZoneSettings& settings);\n\n        /// <summary> Retrieves an existing zone by id. </summary>\n        static std::shared_ptr<NapaZone> Get(const std::string& id);\n\n        /// <see cref=\"Zone::GetId\" />\n        virtual const std::string& GetId() const override;\n\n        /// <see cref=\"Zone::Broadcast\" />\n        virtual void Broadcast(const FunctionSpec& spec, BroadcastCallback callback) override;\n\n        /// <see cref=\"Zone::Execute\" />\n        virtual void Execute(const FunctionSpec& spec, ExecuteCallback callback) override;\n\n        /// <summary> Retrieves the zone settings. </summary>\n        const settings::ZoneSettings& GetSettings() const;\n\n        /// <summary> Retrieves the zone scheduler. </summary>\n        /// <remark> Asynchronous works keep the reference on scheduler, so they can finish up safely. </remarks>\n        std::shared_ptr<zone::Scheduler> GetScheduler();\n\n    private:\n        explicit NapaZone(const settings::ZoneSettings& settings);\n\n        settings::ZoneSettings _settings;\n        std::shared_ptr<zone::Scheduler> _scheduler;\n\n        static std::mutex _mutex;\n        static std::unordered_map<std::string, std::weak_ptr<NapaZone>> _zones;\n    };\n}\n}"
  },
  {
    "path": "src/zone/node-zone.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"node-zone.h\"\n\n#include \"worker-context.h\"\n\n#include <napa/assert.h>\n\nusing namespace napa;\nusing namespace napa::zone;\n\nstd::shared_ptr<NodeZone> NodeZone::_instance;\n\nvoid NodeZone::Init(BroadcastDelegate broadcast, ExecuteDelegate execute) {\n    _instance.reset(new NodeZone(broadcast, execute));\n}\n\nNodeZone::NodeZone(BroadcastDelegate broadcast, ExecuteDelegate execute):\n    _broadcast(std::move(broadcast)), _execute(std::move(execute)), _id(\"node\") {\n\n    NAPA_ASSERT(_broadcast, \"Broadcast delegate must be a valid function.\");\n    NAPA_ASSERT(_execute, \"Execute delegate must be a valid function.\");\n\n    // Init worker context for Node event loop.\n    INIT_WORKER_CONTEXT();\n\n    // Zone instance into TLS.\n    WorkerContext::Set(WorkerContextItem::ZONE, reinterpret_cast<void*>(this));\n\n    // Worker Id into TLS.\n    WorkerContext::Set(WorkerContextItem::WORKER_ID, reinterpret_cast<void*>(static_cast<uintptr_t>(0)));\n}\n\nstd::shared_ptr<NodeZone> NodeZone::Get() {\n    return _instance;\n}\n\nconst std::string& NodeZone::GetId() const {\n    return _id;\n}\n\nvoid NodeZone::Broadcast(const FunctionSpec& source, BroadcastCallback callback) {\n    _broadcast(source, callback);\n}\n\nvoid NodeZone::Execute(const FunctionSpec& spec, ExecuteCallback callback) {\n    _execute(spec, callback);\n}\n"
  },
  {
    "path": "src/zone/node-zone.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\n#include \"zone.h\"\n\n#include <functional>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Delegate for Broadcast on Node zone. </summary>\n    using BroadcastDelegate = std::function<void(const FunctionSpec&, BroadcastCallback)>;\n\n    /// <summary> Delegate for Execute on Node zone. </summary>\n    using ExecuteDelegate = std::function<void(const FunctionSpec&, ExecuteCallback)>;\n\n    /// <summary> Concrete implementation of a Node zone. </summary>\n    class NodeZone : public Zone {\n    public:\n        /// <summary> Set delegate function for Broadcast and Execute on node zone. This is intended to be called from napa-binding.node. </summary>\n        static NAPA_API void Init(BroadcastDelegate broadcast, ExecuteDelegate execute);\n\n        /// <summary> \n        ///    Retrieves an existing zone. \n        ///    If Node is not applicable (like in embed mode), a nullptr will be returned.\n        /// </summary>\n        static std::shared_ptr<NodeZone> Get();\n\n        /// <see cref=\"Zone::GetId\" />\n        virtual const std::string& GetId() const override;\n\n        /// <see cref=\"Zone::Broadcast\" />\n        virtual void Broadcast(const FunctionSpec& spec, BroadcastCallback callback) override;\n\n        /// <see cref=\"Zone::Execute\" />\n        virtual void Execute(const FunctionSpec& spec, ExecuteCallback callback) override;\n\n    private:\n        /// <summary> Constructor. </summary>\n        NodeZone(BroadcastDelegate broadcast, ExecuteDelegate execute);\n\n        /// <summary> Broadcast delegate for node zone. </summary>\n        BroadcastDelegate _broadcast;\n\n        /// <summary> Execute delegate for node zone. </summary>\n        ExecuteDelegate _execute;\n\n        /// <summary> Node zone id. </summary>\n        std::string _id;\n\n        /// <summary> Node zone instance. </summary>\n        static std::shared_ptr<NodeZone> _instance;\n    };\n}\n}"
  },
  {
    "path": "src/zone/schedule-phase.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <stdint.h>\n\nnamespace napa {\nnamespace zone {\n\n    // Define the phase (like priority related type) of tasks. \n    // To be used mainly by schduler and worker to schedule its tasks.\n    enum class SchedulePhase : uint32_t {\n        DefaultPhase = 0,\n        ImmediatePhase = 1\n    };\n    \n};\n}\n"
  },
  {
    "path": "src/zone/scheduler.cpp",
    "content": "#include \"scheduler.h\"\n\ntemplate class napa::zone::SchedulerImpl<napa::zone::Worker>;\n"
  },
  {
    "path": "src/zone/scheduler.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"schedule-phase.h\"\n#include \"simple-thread-pool.h\"\n#include \"task.h\"\n#include \"worker.h\"\n\n#include <settings/settings.h>\n\n#include <napa/log.h>\n\n#include <atomic>\n#include <list>\n#include <memory>\n#include <queue>\n#include <thread>\n#include <vector>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> The scheduler is responsible for assigning tasks to workers. </summary>\n    template <typename WorkerType>\n    class SchedulerImpl {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"settings\"> A settings object. </param>\n        /// <param name=\"workerSetupCallback\"> Callback to setup the isolate after worker created its isolate. </param>\n        SchedulerImpl(const settings::ZoneSettings& settings, std::function<void(WorkerId)> workerSetupCallback);\n\n        /// <summary> Destructor. Waits for all tasks to finish. </summary>\n        ~SchedulerImpl();\n\n        /// <summary> Schedules the task on a single worker. </summary>\n        /// <param name=\"task\"> Task to schedule. </param>\n        void Schedule(std::shared_ptr<Task> task);\n\n        /// <summary> Schedules the task on a specific worker. </summary>\n        /// <param name=\"workerId\"> The id of the worker. </param>\n        /// <param name=\"task\"> Task to schedule. </param>\n        /// <param name=\"phase\"> Which phase of the task, like Immediate or Normal. </param>\n        /// <remarks>\n        /// By design, it enqueues a task immediately,\n        /// so the task will have higher priority than ones called by Schedule().\n        /// </remarks>\n        void ScheduleOnWorker(WorkerId workerId,\n                              std::shared_ptr<Task> task,\n                              SchedulePhase phase = SchedulePhase::DefaultPhase);\n\n        /// <summary> Schedules the task on all workers. </summary>\n        /// <param name=\"task\"> Task to schedule. </param>\n        /// <remarks>\n        /// By design, it enqueues a task immediately,\n        /// so the task will have higher priority than ones called by Schedule().\n        /// </remarks>\n        void ScheduleOnAllWorkers(std::shared_ptr<Task> task);\n\n    private:\n\n        /// <summary> The logic invoked when a worker is idle. </summary>\n        void IdleWorkerNotificationCallback(WorkerId workerId);\n\n        /// <summary> The workers that are used for running the tasks. </summary>\n        std::vector<WorkerType> _workers;\n\n        /// <summary> New tasks that weren't assigned to a specific worker. </summary>\n        std::queue<std::shared_ptr<Task>> _nonScheduledTasks;\n\n        /// <summary> List of idle workers, used when assigning non scheduled tasks. </summary>\n        std::list<WorkerId> _idleWorkers;\n\n        /// <summary> Flags to indicate that a worker is in the idle list. </summary>\n        std::vector<std::list<WorkerId>::iterator> _idleWorkersFlags;\n\n        /// <summary> Uses a single thread to synchronize task queuing and posting. </summary>\n        std::unique_ptr<SimpleThreadPool> _synchronizer;\n\n        /// <summary> A flag to signal that scheduler is stopping. </summary>\n        std::atomic<bool> _shouldStop;\n\n        /// <summary> Tasks being scheduled but not yet dispatched to worker or put into non-scheduled queue. </summary>\n        std::atomic<size_t> _beingScheduled;\n    };\n\n    typedef SchedulerImpl<Worker> Scheduler;\n\n    template <typename WorkerType>\n    SchedulerImpl<WorkerType>::SchedulerImpl(const settings::ZoneSettings& settings, std::function<void(WorkerId)> workerSetupCallback) :\n        _idleWorkersFlags(settings.workers, _idleWorkers.end()),\n        _synchronizer(std::make_unique<SimpleThreadPool>(1)),\n        _shouldStop(false),\n        _beingScheduled(0) {\n\n        _workers.reserve(settings.workers);\n\n        for (WorkerId i = 0; i < settings.workers; i++) {\n            _workers.emplace_back(i, settings, workerSetupCallback, [this](WorkerId workerId) {\n                IdleWorkerNotificationCallback(workerId);\n            });\n            _workers[i].Start();\n        }\n    }\n\n    template <typename WorkerType>\n    SchedulerImpl<WorkerType>::~SchedulerImpl() {\n        NAPA_DEBUG(\"Scheduler\", \"Shutting down: Start draining unscheduled tasks...\");\n\n        // Wait for all tasks to be scheduled.\n        while (_beingScheduled > 0 || !_nonScheduledTasks.empty()) {\n            std::this_thread::yield();\n        }\n\n        // Signal scheduler callbacks to not process anymore tasks.\n        _shouldStop = true;\n\n        // Wait for synchronizer to finish his book-keeping.\n        _synchronizer = nullptr;\n\n        // Wait for all workers to finish processing remaining tasks.\n        _workers.clear();\n\n        NAPA_DEBUG(\"Scheduler\", \"Shutdown completed\");\n    }\n\n    template <typename WorkerType>\n    void SchedulerImpl<WorkerType>::Schedule(std::shared_ptr<Task> task) {\n        NAPA_ASSERT(task, \"task is null\");\n        _beingScheduled++;\n        _synchronizer->Execute([this, task]() {\n            if (_idleWorkers.empty()) {\n                NAPA_DEBUG(\"Scheduler\", \"All workers are busy, putting task to non-scheduled queue.\");\n\n                // If there is no idle worker, put the task into the non-scheduled queue.\n                _nonScheduledTasks.emplace(std::move(task));\n            } else {\n                // Pop the worker id from the idle workers list.\n                auto workerId = _idleWorkers.front();\n                _idleWorkers.pop_front();\n                _idleWorkersFlags[workerId] = _idleWorkers.end();\n\n                // Schedule task on worker\n                _workers[workerId].Schedule(std::move(task));\n\n                NAPA_DEBUG(\"Scheduler\", \"Scheduled task on worker %u.\", workerId);\n            }\n            _beingScheduled--;\n        });\n        \n    }\n\n    template <typename WorkerType>\n    void SchedulerImpl<WorkerType>::ScheduleOnWorker(\n            WorkerId workerId, std::shared_ptr<Task> task, SchedulePhase phase) {\n        NAPA_ASSERT(workerId < _workers.size(), \"worker id out of range\");\n\n        _synchronizer->Execute([workerId, this, task, phase]() {\n            // If the worker is idle, change it's status.\n            if (_idleWorkersFlags[workerId] != _idleWorkers.end()) {\n                _idleWorkers.erase(_idleWorkersFlags[workerId]);\n                _idleWorkersFlags[workerId] = _idleWorkers.end();\n            }\n\n            // Schedule task on worker\n            _workers[workerId].Schedule(std::move(task), phase);\n\n            NAPA_DEBUG(\"Scheduler\", \"Explicitly scheduled task on worker %u.\", workerId);\n        });\n    }\n\n    template <typename WorkerType>\n    void SchedulerImpl<WorkerType>::ScheduleOnAllWorkers(std::shared_ptr<Task> task) {\n        NAPA_ASSERT(task, \"task is null\");\n\n        _synchronizer->Execute([this, task]() {\n            // Clear all idle workers.\n            _idleWorkers.clear();\n            for (auto& flag : _idleWorkersFlags) {\n                flag = _idleWorkers.end();\n            }\n\n            // Schedule the task on all workers.\n            for (auto& worker : _workers) {\n                worker.Schedule(task);\n            }\n            NAPA_DEBUG(\"Scheduler\", \"Scheduled task on all workers\");\n        });\n    }\n\n    template <typename WorkerType>\n    void SchedulerImpl<WorkerType>::IdleWorkerNotificationCallback(WorkerId workerId) {\n        NAPA_ASSERT(workerId < _workers.size(), \"worker id out of range\");\n\n        if (_shouldStop) {\n            return;\n        }\n\n        _synchronizer->Execute([this, workerId]() {\n            if (!_nonScheduledTasks.empty()) {\n                // If there is a non scheduled task, schedule it on the idle worker.\n                auto task = _nonScheduledTasks.front();\n                _nonScheduledTasks.pop();\n                _workers[workerId].Schedule(std::move(task));\n\n                NAPA_DEBUG(\"Scheduler\", \"Worker %u fetched a task from non-scheduled queue\", workerId);\n            } else {\n                // Put worker in idle list.\n                if (_idleWorkersFlags[workerId] == _idleWorkers.end()) {\n                    auto iter = _idleWorkers.emplace(_idleWorkers.end(), workerId);\n                    _idleWorkersFlags[workerId] = iter;\n\n                    NAPA_DEBUG(\"Scheduler\", \"Worker %u becomes idle\", workerId);\n                }\n            }\n        });\n    }\n}\n}\n"
  },
  {
    "path": "src/zone/simple-thread-pool.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"simple-thread-pool.h\"\n\nusing namespace napa::zone;\n\nSimpleThreadPool::Worker::Worker(SimpleThreadPool& pool) : _pool(pool) {}\n\nvoid SimpleThreadPool::Worker::operator()() {\n    std::function<void()> task;\n\n    while (true) {\n        {\n            std::unique_lock<std::mutex> lock(_pool._queueLock);\n            if (!_pool._isStopped) {\n                _pool._queueCondition.wait(lock, [this]() {\n                    return _pool._isStopped || !_pool._taskQueue.empty();\n                });\n            }\n\n            // Drain all existing tasks before actually stopping.\n            if (_pool._isStopped && _pool._taskQueue.empty()) {\n                break;\n            }\n\n            task = std::move(_pool._taskQueue.front());\n            _pool._taskQueue.pop();\n        }\n\n        task();\n    }\n}\n\nSimpleThreadPool::SimpleThreadPool(uint32_t numberOfWorkers) : _isStopped(false) {\n    _workers.reserve(numberOfWorkers);\n\n    for (uint32_t i = 0; i < numberOfWorkers; ++i) {\n        _workers.emplace_back(Worker(*this));\n    }\n}\n\nSimpleThreadPool::~SimpleThreadPool() {\n    {\n        std::unique_lock<std::mutex> lock(_queueLock);\n        _isStopped = true;\n    }\n\n    _queueCondition.notify_all();\n\n    for (auto& thread : _workers) {\n        if (thread.joinable()) {\n            thread.join();\n        }\n    }\n}\n"
  },
  {
    "path": "src/zone/simple-thread-pool.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <condition_variable>\n#include <functional>\n#include <mutex>\n#include <queue>\n#include <stdint.h>\n#include <thread>\n#include <utility>\n#include <vector>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Simple thread pool. </summary>\n    class SimpleThreadPool {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"numberOfWorkers\"> Number of workers. </param>\n        explicit SimpleThreadPool(uint32_t numberOfWorkers);\n\n        /// <summary> Destructor. </summary>\n        virtual ~SimpleThreadPool();\n\n        /// <summary> Execute the given function in one of the workers. </summary>\n        /// <param name=\"function\"> Function to run. </param>\n        /// <param name=\"args\"> Arguments for function. </param>\n        template <typename T, typename... Args>\n        void Execute(T&& function, Args&&... args);\n\n    private:\n\n        /// <summary> Class for worker main loop. </summary>\n        class Worker {\n        public:\n\n            /// <summary> Constructor. </summary>\n            Worker(SimpleThreadPool& pool);\n\n            /// <summary> Main thread function. </summary>\n            void operator()();\n\n        private:\n\n            /// <summary> Thread pool instance. </summary>\n            SimpleThreadPool& _pool;\n        };\n\n        std::vector<std::thread> _workers;\n        std::queue<std::function<void()>> _taskQueue;\n\n        /// <summary> Critical section and event for task queue. </summary>\n        std::mutex _queueLock;\n        std::condition_variable _queueCondition;\n\n        /// <summary> Flag to stop threads. </summary>\n        bool _isStopped;\n    };\n\n\n    template <typename T, typename... Args>\n    void SimpleThreadPool::Execute(T&& function, Args&&... args) {\n        auto task = std::bind(std::forward<T>(function), std::forward<Args>(args)...);\n\n        {\n            std::unique_lock<std::mutex> lock(_queueLock);\n            _taskQueue.emplace(task);\n        }\n\n        _queueCondition.notify_one();\n    }\n\n}\n}"
  },
  {
    "path": "src/zone/task-decorators.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"task.h\"\n#include \"terminable-task.h\"\n#include \"timer.h\"\n\n#include <v8.h>\n\n#include <chrono>\n#include <memory>\n#include <utility>\n\nnamespace napa {\nnamespace zone {\n\n    template <typename TaskType>\n    class TaskDecorator : public Task {\n    public:\n        template <typename... Args>\n        TaskDecorator(Args&&... args) : _innerTask(std::forward<Args>(args)...) {}\n\n    protected:\n        TaskType _innerTask;\n    };\n\n    template <typename TaskType>\n    class TimeoutTaskDecorator : public TaskDecorator<TaskType> {\n    public:\n        static_assert(std::is_base_of<TerminableTask, TaskType>::value, \"TaskType must inherit from TerminableTask\");\n\n        template <typename... Args>\n        TimeoutTaskDecorator(std::chrono::milliseconds timeout, Args&&... args) :\n            TaskDecorator<TaskType>(std::forward<Args>(args)...),\n            _timeout(timeout) {}\n\n        void Execute() override {\n            auto isolate = v8::Isolate::GetCurrent();\n\n            // RAII - timer will automatically stop upon destruction.\n            napa::zone::Timer timer([this, isolate]() {\n                this->_innerTask.Terminate(TerminationReason::TIMEOUT, isolate);\n            }, _timeout);\n            timer.Start();\n\n            this->_innerTask.Execute();\n        }\n\n    private:\n        std::chrono::milliseconds _timeout;\n    };\n}\n}"
  },
  {
    "path": "src/zone/task.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Represents an execution logic that can be scheduled using the Napa scheduler. </summary>\n    class Task {\n    public:\n\n        /// <summary> Executes the task. </summary>\n        virtual void Execute() = 0;\n\n        /// <summary> Virtual destructor. </summary>\n        virtual ~Task() = default;\n    };\n\n}\n}"
  },
  {
    "path": "src/zone/terminable-task.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n// See: https://groups.google.com/forum/#!topic/nodejs/onA0S01INtw\n#ifdef BUILDING_NODE_EXTENSION\n#include <node.h>\n#endif\n\n#include \"terminable-task.h\"\n\n#include <v8.h>\n\nusing namespace napa::zone;\n\nvoid TerminableTask::Terminate(TerminationReason reason, v8::Isolate* isolate) {\n    _terminationReason = reason;\n\n    isolate->TerminateExecution();\n}\n"
  },
  {
    "path": "src/zone/terminable-task.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"task.h\"\n\nnamespace v8 {\n    class Isolate;\n}\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Specifies the possible reasons for termination. </summary>\n    enum class TerminationReason {\n        UNKNOWN,\n        TIMEOUT\n    };\n\n    /// <summary> Base class for tasks that can be terminated. </summary>\n    class TerminableTask : public Task {\n    public:\n\n        /// <summary> Use this to terminate a currently running task. </summary>\n        /// <param name=\"reason\"> The reason for the termination. </param>\n        /// <param name=\"isolate\"> The isolate this task currently runs on. </param>\n        void Terminate(TerminationReason reason, v8::Isolate* isolate);\n\n    protected:\n        TerminationReason _terminationReason = TerminationReason::UNKNOWN;\n    };\n}\n}\n"
  },
  {
    "path": "src/zone/timer.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"timer.h\"\n\n#include <napa/log.h>\n\n#include <atomic>\n#include <chrono>\n#include <condition_variable>\n#include <mutex>\n#include <queue>\n#include <stack>\n#include <thread>\n\n#include <iostream>\n\nusing namespace napa::zone;\n\nstruct TimerInfo {\n    bool active;\n    std::chrono::milliseconds timeout;\n    Timer::Callback callback;\n};\n\nstruct ActiveTimerEntry {\n    Timer::Index index;\n    std::chrono::high_resolution_clock::time_point expirationTime;\n};\n\nstatic bool operator<(const ActiveTimerEntry& first, const ActiveTimerEntry& second) {\n    // We want the entry that is closest to expire to be at the top of the queue.\n    return first.expirationTime > second.expirationTime;\n}\n\nstruct TimersScheduler {\n    ~TimersScheduler();\n\n    bool StartMainLoop();\n\n    std::priority_queue<ActiveTimerEntry> activeTimers;\n    std::stack<Timer::Index> freeSlots;\n\n    std::vector<TimerInfo> timers;\n\n    std::condition_variable cv;\n    std::mutex mutex;\n    std::atomic<bool> running;\n\n    std::thread thread;\n};\n\nTimersScheduler::~TimersScheduler() {\n    running = false;\n    cv.notify_one();\n\n    if (thread.joinable()) {\n        thread.join();\n    }\n}\n\nbool TimersScheduler::StartMainLoop() {\n    running = true;\n    thread = std::thread([this]() {\n        std::unique_lock<std::mutex> lock(mutex);\n\n        // Timers main loop.\n        while (running) {\n            cv.wait(lock, [this]() {\n                return !activeTimers.empty() || !running;\n            });\n\n            if (!running) {\n                return;\n            }\n\n            auto nextExpirationTime = activeTimers.top().expirationTime;\n            if (nextExpirationTime <= std::chrono::high_resolution_clock::now()) {\n                // Pop before callback(), so that it could be re-armed for interval task logic.\n                auto expiredTimer = activeTimers.top();\n                activeTimers.pop();\n\n                if (timers[expiredTimer.index].active) {\n                    timers[expiredTimer.index].active = false;\n\n                    try {\n                        // Fire the callback.\n                        // The callback is assumed to be very fast as it is meant to dispatch to appropriate\n                        // callback queues.\n                        timers[expiredTimer.index].callback();\n                    }\n                    catch (const std::exception &ex) {\n                        LOG_ERROR(\"Timers\", \"Timer callback threw an exception. %s\", ex.what());\n                    }\n                }\n            }\n            else {\n                // Wait for timer expiration. Stop waiting if new urgent active timer is arm-ed.\n                cv.wait_until(lock, nextExpirationTime, [this, nextExpirationTime]() {\n                    return activeTimers.top().expirationTime < nextExpirationTime;\n                });\n            }\n        }\n    });\n\n    return true;\n}\n\nstatic TimersScheduler _timersScheduler;\n\n\nTimer::Timer(Callback callback, std::chrono::milliseconds timeout) {\n    // Start the timers scheduler if this is the first timer created.\n    static bool init = _timersScheduler.StartMainLoop();\n\n    std::lock_guard<std::mutex> lock(_timersScheduler.mutex);\n\n    TimerInfo timerInfo{ false, timeout, callback };\n\n    if (!_timersScheduler.freeSlots.empty()) {\n        _index = _timersScheduler.freeSlots.top();\n        _timersScheduler.freeSlots.pop();\n\n        _timersScheduler.timers[_index] = std::move(timerInfo);\n    }\n    else {\n        _index = static_cast<Timer::Index>(_timersScheduler.timers.size());\n        _timersScheduler.timers.emplace_back(timerInfo);\n    }\n}\n\nTimer::~Timer() {\n    std::lock_guard<std::mutex> lock(_timersScheduler.mutex);\n\n    _timersScheduler.timers[_index].active = false;\n\n    // Free the timer slot.\n    _timersScheduler.freeSlots.emplace(_index);\n}\n\nvoid Timer::Start() {\n    {\n        std::lock_guard<std::mutex> lock(_timersScheduler.mutex);\n        \n        auto& timerInfo = _timersScheduler.timers[_index];\n        timerInfo.active = true;\n\n        ActiveTimerEntry entry = { _index, std::chrono::high_resolution_clock::now() + timerInfo.timeout };\n        _timersScheduler.activeTimers.emplace(std::move(entry));\n    }\n\n    _timersScheduler.cv.notify_one();\n}\n\nvoid Timer::Stop() {\n    std::lock_guard<std::mutex> lock(_timersScheduler.mutex);\n\n    _timersScheduler.timers[_index].active = false;\n}\n"
  },
  {
    "path": "src/zone/timer.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <chrono>\n#include <functional>\n#include <memory>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> A timer class that will trigger a callback after elapsed time. </summary>\n    class Timer {\n    public:\n        typedef uint16_t Index;\n        typedef std::function<void(void)> Callback;\n\n        /// <summary> Creates a new timer which is not active initially. </summary>\n        /// <param name=\"callback\"> The callback. </param>\n        /// <param name=\"timeout\"> The timeout in millisecond after which the callback will be triggered. </param>\n        Timer(Callback callback, std::chrono::milliseconds timeout);\n\n        /// <summary> Destructor. Stops the timer. </summary>\n        ~Timer();\n\n        /// <summary> Activates the timer to trigger the callback after specified milliseconds. </summary>\n        void Start();\n\n        /// <summary> Disables the timer, preventing the calback from triggering. </summary>\n        void Stop();\n\n    private:\n        Index _index;\n    };\n}\n}"
  },
  {
    "path": "src/zone/worker-context.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"worker-context.h\"\n\n#include <napa/log.h>\n#include <platform/process.h>\n#include <platform/thread-local.h>\n#include <array>\n\nusing namespace napa;\nusing namespace napa::zone;\n\nnamespace {\n    tls::ThreadLocal<std::array<\n        void*,\n        static_cast<size_t>(WorkerContextItem::END_OF_WORKER_CONTEXT_ITEM)>> items;\n}\n\nvoid WorkerContext::Init() {\n    items.Install();\n    items->fill(nullptr);\n}\n\nvoid* WorkerContext::Get(WorkerContextItem item) {\n    NAPA_ASSERT(item < WorkerContextItem::END_OF_WORKER_CONTEXT_ITEM, \"Invalid WorkerContextItem\");\n    return (*items)[static_cast<size_t>(item)];\n}\n\nvoid WorkerContext::Set(WorkerContextItem item, void* data) {\n    NAPA_ASSERT(item < WorkerContextItem::END_OF_WORKER_CONTEXT_ITEM, \"Invalid WorkerContextItem\");\n    (*items)[static_cast<size_t>(item)] = data;\n}"
  },
  {
    "path": "src/zone/worker-context.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/exports.h>\n\n#include <array>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Worker context item to store Napa specific data for a module to be able to access. </summary>\n    enum class WorkerContextItem : uint32_t {\n        /// <summary> Isolate instance. </summary>\n        ISOLATE = 0,\n\n        /// <summary> Module's persistent constructor object. </summary>\n        CONSTRUCTOR,\n\n        /// <summary> Module loader instance. </summary>\n        MODULE_LOADER,\n\n        /// <summary> Module object for Napa binding. It will be filled under both Napa and Node isolate. </summary>\n        NAPA_BINDING,\n\n        /// <summary> Zone instance. </summary>\n        ZONE,\n\n        /// <summary> Worker Id. </summary>\n        WORKER_ID,\n\n        /// <summary> End of index. </summary>\n        END_OF_WORKER_CONTEXT_ITEM\n    };\n\n    /// <summary> Napa specific data stored at TLS. </summary>\n    class NAPA_API WorkerContext {\n    public:\n\n        /// <summary> Initialize isolate data. </summary>\n        static void Init();\n\n        /// <summary> Get stored TLS data. </summary>\n        /// <param name=\"item\"> Pre-defined data id for Napa specific data. </param>\n        /// <returns> Stored TLS data. </returns>\n        static void* Get(WorkerContextItem item);\n\n        /// <summary> Set TLS data into the given slot. </summary>\n        /// <param name=\"item\"> Pre-defined data id for Napa specific data. </param>\n        /// <param name=\"data\"> Pointer to stored data. </param>\n        static void Set(WorkerContextItem item, void* data);\n    };\n\n    #define INIT_WORKER_CONTEXT napa::zone::WorkerContext::Init\n\n}   // End of namespace zone.\n}   // End of namespace napa."
  },
  {
    "path": "src/zone/worker.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"worker.h\"\n\n#include <napa/log.h>\n\n#include <v8.h>\n\n#include <condition_variable>\n#include <cstdlib>\n#include <mutex>\n#include <queue>\n#include <thread>\n\n#include <v8-extensions/v8-extensions-macros.h>\n#if !(V8_VERSION_CHECK_FOR_ARRAY_BUFFER_ALLOCATOR)\n    #include <v8-extensions/array-buffer-allocator.h>\n#endif\n\nusing namespace napa;\nusing namespace napa::zone;\n\n// Forward declaration\nstatic v8::Isolate* CreateIsolate(const settings::ZoneSettings& settings);\nstatic void ConfigureIsolate(v8::Isolate* isolate, const settings::ZoneSettings& settings);\n\nstruct Worker::Impl {\n\n    /// <summary> The worker id. </summary>\n    WorkerId id;\n\n    /// <summary> The thread that executes the tasks. </summary>\n    std::thread workerThread;\n\n    /// <summary> Queue for tasks scheduled on this worker. </summary>\n    std::queue<std::shared_ptr<Task>> tasks;\n\n    /// <summary> Queue for tasks scheduled on this worker. </summary>\n    std::queue<std::shared_ptr<Task>> immediateTasks;\n    \n    /// <summary> Condition variable to indicate if there are more tasks to consume. </summary>\n    std::condition_variable hasTaskEvent;\n\n    /// <summary> Lock for task queue and immediate task queue. </summary>\n    std::mutex queueLock;\n\n    /// <summary> V8 isolate associated with this worker. </summary>\n    v8::Isolate* isolate;\n\n    /// <summary> A callback function to setup the isolate after worker created its isolate. </summary>\n    std::function<void(WorkerId)> setupCallback;\n\n    /// <summary> A callback function that is called when worker becomes idle. </summary>\n    std::function<void(WorkerId)> idleNotificationCallback;\n\n    /// <summary> The zone settings for the current worker. </summary>\n    settings::ZoneSettings settings;\n};\n\nWorker::Worker(WorkerId id,\n               const settings::ZoneSettings& settings,\n               std::function<void(WorkerId)> setupCallback,\n               std::function<void(WorkerId)> idleNotificationCallback)\n    : _impl(std::make_unique<Worker::Impl>()) {\n\n    _impl->id = id;\n    _impl->setupCallback = std::move(setupCallback);\n    _impl->idleNotificationCallback = std::move(idleNotificationCallback);\n    _impl->settings = settings;\n}\n\nWorker::~Worker() {\n    // Signal the thread loop that it should stop processing tasks.\n    Enqueue(nullptr, SchedulePhase::DefaultPhase);\n    NAPA_DEBUG(\"Worker\", \"(id=%u) Shutting down: Start draining task queue.\", _impl->id);\n    \n    _impl->workerThread.join();\n\n    if (_impl->isolate != nullptr) {\n        _impl->isolate->Dispose();\n    }\n    NAPA_DEBUG(\"Worker\", \"(id=%u) Shutdown complete.\", _impl->id);\n}\n\nWorker::Worker(Worker&&) = default;\nWorker& Worker::operator=(Worker&&) = default;\n\nvoid Worker::Start() {\n    _impl->workerThread = std::thread(&Worker::WorkerThreadFunc, this, _impl->settings);\n}\n\nvoid Worker::Schedule(std::shared_ptr<Task> task, SchedulePhase phase) {\n    NAPA_ASSERT(task != nullptr, \"Task should not be null\");\n    Enqueue(task, phase);\n    NAPA_DEBUG(\"Worker\", \"(id=%u) Task queued.\", _impl->id);\n}\n\nvoid Worker::Enqueue(std::shared_ptr<Task> task, SchedulePhase phase) {\n    {\n        std::unique_lock<std::mutex> lock(_impl->queueLock);\n        if (phase == SchedulePhase::ImmediatePhase && task != nullptr) {\n            _impl->immediateTasks.emplace(std::move(task));\n        }\n        else {\n            _impl->tasks.emplace(std::move(task));\n        }\n    }\n    _impl->hasTaskEvent.notify_one();\n}\n\nvoid Worker::WorkerThreadFunc(const settings::ZoneSettings& settings) {\n    \n    _impl->isolate = CreateIsolate(settings);\n\n    // If any user of v8 library uses a locker on any isolate, all isolates must be locked before use.\n    // Since we are 1-1 with threads and isolates, a top level lock that is never released is ok.\n    v8::Locker locker(_impl->isolate);\n\n    ConfigureIsolate(_impl->isolate, settings);\n\n    v8::Isolate::Scope isolateScope(_impl->isolate);\n    v8::HandleScope handleScope(_impl->isolate);\n    v8::Local<v8::Context> context = v8::Context::New(_impl->isolate);\n\n    // We set an empty security token so callee can access caller's context.\n    context->SetSecurityToken(v8::Undefined(_impl->isolate));\n    v8::Context::Scope contextScope(context);\n\n    NAPA_DEBUG(\"Worker\", \"(id=%u) V8 Isolate created.\", _impl->id);\n\n    // Setup worker after isolate creation.\n    _impl->setupCallback(_impl->id);\n\n    NAPA_DEBUG(\"Worker\", \"(id=%u) Setup completed.\", _impl->id);\n\n    while (true) {\n        std::shared_ptr<Task> task;\n\n        {\n            // Logically one merged task queue is the concatenation of immediate queue and\n            // the normal queue. The logically merged queue is treated as empty only when both queues\n            // are empty. And when not empty, immediate tasks will be handled prior to normal tasks.\n            // Inside each single queue (immediate or normal), tasks are first in first out.\n            std::unique_lock<std::mutex> lock(_impl->queueLock);\n            if (_impl->tasks.empty() && _impl->immediateTasks.empty()) {\n                _impl->idleNotificationCallback(_impl->id);\n\n                // Wait until new tasks come.\n                _impl->hasTaskEvent.wait(\n                    lock, \n                    [this]() { return !(_impl->tasks.empty() && _impl->immediateTasks.empty()); });\n            }\n\n            if (_impl->immediateTasks.empty()) {\n                task = _impl->tasks.front();\n                _impl->tasks.pop();\n            }\n            else {\n                task = _impl->immediateTasks.front();\n                _impl->immediateTasks.pop();\n            }\n        }\n\n        // A null task means that the worker needs to shutdown.\n        if (task == nullptr) {\n            NAPA_DEBUG(\"Worker\", \"(id=%u) Finish serving tasks.\", _impl->id);\n            break;\n        }\n\n        // Resume execution capabilities if isolate was previously terminated.\n        _impl->isolate->CancelTerminateExecution();\n\n        task->Execute();\n    }\n}\n\nstatic v8::Isolate* CreateIsolate(const settings::ZoneSettings& settings) {\n    v8::Isolate::CreateParams createParams;\n\n    // The allocator is a global V8 setting.\n#if V8_VERSION_CHECK_FOR_ARRAY_BUFFER_ALLOCATOR\n    static std::unique_ptr<v8::ArrayBuffer::Allocator> defaultArrayBufferAllocator(v8::ArrayBuffer::Allocator::NewDefaultAllocator());\n    createParams.array_buffer_allocator = defaultArrayBufferAllocator.get();\n#else\n    static napa::v8_extensions::ArrayBufferAllocator commonAllocator;\n    createParams.array_buffer_allocator = &commonAllocator;\n#endif\n\n    // Set the maximum V8 heap size.\n    createParams.constraints.set_max_old_space_size(settings.maxOldSpaceSize);\n    createParams.constraints.set_max_semi_space_size(settings.maxSemiSpaceSize);\n    createParams.constraints.set_max_executable_size(settings.maxExecutableSize);\n\n    return v8::Isolate::New(createParams);\n}\n\nstatic void ConfigureIsolate(v8::Isolate* isolate, const settings::ZoneSettings& settings) {\n    isolate->SetFatalErrorHandler([](const char* location, const char* message) {\n        LOG_ERROR(\"V8\", \"V8 Fatal error at %s. Error: %s\", location, message);\n    });\n\n    // Prevent V8 from aborting on uncaught exception.\n    isolate->SetAbortOnUncaughtExceptionCallback([](v8::Isolate*) {\n        LOG_ERROR(\"V8\", \"V8 uncaught exception was thrown.\");\n        return false;\n    });\n\n    // V8 takes a pointer to the minimum (x86 stack grows down) allowed stack address\n    // so, capture the current top of the stack and calculate minimum allowed\n    uint32_t currentStackAddress;\n    auto limit = (reinterpret_cast<uintptr_t>(&currentStackAddress - settings.maxStackSize / sizeof(uint32_t*)));\n    isolate->SetStackLimit(limit);\n}\n"
  },
  {
    "path": "src/zone/worker.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include \"task.h\"\n#include \"schedule-phase.h\"\n#include \"settings/settings.h\"\n\n#include <functional>\n#include <memory>\n\n\nnamespace napa {\nnamespace zone {\n\n    // Represent the worker id type.\n    using WorkerId = uint32_t;\n\n    /// <summary> Represents an execution unit (a worker) for running tasks. </summary>\n    class Worker {\n    public:\n\n        /// <summary> Constructor. </summary>\n        /// <param name=\"id\"> The task id. </param>\n        /// <param name=\"settings\"> A settings object. </param>\n        /// <param name=\"setupCallback\"> Callback to setup the isolate after worker created its isolate. </param>\n        /// <param name=\"idleNotificationCallback\"> Triggers when the worker becomes idle. </param>\n        Worker(WorkerId id,\n               const settings::ZoneSettings &settings,\n               std::function<void(WorkerId)> setupCallback,\n               std::function<void(WorkerId)> idleNotificationCallback);\n\n        /// <summary> Destructor. </summary>\n        /// <note> This will block until all pending tasks are completed. </note>\n        ~Worker();\n\n        /// <summary> Non-copyable. </summary>\n        Worker(const Worker&) = delete;\n        Worker& operator=(const Worker&) = delete;\n\n        /// <summary> Moveable. </summary>\n        Worker(Worker&&);\n        Worker& operator=(Worker&&);\n\n        /// <summary> Start the underlying worker thread. </summary>\n        void Start();\n\n        /// <summary> Schedules a task on this worker. </summary>\n        /// <param name=\"task\"> Task to schedule. </param>\n        /// <note> Same task instance may run on multiple workers, hence the use of shared_ptr. </node>\n        void Schedule(std::shared_ptr<Task> task, SchedulePhase phase=SchedulePhase::DefaultPhase);\n\n    private:\n\n        /// <summary> The worker thread logic. </summary>\n        void WorkerThreadFunc(const settings::ZoneSettings& settings);\n\n        /// <summary> Enqueue a task. </summary>\n        void Enqueue(std::shared_ptr<Task> task, SchedulePhase phase);\n        \n        struct Impl;\n        std::unique_ptr<Impl> _impl;\n    };\n}\n}\n"
  },
  {
    "path": "src/zone/zone.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa/types.h>\n\nnamespace napa {\nnamespace zone {\n\n    /// <summary> Interface for Zone. </summary>\n    struct Zone {\n\n        /// <summary> Get the zone id. </summary>\n        virtual const std::string& GetId() const = 0;\n\n        /// <summary> Executes a pre-loaded JS function on all zone workers asynchronously. </summary>\n        /// <param name=\"spec\"> The function spec. </param>\n        /// <param name=\"callback\"> A callback that is triggered when broadcasting is done. </param>\n        virtual void Broadcast(const FunctionSpec& spec, BroadcastCallback callback) = 0;\n\n        /// <summary> Executes a pre-loaded JS function asynchronously. </summary>\n        /// <param name=\"spec\"> The function spec. </param>\n        /// <param name=\"callback\"> A callback that is triggered when execution is done. </param>\n        virtual void Execute(const FunctionSpec& spec, ExecuteCallback callback) = 0;\n\n        /// <summary> Virtual destructor. </summary>\n        virtual ~Zone() {}\n    };\n}\n}"
  },
  {
    "path": "test/memory-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport * as assert from 'assert';\nimport * as path from 'path';\n\ndescribe('napajs/memory', function() {\n    let napaZone = napa.zone.create('zone5');\n\n    describe('Handle', () => {\n        it('#isEmpty', () => {\n            assert(napa.memory.isEmpty([0, 0]));\n            assert(!napa.memory.isEmpty([1, 2]));\n        });\n    });\n\n    describe('Shareable', () => {\n        it('#isShareable', () => {\n            assert(napa.memory.isShareable(napa.memory.crtAllocator));\n            assert(!napa.memory.isShareable(\"hello world\"));\n            assert(!napa.memory.isShareable(1));\n            assert(!napa.memory.isShareable({ a: 1 }));\n        });\n    });\n\n    describe('Allocators', () => {\n        it('@node: crtAllocator', () => {\n            let handle = napa.memory.crtAllocator.allocate(10);\n            assert(!napa.memory.isEmpty(handle));\n            napa.memory.crtAllocator.deallocate(handle, 10);\n        });\n        \n        it('@napa: crtAllocator', () => {\n            napaZone.execute('./napa-zone/test', \"crtAllocatorTest\");\n        });\n    \n        it('@node: defaultAllocator', () => {\n            let handle = napa.memory.defaultAllocator.allocate(10);\n            assert(!napa.memory.isEmpty(handle));\n            napa.memory.defaultAllocator.deallocate(handle, 10);\n        });\n\n        it('@napa: defaultAllocator', () => {\n            napaZone.execute('./napa-zone/test', \"defaultAllocatorTest\");\n        });\n\n        it('@node: debugAllocator', () => {\n            let allocator = napa.memory.debugAllocator(napa.memory.defaultAllocator);\n            let handle = allocator.allocate(10);\n            assert(!napa.memory.isEmpty(handle));\n            allocator.deallocate(handle, 10);\n            let debugInfo = JSON.parse(allocator.getDebugInfo());\n            assert.deepEqual(debugInfo, {\n                allocate: 1,\n                allocatedSize: 10,\n                deallocate: 1,\n                deallocatedSize: 10\n            });\n        });\n\n        it('@napa: debugAllocator', () => {\n            napaZone.execute('./napa-zone/test', \"debugAllocatorTest\");\n        });\n    });\n});"
  },
  {
    "path": "test/module/addon/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"simple-addon\")\n\nset(NAPA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../..)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# The target name\nset(TARGET_NAME ${PROJECT_NAME})\n\n# The generated library\nadd_library(${TARGET_NAME} SHARED\n    addon.cpp\n    simple-object-wrap.cpp)\n\n# Change output extension to 'napa'\nset_target_properties(${TARGET_NAME} PROPERTIES PREFIX \"\" SUFFIX \".napa\")\n\n# Set output directory for the addon\nset_target_properties(${TARGET_NAME} PROPERTIES\n    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${NAPA_ROOT}/bin\n    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${NAPA_ROOT}/bin\n    LIBRARY_OUTPUT_DIRECTORY_DEBUG ${NAPA_ROOT}/bin\n    LIBRARY_OUTPUT_DIRECTORY_RELEASE ${NAPA_ROOT}/bin\n)\n\n# Include directories\ntarget_include_directories(${TARGET_NAME}\n    PRIVATE\n    ${NAPA_ROOT}/inc\n    ${CMAKE_JS_INC})\n\n# Link libraries\ntarget_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_JS_LIB})\n\n# Link with napa shared library\nif (WIN32)\n    target_link_libraries(${TARGET_NAME} PRIVATE ${NAPA_ROOT}/bin/napa.lib)\nelseif (APPLE)\n    target_link_libraries(${TARGET_NAME} PRIVATE ${NAPA_ROOT}/bin/libnapa.dylib)\nelse()\n    target_link_libraries(${TARGET_NAME} PRIVATE ${NAPA_ROOT}/bin/libnapa.so)\nendif()\n\n# Compiler definitions\ntarget_compile_definitions(${TARGET_NAME} PRIVATE BUILDING_NAPA_EXTENSION)\n\n\n"
  },
  {
    "path": "test/module/addon/addon.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <napa/module.h>\n\n#include \"simple-object-wrap.h\"\n\nusing namespace napa;\nusing namespace napa::test;\nusing namespace napa::module;\n\n\nvoid GetModuleName(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    v8::HandleScope scope(isolate);\n\n    args.GetReturnValue().Set(v8_helpers::MakeV8String(isolate, \"simple-napa-addon\"));\n}\n\nvoid CreateSimpleObjectWrap(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    SimpleObjectWrap::NewInstance(args);\n}\n\nvoid Init(v8::Local<v8::Object> exports) {\n    SimpleObjectWrap::Init();\n\n    NAPA_SET_METHOD(exports, \"getModuleName\", GetModuleName);\n    NAPA_SET_METHOD(exports, \"createSimpleObjectWrap\", CreateSimpleObjectWrap);\n}\n\nNAPA_MODULE(addon, Init);\n"
  },
  {
    "path": "test/module/addon/simple-object-wrap.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include \"simple-object-wrap.h\"\n\n#include <napa/zone.h>\n#include <napa/assert.h>\n#include <napa/async.h>\n#include <napa/v8-helpers.h>\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <unistd.h>\n#endif\n\nusing namespace napa::module;\nusing namespace napa::test;\nusing namespace napa::v8_helpers;\n\nNAPA_DEFINE_PERSISTENT_CONSTRUCTOR(SimpleObjectWrap);\n\nvoid SimpleObjectWrap::Init() {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    // Prepare constructor template.\n    auto functionTemplate = v8::FunctionTemplate::New(isolate, DefaultConstructorCallback<SimpleObjectWrap>);\n    functionTemplate->SetClassName(MakeV8String(isolate, exportName));\n    functionTemplate->InstanceTemplate()->SetInternalFieldCount(1);\n\n    // Prototypes.\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"getValue\", GetValue);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"setValue\", SetValue);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"doIncrementWork\", DoIncrementWork);\n    NAPA_SET_PROTOTYPE_METHOD(functionTemplate, \"postIncrementWork\", PostIncrementWork);\n\n    // Set persistent constructor into V8.\n    NAPA_SET_PERSISTENT_CONSTRUCTOR(exportName, functionTemplate->GetFunction());\n}\n\nvoid SimpleObjectWrap::NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n    auto context = isolate->GetCurrentContext();\n\n    auto constructor = NAPA_GET_PERSISTENT_CONSTRUCTOR(exportName, ZoneWrap);\n    args.GetReturnValue().Set(constructor->NewInstance(context).ToLocalChecked());\n}\n\nvoid SimpleObjectWrap::GetValue(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    auto wrap = ObjectWrap::Unwrap<SimpleObjectWrap>(args.Holder());\n\n    args.GetReturnValue().Set(wrap->value);\n}\n\nvoid SimpleObjectWrap::SetValue(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args[0]->IsUint32(), \"first argument to setValue must be a uint32\");\n\n    auto wrap = ObjectWrap::Unwrap<SimpleObjectWrap>(args.Holder());\n    wrap->value = args[0]->Uint32Value();\n}\n\nvoid SimpleObjectWrap::DoIncrementWork(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args.Length() == 1 && args[0]->IsFunction(), \"It requires a callback as arguments\");\n\n    auto wrap = ObjectWrap::Unwrap<SimpleObjectWrap>(args.Holder());\n\n    napa::zone::DoAsyncWork(\n        v8::Local<v8::Function>::Cast(args[0]),\n        [wrap](auto complete) {\n            // This runs at the same thread.\n            auto newValue = ++wrap->value;\n\n            complete(reinterpret_cast<void*>(static_cast<uintptr_t>(newValue)));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs at the same thread as one DoIncrementWork() is called.\n            auto isolate = v8::Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            v8::Local<v8::Value> argv[] = {\n                v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result)))\n            };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n\nvoid SimpleObjectWrap::PostIncrementWork(const v8::FunctionCallbackInfo<v8::Value>& args) {\n    auto isolate = v8::Isolate::GetCurrent();\n\n    CHECK_ARG(isolate, args.Length() == 1 && args[0]->IsFunction(), \"It requires a callback as arguments\");\n\n    auto wrap = ObjectWrap::Unwrap<SimpleObjectWrap>(args.Holder());\n\n    napa::zone::PostAsyncWork(\n        v8::Local<v8::Function>::Cast(args[0]),\n        [wrap]() {\n            #ifdef _WIN32\n                Sleep(10);\n            #else\n                // Sleep 10 ms.\n                usleep(10 * 1000);\n            #endif\n\n            // This runs at the separate thread.\n            auto newValue = ++wrap->value;\n\n            return reinterpret_cast<void*>(static_cast<uintptr_t>(newValue));\n        },\n        [](auto jsCallback, void* result) {\n            // This runs at the same thread as one PostIncrementWork() is called.\n            auto isolate = v8::Isolate::GetCurrent();\n\n            int32_t argc = 1;\n            v8::Local<v8::Value> argv[] = { \n                v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(result)))\n            };\n\n            jsCallback->Call(isolate->GetCurrentContext()->Global(), argc, argv);\n        }\n    );\n}\n"
  },
  {
    "path": "test/module/addon/simple-object-wrap.h",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#pragma once\n\n#include <napa.h>\n\n#include <atomic>\n\nnamespace napa {\nnamespace test {\n\n    /// <summary> A simple object wrap for testing. </summary>\n    class SimpleObjectWrap : public NAPA_OBJECTWRAP {\n    public:\n\n        /// <summary> Exported class name. </summary>\n        static constexpr const char* exportName = \"SimpleObjectWrap\";\n\n        /// <summary> Initializes the wrap. </summary>\n        static void Init();\n\n        /// <summary> Create a new wrap instance. </summary>\n        static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        std::atomic<uint32_t> value = { 0 };\n\n    private:\n\n        /// <summary> Declare persistent constructor to create Zone Javascript wrapper instance. </summary>\n        NAPA_DECLARE_PERSISTENT_CONSTRUCTOR();\n\n        // SimpleObjectWrap methods\n        static void GetValue(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void SetValue(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void DoIncrementWork(const v8::FunctionCallbackInfo<v8::Value>& args);\n        static void PostIncrementWork(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n        /// <summary> Friend default constructor callback. </summary>\n        template <typename WrapType>\n        friend void napa::module::DefaultConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>&);\n    };\n}\n}"
  },
  {
    "path": "test/module/cycle-a.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexports.done = false;\nvar cycle_b = require('./cycle-b.js');\nif (cycle_b.done == true) {\n    exports.done = true;\n}\n"
  },
  {
    "path": "test/module/cycle-b.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexports.done = false;\nvar cycle_a = require('./cycle-a.js');\nif (cycle_a.done == false) {\n    exports.done = true;\n}\n"
  },
  {
    "path": "test/module/jsmodule.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nexports.wasLoaded = true;"
  },
  {
    "path": "test/module/node_modules/file.js",
    "content": ""
  },
  {
    "path": "test/module/resolution-tests.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar assert = require('assert');\n\nfunction run() {\n    // Core module\n    assert(require.resolve('fs'), 'fs');\n\n    // Full path with extension\n    assert(require.resolve(__dirname + '/sub-folder/file.js'), __dirname + '/sub-folder/file.js');\n\n    // Full path without extension\n    assert(require.resolve(__dirname + '/sub-folder/file'), __dirname + '/sub-folder/file.js');\n\n    // Relative path with extension\n    assert(require.resolve('./sub-folder/file.js'), __dirname + '/sub-folder/file.js');\n\n    // Relative path without extension\n    assert(require.resolve('./sub-folder/file'), __dirname + '/sub-folder/file.js');\n\n    // Relative path with non normalized path\n    assert(require.resolve('./sub-folder/.././sub-folder/file.js'), __dirname + '/sub-folder/file.js');\n\n    // Relative path without extension to napa addon\n    assert(require.resolve('./sub-folder/addon/mock-addon'), __dirname + '/sub-folder/addon/mock-addon.napa');\n\n    // From node_modules with extension\n    assert(require.resolve('file.js'), __dirname + '/node_modules/file.js');\n\n    // From node_modules without extension\n    assert(require.resolve('file'), __dirname + '/node_modules/file.js');\n\n    // Resolving non-existing file should throw\n    assert.throws(() => { \n        require.resolve('./sub-folder/non-existing-file.js');\n    });\n}\n\nexports.run = run;\n"
  },
  {
    "path": "test/module/sub-folder/addon/mock-addon.napa",
    "content": ""
  },
  {
    "path": "test/module/sub-folder/file.js",
    "content": ""
  },
  {
    "path": "test/module/test.json",
    "content": "{\n  \"prop1\": \"val1\",\n  \"prop2\": \"val2\"\n}\n"
  },
  {
    "path": "test/module-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport * as assert from \"assert\";\nimport * as path from \"path\";\n\ntype Zone = napa.zone.Zone;\n\ndescribe('napajs/module', function () {\n    let napaZone = napa.zone.create('module-tests-zone', { workers: 1 });\n\n    describe('load', function () {\n        it('javascript module', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var jsmodule = require('./module/jsmodule');\n\n                assert.notEqual(jsmodule, undefined);\n                assert.equal(jsmodule.wasLoaded, true);\n            });\n        });\n\n        it('javascript module from string', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var path = require('path');\n\n                var jsmodule = (<any>require)(\n                    './module/jsmodule-from-string', \n                    \"module.exports = function() { return __filename;}\");\n\n                assert.notEqual(jsmodule, undefined);\n                assert.equal(jsmodule(), path.resolve(__dirname, 'module/jsmodule-from-string'));\n            });\n        });\n\n        it('json module', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var jsonModule = require('./module/test.json');\n\n                assert.notEqual(jsonModule, undefined);\n                assert.equal(jsonModule.prop1, \"val1\");\n                assert.equal(jsonModule.prop2, \"val2\");\n            });\n        });\n\n        it('napa module', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var napaModule = require('../bin/simple-addon.napa');\n\n                assert.notEqual(napaModule, undefined);\n                assert.equal(napaModule.getModuleName(), \"simple-napa-addon\");\n            });\n        });\n\n        it('object wrap module', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var napaModule = require('../bin/simple-addon.napa');\n\n                var obj = napaModule.createSimpleObjectWrap();\n                assert.notEqual(obj, undefined);\n                obj.setValue(3);\n                assert.equal(obj.getValue(), 3);\n            }, [__dirname]);\n        });\n\n        it('circular dependencies', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n\n                var cycle_a = require('./module/cycle-a.js');\n                var cycle_b = require('./module/cycle-b.js');\n\n                assert(cycle_a.done);\n                assert(cycle_b.done);\n            }, [__dirname]);\n        });\n\n        it('module that does not exist', () => {\n            return napaZone.execute(() => {\n                try {\n                    var jsmodule = require('./module/module-does-not-exist');\n                    assert.fail(\"require on module that does not exist shall throw\");\n                }\n                catch (e) {\n                }\n            });\n        });\n    });\n\n    describe('resolve', function () {\n        // TODO: support correct __dirname in anonymous function and move tests from 'resolution-tests.js' here.\n        it('require.resolve', () => {\n            return napaZone.execute(\"./module/resolution-tests.js\", \"run\");\n        });\n    });\n\n    describe('core-modules', function () {\n        describe('process', function () {\n            it.skip('argv', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                \n                    assert(process.argv.length > 0);\n                    assert(process.argv[0].includes('node'));\n                });\n            });\n\n            it('execPath', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                \n                    assert(process.execPath.includes('node'));\n                });\n            });\n\n            it('env', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                \n                    process.env.test = \"napa-test\";\n                    assert.equal(process.env.test, \"napa-test\");\n                });\n            });\n\n            it('platform', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                \n                    assert(process.platform == 'win32' || \n                           process.platform == 'darwin' || \n                           process.platform == 'linux' || \n                           process.platform == 'freebsd');\n                });\n            });\n\n            it('umask', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    \n                    var old = process.umask(0);\n                    assert.equal(process.umask(old), 0);\n                });\n            });\n\n            it('chdir', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    \n                    var cwd = process.cwd();\n                    process.chdir('..');\n                    assert.notEqual(cwd, process.cwd());\n                    assert(cwd.includes(process.cwd()));\n                    process.chdir(cwd);\n                    assert.equal(cwd, process.cwd());\n                });\n            });\n\n            it('pid', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    \n                    assert.notEqual(typeof process.pid, undefined);\n                    assert(!isNaN(process.pid));\n                });\n            });\n        });\n\n        describe('fs', function () {\n            it('existsSync', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var fs = require('fs');\n\n                    assert(fs.existsSync(__dirname + '/module/jsmodule.js'));\n                    assert(!fs.existsSync(__dirname + '/non-existing-file.txt'));\n                });\n            });\n\n            it('readFileSync', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var fs = require('fs');\n\n                    var content = JSON.parse(fs.readFileSync(__dirname + '/module/test.json'));\n                    assert.equal(content.prop1, 'val1');\n                    assert.equal(content.prop2, 'val2');\n                });\n            });\n\n            it('mkdirSync', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var fs = require('fs');\n\n                    fs.mkdirSync(__dirname + '/module/test-dir');\n                    assert(fs.existsSync(__dirname + '/module/test-dir'));\n                }).then(()=> {\n                    // Cleanup\n                    var fs = require('fs');\n                    if (fs.existsSync('./module/test-dir')) {\n                        fs.rmdir('./module/test-dir');\n                    }\n                })\n            });\n\n            it('writeFileSync', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var fs = require('fs');\n\n                    fs.writeFileSync(__dirname + '/module/test-file', 'test');\n                    assert.equal(fs.readFileSync(__dirname + '/module/test-file'), 'test');\n                }, [__dirname]).then(()=> {\n                    // Cleanup\n                    var fs = require('fs');\n                    if (fs.existsSync('./module/test-file')) {\n                        fs.unlinkSync('./module/test-file');\n                    }\n                })\n            });\n\n            it('readFileSync', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var fs = require('fs');\n\n                    var testDir = __dirname + '/module/test-dir';\n                    fs.mkdirSync(testDir);\n                    fs.writeFileSync(testDir + '/1', 'test');\n                    fs.writeFileSync(testDir + '/2', 'test');\n                    \n                    assert.deepEqual(fs.readdirSync(testDir).sort(), ['1', '2']);\n                }).then(()=> {\n                    // Cleanup\n                    var fs = require('fs');\n                    if (fs.existsSync('./module/test-dir')) {\n                        fs.unlinkSync('./module/test-dir/1');\n                        fs.unlinkSync('./module/test-dir/2');\n                        fs.rmdir('./module/test-dir');\n                    }\n                })\n            });\n        });\n\n        describe('path', function () {\n            it('normalize', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.normalize('a\\\\b\\\\..\\\\c/./d/././.'), \"a\\\\c\\\\d\");\n                    } else {\n                        assert.equal(path.normalize('a\\\\b\\\\..\\\\c/./d/././.'), \"a/c/d\");\n                    }\n                });\n            });\n\n            it('resolve', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.resolve('c:\\\\foo/bar', \"a.txt\"), \"c:\\\\foo\\\\bar\\\\a.txt\");\n                        assert.equal(path.resolve(\"abc.txt\"), process.cwd() + \"\\\\abc.txt\");\n                        assert.equal(path.resolve(\"abc\", \"efg\", \"../hij\", \"./xyz.txt\"), process.cwd() + \"\\\\abc\\\\hij\\\\xyz.txt\");\n                        assert.equal(path.resolve(\"abc\", \"d:/a.txt\"), \"d:\\\\a.txt\");\n                    } else {\n                        assert.equal(path.resolve('/foo/bar', \"a.txt\"), \"/foo/bar/a.txt\");\n                        assert.equal(path.resolve(\"abc.txt\"), process.cwd() + \"/abc.txt\");\n                        assert.equal(path.resolve(\"abc\", \"efg\", \"../hij\", \"./xyz.txt\"), process.cwd() + \"/abc/hij/xyz.txt\");\n                        assert.equal(path.resolve(\"abc\", \"/a.txt\"), \"/a.txt\");\n                    }\n                });\n            });\n\n            it('join', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.join(\"/foo\", \"bar\", \"baz/asdf\", \"quux\", \"..\"), \"\\\\foo\\\\bar\\\\baz\\\\asdf\");\n                    } else {\n                        assert.equal(path.join(\"/foo\", \"bar\", \"baz/asdf\", \"quux\", \"..\"), \"/foo/bar/baz/asdf\");\n                    }\n                });\n            });\n\n            // TODO: fix bugs\n            //      1. Error: the string \"AssertionError: '.' == 'c:'\" was thrown, throw an Error :)\n            //      2. Error: the string \"AssertionError: 'c:' == 'c:\\\\\\\\'\" was thrown, throw an Error :)\n            it.skip('dirname', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.dirname(\"c:\"), \"c:\");\n                        assert.equal(path.dirname(\"c:\\\\windows\"), \"c:\\\\\");\n                        assert.equal(path.dirname(\"c:\\\\windows\\\\abc.txt\"), \"c:\\\\windows\");\n                    } else {\n                        assert.equal(path.dirname(\"/\"), \"/\");\n                        assert.equal(path.dirname(\"/etc\"), \"/\");\n                        assert.equal(path.dirname(\"/etc/passwd\"), \"/etc\");\n                    }\n                });\n            });\n\n            it('basename', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.basename(\"c:\\\\windows\\\\abc.txt\"), \"abc.txt\");\n                        assert.equal(path.basename(\"c:\\\\windows\\\\a\"), \"a\");\n                        assert.equal(path.basename(\"c:\\\\windows\\\\abc.txt\", \".txt\"), \"abc\");\n                        assert.equal(path.basename(\"c:\\\\windows\\\\abc.txt\", \".Txt\"), \"abc.txt\");\n                    } else {\n                        assert.equal(path.basename(\"/test//abc.txt\"), \"abc.txt\");\n                        assert.equal(path.basename(\"/test//a\"), \"a\");\n                        assert.equal(path.basename(\"/test/abc.txt\", \".txt\"), \"abc\");\n                        assert.equal(path.basename(\"/windows/abc.txt\", \".Txt\"), \"abc.txt\");\n                    }\n                });\n            });\n\n            // TODO: fix bugs\n            //      1. Error: the string \"AssertionError: '' == '.'\" was thrown, throw an Error :)\n            it.skip('extname', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.extname(\"c:\\\\windows\\\\abc.txt\"), \".txt\");\n                        assert.equal(path.extname(\"c:\\\\windows\\\\a.json.txt\"), \".txt\");\n                        assert.equal(path.extname(\"c:\\\\windows\\\\a.\"), \".\");\n                    } else {\n                        assert.equal(path.extname(\"/test/abc.txt\"), \".txt\");\n                        assert.equal(path.extname(\"/test/a.json.txt\"), \".txt\");\n                        assert.equal(path.extname(\"/test/a.\"), \".\");\n                    }\n                });\n            });\n\n            it('isAbsolute', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.isAbsolute(\"c:\\\\windows\\\\a.\"), true);\n                        assert.equal(path.isAbsolute(\"c:/windows/..\"), true);\n                        assert.equal(path.isAbsolute(\"../abc\"), false);\n                        assert.equal(path.isAbsolute(\"./abc\"), false);\n                        assert.equal(path.isAbsolute(\"abc\"), false);\n                    } else {\n                        assert.equal(path.isAbsolute(\"/test/a.\"), true);\n                        assert.equal(path.isAbsolute(\"/test/..\"), true);\n                        assert.equal(path.isAbsolute(\"../abc\"), false);\n                        assert.equal(path.isAbsolute(\"./abc\"), false);\n                        assert.equal(path.isAbsolute(\"abc\"), false);\n                    }\n                });\n            });\n\n            it('relative', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.relative(\"c:\\\\a\\\\..\\\\b\", \"c:\\\\b\"), \"\");\n                        assert.equal(path.relative(\"c:/a\", \"d:/b/../c\"), \"d:\\\\c\");\n                        assert.equal(path.relative(\"z:/a\", \"a.txt\"), process.cwd() + \"\\\\a.txt\");\n                        assert.equal(path.relative(\"c:/a\", \"c:/\"), \"..\");\n                    } else {\n                        assert.equal(path.relative(\"/test/a/../b\", \"/test/b\"), \"\");\n                        assert.equal(path.relative(\"/test/a\", \"/test1/b/../c\"), \"../../test1/c\");\n                        assert.equal(path.relative(\"/test/a\", \"a.txt\"), \"../..\" + process.cwd() + \"/a.txt\");\n                        assert.equal(path.relative(\"/test/a\", \"/test/\"), \"..\");\n                    }\n                });\n            });\n\n            it('sep', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var path = require(\"path\");\n                    \n                    if (process.platform == 'win32') {\n                        assert.equal(path.sep, \"\\\\\");\n                    } else {\n                        assert.equal(path.sep, \"/\");\n                    }\n                });\n            });\n        });\n\n        describe('os', function () {\n            it('type', () => {\n                return napaZone.execute(() => {\n                    var assert = require(\"assert\");\n                    var os = require(\"os\");\n                    \n                    assert(os.type() == \"Windows_NT\" || os.type() == \"Darwin\" || os.type() == \"Linux\");\n                });\n            });\n        });\n    });\n\n    describe('async', function () {\n        it('post async work', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var napaModule = require('../bin/simple-addon.napa');\n\n                var obj = napaModule.createSimpleObjectWrap();\n                obj.setValue(3);\n\n                var promise = new Promise((resolve) => {\n                    obj.postIncrementWork((newValue: number) => {\n                        resolve(newValue);\n                    });\n                });\n\n                // The value shouldn't have changed yet.\n                assert.equal(obj.getValue(), 3);\n\n                return promise;\n            }).then((result: napa.zone.Result) => {\n                assert.equal(result.value, 4);\n            });\n        });\n\n        it('do async work', () => {\n            return napaZone.execute(() => {\n                var assert = require(\"assert\");\n                var napaModule = require('../bin/simple-addon.napa');\n\n                var obj = napaModule.createSimpleObjectWrap();\n                obj.setValue(8);\n\n                var promise = new Promise((resolve) => {\n                    obj.doIncrementWork((newValue: number) => {\n                        resolve(newValue);\n                    });\n                });\n\n                // The actual increment happened in the same thread.\n                assert.equal(obj.getValue(), 9);\n\n                return promise;\n            }).then((result: napa.zone.Result) => {\n                assert.equal(result.value, 9);\n            });\n        });\n    });\n});"
  },
  {
    "path": "test/napa-zone/function-as-module.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nmodule.exports = function (input: any): any {\n    return input;\n}"
  },
  {
    "path": "test/napa-zone/test-main.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from '../../lib/index';\n\nexport function foo() {\n    return \"hello world\";\n}"
  },
  {
    "path": "test/napa-zone/test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as assert from 'assert';\nimport * as path from 'path';\nimport * as util from 'util';\nimport * as napa from '../../lib/index';\n\nexport function bar(input: any) {\n    return input;\n}\n\nexport namespace ns1 {\n    export namespace ns2 {\n        export function foo(input: any) {\n            return input;\n        }\n    }\n}\n\nexport function getCurrentZone(): napa.zone.Zone {\n    return napa.zone.current;\n}\n\nexport function broadcast(id: string, code: string): Promise<void> {\n    let zone = napa.zone.get(id);\n    return zone.broadcast(code);\n}\n\nexport function broadcastSync(id: string, code: string): void {\n    let zone = napa.zone.get(id);\n    zone.broadcastSync(code);\n}\n\nexport function broadcastTestFunction(id: string): Promise<void> {\n    return napa.zone.get(id).broadcast((input: string) => {\n            console.log(input);\n        }, [\"hello world\"]);\n}\n\nexport function broadcastSyncTestFunction(id: string): void {\n    napa.zone.get(id).broadcastSync((input: string) => {\n            console.log(input);\n        }, [\"hello world\"]);\n}\n\nexport function broadcastTransportable(id: string): Promise<void> {\n    return napa.zone.get(id).broadcast((input: any) => {\n            console.log(input);\n        }, [napa.memory.crtAllocator]);\n}\n\nexport function broadcastClosure(id: string): Promise<void> {\n    let zone = napa.zone.get(id);\n    return zone.broadcast(() => {\n            console.log(zone);\n        }, []);\n}\n\nexport function execute(id: string, moduleName: string, functionName: string, args?: any[]): Promise<any> {\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute(moduleName, functionName, args)\n            .then((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function executeTestFunction(id: string): Promise<any> {\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute((input: string) => { return input; }, ['hello world'])\n            .then((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function executeTestFunctionWithClosure(id: string): Promise<any> {\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute(() => { return zone; }, [])\n            .then((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function waitMS(waitTimeInMS: number): number {\n    var start = new Date().getTime();\n    var wait = 0;\n    do {\n        wait = new Date().getTime() - start;\n    } while (wait < waitTimeInMS);\n    return wait - waitTimeInMS;\n}\n\nexport function executeTestFunctionWithTimeout(id: string, waitTimeInMS: number, timeoutInMS?: number): Promise<any> {\n    timeoutInMS = timeoutInMS ? timeoutInMS : Number.MAX_SAFE_INTEGER;\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute(waitMS, [waitTimeInMS], {timeout: timeoutInMS})\n            .then((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function executeWithTransportableArgs(id: string): Promise<any> {\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute((allocator: napa.memory.Allocator) => {\n                var assert = require(\"assert\");\n                assert.deepEqual(allocator.handle, (<any>global).napa.memory.crtAllocator.handle);\n                return 1;\n            }, [napa.memory.crtAllocator])\n            .then ((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function executeWithTransportableReturns(id: string): Promise<any> {\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute((allocator: napa.memory.Allocator) => {\n                return allocator;\n            }, [napa.memory.crtAllocator])\n            .then ((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\nexport function executeWithArgsContainingUnicodeString(id: string): Promise<any> {\n    let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\";\n    let zone = napa.zone.get(id);\n    return new Promise((resolve, reject) => {\n        zone.execute((str: string) => {\n                var assert = require(\"assert\");\n                let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\";\n                assert.equal(str, unicodeStr);\n                return str;\n            }, [unicodeStr])\n            .then ((result: napa.zone.Result) => resolve(result.value))\n            .catch((error: any) => reject(error));\n    });\n}\n\n/// <summary> Memory test helpers. </summary>\nexport function crtAllocatorTest(): void {\n    let handle = napa.memory.crtAllocator.allocate(10);\n    assert(!napa.memory.isEmpty(handle));\n    napa.memory.crtAllocator.deallocate(handle, 10);\n}\n\nexport function defaultAllocatorTest(): void {\n    let handle = napa.memory.defaultAllocator.allocate(10);\n    assert(!napa.memory.isEmpty(handle));\n    napa.memory.defaultAllocator.deallocate(handle, 10);\n}\n\nexport function debugAllocatorTest(): void {\n    let allocator = napa.memory.debugAllocator(napa.memory.defaultAllocator);\n    let handle = allocator.allocate(10);\n    assert(!napa.memory.isEmpty(handle));\n    allocator.deallocate(handle, 10);\n    let debugInfo = JSON.parse(allocator.getDebugInfo());\n    assert.deepEqual(debugInfo, {\n            allocate: 1,\n            allocatedSize: 10,\n            deallocate: 1,\n            deallocatedSize: 10\n        });\n}\n\nlet store2: napa.store.Store = null;\nexport function getOrCreateStoreTest() {\n    store2 = napa.store.getOrCreate('store2');\n    assert(store2 != null);\n    assert.equal(store2.id, 'store2');\n    assert.equal(store2.size, 0);\n}\n\nexport function getStoreTest() {\n    let store = napa.store.get('store2');\n    assert.equal(store.id, 'store2');\n\n    // Store created from node zone.\n    let store1 = napa.store.get('store1');\n    assert.equal(store1.id, 'store1');\n}\n\nexport function storeVerifyGet(storeId: string, key: string, expectedValue: any) {\n    let store = napa.store.get(storeId);\n    assert.deepEqual(store.get(key), expectedValue);\n}\n\nexport function storeGetCompareHandle(storeId: string, key: string, expectedHandle: napa.memory.Handle) {\n    let store = napa.store.get(storeId);\n    assert.deepEqual(store.get(key).handle, expectedHandle);\n}\n\nexport function storeSet(storeId: string, key: string, expectedValue: any) {\n    let store = napa.store.get(storeId);\n    store.set(key, expectedValue);\n}\n\nexport function storeDelete(storeId: string, key: string) {\n    let store = napa.store.get(storeId);\n    store.delete(key);\n}\n\nexport function storeVerifyNotExist(storeId: string, key: string) {\n    let store = napa.store.get(storeId);\n    assert(!store.has(key));\n    assert(store.get(key) === undefined);\n}\n\n/// <summary> Transport test helpers. </summary>\nexport class CannotPass {\n    field1: string;\n    field2: number;\n}\n\n@napa.transport.cid()\nexport class CanPass extends napa.transport.TransportableObject {\n    constructor(allocator: napa.memory.Allocator) {\n        super();\n        this._allocator = allocator;\n    }\n    \n    save(payload: any, tc: napa.transport.TransportContext): void {\n        payload['_allocator'] = this._allocator.marshall(tc) \n    }\n\n    load(payload: any, tc: napa.transport.TransportContext): void {\n        // member '_allocator' is already unmarshalled.\n        this._allocator = payload['_allocator'];\n    }\n\n    _allocator: napa.memory.Allocator;\n}\n\n@napa.transport.cid()\nexport class CanAutoPass extends napa.transport.AutoTransportable {\n    constructor(data: any) {\n        super();\n        this._data = data;\n    }\n\n    _data: any;\n}\n\nfunction testMarshallUnmarshall(input: any) {\n    let tc = napa.transport.createTransportContext();\n    let payload = napa.transport.marshall(input, tc);\n    let expected = napa.transport.unmarshall(payload, tc);\n    assert.equal(input.toString(), expected.toString());\n    assert.equal(JSON.stringify(input), JSON.stringify(expected));\n    assert.equal(util.inspect(input), util.inspect(expected));\n}\n\nexport function simpleTypeTransportTest() {\n    testMarshallUnmarshall({ \n        a: 'hello',\n        b: {\n            c: [0, 1]\n        },\n        c: null\n    });\n}\n\nexport function jsTransportTest() {\n    testMarshallUnmarshall(new CanPass(napa.memory.crtAllocator));\n}\n\nexport function jsAutoTransportTest() {\n    testMarshallUnmarshall(new CanAutoPass({ a: 'foo', b: 'bar', c: 123 }));\n}\n\nexport function functionTransportTest() {\n    testMarshallUnmarshall(() => { return 0; });\n}\n\nexport function addonTransportTest() {\n    testMarshallUnmarshall(napa.memory.debugAllocator(napa.memory.crtAllocator));\n}\n\nexport function compositeTransportTest() {\n    testMarshallUnmarshall({\n        a: napa.memory.debugAllocator(napa.memory.crtAllocator),\n        b: [1, 2],\n        c: {\n            d: napa.memory.defaultAllocator,\n            e: 1\n        }\n    });\n}\n\nexport function nontransportableTest() {\n    let tc = napa.transport.createTransportContext();\n    let input = new CannotPass();\n    let success = false;\n    try {\n        napa.transport.marshall(input, tc);\n        success = true;\n    }\n    catch(error) {\n    }\n    assert(!success);\n}"
  },
  {
    "path": "test/store-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport * as assert from 'assert';\nimport * as path from 'path';\n\ndescribe('napajs/store', function () {\n    let napaZone = napa.zone.create('zone6');\n    let store1 = napa.store.create('store1');\n    it('@node: store.create - succeed', () => {\n        assert(store1 != null);\n        assert.equal(store1.id, 'store1');\n        assert.equal(store1.size, 0);\n    });\n\n    it('@node: store.create - already exists', () => {\n        let succeed = false;\n        try {\n            let store = napa.store.create('store1');\n            succeed = true;\n        }\n        catch (error) {\n        }\n        assert(!succeed);\n    });\n\n    let store2CreationComplete: Promise<napa.zone.Result>;\n\n    it('@napa: store.getOrCreate', () => {\n        store2CreationComplete = napaZone.execute('./napa-zone/test', \"getOrCreateStoreTest\");\n    });\n\n    it('@node: store.get', async () => {\n        let store = napa.store.get('store1');\n        assert.equal(store.id, store1.id);\n\n        // Store created from napa zone.\n        await store2CreationComplete;\n        let store2 = napa.store.get('store2');\n        assert.equal(store2.id, 'store2');\n    });\n\n    it('@napa: store.get', async () => {\n        await napaZone.execute('./napa-zone/test', \"getStoreTest\");\n    });\n\n    it('simple types: set in node, get in node', () => {\n        store1.set('a', 1);\n        assert.equal(store1.get('a'), 1);\n    });\n\n    it('simple types: set in node, get in napa', async () => {\n        store1.set('b', 'hi');\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store1', 'b', 'hi']);\n    });\n\n    it('simple types: set in napa, get in napa', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'c', 1]);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store1', 'c', 1]);\n    });\n\n    it('simple types: set in napa, get in node', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'd', { a: 1, b: 1}]);\n        assert.deepEqual(store1.get('d'), {\n            a: 1,\n            b: 1\n        });\n    });\n\n    let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\";\n    let store2 = napa.store.create('store2');\n\n    it('unicode string: set in node, get in node', () => {\n        store2.set('a', unicodeStr);\n        assert.equal(store2.get('a'), unicodeStr);\n    });\n\n    it('unicode string: set in node, get in napa', async () => {\n        store2.set('b', unicodeStr);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store2', 'b', unicodeStr]);\n    });\n\n    it('unicode string: set in napa, get in napa', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store2', 'c', unicodeStr]);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store2', 'c', unicodeStr]);\n    });\n\n    it('unicode string: set in napa, get in node', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store2', 'd', { a: 1, b: unicodeStr}]);\n        assert.deepEqual(store2.get('d'), {\n            a: 1,\n            b: unicodeStr\n        });\n    });\n\n    it('transportable types: set in node, get in node', () => {\n        store1.set('a', napa.memory.crtAllocator);\n        assert.deepEqual(store1.get('a'), napa.memory.crtAllocator);\n    });\n\n    it('transportable types: set in node, get in napa', async () => {\n        store1.set('b', napa.memory.defaultAllocator);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store1', 'b', napa.memory.defaultAllocator]);\n    });\n\n    it('transportable types: set in napa, get in napa', async () => {\n        // We have to compare handle in this case, since napa.memory.defaultAllocator retrieved from napa zone will have 2+ refCount.\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'e', napa.memory.defaultAllocator]);\n        await napaZone.execute('./napa-zone/test', \"storeGetCompareHandle\", ['store1', 'e', napa.memory.defaultAllocator.handle]);\n    });\n\n    it('transportable types: set in napa, get in node', async () => {\n        let debugAllocator = napa.memory.debugAllocator(napa.memory.defaultAllocator);\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'f', debugAllocator]);\n        assert.deepEqual(store1.get('f'), debugAllocator);\n    });\n\n    it('function type: set in node, get in node', () => {\n        store1.set('g', () => { return 0; });\n        assert.equal(store1.get('g').toString(), (() => { return 0; }).toString());\n    });\n\n    it('function type: set in node, get in napa', async () => {\n        store1.set('h', () => { return 0; });\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store1', 'h', () => { return 0; }]);\n    });\n\n    it('function type: set in napa, get in napa', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'i', () => { return 0; }]);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyGet\", ['store1', 'i', () => { return 0; }]);\n    });\n\n    it('function type: set in napa, get in node', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeSet\", ['store1', 'j', () => { return 0; }]);\n        assert.deepEqual(store1.get('j').toString(), (() => { return 0; }).toString());\n    });\n\n    it('delete in node, check in node', () => {\n        assert(store1.has('a'));\n        store1.delete('a');\n        assert(!store1.has('a'));\n        assert(store1.get('a') === undefined);\n        store1.delete('not-exist');\n    });\n\n    it('delete in node, check in napa', async () => {\n        assert(store1.has('b'));\n        store1.delete('b');\n        await napaZone.execute('./napa-zone/test', \"storeVerifyNotExist\", ['store1', 'b']);\n    });\n\n    it('delete in napa, check in napa', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeDelete\", ['store1', 'c']);\n        await napaZone.execute('./napa-zone/test', \"storeVerifyNotExist\", ['store1', 'c']);\n    })\n\n    it('delete in napa, check in node', async () => {\n        await napaZone.execute('./napa-zone/test', \"storeDelete\", ['store1', 'd']);\n        assert(!store1.has('d'));\n        assert(store1.get('d') === undefined);\n    });\n\n    it('size', () => {\n        // set 'a', 'b', 'c', 'd', 'a', 'b', 'e', 'f', 'g', 'h', 'i', 'j'.\n        // delete 'a', 'b', 'c', 'd'\n        assert.equal(store1.size, 6);\n    });\n});\n"
  },
  {
    "path": "test/sync-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport * as assert from 'assert';\n\n// spin-wait for the specific time, in milliseconds.\nfunction spinWait(time: number) {\n    let now = Date.now();\n    while (Date.now() - now < time) {}\n}\n\ndescribe('napajs/sync', function () {\n\n    it('@node: sync.Lock - create a lock', () => {\n        let succeed = false;\n        try {\n            let lock = napa.sync.createLock();\n            succeed = true;\n        }\n        catch (error) {\n        }\n        assert(succeed);\n    });\n\n    it('@node: sync.Lock - parameters passing', () => {\n        let succeed = false;\n        try {\n            let lock = napa.sync.createLock();\n            lock.guardSync((a, b, c) => {\n                assert.strictEqual(a, 123);\n                assert.strictEqual(b, '456');\n                assert.strictEqual(c, undefined);\n            }, [123, '456']);\n            succeed = true;\n        }\n        catch (error) {\n        }\n        assert(succeed);\n    });\n\n    it('@node: sync.Lock - guard single thread sync execution', () => {\n        let succeed = false;\n        let index = 0;\n        try {\n            let lock = napa.sync.createLock();\n            lock.guardSync(function () {\n                spinWait(100);\n                assert.equal(index, 0);\n                index++;\n            });\n            lock.guardSync(function () {\n                spinWait(100);\n                assert.equal(index, 1);\n                index++;\n            });\n            assert.equal(index, 2);\n            succeed = true;\n        }\n        catch (error) {\n        }\n        assert(succeed);\n    });\n\n    it('@napa: sync.Lock - multi thread sync execution (not using lock)', () => {\n        let napaZone = napa.zone.create('zone-for-sync-test-1', { workers: 2 });\n        napaZone.broadcast(spinWait.toString());\n\n        // If not using lock, the store.set() in second execute() function should start before the first complete.\n        let succeed = false;\n        try {\n            let lock = napa.sync.createLock();\n            // We use napa.store to verify the result\n            let store = napa.store.create('store-for-sync-test-1');\n            store.set('before-wait', 0);\n            store.set('after-wait', 0);\n\n            let exe1 = napaZone.execute(function () {\n                let napa = require('../lib/index');\n                let store = napa.store.get('store-for-sync-test-1');\n                store.set('before-wait', 1);\n                (<any>global).spinWait(500);\n                store.set('after-wait', 1);\n            });\n\n            let exe2 = napaZone.execute(function () {\n                let assert = require('assert');\n                let napa = require('../lib/index');\n                let store = napa.store.get('store-for-sync-test-1');\n                \n                (<any>global).spinWait(100);\n                assert.equal(store.get('before-wait'), 1);\n                assert.equal(store.get('after-wait'), 0);\n            });\n\n            return Promise.all([exe1, exe2]).then(function () {\n                assert.equal(store.get('before-wait'), 1);\n                assert.equal(store.get('after-wait'), 1);\n            });\n        }\n        catch (error) {\n        }\n    }).timeout(5000);\n    \n    it('@napa: sync.Lock - multi thread sync execution (using lock)', () => {\n        let napaZone = napa.zone.create('zone-for-sync-test-2', { workers: 2 });\n        napaZone.broadcast(spinWait.toString());\n\n        // If guard by lock, the store.set() in second execute() function should start after the first complete.\n        let succeed = false;\n        try {\n            let lock = napa.sync.createLock();\n            // We use napa.store to verify the result\n            let store = napa.store.create('store-for-sync-test-2');\n            store.set('before-wait', 0);\n            store.set('after-wait', 0);\n\n            let exe1 = napaZone.execute(function (lock) {\n                let napa = require('../lib/index');\n                let store = napa.store.get('store-for-sync-test-2');\n                \n                lock.guardSync(function () {\n                    store.set('before-wait', 1);\n                    (<any>global).spinWait(500);\n                    store.set('after-wait', 1);\n                });\n            }, [lock]);\n\n            let exe2 = napaZone.execute(function (lock) {\n                let assert = require('assert');\n                let napa = require('../lib/index');\n                let store = napa.store.get('store-for-sync-test-2');\n                \n                (<any>global).spinWait(100);\n\n                lock.guardSync(function () {\n                    assert.equal(store.get('before-wait'), 1);\n                    assert.equal(store.get('after-wait'), 1);\n                });\n            }, [lock]);\n\n            return Promise.all([exe1, exe2]).then(function () {\n                assert.equal(store.get('before-wait'), 1);\n                assert.equal(store.get('after-wait'), 1);\n            });\n        }\n        catch (error) {\n        }\n    }).timeout(5000);\n\n});\n"
  },
  {
    "path": "test/timer-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport {setImmediate, clearImmediate, setTimeout, clearTimeout, setInterval, clearInterval } from \"timers\";\n\n// To be execute in napa workers\nexport function setImmediateTest(taskGroupId: number) : Promise<string> {\n    const kTaskGroupSize = 4;\n    const kAllowedScheduleDiffInMS = 200;\n\n    let correctResult = \"\";\n    let lastTaskId = 0;\n    for (let taskId = 0; taskId < kTaskGroupSize; taskId++) {\n        if (taskId != 1) {\n            correctResult = `${correctResult}:${taskId}_OnTime`;\n            lastTaskId = taskId;\n        }\n    }\n\n    let promise = new Promise<string>((resolve, reject) => {\n        let execResult = \"\";\n        for (let taskId = 0; taskId < kTaskGroupSize; taskId++) {\n            let startTime = Date.now();\n            let immedidate = setImmediate((lastTaskId: number) => {\n                let delayToRun = Date.now() - startTime;\n                execResult = `${execResult}:${taskId}_OnTime`;\n                if (delayToRun > kAllowedScheduleDiffInMS) {\n                    execResult = `${execResult}(X)`;\n                }\n                if (taskId == lastTaskId) {\n                    if (execResult == correctResult) {\n                        resolve(`OK:${execResult}`)\n                    }\n                    else {\n                        reject(`FAIL:${execResult} vs ${correctResult}`)\n                    }\n                }\n            }, lastTaskId);\n    \n            if (taskId == 1) {\n                clearImmediate(immedidate);\n            }\n        }\n    });\n\n    return promise;\n}\n\nexport function setTimeoutTest(taskGroupId: number) : Promise<string> {\n    const kTaskGroupSize = 4;\n    const kAllowedScheduleDiffInMS = 200;\n\n    setTimeout(() => {}, 10);  // Just a warm up.\n\n    let correctResult = \"\";\n    let lastTaskId = 0;\n    for (let taskId = 0; taskId < kTaskGroupSize; taskId++) {\n        if (taskId != 1) {\n            correctResult = `${correctResult}:${taskId}_OnTime`;\n            lastTaskId = taskId;\n        }\n    }\n    \n    let promise = new Promise<string>((resolve, reject) => {\n        let execResult = \"\";\n        for (let taskId = 0; taskId < kTaskGroupSize; taskId++) {\n            let wait = 300 * (taskGroupId * kTaskGroupSize + taskId + 1);\n            let startTime = Date.now();\n            let timeout = setTimeout((lastTaskId: number) => {\n                let waitToRun = Date.now() - startTime;\n                execResult = `${execResult}:${taskId}_OnTime`;\n                if (Math.abs(waitToRun - wait) > kAllowedScheduleDiffInMS) {\n                    execResult = `${execResult}(X)`;\n                }\n\n                if (taskId == lastTaskId) {\n                    if (execResult == correctResult) {\n                        resolve(`OK:${execResult}`)\n                    }\n                    else {\n                        reject(`FAIL:${execResult} .vs. ${correctResult}`)\n                    }\n                }\n            }, wait, lastTaskId);\n\n            if (taskId == 1) {\n                clearTimeout(timeout);\n            }\n        }\n    });\n\n    return promise;\n}\n\nexport function setIntervalTest(taskGroupId: number, duration: number, count: number) : Promise<string> {\n    const kAllowedScheduleDiffInMS = 200;\n\n    let correctResult = \"\";\n    for (let i = 0; i < count; ++i) {\n        correctResult += `:${i}_OnTime`\n    }\n\n    let repeatCount = 0;\n    let execResult = \"\";\n    let startTime = Date.now();\n    let interval = setInterval(() => {\n        let wait = Date.now() - startTime;\n        execResult += `:${repeatCount}_OnTime`;\n        ++repeatCount;\n        let avgScheduleDiff = Math.abs(wait - repeatCount * duration) / repeatCount;\n        if (avgScheduleDiff > kAllowedScheduleDiffInMS) {\n            execResult += `(X)`;\n        }\n    }, duration);\n\n    let promise = new Promise<string>((resolve, reject) => {\n        setTimeout(() => {\n            if (execResult == correctResult) {\n                resolve(`OK:${execResult}`)\n            }\n            else {\n                reject(`FAIL:${execResult} .vs. ${correctResult}`)\n            }\n        }, duration * (count + 2.6));\n    });\n\n    setTimeout(()=> {\n        clearInterval(interval);\n    },  Math.ceil(duration * (count + 0.8)));\n\n    return promise;\n}\n\n\ndeclare var __in_napa: boolean;\nif (typeof __in_napa === 'undefined') {\n    let assert = require('assert');\n\n    const NUMBER_OF_WORKERS = 3;\n    const kTaskGroupCount = 3;\n    let zone = napa.zone.create('zone', { workers: NUMBER_OF_WORKERS });\n\n    describe(\"napajs/timers\", () => {\n    \n        describe(\"setImmediate/clearImmediate\", function() {\n            let promises: Promise<napa.zone.Result>[] = [];\n            for (let groupId = 0; groupId < kTaskGroupCount; groupId++) {\n                let res = zone.execute('./timer-test', 'setImmediateTest', [groupId]);\n                promises.push(res);\n            }\n\n            for (let groupId = 0; groupId < kTaskGroupCount; groupId++) {\n                it(`Immediate test group:${groupId} should return string prefixed with OK`, \n                    async function() {\n                        let result = (await promises[groupId]).value;\n                        assert(result.startsWith('OK'), `${result}`);\n                    }\n                );\n            }\n        });\n\n        describe(\"setTimeout/clearTimeout\", function() {\n            let promises: Promise<napa.zone.Result>[] = [];\n            for (let groupId = 0; groupId < kTaskGroupCount; groupId++) {\n                let res = zone.execute('./timer-test', 'setTimeoutTest', [groupId]);\n                promises.push(res);\n            }\n\n            for (let groupId = 0; groupId < kTaskGroupCount; groupId++) {\n                it(`Timeout test group:${groupId} should return string prefixed with OK`, \n                    async function() {\n                        let result = (await promises[groupId]).value;\n                        assert(result.startsWith('OK'), `${result}`);\n                    }\n                ).timeout(3000);;\n            }\n        });\n\n        describe(\"setInterval/clearInterval\", function() {\n            it(`Interval test should return string prefixed with OK`, \n                async function() {\n                    let promise = zone.execute('./timer-test', 'setIntervalTest', [\"0\", 500, 4]);\n                    let result = (await promise).value;\n                    assert(result.startsWith('OK'), `${result}`);\n                }\n            ).timeout(6000);\n        });\n    });\n}\n"
  },
  {
    "path": "test/transport-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as napa from \"../lib/index\";\nimport * as assert from 'assert';\nimport * as path from 'path';\nimport * as t from './napa-zone/test';\n\ndescribe('napajs/transport', () => {\n    let napaZone = napa.zone.create('zone10');\n    describe('TransportContext', () => {\n        let tc = napa.transport.createTransportContext();\n        let allocator = napa.memory.debugAllocator(napa.memory.crtAllocator);\n        it('#saveShared', () => {\n            tc.saveShared(allocator);\n        });\n\n        let shareable: napa.memory.Shareable = null;\n        it('#loadShared', () => {\n            shareable = tc.loadShared(allocator.handle);\n            assert.deepEqual(shareable.handle, allocator.handle);\n        });\n\n        it('#sharedCount', () => {\n            assert.equal(shareable.refCount, 3);\n        });\n    });\n\n    describe('Transportable', () => {\n        it('#IsTransportable', () => {\n            assert(napa.transport.isTransportable(new t.CanPass(napa.memory.crtAllocator)));\n            assert(napa.transport.isTransportable(1));\n            assert(napa.transport.isTransportable('hello world'));\n            assert(napa.transport.isTransportable([1, 2, 3]));\n            assert(napa.transport.isTransportable([1, 2, new t.CanPass(napa.memory.crtAllocator)]));\n            assert(napa.transport.isTransportable({ a: 1}));\n            assert(napa.transport.isTransportable({ a: 1, b: new t.CanPass(napa.memory.crtAllocator)}));\n            assert(napa.transport.isTransportable(() => { return 0; }));\n            assert(!napa.transport.isTransportable(new t.CannotPass()));\n            assert(!napa.transport.isTransportable([1, new t.CannotPass()]));\n            assert(!napa.transport.isTransportable({ a: 1, b: new t.CannotPass()}));\n        });\n    });\n\n    describe('Marshall/Unmarshall', () => {\n        it('@node: simple types', () => {\n            t.simpleTypeTransportTest();\n        });\n\n        it('@napa: simple types', () => {\n            napaZone.execute('./napa-zone/test', \"simpleTypeTransportTest\");\n        }).timeout(3000);\n\n        it('@node: JS transportable', () => {\n            t.jsTransportTest();\n        });\n\n        it('@napa: JS transportable', () => {\n            napaZone.execute('./napa-zone/test', \"jsTransportTest\");\n        });\n\n        it('@node: addon transportable', () => {\n            t.addonTransportTest();\n        });\n\n        it('@napa: addon transportable', () => {\n            napaZone.execute('./napa-zone/test', \"addonTransportTest\");\n        });\n\n        it('@node: function transportable', () => {\n            t.functionTransportTest();\n        });\n\n        it('@napa: function transportable', () => {\n            napaZone.execute('./napa-zone/test', \"functionTransportTest\");\n        });\n\n        it('@node: composite transportable', () => {\n            t.compositeTransportTest();\n        });\n\n        it('@napa: composite transportable', () => {\n            napaZone.execute('./napa-zone/test', \"compositeTransportTest\");\n        });\n\n        it('@node: non-transportable', () => {\n            t.nontransportableTest();\n        });\n\n        it('@napa: non-transportable', () => {\n            napaZone.execute('./napa-zone/test', \"nontransportableTest\");\n        });\n    });\n\n    function transportBuiltinObjects() {\n        let zoneId: string = 'transport-built-in-test-zone';\n        let transportTestZone: napa.zone.Zone = napa.zone.create(zoneId, { workers: 4 });\n\n        /// Construct an expected result string.\n        /// constructExpectedResult(5, 5, 255, 0) returns '0,0,0,0,0'\n        /// constructExpectedResult(2, 5, 255, 0) returns '0,0,255,255,255'\n        /// constructExpectedResult(0, 5, 255, 0) returns '255,255,255,255,255'\n        function constructExpectedResult(i: number, size: number, expectedValue: number, defaultValue: number = 0): string {\n            const assert = require('assert');\n            assert(i >= 0 && size >= i);\n            let expected: string = '';\n            for (let t: number = 0; t < i; t++) {\n                if (t > 0) expected += ',';\n                expected += defaultValue.toString();\n            }\n            for (var t = i; t < size; t++) {\n                if (t > 0) expected += ',';\n                expected += expectedValue.toString();\n            }\n            return expected;\n        }\n        (<any>global).constructExpectedResult = constructExpectedResult;\n        transportTestZone.broadcast(\"global.constructExpectedResult = \" + constructExpectedResult.toString());\n\n        it('@node: transport SharedArrayBuffer (SAB)', () => {\n            let promises: Array<Promise<any>> = [];\n            let sab: SharedArrayBuffer = new SharedArrayBuffer(4);\n            for (let i: number = 0; i < 4; i++) {\n                promises[i] = transportTestZone.execute((sab, i) => {\n                    let ta: Uint8Array = new Uint8Array(sab);\n                    ta[i] = 100;\n                }, [sab, i]);\n            }\n\n            return Promise.all(promises).then((values: Array<napa.zone.Result>) => {\n                let ta: Uint8Array = new Uint8Array(sab);\n                assert.deepEqual(ta.toString(), '100,100,100,100');\n            });\n        });\n\n        it('@node: transport composite object of SharedArrayBuffer', () => {\n            let sab: SharedArrayBuffer = new SharedArrayBuffer(4);\n            let ta1: Uint8Array = new Uint8Array(sab);\n            let ta2: Uint8Array = new Uint8Array(sab);\n            let obj: Object = { sab: sab, tas: { ta1: ta1, ta2: ta2 }, ta22:ta2 };\n            return transportTestZone.execute((obj) => {\n                let ta: Uint8Array = new Uint8Array(obj.sab);\n                ta[0] = 99;\n                obj.tas.ta1[1] = 88;\n                obj.tas.ta2[2] = 77;\n                obj.ta22[3] = 66;\n                }, [obj]).then((result: napa.zone.Result) => {\n                    var ta_sab: Uint8Array = new Uint8Array(sab);\n                    assert.deepEqual(ta_sab.toString(), '99,88,77,66');\n            });\n        });\n\n        function recursivelySetElementOfSharedArrayBuffer(zoneId: string, sab: SharedArrayBuffer, i: number, value: number) {\n            if (i < 0) return;\n            let ta: Uint8Array = new Uint8Array(sab);\n            ta[i] = value;\n\n            const assert = require('assert');\n\n            // SharedArrayBuffer shares storage when it is transported,\n            // so elements with index > i have been set to {value} by those finished zone.executions.\n            let expected: string = (<any>global).constructExpectedResult(i, ta.length, value);\n            assert.equal(ta.toString(), expected);\n\n            const napa = require('../lib/index');\n            let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node;\n            zone.execute(\n                recursivelySetElementOfSharedArrayBuffer,\n                [zoneId, sab, i - 1, value]\n            ).then((result: napa.zone.Result) => {\n                // SharedArrayBuffer shares storage when it is transported,\n                // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute,\n                // so ta.toString() should be larger than {expected} constructed before.\n                if (i > 0) assert(ta.toString() > expected);\n                else if (i === 0) assert.equal(ta.toString(), expected);\n                else assert(false);\n            });\n        }\n\n        // @node: node -> napa -> napa -> node -> node -> napa -> napa\n        it('@node: recursively transport received SharedArrayBuffer (SAB)', () => {\n            let size: number = 8;\n            let timeout: number = 50;\n            let value: number = 255;\n            let sab: SharedArrayBuffer = new SharedArrayBuffer(size);\n            let ta: Uint8Array = new Uint8Array(sab);\n            recursivelySetElementOfSharedArrayBuffer(zoneId, sab, size - 1, value);\n\n            return new Promise((resolve, reject) => {\n                setTimeout(() => {\n                    // Because SharedArrayBuffer will share storage when it is transported,\n                    // once the recursive process finished, all elements of\n                    // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}.\n                    let expected = (<any>global).constructExpectedResult(0, ta.length, value);\n                    assert.equal(ta.toString(), expected);\n                    resolve();\n                }, timeout);\n            });\n        });\n\n        function recursivelySetElementOfTypedArray_SAB(zoneId: string, ta: Uint8Array, i: number, value: number) {\n            if (i < 0) return;\n            ta[i] = value;\n\n            const assert = require('assert');\n\n            // SharedArrayBuffer shares storage when it is transported,\n            // so elements with index > i have been set to {value} by those finished zone.executions.\n            let expected: string = (<any>global).constructExpectedResult(i, ta.length, value);\n            assert.equal(ta.toString(), expected);\n\n            const napa = require('../lib/index');\n            let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node;\n            zone.execute(\n                recursivelySetElementOfTypedArray_SAB,\n                [zoneId, ta, i - 1, value]\n            ).then((result: napa.zone.Result) => {\n                // SharedArrayBuffer shares storage when it is transported,\n                // if i > 0, ta[i - 1] has been set to {value} by the previous zone.execute,\n                // so ta.toString() should be larger than {expected} constructed before.\n                if (i > 0) assert(ta.toString() > expected);\n                else if (i === 0) assert.equal(ta.toString(), expected);\n                else assert(false);\n            });\n        }\n\n        // @node: node -> napa -> napa -> node -> node -> napa -> napa\n        it('@node: recursively transport received TypedArray based on SAB', () => {\n            let size: number = 8;\n            let timeout: number = 50;\n            let value: number = 255;\n            let sab: SharedArrayBuffer = new SharedArrayBuffer(size);\n            let ta: Uint8Array = new Uint8Array(sab);\n            recursivelySetElementOfTypedArray_SAB(zoneId, ta, size - 1, value);\n\n            return new Promise((resolve, reject) => {\n                setTimeout(() => {\n                    // Because SharedArrayBuffer will share storage when it is transported,\n                    // once the recursive process finished, all elements of\n                    // the original TypeArray (based on SharedArrayBuffer) should have been set to {value}.\n                    let expected: string = (<any>global).constructExpectedResult(0, ta.length, value);\n                    assert.equal(ta.toString(), expected);\n                    resolve();\n                }, timeout);\n            });\n        });\n\n        function recursivelySetElementOfArrayBuffer(zoneId: string, ab: ArrayBuffer, i: number, value: number) {\n            if (i < 0) {\n                return;\n            }\n\n            let ta: Uint8Array = new Uint8Array(ab);\n            ta[i] = value;\n\n            const assert = require('assert');\n\n            // ArrayBuffer's storage will be copied when it is transported.\n            // Elements with index > i should all be {value}.\n            // They are copied from the previous zone.execution.\n            let expected: string = (<any>global).constructExpectedResult(i, ta.length, value);\n            assert.equal(ta.toString(), expected);\n\n            const napa = require('../lib/index');\n            let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node;\n            zone.execute(\n                recursivelySetElementOfArrayBuffer,\n                [zoneId, ab, i - 1, value]\n            ).then((result: napa.zone.Result) => {\n                // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute.\n                assert.equal(ta.toString(), expected);\n            });\n        }\n\n        // @node: node -> napa -> napa -> node -> node -> napa -> napa\n        it('@node: recursively transport received ArrayBuffer (AB)', () => {\n            let size: number = 8;\n            let timeout: number = 50;\n            let value: number = 255;\n            let ab: ArrayBuffer = new ArrayBuffer(size);\n            let ta: Uint8Array = new Uint8Array(ab);\n            recursivelySetElementOfArrayBuffer(zoneId, ab, size - 1, value);\n\n            return new Promise((resolve, reject) => {\n                setTimeout(() => {\n                    // Except ta[ta-length -1] was set to {value} before the 1st transportation,\n                    // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution.\n                    let expected: string = (<any>global).constructExpectedResult(ta.length - 1, ta.length, value);\n                    assert.equal(ta.toString(), expected);\n                    resolve();\n                }, timeout);\n            });\n        });\n\n        function recursivelySetElementOfTypeArray_AB(zoneId: string, ta: Uint8Array, i: number, value: number) {\n            if (i < 0) {\n                return;\n            }\n\n            ta[i] = value;\n\n            const assert = require('assert');\n\n            // ArrayBuffer's storage will be copied when it is transported.\n            // Elements with index > i should all be {value}.\n            // They are copied from the previous zone.execution.\n            let expected: string = (<any>global).constructExpectedResult(i, ta.length, value);\n            assert.equal(ta.toString(), expected);\n\n            const napa = require('../lib/index');\n            let zone: napa.zone.Zone = (i % 4 < 2) ? napa.zone.get(zoneId) : napa.zone.node;\n            zone.execute(\n                recursivelySetElementOfTypeArray_AB,\n                [zoneId, ta, i - 1, value]\n            ).then((result: napa.zone.Result) => {\n                // The original TypeArray (based on ArrayBuffer) shouldn't been changed by the just-finished zone.execute.\n                assert.equal(ta.toString(), expected);\n            });\n        }\n\n        // @node: node -> napa -> napa -> node -> node -> napa -> napa\n        it('@node: recursively transport received TypedArray based on AB', () => {\n            let size: number = 8;\n            let timeout: number = 50;\n            let value: number = 255;\n            let ab: ArrayBuffer = new ArrayBuffer(size);\n            let ta: Uint8Array = new Uint8Array(ab);\n            recursivelySetElementOfTypeArray_AB(zoneId, ta, size - 1, value);\n\n            return new Promise((resolve, reject) => {\n                setTimeout(() => {\n                    // Except ta[ta-length -1] was set to {value} before the 1st transportation,\n                    // the original TypeArray (based on ArrayBuffer) shouldn't been changed by the recursive execution.\n                    let expected: string = (<any>global).constructExpectedResult(ta.length - 1, ta.length, value);\n                    assert.equal(ta.toString(), expected);\n                    resolve();\n                }, timeout);\n            });\n        });\n    }\n\n    let builtinTestGroup = 'Transport built-in objects';\n    let nodeVersionMajor = parseInt(process.versions.node.split('.')[0]);\n\n    if (nodeVersionMajor >= 9) {\n        describe(builtinTestGroup, transportBuiltinObjects);\n    } else {\n        describe.skip(builtinTestGroup, transportBuiltinObjects);\n        require('npmlog').warn(builtinTestGroup, 'This test group is skipped since it requires node v9.0.0 or above.');\n    }\n});\n"
  },
  {
    "path": "test/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"commonjs\",\n        \"target\": \"es5\",\n        \"experimentalDecorators\": true,\n        \"noImplicitAny\": true,\n        \"declaration\": false,\n        \"preserveConstEnums\": true,\n        \"lib\": [ \"es2017\" ]\n    }\n}"
  },
  {
    "path": "test/zone-test.ts",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nimport * as assert from \"assert\";\nimport * as path from \"path\";\nimport * as napa from \"../lib/index\";\n\ntype Zone = napa.zone.Zone;\n\nfunction shouldFail<T>(func: () => Promise<T>) {\n    return func().then(\n        (value: T) => {\n            assert(false, \"Failure was expected.\");\n        }, \n        (reason: any) => { \n            // Swallow the rejection since we expect failure\n        });\n}\n\ndescribe('napajs/zone', function () {\n    let napaZone1: Zone = napa.zone.create('napa-zone1');\n    let napaZone2: Zone = napa.zone.create('napa-zone2');\n    let napaLibPath: string = path.resolve(__dirname, '../lib');\n    \n    describe('create', () => {\n        it('@node: default settings', () => {\n            assert(napaZone1 != null);\n            assert.strictEqual(napaZone1.id, 'napa-zone1');\n        });\n\n        // This case may be slow as the first hit of napa zone execute API, so we clear timeout.\n        it('@napa: default settings', async () => {\n            // Zone should be destroyed when going out of scope.\n            let result = await napaZone1.execute(`${napaLibPath}/zone`, 'create', ['new-zone']);\n            assert.equal(result.value.id, \"new-zone\");\n        }).timeout(0);\n\n        it('@node: zone id already exists', () => {\n            assert.throws(() => { napa.zone.create('napa-zone1'); });\n        });\n\n        it('@napa: zone id already exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute(`${napaLibPath}/zone`, 'create', ['napa-zone1']);\n            });\n        });\n    });\n\n    describe(\"get\", () => {\n        it('@node: get node zone', () => {\n            let zone = napa.zone.get('node');\n            assert(zone != null);\n            assert.strictEqual(zone.id, 'node');\n        });\n\n        it('@node: get napa zone', () => {\n            let zone = napa.zone.get('napa-zone1');\n            assert(zone != null);\n            assert.strictEqual(zone.id, 'napa-zone1');\n        });\n\n        it('@napa: get napa zone', async () => {\n            let result = await napaZone1.execute(`${napaLibPath}/zone`, \"get\", ['napa-zone1']);\n            assert.strictEqual(result.value.id, 'napa-zone1');\n        });\n\n        it('@napa: get node zone', async () => {\n            let result = await napaZone1.execute(`${napaLibPath}/zone`, \"get\", ['node']);\n            assert.strictEqual(result.value.id, 'node');\n        });\n\n        it('@node: get napa created zone', () => {\n            let zone = napa.zone.get('napa-zone2');\n            assert(zone != null);\n            assert.strictEqual(zone.id, 'napa-zone2');\n        });\n\n        it('@napa: get napa created zone', async () => {\n            let result = await napaZone1.execute(`${napaLibPath}/zone`, 'get', ['napa-zone2']);\n            assert.strictEqual(result.value.id, 'napa-zone2');\n        });\n\n        it('@node: id not existed', () => {\n            assert.throws(() => { napa.zone.get('zonex'); });\n        });\n\n        it('@napa: zone not existed', () => {\n            return shouldFail(() => {\n                return napaZone1.execute(`${napaLibPath}/zone`, 'get', ['zonex']); \n            });\n        });\n    });\n\n    describe(\"currentZone\", () => {\n        it('@node', () => {\n            assert.strictEqual(napa.zone.current.id, 'node');\n        });\n\n        it('@napa', async () => {\n            let result = await napaZone1.execute('./napa-zone/test', \"getCurrentZone\");\n            assert.strictEqual(result.value.id, 'napa-zone1');\n        });\n    });\n\n    describe('broadcast', () => {\n        it('@node: -> node zone with JavaScript code', () => {\n            return napa.zone.current.broadcast(\"var state = 0;\");\n        });\n\n        it('@node: -> napa zone with JavaScript code', () => {\n            return napaZone1.broadcast(\"var state = 0;\");\n        });\n\n        it('@napa: -> napa zone with JavaScript code', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"napa-zone2\", \"var state = 0;\"]);\n        });\n\n        it('@napa: -> napa zone with JavaScript code', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"napa-zone1\", \"var state = 0;\"]);\n        });\n\n        it('@napa: -> node zone with JavaScript code', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"node\", \"var state = 0;\"]);\n        });\n\n        it('@node: bad JavaScript code', () => {\n            return shouldFail(() => {\n                return napaZone1.broadcast(\"var state() = 0;\");\n            });\n        });\n\n        it('@napa: bad JavaScript code', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"napa-zone2\", \"var state() = 0;\"]);\n            });\n        });\n\n        it('@node: -> node zone throw runtime error', () => {\n            return shouldFail(() => {\n                return napa.zone.current.broadcast(\"throw new Error();\");\n            });\n        });\n\n        it('@node: -> napa zone throw runtime error', () => {\n            return shouldFail(() => {\n                return napaZone1.broadcast(\"throw new Error();\");\n            });\n        });\n\n        it('@napa: -> napa zone throw runtime error', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"napa-zone2\", \"throw new Error();\"]);\n            });\n        });\n\n        it('@napa: -> node zone throw runtime error', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcast\", [\"node\", \"throw new Error();\"]);\n            });\n        });\n\n        it('@node: -> node zone with anonymous function', () => {\n            return napa.zone.current.broadcast((input: string) => {\n                console.log(input);\n            }, ['hello world']);\n        });\n\n        it('@node: -> napa zone with anonymous function', () => {\n            return napaZone1.broadcast((input: string) => {\n                console.log(input);\n            }, ['hello world']);\n        });\n\n        it('@napa: -> napa zone with anonymous function', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastTestFunction\", ['napa-zone2']);\n        });\n\n        it('@napa: -> node zone with anonymous function', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastTestFunction\", ['node']);\n        });\n\n        // TODO #4: support transportable args in broadcast.\n        it.skip('@node: -> node zone with transportable args', () => {\n            return napa.zone.current.broadcast((allocator: any) => {\n                console.log(allocator);\n            }, [napa.memory.crtAllocator]);\n        });\n\n        // TODO #4: support transportable args in broadcast.\n        it.skip('@node: -> napa zone with transportable args', () => {\n            return napaZone1.broadcast((allocator: any) => {\n                console.log(allocator);\n            }, [napa.memory.crtAllocator]);\n        });\n\n        // Blocked by TODO #4.\n        it.skip('@napa: -> napa zone with transportable args', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastTransportable\", ['napa-zone2']);\n        });\n\n        // Blocked by TODO #4.\n        it.skip('@napa: -> node zone with transportable args', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastTransportable\", ['node']);\n        });\n\n        // This will not fail any more because current implementation uses function `eval()`.\n        // Re-enable this case if we use `Function()` in future\n        it.skip('@node: -> node zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napa.zone.current.broadcast(() => {\n                    console.log(napaZone1.id);\n                });\n            });\n        });\n\n        it('@node: -> napa zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.broadcast(() => {\n                    console.log(napaZone1.id);\n                });\n            });\n        });\n\n        it('@napa: -> napa zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcastClosure\", ['napa-zone2']);\n            });\n        });\n\n        it('@napa: -> node zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcastClosure\", ['node']);\n            });\n        });\n    });\n\n    describe('broadcastSync', () => {\n        it('@node: -> napa zone with JavaScript code', () => {\n            napaZone1.broadcastSync(\"var state = 0;\");\n        });\n\n        it('@napa: -> napa zone with JavaScript code in different zone', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastSync\", [\"napa-zone2\", \"var state = 0;\"]);\n        });\n\n        it('@napa: -> napa zone with JavaScript code in current zone (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcastSync\", [\"napa-zone1\", \"var state = 0;\"]);\n            });\n        });\n\n        it('@node: -> napa zone with anonymous function', () => {\n            napaZone1.broadcastSync((input: string) => {\n                console.log(input);\n            }, ['hello world']);\n        });\n\n        it('@napa: -> napa zone with anonymous function', () => {\n            return napaZone1.execute('./napa-zone/test', \"broadcastSyncTestFunction\", ['napa-zone2']);\n        });\n\n        it('@node: -> napa zone throw runtime error', () => {\n            assert.throws(() => {\n                napaZone1.broadcastSync(\"throw new Error();\");\n            }, Error);\n        });\n\n        it('@napa: -> napa zone throw runtime error', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"broadcastSync\", [\"napa-zone2\", \"throw new Error();\"]);\n            });\n        });\n\n    });\n\n    describe('execute', () => {\n        let fooDef = 'function foo(input) { return input; }';\n        let nestedFunctionDef = `\n            var ns1 = {\n                ns2: {\n                    foo: function (input) {\n                    return input;\n                    }\n                }\n            };\n        `;\n\n        napaZone1.broadcast(fooDef);\n        napaZone1.broadcast(nestedFunctionDef);\n        napaZone2.broadcast(fooDef);\n        \n        napa.zone.node.broadcast(fooDef);\n        napa.zone.node.broadcast(nestedFunctionDef);\n\n        it('@node: -> node zone with global function name', () => {\n            return napa.zone.current.execute(\"\", \"foo\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with global function name', () => {\n            return napaZone1.execute(\"\", \"foo\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> napa zone with global function name', () => {\n            return napaZone1.execute('./napa-zone/test', 'execute', [\"napa-zone2\", \"\", \"foo\", ['hello world']])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> node zone with global function name', () => {\n            return napaZone1.execute('./napa-zone/test', 'execute', [\"node\", \"\", \"foo\", ['hello world']])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with global function name: function with namespaces', () => {\n            return napaZone1.execute(\"\", \"ns1.ns2.foo\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> node zone with global function name not exists', () => {\n            return shouldFail(() => {\n                return napa.zone.current.execute(\"\", \"foo1\", ['hello world']);\n            });\n        });\n\n        it('@node: -> napa zone with global function name not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute(\"\", \"foo1\", ['hello world']);\n            });\n        });\n\n        it('@napa: -> napa zone with global function name not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"napa-zone2\", \"\", \"foo1\", []]);\n            });\n        });\n\n        it('@napa: -> node zone with global function name not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"node\", \"\", \"foo1\", []]);\n            });\n        });\n\n        it('@node: -> node zone with module function name', () => {\n            return napa.zone.current.execute('./napa-zone/test', \"bar\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with module function name', () => {\n            return napaZone1.execute('./napa-zone/test', \"bar\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> napa zone with module function name', () => {\n            return napaZone1.execute('./napa-zone/test', 'execute', [\"napa-zone2\", path.resolve(__dirname, './napa-zone/test'), \"bar\", ['hello world']])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> node zone with module function name', () => {\n            return napaZone1.execute('./napa-zone/test', 'execute', [\"node\", path.resolve(__dirname, './napa-zone/test'), \"bar\", ['hello world']])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with module function name: function with namespaces', () => {\n            return napaZone1.execute('./napa-zone/test', \"ns1.ns2.foo\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with module function name: module is a function', () => {\n            return napaZone1.execute(path.resolve(__dirname, \"./napa-zone/function-as-module\"), \"\", ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> node zone with module not exists', () => {\n            return shouldFail(() => {\n                return napa.zone.current.execute(\"abc\", \"foo1\", ['hello world']);\n            });\n        });\n\n        it('@node: -> napa zone with module not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute(\"abc\", \"foo1\", ['hello world']);\n            });\n        });\n\n        it('@napa: -> napa zone with module not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"napa-zone2\", \"abc\", \".foo\", []]);\n            });\n        });\n\n        it('@napa: -> node zone with module not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"node\", \"abc\", \"foo.\", []]);\n            });\n        });\n\n        it('@node: -> node zone with module function not exists', () => {\n            return shouldFail(() => {\n                return napa.zone.current.execute('./napa-zone/test', \"foo1\", ['hello world']);\n            });\n        });\n\n        it('@node: -> napa zone with module function not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', \"foo1\", ['hello world'])\n            });\n        });\n\n        it('@napa: -> napa zone with module function not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"napa-zone1\", './napa-zone/test', \"foo1\", []]);\n            });\n        });\n\n        it('@napa: -> node zone with module function not exists', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'execute', [\"node\", './napa-zone/test', \"foo1\", []]);\n            });\n        });\n\n        it('@node: -> node zone with anonymous function', () => {\n            return napa.zone.current.execute((input: string) => {\n                return input;\n            }, ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> napa zone with anonymous function', () => {\n            return napaZone1.execute((input: string) => {\n                return input;\n            }, ['hello world'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> napa zone with anonymous function', () => {\n            return napaZone1.execute('./napa-zone/test', 'executeTestFunction', [\"napa-zone2\"])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@napa: -> node zone with anonymous function', () => {\n            return napaZone1.execute('./napa-zone/test', 'executeTestFunction', [\"node\"])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, 'hello world');\n                });\n        });\n\n        it('@node: -> node zone with anonymous function having closure (should success)', () => {\n            return napa.zone.current.execute(() => { return napaZone1; });\n        });\n\n        it('@node: -> napa zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute(() => { return napaZone1; });\n            });\n        });\n\n        it('@napa: -> napa zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'executeTestFunctionWithClosure', [\"napa-zone2\"]);\n            });\n        });\n\n        it('@napa: -> node zone with anonymous function having closure (should fail)', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'executeTestFunctionWithClosure', [\"node\"]);\n            });\n        });\n\n        it('@node: -> node zone with transportable args', () => {\n            return napa.zone.current.execute((allocator: napa.memory.Allocator) => {\n                var assert = require(\"assert\");\n                assert.deepEqual(allocator.handle, (<any>global).napa.memory.crtAllocator.handle);\n            }, [napa.memory.crtAllocator]);\n        });\n\n        it('@node: -> napa zone with transportable args', () => {\n            return napaZone1.execute((allocator: napa.memory.Allocator) => {\n                var assert = require(\"assert\");\n                assert.deepEqual(allocator.handle, (<any>global).napa.memory.crtAllocator.handle);\n            }, [napa.memory.crtAllocator]);\n        });\n\n        it('@napa: -> napa zone with transportable args', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithTransportableArgs\", ['napa-zone2']);\n        });\n\n        it('@napa: -> node zone with transportable args', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithTransportableArgs\", ['node']);\n        });\n\n        it('@node: -> node zone with transportable returns', () => {\n            return napa.zone.current.execute((allocator: napa.memory.Allocator) => {\n                return allocator;\n            }, [napa.memory.crtAllocator])\n            .then((result: napa.zone.Result) => {\n                assert.deepEqual(result.value.handle, napa.memory.crtAllocator.handle);\n            });\n        });\n\n        it('@node: -> napa zone with transportable returns', () => {\n            return napaZone1.execute((allocator: napa.memory.Allocator) => {\n                return allocator;\n            }, [napa.memory.crtAllocator])\n            .then((result: napa.zone.Result) => {\n                assert.deepEqual(result.value.handle, napa.memory.crtAllocator.handle);\n            });\n        });\n\n        it('@napa: -> napa zone with transportable returns', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithTransportableReturns\", ['napa-zone2'])\n                .then((result: napa.zone.Result) => {\n                    assert.deepEqual(result.value.handle, napa.memory.crtAllocator.handle);\n                });\n        });\n\n        it('@napa: -> node zone with transportable returns', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithTransportableReturns\", ['node'])\n                .then((result: napa.zone.Result) => {\n                    assert.deepEqual(result.value.handle, napa.memory.crtAllocator.handle);\n                });\n        });\n\n        let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\"; // len = 92\n\n        it('@node: -> node zone with args containing unicode string', () => {\n            return napa.zone.current.execute((str: string) => {\n                var assert = require(\"assert\");\n                let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\";\n                assert.equal(str, unicodeStr);\n                return str;\n            }, [unicodeStr]).then((result: napa.zone.Result) => {\n                assert.equal(result.value, unicodeStr);\n            });\n        });\n\n        it('@node: -> napa zone with args containing unicode string', () => {\n            return napaZone1.execute((str: string) => {\n                var assert = require(\"assert\");\n                let unicodeStr = \"中文 español deutsch English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ் עברית\";\n                assert.equal(str, unicodeStr);\n                return unicodeStr;\n            }, [unicodeStr]).then((result: napa.zone.Result) => {\n                assert.equal(result.value, unicodeStr);\n            });\n        });\n\n        it('@napa: -> napa zone with args containing unicode string', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithArgsContainingUnicodeString\", ['napa-zone2'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, unicodeStr);\n                });\n        });\n\n        it('@napa: -> node zone with args containing unicode string', () => {\n            return napaZone1.execute('./napa-zone/test', \"executeWithArgsContainingUnicodeString\", ['node'])\n                .then((result: napa.zone.Result) => {\n                    assert.equal(result.value, unicodeStr);\n                });\n        });\n\n        it.skip('@node: -> napa zone with timeout and succeed', () => {\n            return napaZone1.execute('./napa-zone/test', 'waitMS', [1], {timeout: 100});\n        });\n        \n        it.skip('@napa: -> napa zone with timeout and succeed', () => {\n            return napaZone1.execute('./napa-zone/test', 'executeTestFunctionWithTimeout', [\"napa-zone2\", 1], {timeout: 100});\n        });\n\n        it.skip('@node: -> napa zone with timed out in JavaScript', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'waitMS', [100], {timeout: 1});\n            });\n        });\n\n        it.skip('@napa: -> napa zone with timed out in JavaScript', () => {\n            return shouldFail(() => {\n                return napaZone1.execute('./napa-zone/test', 'executeTestFunctionWithTimeout', [\"napa-zone2\", 100], {timeout: 1});\n            });\n        });\n\n        it.skip('@node: -> napa zone with timed out in add-on', () => {\n        });\n\n        it.skip('@napa: -> napa zone with timed out in add-on', () => {\n        });\n\n        it.skip('@node: -> napa zone with timed out in multiple hops', () => {\n        });\n\n        it.skip('@napa: -> napa zone with timed out in multiple hops', () => {\n        });\n    });\n});"
  },
  {
    "path": "third-party/args/LICENSE",
    "content": "Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel Belikov\n\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "third-party/args/args.hxx",
    "content": "/* Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel\n * Belikov\n * \n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n * \n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n * \n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/** \\file args.hxx\n * \\brief this single-header lets you use all of the args functionality\n *\n * The important stuff is done inside the args namespace\n */\n\n#ifndef ARGS_HXX\n#define ARGS_HXX\n\n#include <algorithm>\n#include <iterator>\n#include <exception>\n#include <functional>\n#include <sstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n#include <unordered_set>\n#include <type_traits>\n\n#ifdef ARGS_TESTNAMESPACE\nnamespace argstest\n{\n#else\n\n/** \\namespace args\n * \\brief contains all the functionality of the args library\n */\nnamespace args\n{\n#endif\n    /** Getter to grab the value from the argument type.\n     *\n     * If the Get() function of the type returns a reference, so does this, and\n     * the value will be modifiable.\n     */\n    template <typename Option>\n    auto get(Option &option_) -> decltype(option_.Get())\n    {\n        return option_.Get();\n    }\n\n    /** (INTERNAL) Count UTF-8 glyphs\n     *\n     * This is not reliable, and will fail for combinatory glyphs, but it's\n     * good enough here for now.\n     *\n     * \\param string The string to count glyphs from\n     * \\return The UTF-8 glyphs in the string\n     */\n    inline std::string::size_type Glyphs(const std::string &string_)\n    {\n        std::string::size_type length = 0;\n        for (const char c: string_)\n        {\n            if ((c & 0xc0) != 0x80)\n            {\n                ++length;\n            }\n        }\n        return length;\n    }\n\n    /** (INTERNAL) Wrap a vector of words into a vector of lines\n     *\n     * Empty words are skipped. Word \"\\n\" forces wrapping.\n     *\n     * \\param begin The begin iterator\n     * \\param end The end iterator\n     * \\param width The width of the body\n     * \\param firstlinewidth the width of the first line, defaults to the width of the body\n     * \\param firstlineindent the indent of the first line, defaults to 0\n     * \\return the vector of lines\n     */\n    template <typename It>\n    inline std::vector<std::string> Wrap(It begin,\n                                         It end,\n                                         const std::string::size_type width,\n                                         std::string::size_type firstlinewidth = 0,\n                                         std::string::size_type firstlineindent = 0)\n    {\n        std::vector<std::string> output;\n        std::string line(firstlineindent, ' ');\n        bool empty = true;\n\n        if (firstlinewidth == 0)\n        {\n            firstlinewidth = width;\n        }\n\n        auto currentwidth = firstlinewidth;\n\n        for (auto it = begin; it != end; ++it)\n        {\n            if (it->empty())\n            {\n                continue;\n            }\n\n            if (*it == \"\\n\")\n            {\n                if (!empty)\n                {\n                    output.push_back(line);\n                    line.clear();\n                    empty = true;\n                    currentwidth = width;\n                }\n\n                continue;\n            }\n\n            auto itemsize = Glyphs(*it);\n            if ((line.length() + 1 + itemsize) > currentwidth)\n            {\n                if (!empty)\n                {\n                    output.push_back(line);\n                    line.clear();\n                    empty = true;\n                    currentwidth = width;\n                }\n            }\n\n            if (itemsize > 0)\n            {\n                if (!empty)\n                {\n                    line += ' ';\n                }\n\n                line += *it;\n                empty = false;\n            }\n        }\n\n        if (!empty)\n        {\n            output.push_back(line);\n        }\n\n        return output;\n    }\n\n    namespace detail\n    {\n        template <typename T>\n        std::string Join(const T& array, const std::string &delimiter)\n        {\n            std::string res;\n            for (auto &element : array)\n            {\n                if (!res.empty())\n                {\n                    res += delimiter;\n                }\n\n                res += element;\n            }\n\n            return res;\n        }\n    }\n\n    /** (INTERNAL) Wrap a string into a vector of lines\n     *\n     * This is quick and hacky, but works well enough.  You can specify a\n     * different width for the first line\n     *\n     * \\param width The width of the body\n     * \\param firstlinewid the width of the first line, defaults to the width of the body\n     * \\return the vector of lines\n     */\n    inline std::vector<std::string> Wrap(const std::string &in, const std::string::size_type width, std::string::size_type firstlinewidth = 0)\n    {\n        // Preserve existing line breaks\n        const auto newlineloc = in.find('\\n');\n        if (newlineloc != in.npos)\n        {\n            auto first = Wrap(std::string(in, 0, newlineloc), width);\n            auto second = Wrap(std::string(in, newlineloc + 1), width);\n            first.insert(\n                std::end(first),\n                std::make_move_iterator(std::begin(second)),\n                std::make_move_iterator(std::end(second)));\n            return first;\n        }\n\n        std::istringstream stream(in);\n        std::string::size_type indent = 0;\n\n        for (char c : in)\n        {\n            if (!isspace(c))\n            {\n                break;\n            }\n            ++indent;\n        }\n\n        return Wrap(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>(),\n                    width, firstlinewidth, indent);\n    }\n\n#ifdef ARGS_NOEXCEPT\n    /// Error class, for when ARGS_NOEXCEPT is defined\n    enum class Error\n    {\n        None,\n        Usage,\n        Parse,\n        Validation,\n        Required,\n        Map,\n        Extra,\n        Help,\n        Subparser,\n        Completion,\n    };\n#else\n    /** Base error class\n     */\n    class Error : public std::runtime_error\n    {\n        public:\n            Error(const std::string &problem) : std::runtime_error(problem) {}\n            virtual ~Error() {}\n    };\n\n    /** Errors that occur during usage\n     */\n    class UsageError : public Error\n    {\n        public:\n            UsageError(const std::string &problem) : Error(problem) {}\n            virtual ~UsageError() {}\n    };\n\n    /** Errors that occur during regular parsing\n     */\n    class ParseError : public Error\n    {\n        public:\n            ParseError(const std::string &problem) : Error(problem) {}\n            virtual ~ParseError() {}\n    };\n\n    /** Errors that are detected from group validation after parsing finishes\n     */\n    class ValidationError : public Error\n    {\n        public:\n            ValidationError(const std::string &problem) : Error(problem) {}\n            virtual ~ValidationError() {}\n    };\n\n    /** Errors that when a required flag is omitted\n     */\n    class RequiredError : public ValidationError\n    {\n        public:\n            RequiredError(const std::string &problem) : ValidationError(problem) {}\n            virtual ~RequiredError() {}\n    };\n\n    /** Errors in map lookups\n     */\n    class MapError : public ParseError\n    {\n        public:\n            MapError(const std::string &problem) : ParseError(problem) {}\n            virtual ~MapError() {}\n    };\n\n    /** Error that occurs when a singular flag is specified multiple times\n     */\n    class ExtraError : public ParseError\n    {\n        public:\n            ExtraError(const std::string &problem) : ParseError(problem) {}\n            virtual ~ExtraError() {}\n    };\n\n    /** An exception that indicates that the user has requested help\n     */\n    class Help : public Error\n    {\n        public:\n            Help(const std::string &flag) : Error(flag) {}\n            virtual ~Help() {}\n    };\n\n    /** (INTERNAL) An exception that emulates coroutine-like control flow for subparsers.\n     */\n    class SubparserError : public Error\n    {\n        public:\n            SubparserError() : Error(\"\") {}\n            virtual ~SubparserError() {}\n    };\n\n    /** An exception that contains autocompletion reply\n     */\n    class Completion : public Error\n    {\n        public:\n            Completion(const std::string &flag) : Error(flag) {}\n            virtual ~Completion() {}\n    };\n#endif\n\n    /** A simple unified option type for unified initializer lists for the Matcher class.\n     */\n    struct EitherFlag\n    {\n        const bool isShort;\n        const char shortFlag;\n        const std::string longFlag;\n        EitherFlag(const std::string &flag) : isShort(false), shortFlag(), longFlag(flag) {}\n        EitherFlag(const char *flag) : isShort(false), shortFlag(), longFlag(flag) {}\n        EitherFlag(const char flag) : isShort(true), shortFlag(flag), longFlag() {}\n\n        /** Get just the long flags from an initializer list of EitherFlags\n         */\n        static std::unordered_set<std::string> GetLong(std::initializer_list<EitherFlag> flags)\n        {\n            std::unordered_set<std::string>  longFlags;\n            for (const EitherFlag &flag: flags)\n            {\n                if (!flag.isShort)\n                {\n                    longFlags.insert(flag.longFlag);\n                }\n            }\n            return longFlags;\n        }\n\n        /** Get just the short flags from an initializer list of EitherFlags\n         */\n        static std::unordered_set<char> GetShort(std::initializer_list<EitherFlag> flags)\n        {\n            std::unordered_set<char>  shortFlags;\n            for (const EitherFlag &flag: flags)\n            {\n                if (flag.isShort)\n                {\n                    shortFlags.insert(flag.shortFlag);\n                }\n            }\n            return shortFlags;\n        }\n\n        std::string str() const\n        {\n            return isShort ? std::string(1, shortFlag) : longFlag;\n        }\n\n        std::string str(const std::string &shortPrefix, const std::string &longPrefix) const\n        {\n            return isShort ? shortPrefix + std::string(1, shortFlag) : longPrefix + longFlag;\n        }\n    };\n\n\n\n    /** A class of \"matchers\", specifying short and flags that can possibly be\n     * matched.\n     *\n     * This is supposed to be constructed and then passed in, not used directly\n     * from user code.\n     */\n    class Matcher\n    {\n        private:\n            const std::unordered_set<char> shortFlags;\n            const std::unordered_set<std::string> longFlags;\n\n        public:\n            /** Specify short and long flags separately as iterators\n             *\n             * ex: `args::Matcher(shortFlags.begin(), shortFlags.end(), longFlags.begin(), longFlags.end())`\n             */\n            template <typename ShortIt, typename LongIt>\n            Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd) :\n                shortFlags(shortFlagsStart, shortFlagsEnd),\n                longFlags(longFlagsStart, longFlagsEnd)\n            {\n                if (shortFlags.empty() && longFlags.empty())\n                {\n#ifndef ARGS_NOEXCEPT\n                    throw UsageError(\"empty Matcher\");\n#endif\n                }\n            }\n\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            Error GetError() const noexcept\n            {\n                return shortFlags.empty() && longFlags.empty() ? Error::Usage : Error::None;\n            }\n#endif\n\n            /** Specify short and long flags separately as iterables\n             *\n             * ex: `args::Matcher(shortFlags, longFlags)`\n             */\n            template <typename Short, typename Long>\n            Matcher(Short &&shortIn, Long &&longIn) :\n                Matcher(std::begin(shortIn), std::end(shortIn), std::begin(longIn), std::end(longIn))\n            {}\n\n            /** Specify a mixed single initializer-list of both short and long flags\n             *\n             * This is the fancy one.  It takes a single initializer list of\n             * any number of any mixed kinds of flags.  Chars are\n             * automatically interpreted as short flags, and strings are\n             * automatically interpreted as long flags:\n             *\n             *     args::Matcher{'a'}\n             *     args::Matcher{\"foo\"}\n             *     args::Matcher{'h', \"help\"}\n             *     args::Matcher{\"foo\", 'f', 'F', \"FoO\"}\n             */\n            Matcher(std::initializer_list<EitherFlag> in) :\n                Matcher(EitherFlag::GetShort(in), EitherFlag::GetLong(in)) {}\n\n            Matcher(Matcher &&other) : shortFlags(std::move(other.shortFlags)), longFlags(std::move(other.longFlags))\n            {}\n\n            ~Matcher() {}\n\n            /** (INTERNAL) Check if there is a match of a short flag\n             */\n            bool Match(const char flag) const\n            {\n                return shortFlags.find(flag) != shortFlags.end();\n            }\n\n            /** (INTERNAL) Check if there is a match of a long flag\n             */\n            bool Match(const std::string &flag) const\n            {\n                return longFlags.find(flag) != longFlags.end();\n            }\n\n            /** (INTERNAL) Check if there is a match of a flag\n             */\n            bool Match(const EitherFlag &flag) const\n            {\n                return flag.isShort ? Match(flag.shortFlag) : Match(flag.longFlag);\n            }\n\n            /** (INTERNAL) Get all flag strings as a vector, with the prefixes embedded\n             */\n            std::vector<EitherFlag> GetFlagStrings() const\n            {\n                std::vector<EitherFlag> flagStrings;\n                flagStrings.reserve(shortFlags.size() + longFlags.size());\n                for (const char flag: shortFlags)\n                {\n                    flagStrings.emplace_back(flag);\n                }\n                for (const std::string &flag: longFlags)\n                {\n                    flagStrings.emplace_back(flag);\n                }\n                return flagStrings;\n            }\n\n            /** (INTERNAL) Get long flag if it exists or any short flag\n             */\n            EitherFlag GetLongOrAny() const\n            {\n                if (!longFlags.empty())\n                {\n                    return *longFlags.begin();\n                }\n\n                if (!shortFlags.empty())\n                {\n                    return *shortFlags.begin();\n                }\n\n                // should be unreachable\n                return ' ';\n            }\n\n            /** (INTERNAL) Get short flag if it exists or any long flag\n             */\n            EitherFlag GetShortOrAny() const\n            {\n                if (!shortFlags.empty())\n                {\n                    return *shortFlags.begin();\n                }\n\n                if (!longFlags.empty())\n                {\n                    return *longFlags.begin();\n                }\n\n                // should be unreachable\n                return ' ';\n            }\n    };\n\n    /** Attributes for flags.\n     */\n    enum class Options\n    {\n        /** Default options.\n         */\n        None = 0x0,\n\n        /** Flag can't be passed multiple times.\n         */\n        Single = 0x01,\n\n        /** Flag can't be omitted.\n         */\n        Required = 0x02,\n\n        /** Flag is excluded from usage line.\n         */\n        HiddenFromUsage = 0x04,\n\n        /** Flag is excluded from options help.\n         */\n        HiddenFromDescription = 0x08,\n\n        /** Flag is global and can be used in any subcommand.\n         */\n        Global = 0x10,\n\n        /** Flag stops a parser.\n         */\n        KickOut = 0x20,\n\n        /** Flag is excluded from auto completion.\n         */\n        HiddenFromCompletion = 0x40,\n\n        /** Flag is excluded from options help and usage line\n         */\n        Hidden = HiddenFromUsage | HiddenFromDescription | HiddenFromCompletion,\n    };\n\n    inline Options operator | (Options lhs, Options rhs)\n    {\n        return static_cast<Options>(static_cast<int>(lhs) | static_cast<int>(rhs));\n    }\n\n    inline Options operator & (Options lhs, Options rhs)\n    {\n        return static_cast<Options>(static_cast<int>(lhs) & static_cast<int>(rhs));\n    }\n\n    class FlagBase;\n    class PositionalBase;\n    class Command;\n    class ArgumentParser;\n\n    /** A simple structure of parameters for easy user-modifyable help menus\n     */\n    struct HelpParams\n    {\n        /** The width of the help menu\n         */\n        unsigned int width = 80;\n        /** The indent of the program line\n         */\n        unsigned int progindent = 2;\n        /** The indent of the program trailing lines for long parameters\n         */\n        unsigned int progtailindent = 4;\n        /** The indent of the description and epilogs\n         */\n        unsigned int descriptionindent = 4;\n        /** The indent of the flags\n         */\n        unsigned int flagindent = 6;\n        /** The indent of the flag descriptions\n         */\n        unsigned int helpindent = 40;\n        /** The additional indent each group adds\n         */\n        unsigned int eachgroupindent = 2;\n\n        /** The minimum gutter between each flag and its help\n         */\n        unsigned int gutter = 1;\n\n        /** Show the terminator when both options and positional parameters are present\n         */\n        bool showTerminator = true;\n\n        /** Show the {OPTIONS} on the prog line when this is true\n         */\n        bool showProglineOptions = true;\n\n        /** Show the positionals on the prog line when this is true\n         */\n        bool showProglinePositionals = true;\n\n        /** The prefix for short flags\n         */\n        std::string shortPrefix;\n\n        /** The prefix for long flags\n         */\n        std::string longPrefix;\n\n        /** The separator for short flags\n         */\n        std::string shortSeparator;\n\n        /** The separator for long flags\n         */\n        std::string longSeparator;\n\n        /** The program name for help generation\n         */\n        std::string programName;\n\n        /** Show command's flags\n         */\n        bool showCommandChildren = false;\n\n        /** Show command's descriptions and epilog\n         */\n        bool showCommandFullHelp = false;\n\n        /** The postfix for progline when showProglineOptions is true and command has any flags\n         */\n        std::string proglineOptions = \"{OPTIONS}\";\n\n        /** The prefix for progline when command has any subcommands\n         */\n        std::string proglineCommand = \"COMMAND\";\n\n        /** The prefix for progline value\n         */\n        std::string proglineValueOpen = \" <\";\n\n        /** The postfix for progline value\n         */\n        std::string proglineValueClose = \">\";\n\n        /** The prefix for progline required argument\n         */\n        std::string proglineRequiredOpen = \"\";\n\n        /** The postfix for progline required argument\n         */\n        std::string proglineRequiredClose = \"\";\n\n        /** The prefix for progline non-required argument\n         */\n        std::string proglineNonrequiredOpen = \"[\";\n\n        /** The postfix for progline non-required argument\n         */\n        std::string proglineNonrequiredClose = \"]\";\n\n        /** Show flags in program line\n         */\n        bool proglineShowFlags = false;\n\n        /** Use short flags in program lines when possible\n         */\n        bool proglinePreferShortFlags = false;\n\n        /** Program line prefix\n         */\n        std::string usageString;\n\n        /** String shown in help before flags descriptions\n         */\n        std::string optionsString = \"OPTIONS:\";\n\n        /** Display value name after all the long and short flags\n         */\n        bool useValueNameOnce = false;\n\n        /** Show value name\n         */\n        bool showValueName = true;\n\n        /** Add newline before flag description\n         */\n        bool addNewlineBeforeDescription = false;\n\n        /** The prefix for option value\n         */\n        std::string valueOpen = \"[\";\n\n        /** The postfix for option value\n         */\n        std::string valueClose = \"]\";\n\n        /** Add choices to argument description\n         */\n        bool addChoices = false;\n\n        /** The prefix for choices\n         */\n        std::string choiceString = \"\\nOne of: \";\n\n        /** Add default values to argument description\n         */\n        bool addDefault = false;\n\n        /** The prefix for default values\n         */\n        std::string defaultString = \"\\nDefault: \";\n    };\n\n    /** A number of arguments which can be consumed by an option.\n     *\n     * Represents a closed interval [min, max].\n     */\n    struct Nargs\n    {\n        const size_t min;\n        const size_t max;\n\n        Nargs(size_t min_, size_t max_) : min(min_), max(max_)\n        {\n#ifndef ARGS_NOEXCEPT\n            if (max < min)\n            {\n                throw UsageError(\"Nargs: max > min\");\n            }\n#endif\n        }\n\n        Nargs(size_t num_) : min(num_), max(num_)\n        {\n        }\n\n        friend bool operator == (const Nargs &lhs, const Nargs &rhs)\n        {\n            return lhs.min == rhs.min && lhs.max == rhs.max;\n        }\n\n        friend bool operator != (const Nargs &lhs, const Nargs &rhs)\n        {\n            return !(lhs == rhs);\n        }\n    };\n\n    /** Base class for all match types\n     */\n    class Base\n    {\n        private:\n            Options options = {};\n\n        protected:\n            bool matched = false;\n            const std::string help;\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            mutable Error error = Error::None;\n            mutable std::string errorMsg;\n#endif\n\n        public:\n            Base(const std::string &help_, Options options_ = {}) : options(options_), help(help_) {}\n            virtual ~Base() {}\n\n            Options GetOptions() const noexcept\n            {\n                return options;\n            }\n\n            bool IsRequired() const noexcept\n            {\n                return (GetOptions() & Options::Required) != Options::None;\n            }\n\n            virtual bool Matched() const noexcept\n            {\n                return matched;\n            }\n\n            virtual void Validate(const std::string &, const std::string &) const\n            {\n            }\n\n            operator bool() const noexcept\n            {\n                return Matched();\n            }\n\n            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &, const unsigned indentLevel) const\n            {\n                std::tuple<std::string, std::string, unsigned> description;\n                std::get<1>(description) = help;\n                std::get<2>(description) = indentLevel;\n                return { std::move(description) };\n            }\n\n            virtual std::vector<Command*> GetCommands()\n            {\n                return {};\n            }\n\n            virtual bool IsGroup() const\n            {\n                return false;\n            }\n\n            virtual FlagBase *Match(const EitherFlag &)\n            {\n                return nullptr;\n            }\n\n            virtual PositionalBase *GetNextPositional()\n            {\n                return nullptr;\n            }\n\n            virtual std::vector<FlagBase*> GetAllFlags()\n            {\n                return {};\n            }\n\n            virtual bool HasFlag() const\n            {\n                return false;\n            }\n\n            virtual bool HasPositional() const\n            {\n                return false;\n            }\n\n            virtual bool HasCommand() const\n            {\n                return false;\n            }\n\n            virtual std::vector<std::string> GetProgramLine(const HelpParams &) const\n            {\n                return {};\n            }\n\n            /// Sets a kick-out value for building subparsers\n            void KickOut(bool kickout_) noexcept\n            {\n                if (kickout_)\n                {\n                    options = options | Options::KickOut;\n                }\n                else\n                {\n                    options = static_cast<Options>(static_cast<int>(options) & ~static_cast<int>(Options::KickOut));\n                }\n            }\n\n            /// Gets the kick-out value for building subparsers\n            bool KickOut() const noexcept\n            {\n                return (options & Options::KickOut) != Options::None;\n            }\n\n            virtual void Reset() noexcept\n            {\n                matched = false;\n#ifdef ARGS_NOEXCEPT\n                error = Error::None;\n                errorMsg.clear();\n#endif\n            }\n\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            virtual Error GetError() const\n            {\n                return error;\n            }\n\n            /// Only for ARGS_NOEXCEPT\n            std::string GetErrorMsg() const\n            {\n                return errorMsg;\n            }\n#endif\n    };\n\n    /** Base class for all match types that have a name\n     */\n    class NamedBase : public Base\n    {\n        protected:\n            const std::string name;\n            bool kickout = false;\n            std::string defaultString;\n            bool defaultStringManual = false;\n            std::vector<std::string> choicesStrings;\n            bool choicesStringManual = false;\n\n            virtual std::string GetDefaultString(const HelpParams&) const { return {}; }\n\n            virtual std::vector<std::string> GetChoicesStrings(const HelpParams&) const { return {}; }\n\n            virtual std::string GetNameString(const HelpParams&) const { return Name(); }\n\n            void AddDescriptionPostfix(std::string &dest, const bool isManual, const std::string &manual, bool isGenerated, const std::string &generated, const std::string &str) const\n            {\n                if (isManual && !manual.empty())\n                {\n                    dest += str;\n                    dest += manual;\n                }\n                else if (!isManual && isGenerated && !generated.empty())\n                {\n                    dest += str;\n                    dest += generated;\n                }\n            }\n\n        public:\n            NamedBase(const std::string &name_, const std::string &help_, Options options_ = {}) : Base(help_, options_), name(name_) {}\n            virtual ~NamedBase() {}\n\n            /** Sets default value string that will be added to argument description.\n             *  Use empty string to disable it for this argument.\n             */\n            void HelpDefault(const std::string &str)\n            {\n                defaultStringManual = true;\n                defaultString = str;\n            }\n\n            /** Gets default value string that will be added to argument description.\n             */\n            std::string HelpDefault(const HelpParams &params) const\n            {\n                return defaultStringManual ? defaultString : GetDefaultString(params);\n            }\n\n            /** Sets choices strings that will be added to argument description.\n             *  Use empty vector to disable it for this argument.\n             */\n            void HelpChoices(const std::vector<std::string> &array)\n            {\n                choicesStringManual = true;\n                choicesStrings = array;\n            }\n\n            /** Gets choices strings that will be added to argument description.\n             */\n            std::vector<std::string> HelpChoices(const HelpParams &params) const\n            {\n                return choicesStringManual ? choicesStrings : GetChoicesStrings(params);\n            }\n\n            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned indentLevel) const override\n            {\n                std::tuple<std::string, std::string, unsigned> description;\n                std::get<0>(description) = GetNameString(params);\n                std::get<1>(description) = help;\n                std::get<2>(description) = indentLevel;\n\n                AddDescriptionPostfix(std::get<1>(description), choicesStringManual, detail::Join(choicesStrings, \", \"), params.addChoices, detail::Join(GetChoicesStrings(params), \", \"), params.choiceString);\n                AddDescriptionPostfix(std::get<1>(description), defaultStringManual, defaultString, params.addDefault, GetDefaultString(params), params.defaultString);\n\n                return { std::move(description) };\n            }\n\n            virtual std::string Name() const\n            {\n                return name;\n            }\n    };\n\n    namespace detail\n    {\n        template <typename T, typename = int>\n        struct IsConvertableToString : std::false_type {};\n\n        template <typename T>\n        struct IsConvertableToString<T, decltype(std::declval<std::ostringstream&>() << std::declval<T>(), int())> : std::true_type {};\n\n        template <typename T>\n        typename std::enable_if<IsConvertableToString<T>::value, std::string>::type\n        ToString(const T &value)\n        {\n            std::ostringstream s;\n            s << value;\n            return s.str();\n        }\n\n        template <typename T>\n        typename std::enable_if<!IsConvertableToString<T>::value, std::string>::type\n        ToString(const T &)\n        {\n            return {};\n        }\n\n        template <typename T>\n        std::vector<std::string> MapKeysToStrings(const T &map)\n        {\n            std::vector<std::string> res;\n            using K = typename std::decay<decltype(std::begin(map)->first)>::type;\n            if (IsConvertableToString<K>::value)\n            {\n                for (const auto &p : map)\n                {\n                    res.push_back(detail::ToString(p.first));\n                }\n\n                std::sort(res.begin(), res.end());\n            }\n            return res;\n        }\n    }\n\n    /** Base class for all flag options\n     */\n    class FlagBase : public NamedBase\n    {\n        protected:\n            const Matcher matcher;\n\n            virtual std::string GetNameString(const HelpParams &params) const override\n            {\n                const std::string postfix = !params.showValueName || NumberOfArguments() == 0 ? std::string() : Name();\n                std::string flags;\n                const auto flagStrings = matcher.GetFlagStrings();\n                const bool useValueNameOnce = flagStrings.size() == 1 ? false : params.useValueNameOnce;\n                for (auto it = flagStrings.begin(); it != flagStrings.end(); ++it)\n                {\n                    auto &flag = *it;\n                    if (it != flagStrings.begin())\n                    {\n                        flags += \", \";\n                    }\n\n                    flags += flag.isShort ? params.shortPrefix : params.longPrefix;\n                    flags += flag.str();\n\n                    if (!postfix.empty() && (!useValueNameOnce || it + 1 == flagStrings.end()))\n                    {\n                        flags += flag.isShort ? params.shortSeparator : params.longSeparator;\n                        flags += params.valueOpen + postfix + params.valueClose;\n                    }\n                }\n\n                return flags;\n            }\n\n        public:\n            FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : NamedBase(name_, help_, extraError_ ? Options::Single : Options()), matcher(std::move(matcher_)) {}\n\n            FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : NamedBase(name_, help_, options_), matcher(std::move(matcher_)) {}\n\n            virtual ~FlagBase() {}\n\n            virtual FlagBase *Match(const EitherFlag &flag) override\n            {\n                if (matcher.Match(flag))\n                {\n                    if ((GetOptions() & Options::Single) != Options::None && matched)\n                    {\n                        std::ostringstream problem;\n                        problem << \"Flag '\" << flag.str() << \"' was passed multiple times, but is only allowed to be passed once\";\n#ifdef ARGS_NOEXCEPT\n                        error = Error::Extra;\n                        errorMsg = problem.str();\n#else\n                        throw ExtraError(problem.str());\n#endif\n                    }\n                    matched = true;\n                    return this;\n                }\n                return nullptr;\n            }\n\n            virtual std::vector<FlagBase*> GetAllFlags() override\n            {\n                return { this };\n            }\n\n            const Matcher &GetMatcher() const\n            {\n                return matcher;\n            }\n\n            virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) const override\n            {\n                if (!Matched() && IsRequired())\n                {\n                        std::ostringstream problem;\n                        problem << \"Flag '\" << matcher.GetLongOrAny().str(shortPrefix, longPrefix) << \"' is required\";\n#ifdef ARGS_NOEXCEPT\n                        error = Error::Required;\n                        errorMsg = problem.str();\n#else\n                        throw RequiredError(problem.str());\n#endif\n                }\n            }\n\n            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override\n            {\n                if (!params.proglineShowFlags)\n                {\n                    return {};\n                }\n\n                const std::string postfix = NumberOfArguments() == 0 ? std::string() : Name();\n                const EitherFlag flag = params.proglinePreferShortFlags ? matcher.GetShortOrAny() : matcher.GetLongOrAny();\n                std::string res = flag.str(params.shortPrefix, params.longPrefix);\n                if (!postfix.empty())\n                {\n                    res += params.proglineValueOpen + postfix + params.proglineValueClose;\n                }\n\n                return { IsRequired() ? params.proglineRequiredOpen + res + params.proglineRequiredClose\n                                      : params.proglineNonrequiredOpen + res + params.proglineNonrequiredClose };\n            }\n\n            virtual bool HasFlag() const override\n            {\n                return true;\n            }\n\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            virtual Error GetError() const override\n            {\n                const auto nargs = NumberOfArguments();\n                if (nargs.min > nargs.max)\n                {\n                    return Error::Usage;\n                }\n\n                const auto matcherError = matcher.GetError();\n                if (matcherError != Error::None)\n                {\n                    return matcherError;\n                }\n\n                return error;\n            }\n#endif\n\n            /** Defines how many values can be consumed by this option.\n             *\n             * \\return closed interval [min, max]\n             */\n            virtual Nargs NumberOfArguments() const noexcept = 0;\n\n            /** Parse values of this option.\n             *\n             * \\param value Vector of values. It's size must be in NumberOfArguments() interval.\n             */\n            virtual void ParseValue(const std::vector<std::string> &value) = 0;\n    };\n\n    /** Base class for value-accepting flag options\n     */\n    class ValueFlagBase : public FlagBase\n    {\n        public:\n            ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : FlagBase(name_, help_, std::move(matcher_), extraError_) {}\n            ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : FlagBase(name_, help_, std::move(matcher_), options_) {}\n            virtual ~ValueFlagBase() {}\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            {\n                return 1;\n            }\n    };\n\n    class CompletionFlag : public ValueFlagBase\n    {\n        public:\n            std::vector<std::string> reply;\n            size_t cword = 0;\n            std::string syntax;\n\n            template <typename GroupClass>\n            CompletionFlag(GroupClass &group_, Matcher &&matcher_): ValueFlagBase(\"completion\", \"completion flag\", std::move(matcher_), Options::Hidden)\n            {\n                group_.AddCompletion(*this);\n            }\n\n            virtual ~CompletionFlag() {}\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            {\n                return 2;\n            }\n\n            virtual void ParseValue(const std::vector<std::string> &value_) override\n            {\n                syntax = value_.at(0);\n                std::istringstream(value_.at(1)) >> cword;\n            }\n\n            /** Get the completion reply\n             */\n            std::string Get() noexcept\n            {\n                return detail::Join(reply, \"\\n\");\n            }\n\n            virtual void Reset() noexcept override\n            {\n                ValueFlagBase::Reset();\n                cword = 0;\n                syntax.clear();\n                reply.clear();\n            }\n    };\n\n\n    /** Base class for positional options\n     */\n    class PositionalBase : public NamedBase\n    {\n        protected:\n            bool ready;\n\n        public:\n            PositionalBase(const std::string &name_, const std::string &help_, Options options_ = {}) : NamedBase(name_, help_, options_), ready(true) {}\n            virtual ~PositionalBase() {}\n\n            bool Ready()\n            {\n                return ready;\n            }\n\n            virtual void ParseValue(const std::string &value_) = 0;\n\n            virtual void Reset() noexcept override\n            {\n                matched = false;\n                ready = true;\n#ifdef ARGS_NOEXCEPT\n                error = Error::None;\n                errorMsg.clear();\n#endif\n            }\n\n            virtual PositionalBase *GetNextPositional() override\n            {\n                return Ready() ? this : nullptr;\n            }\n\n            virtual bool HasPositional() const override\n            {\n                return true;\n            }\n\n            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override\n            {\n                return { IsRequired() ? params.proglineRequiredOpen + Name() + params.proglineRequiredClose\n                                      : params.proglineNonrequiredOpen + Name() + params.proglineNonrequiredClose };\n            }\n\n            virtual void Validate(const std::string &, const std::string &) const override\n            {\n                if (IsRequired() && !Matched())\n                {\n                    std::ostringstream problem;\n                    problem << \"Option '\" << Name() << \"' is required\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Required;\n                    errorMsg = problem.str();\n#else\n                    throw RequiredError(problem.str());\n#endif\n                }\n            }\n    };\n\n    /** Class for all kinds of validating groups, including ArgumentParser\n     */\n    class Group : public Base\n    {\n        private:\n            std::vector<Base*> children;\n            std::function<bool(const Group &)> validator;\n\n        public:\n            /** Default validators\n             */\n            struct Validators\n            {\n                static bool Xor(const Group &group)\n                {\n                    return group.MatchedChildren() == 1;\n                }\n\n                static bool AtLeastOne(const Group &group)\n                {\n                    return group.MatchedChildren() >= 1;\n                }\n\n                static bool AtMostOne(const Group &group)\n                {\n                    return group.MatchedChildren() <= 1;\n                }\n\n                static bool All(const Group &group)\n                {\n                    return group.Children().size() == group.MatchedChildren();\n                }\n\n                static bool AllOrNone(const Group &group)\n                {\n                    return (All(group) || None(group));\n                }\n\n                static bool AllChildGroups(const Group &group)\n                {\n                    return std::none_of(std::begin(group.Children()), std::end(group.Children()), [](const Base* child) -> bool {\n                            return child->IsGroup() && !child->Matched();\n                            });\n                }\n\n                static bool DontCare(const Group &)\n                {\n                    return true;\n                }\n\n                static bool CareTooMuch(const Group &)\n                {\n                    return false;\n                }\n\n                static bool None(const Group &group)\n                {\n                    return group.MatchedChildren() == 0;\n                }\n            };\n            /// If help is empty, this group will not be printed in help output\n            Group(const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare, Options options_ = {}) : Base(help_, options_), validator(validator_) {}\n            /// If help is empty, this group will not be printed in help output\n            Group(Group &group_, const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare, Options options_ = {}) : Base(help_, options_), validator(validator_)\n            {\n                group_.Add(*this);\n            }\n            virtual ~Group() {}\n\n            /** Append a child to this Group.\n             */\n            void Add(Base &child)\n            {\n                children.emplace_back(&child);\n            }\n\n            /** Get all this group's children\n             */\n            const std::vector<Base *> &Children() const\n            {\n                return children;\n            }\n\n            /** Return the first FlagBase that matches flag, or nullptr\n             *\n             * \\param flag The flag with prefixes stripped\n             * \\return the first matching FlagBase pointer, or nullptr if there is no match\n             */\n            virtual FlagBase *Match(const EitherFlag &flag) override\n            {\n                for (Base *child: Children())\n                {\n                    if (FlagBase *match = child->Match(flag))\n                    {\n                        return match;\n                    }\n                }\n                return nullptr;\n            }\n\n            virtual std::vector<FlagBase*> GetAllFlags() override\n            {\n                std::vector<FlagBase*> res;\n                for (Base *child: Children())\n                {\n                    auto childRes = child->GetAllFlags();\n                    res.insert(res.end(), childRes.begin(), childRes.end());\n                }\n                return res;\n            }\n\n            virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) const override\n            {\n                for (Base *child: Children())\n                {\n                    child->Validate(shortPrefix, longPrefix);\n                }\n            }\n\n            /** Get the next ready positional, or nullptr if there is none\n             *\n             * \\return the first ready PositionalBase pointer, or nullptr if there is no match\n             */\n            virtual PositionalBase *GetNextPositional() override\n            {\n                for (Base *child: Children())\n                {\n                    if (auto next = child->GetNextPositional())\n                    {\n                        return next;\n                    }\n                }\n                return nullptr;\n            }\n\n            /** Get whether this has any FlagBase children\n             *\n             * \\return Whether or not there are any FlagBase children\n             */\n            virtual bool HasFlag() const override\n            {\n                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasFlag(); });\n            }\n\n            /** Get whether this has any PositionalBase children\n             *\n             * \\return Whether or not there are any PositionalBase children\n             */\n            virtual bool HasPositional() const override\n            {\n                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasPositional(); });\n            }\n\n            /** Get whether this has any Command children\n             *\n             * \\return Whether or not there are any Command children\n             */\n            virtual bool HasCommand() const override\n            {\n                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasCommand(); });\n            }\n\n            /** Count the number of matched children this group has\n             */\n            std::vector<Base *>::size_type MatchedChildren() const\n            {\n                return std::count_if(std::begin(Children()), std::end(Children()), [](const Base *child){return child->Matched();});\n            }\n\n            /** Whether or not this group matches validation\n             */\n            virtual bool Matched() const noexcept override\n            {\n                return validator(*this);\n            }\n\n            /** Get validation\n             */\n            bool Get() const\n            {\n                return Matched();\n            }\n\n            /** Get all the child descriptions for help generation\n             */\n            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned int indent) const override\n            {\n                std::vector<std::tuple<std::string, std::string, unsigned int>> descriptions;\n\n                // Push that group description on the back if not empty\n                unsigned addindent = 0;\n                if (!help.empty())\n                {\n                    descriptions.emplace_back(help, \"\", indent);\n                    addindent = 1;\n                }\n\n                for (Base *child: Children())\n                {\n                    if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)\n                    {\n                        continue;\n                    }\n\n                    auto groupDescriptions = child->GetDescription(params, indent + addindent);\n                    descriptions.insert(\n                        std::end(descriptions),\n                        std::make_move_iterator(std::begin(groupDescriptions)),\n                        std::make_move_iterator(std::end(groupDescriptions)));\n                }\n                return descriptions;\n            }\n\n            /** Get the names of positional parameters\n             */\n            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override\n            {\n                std::vector <std::string> names;\n                for (Base *child: Children())\n                {\n                    if ((child->GetOptions() & Options::HiddenFromUsage) != Options::None)\n                    {\n                        continue;\n                    }\n\n                    auto groupNames = child->GetProgramLine(params);\n                    names.insert(\n                        std::end(names),\n                        std::make_move_iterator(std::begin(groupNames)),\n                        std::make_move_iterator(std::end(groupNames)));\n                }\n                return names;\n            }\n\n            virtual std::vector<Command*> GetCommands() override\n            {\n                std::vector<Command*> res;\n                for (const auto &child : Children())\n                {\n                    auto subparsers = child->GetCommands();\n                    res.insert(std::end(res), std::begin(subparsers), std::end(subparsers));\n                }\n                return res;\n            }\n\n            virtual bool IsGroup() const override\n            {\n                return true;\n            }\n\n            virtual void Reset() noexcept override\n            {\n                Base::Reset();\n\n                for (auto &child: Children())\n                {\n                    child->Reset();\n                }\n#ifdef ARGS_NOEXCEPT\n                error = Error::None;\n                errorMsg.clear();\n#endif\n            }\n\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            virtual Error GetError() const override\n            {\n                if (error != Error::None)\n                {\n                    return error;\n                }\n\n                auto it = std::find_if(Children().begin(), Children().end(), [](const Base *child){return child->GetError() != Error::None;});\n                if (it == Children().end())\n                {\n                    return Error::None;\n                } else\n                {\n                    return (*it)->GetError();\n                }\n            }\n#endif\n\n    };\n\n    /** Class for using global options in ArgumentParser.\n     */\n    class GlobalOptions : public Group\n    {\n        public:\n            GlobalOptions(Group &base, Base &options_) : Group(base, {}, Group::Validators::DontCare, Options::Global)\n            {\n                Add(options_);\n            }\n    };\n\n    /** Utility class for building subparsers with coroutines/callbacks.\n     *\n     * Brief example:\n     * \\code\n     * Command command(argumentParser, \"command\", \"my command\", [](args::Subparser &s)\n     * {\n     *      // your command flags/positionals\n     *      s.Parse(); //required\n     *      //your command code\n     * });\n     * \\endcode\n     *\n     * For ARGS_NOEXCEPT mode don't forget to check `s.GetError()` after `s.Parse()`\n     * and return if it isn't equals to args::Error::None.\n     *\n     * \\sa Command\n     */\n    class Subparser : public Group\n    {\n        private:\n            std::vector<std::string> args;\n            std::vector<std::string> kicked;\n            ArgumentParser *parser = nullptr;\n            const HelpParams &helpParams;\n            const Command &command;\n            bool isParsed = false;\n\n        public:\n            Subparser(std::vector<std::string> args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_)\n                : args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)\n            {\n            }\n\n            Subparser(const Command &command_, const HelpParams &helpParams_) : helpParams(helpParams_), command(command_)\n            {\n            }\n\n            Subparser(const Subparser&) = delete;\n            Subparser(Subparser&&) = delete;\n            Subparser &operator = (const Subparser&) = delete;\n            Subparser &operator = (Subparser&&) = delete;\n\n            const Command &GetCommand()\n            {\n                return command;\n            }\n\n            /** (INTERNAL) Determines whether Parse was called or not.\n             */\n            bool IsParsed() const\n            {\n                return isParsed;\n            }\n\n            /** Continue parsing arguments for new command.\n             */\n            void Parse();\n\n            /** Returns a vector of kicked out arguments.\n             *\n             * \\sa Base::KickOut\n             */\n            const std::vector<std::string> &KickedOut() const noexcept\n            {\n                return kicked;\n            }\n    };\n\n    /** Main class for building subparsers.\n     *\n     * /sa Subparser\n     */\n    class Command : public Group\n    {\n        private:\n            friend class Subparser;\n\n            std::string name;\n            std::string help;\n            std::string description;\n            std::string epilog;\n            std::string proglinePostfix;\n\n            std::function<void(Subparser&)> parserCoroutine;\n            bool commandIsRequired = true;\n            Command *selectedCommand = nullptr;\n\n            mutable std::vector<std::tuple<std::string, std::string, unsigned>> subparserDescription;\n            mutable std::vector<std::string> subparserProgramLine;\n            mutable bool subparserHasFlag = false;\n            mutable bool subparserHasPositional = false;\n            mutable bool subparserHasCommand = false;\n#ifdef ARGS_NOEXCEPT\n            mutable Error subparserError = Error::None;\n#endif\n            mutable Subparser *subparser = nullptr;\n\n        protected:\n\n            class RaiiSubparser\n            {\n                public:\n                    RaiiSubparser(ArgumentParser &parser_, std::vector<std::string> args_);\n                    RaiiSubparser(const Command &command_, const HelpParams &params_);\n\n                    ~RaiiSubparser()\n                    {\n                        command.subparser = oldSubparser;\n                    }\n\n                    Subparser &Parser()\n                    {\n                        return parser;\n                    }\n\n                private:\n                    const Command &command;\n                    Subparser parser;\n                    Subparser *oldSubparser;\n            };\n\n            Command() = default;\n\n            std::function<void(Subparser&)> &GetCoroutine()\n            {\n                return selectedCommand != nullptr ? selectedCommand->GetCoroutine() : parserCoroutine;\n            }\n\n            Command &SelectedCommand()\n            {\n                Command *res = this;\n                while (res->selectedCommand != nullptr)\n                {\n                    res = res->selectedCommand;\n                }\n\n                return *res;\n            }\n\n            const Command &SelectedCommand() const\n            {\n                const Command *res = this;\n                while (res->selectedCommand != nullptr)\n                {\n                    res = res->selectedCommand;\n                }\n\n                return *res;\n            }\n\n            void UpdateSubparserHelp(const HelpParams &params) const\n            {\n                if (parserCoroutine)\n                {\n                    RaiiSubparser coro(*this, params);\n#ifndef ARGS_NOEXCEPT\n                    try\n                    {\n                        parserCoroutine(coro.Parser());\n                    }\n                    catch (args::SubparserError)\n                    {\n                    }\n#else\n                    parserCoroutine(coro.Parser());\n#endif\n                }\n            }\n\n        public:\n            Command(Group &base_, std::string name_, std::string help_, std::function<void(Subparser&)> coroutine_ = {})\n                : name(std::move(name_)), help(std::move(help_)), parserCoroutine(std::move(coroutine_))\n            {\n                base_.Add(*this);\n            }\n\n            /** The description that appears on the prog line after options\n             */\n            const std::string &ProglinePostfix() const\n            { return proglinePostfix; }\n\n            /** The description that appears on the prog line after options\n             */\n            void ProglinePostfix(const std::string &proglinePostfix_)\n            { this->proglinePostfix = proglinePostfix_; }\n\n            /** The description that appears above options\n             */\n            const std::string &Description() const\n            { return description; }\n            /** The description that appears above options\n             */\n\n            void Description(const std::string &description_)\n            { this->description = description_; }\n\n            /** The description that appears below options\n             */\n            const std::string &Epilog() const\n            { return epilog; }\n\n            /** The description that appears below options\n             */\n            void Epilog(const std::string &epilog_)\n            { this->epilog = epilog_; }\n\n            /** The name of command\n             */\n            const std::string &Name() const\n            { return name; }\n\n            /** The description of command\n             */\n            const std::string &Help() const\n            { return help; }\n\n            /** If value is true, parser will fail if no command was parsed.\n             *\n             * Default: true.\n             */\n            void RequireCommand(bool value)\n            { commandIsRequired = value; }\n\n            virtual bool IsGroup() const override\n            { return false; }\n\n            virtual bool Matched() const noexcept override\n            { return Base::Matched(); }\n\n            operator bool() const noexcept\n            { return Matched(); }\n\n            void Match() noexcept\n            { matched = true; }\n\n            void SelectCommand(Command *c) noexcept\n            {\n                selectedCommand = c;\n\n                if (c != nullptr)\n                {\n                    c->Match();\n                }\n            }\n\n            virtual FlagBase *Match(const EitherFlag &flag) override\n            {\n                if (selectedCommand != nullptr)\n                {\n                    if (auto *res = selectedCommand->Match(flag))\n                    {\n                        return res;\n                    }\n\n                    for (auto *child: Children())\n                    {\n                        if ((child->GetOptions() & Options::Global) != Options::None)\n                        {\n                            if (auto *res = child->Match(flag))\n                            {\n                                return res;\n                            }\n                        }\n                    }\n\n                    return nullptr;\n                }\n\n                if (subparser != nullptr)\n                {\n                    return subparser->Match(flag);\n                }\n\n                return Matched() ? Group::Match(flag) : nullptr;\n            }\n\n            virtual std::vector<FlagBase*> GetAllFlags() override\n            {\n                std::vector<FlagBase*> res;\n\n                if (!Matched())\n                {\n                    return res;\n                }\n\n                for (auto *child: Children())\n                {\n                    if (selectedCommand == nullptr || (child->GetOptions() & Options::Global) != Options::None)\n                    {\n                        auto childFlags = child->GetAllFlags();\n                        res.insert(res.end(), childFlags.begin(), childFlags.end());\n                    }\n                }\n\n                if (selectedCommand != nullptr)\n                {\n                    auto childFlags = selectedCommand->GetAllFlags();\n                    res.insert(res.end(), childFlags.begin(), childFlags.end());\n                }\n\n                if (subparser != nullptr)\n                {\n                    auto childFlags = subparser->GetAllFlags();\n                    res.insert(res.end(), childFlags.begin(), childFlags.end());\n                }\n\n                return res;\n            }\n\n            virtual PositionalBase *GetNextPositional() override\n            {\n                if (selectedCommand != nullptr)\n                {\n                    if (auto *res = selectedCommand->GetNextPositional())\n                    {\n                        return res;\n                    }\n\n                    for (auto *child: Children())\n                    {\n                        if ((child->GetOptions() & Options::Global) != Options::None)\n                        {\n                            if (auto *res = child->GetNextPositional())\n                            {\n                                return res;\n                            }\n                        }\n                    }\n\n                    return nullptr;\n                }\n\n                if (subparser != nullptr)\n                {\n                    return subparser->GetNextPositional();\n                }\n\n                return Matched() ? Group::GetNextPositional() : nullptr;\n            }\n\n            virtual bool HasFlag() const override\n            {\n                return subparserHasFlag || Group::HasFlag();\n            }\n\n            virtual bool HasPositional() const override\n            {\n                return subparserHasPositional || Group::HasPositional();\n            }\n\n            virtual bool HasCommand() const override\n            {\n                return true;\n            }\n\n            std::vector<std::string> GetCommandProgramLine(const HelpParams &params) const\n            {\n                UpdateSubparserHelp(params);\n\n                auto res = Group::GetProgramLine(params);\n                res.insert(res.end(), subparserProgramLine.begin(), subparserProgramLine.end());\n\n                if (!params.proglineCommand.empty() && (Group::HasCommand() || subparserHasCommand))\n                {\n                    res.insert(res.begin(), commandIsRequired ? params.proglineCommand : \"[\" + params.proglineCommand + \"]\");\n                }\n\n                if (!Name().empty())\n                {\n                    res.insert(res.begin(), Name());\n                }\n\n                if ((subparserHasFlag || Group::HasFlag()) && params.showProglineOptions && !params.proglineShowFlags)\n                {\n                    res.push_back(params.proglineOptions);\n                }\n\n                if (!ProglinePostfix().empty())\n                {\n                    std::string line;\n                    for (char c : ProglinePostfix())\n                    {\n                        if (isspace(c))\n                        {\n                            if (!line.empty())\n                            {\n                                res.push_back(line);\n                                line.clear();\n                            }\n\n                            if (c == '\\n')\n                            {\n                                res.push_back(\"\\n\");\n                            }\n                        }\n                        else\n                        {\n                            line += c;\n                        }\n                    }\n\n                    if (!line.empty())\n                    {\n                        res.push_back(line);\n                    }\n                }\n\n                return res;\n            }\n\n            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override\n            {\n                if (!Matched())\n                {\n                    return {};\n                }\n\n                return GetCommandProgramLine(params);\n            }\n\n            virtual std::vector<Command*> GetCommands() override\n            {\n                if (selectedCommand != nullptr)\n                {\n                    return selectedCommand->GetCommands();\n                }\n\n                if (Matched())\n                {\n                    return Group::GetCommands();\n                }\n\n                return { this };\n            }\n\n            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned int indent) const override\n            {\n                std::vector<std::tuple<std::string, std::string, unsigned>> descriptions;\n                unsigned addindent = 0;\n\n                UpdateSubparserHelp(params);\n\n                if (!Matched())\n                {\n                    if (params.showCommandFullHelp)\n                    {\n                        std::ostringstream s;\n                        bool empty = true;\n                        for (const auto &progline: GetCommandProgramLine(params))\n                        {\n                            if (!empty)\n                            {\n                                s << ' ';\n                            }\n                            else\n                            {\n                                empty = false;\n                            }\n\n                            s << progline;\n                        }\n\n                        descriptions.emplace_back(s.str(), \"\", indent);\n                    }\n                    else\n                    {\n                        descriptions.emplace_back(Name(), help, indent);\n                    }\n\n                    if (!params.showCommandChildren && !params.showCommandFullHelp)\n                    {\n                        return descriptions;\n                    }\n\n                    addindent = 1;\n                }\n\n                if (params.showCommandFullHelp && !Matched())\n                {\n                    descriptions.emplace_back(\"\", \"\", indent + addindent);\n                    descriptions.emplace_back(Description().empty() ? Help() : Description(), \"\", indent + addindent);\n                    descriptions.emplace_back(\"\", \"\", indent + addindent);\n                }\n\n                for (Base *child: Children())\n                {\n                    if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)\n                    {\n                        continue;\n                    }\n\n                    auto groupDescriptions = child->GetDescription(params, indent + addindent);\n                    descriptions.insert(\n                                        std::end(descriptions),\n                                        std::make_move_iterator(std::begin(groupDescriptions)),\n                                        std::make_move_iterator(std::end(groupDescriptions)));\n                }\n\n                for (auto childDescription: subparserDescription)\n                {\n                    std::get<2>(childDescription) += indent + addindent;\n                    descriptions.push_back(std::move(childDescription));\n                }\n\n                if (params.showCommandFullHelp && !Matched())\n                {\n                    descriptions.emplace_back(\"\", \"\", indent + addindent);\n                    if (!Epilog().empty())\n                    {\n                        descriptions.emplace_back(Epilog(), \"\", indent + addindent);\n                        descriptions.emplace_back(\"\", \"\", indent + addindent);\n                    }\n                }\n\n                return descriptions;\n            }\n\n            virtual void Validate(const std::string &shortprefix, const std::string &longprefix) const override\n            {\n                if (!Matched())\n                {\n                    return;\n                }\n\n                for (Base *child: Children())\n                {\n                    if (child->IsGroup() && !child->Matched())\n                    {\n                        std::ostringstream problem;\n                        problem << \"Group validation failed somewhere!\";\n#ifdef ARGS_NOEXCEPT\n                        error = Error::Validation;\n                        errorMsg = problem.str();\n#else\n                        throw ValidationError(problem.str());\n#endif\n                    }\n\n                    child->Validate(shortprefix, longprefix);\n                }\n\n                if (subparser != nullptr)\n                {\n                    subparser->Validate(shortprefix, longprefix);\n                }\n\n                if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand))\n                {\n                    std::ostringstream problem;\n                    problem << \"Command is required\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Validation;\n                    errorMsg = problem.str();\n#else\n                    throw ValidationError(problem.str());\n#endif\n                }\n            }\n\n            virtual void Reset() noexcept override\n            {\n                Group::Reset();\n                selectedCommand = nullptr;\n                subparserProgramLine.clear();\n                subparserDescription.clear();\n                subparserHasFlag = false;\n                subparserHasPositional = false;\n                subparserHasCommand = false;\n#ifdef ARGS_NOEXCEPT\n                subparserError = Error::None;\n#endif\n            }\n\n#ifdef ARGS_NOEXCEPT\n            /// Only for ARGS_NOEXCEPT\n            virtual Error GetError() const override\n            {\n                if (!Matched())\n                {\n                    return Error::None;\n                }\n\n                if (error != Error::None)\n                {\n                    return error;\n                }\n\n                if (subparserError != Error::None)\n                {\n                    return subparserError;\n                }\n\n                return Group::GetError();\n            }\n#endif\n    };\n\n    /** The main user facing command line argument parser class\n     */\n    class ArgumentParser : public Command\n    {\n        friend class Subparser;\n\n        private:\n            std::string longprefix;\n            std::string shortprefix;\n\n            std::string longseparator;\n\n            std::string terminator;\n\n            bool allowJoinedShortValue = true;\n            bool allowJoinedLongValue = true;\n            bool allowSeparateShortValue = true;\n            bool allowSeparateLongValue = true;\n\n            CompletionFlag *completion = nullptr;\n            bool readCompletion = false;\n\n        protected:\n            enum class OptionType\n            {\n                LongFlag,\n                ShortFlag,\n                Positional\n            };\n\n            OptionType ParseOption(const std::string &s, bool allowEmpty = false)\n            {\n                if (s.find(longprefix) == 0 && (allowEmpty || s.length() > longprefix.length()))\n                {\n                    return OptionType::LongFlag;\n                }\n\n                if (s.find(shortprefix) == 0 && (allowEmpty || s.length() > shortprefix.length()))\n                {\n                    return OptionType::ShortFlag;\n                }\n\n                return OptionType::Positional;\n            }\n\n            template <typename It>\n            bool Complete(FlagBase &flag, It it, It end)\n            {\n                auto nextIt = it;\n                if (!readCompletion || (++nextIt != end))\n                {\n                    return false;\n                }\n\n                const auto &chunk = *it;\n                for (auto &choice : flag.HelpChoices(helpParams))\n                {\n                    AddCompletionReply(chunk, choice);\n                }\n\n#ifndef ARGS_NOEXCEPT\n                throw Completion(completion->Get());\n#else\n                return true;\n#endif\n            }\n\n            /** (INTERNAL) Parse flag's values\n             *\n             * \\param arg The string to display in error message as a flag name\n             * \\param[in, out] it The iterator to first value. It will point to the last value\n             * \\param end The end iterator\n             * \\param joinedArg Joined value (e.g. bar in --foo=bar)\n             * \\param canDiscardJoined If true joined value can be parsed as flag not as a value (as in -abcd)\n             * \\param[out] values The vector to store parsed arg's values\n             */\n            template <typename It>\n            std::string ParseArgsValues(FlagBase &flag, const std::string &arg, It &it, It end,\n                                        const bool allowSeparate, const bool allowJoined,\n                                        const bool hasJoined, const std::string &joinedArg,\n                                        const bool canDiscardJoined, std::vector<std::string> &values)\n            {\n                values.clear();\n\n                Nargs nargs = flag.NumberOfArguments();\n\n                if (hasJoined && !allowJoined && nargs.min != 0)\n                {\n                    return \"Flag '\" + arg + \"' was passed a joined argument, but these are disallowed\";\n                }\n\n                if (hasJoined)\n                {\n                    if (!canDiscardJoined || nargs.max != 0)\n                    {\n                        values.push_back(joinedArg);\n                    }\n                } else if (!allowSeparate)\n                {\n                    if (nargs.min != 0)\n                    {\n                        return \"Flag '\" + arg + \"' was passed a separate argument, but these are disallowed\";\n                    }\n                } else\n                {\n                    auto valueIt = it;\n                    ++valueIt;\n\n                    while (valueIt != end &&\n                           values.size() < nargs.max &&\n                           (nargs.min == nargs.max || ParseOption(*valueIt) == OptionType::Positional))\n                    {\n                        if (Complete(flag, valueIt, end))\n                        {\n                            it = end;\n                            return \"\";\n                        }\n\n                        values.push_back(*valueIt);\n                        ++it;\n                        ++valueIt;\n                    }\n                }\n\n                if (values.size() > nargs.max)\n                {\n                    return \"Passed an argument into a non-argument flag: \" + arg;\n                } else if (values.size() < nargs.min)\n                {\n                    if (nargs.min == 1 && nargs.max == 1)\n                    {\n                        return \"Flag '\" + arg + \"' requires an argument but received none\";\n                    } else if (nargs.min == 1)\n                    {\n                        return \"Flag '\" + arg + \"' requires at least one argument but received none\";\n                    } else if (nargs.min != nargs.max)\n                    {\n                        return \"Flag '\" + arg + \"' requires at least \" + std::to_string(nargs.min) +\n                               \" arguments but received \" + std::to_string(values.size());\n                    } else\n                    {\n                        return \"Flag '\" + arg + \"' requires \" + std::to_string(nargs.min) +\n                               \" arguments but received \" + std::to_string(values.size());\n                    }\n                }\n\n                return {};\n            }\n\n            template <typename It>\n            bool ParseLong(It &it, It end)\n            {\n                const auto &chunk = *it;\n                const auto argchunk = chunk.substr(longprefix.size());\n                // Try to separate it, in case of a separator:\n                const auto separator = longseparator.empty() ? argchunk.npos : argchunk.find(longseparator);\n                // If the separator is in the argument, separate it.\n                const auto arg = (separator != argchunk.npos ?\n                    std::string(argchunk, 0, separator)\n                    : argchunk);\n                const auto joined = (separator != argchunk.npos ?\n                    argchunk.substr(separator + longseparator.size())\n                    : std::string());\n\n                if (auto flag = Match(arg))\n                {\n                    std::vector<std::string> values;\n                    const std::string errorMessage = ParseArgsValues(*flag, arg, it, end, allowSeparateLongValue, allowJoinedLongValue,\n                                                                     separator != argchunk.npos, joined, false, values);\n                    if (!errorMessage.empty())\n                    {\n#ifndef ARGS_NOEXCEPT\n                        throw ParseError(errorMessage);\n#else\n                        error = Error::Parse;\n                        errorMsg = errorMessage;\n                        return false;\n#endif\n                    }\n\n                    if (!readCompletion)\n                    {\n                        flag->ParseValue(values);\n                    }\n\n                    if (flag->KickOut())\n                    {\n                        ++it;\n                        return false;\n                    }\n                } else\n                {\n                    const std::string errorMessage(\"Flag could not be matched: \" + arg);\n#ifndef ARGS_NOEXCEPT\n                    throw ParseError(errorMessage);\n#else\n                    error = Error::Parse;\n                    errorMsg = errorMessage;\n                    return false;\n#endif\n                }\n\n                return true;\n            }\n\n            template <typename It>\n            bool ParseShort(It &it, It end)\n            {\n                const auto &chunk = *it;\n                const auto argchunk = chunk.substr(shortprefix.size());\n                for (auto argit = std::begin(argchunk); argit != std::end(argchunk); ++argit)\n                {\n                    const auto arg = *argit;\n\n                    if (auto flag = Match(arg))\n                    {\n                        const std::string value(argit + 1, std::end(argchunk));\n                        std::vector<std::string> values;\n                        const std::string errorMessage = ParseArgsValues(*flag, std::string(1, arg), it, end,\n                                                                         allowSeparateShortValue, allowJoinedShortValue,\n                                                                         !value.empty(), value, !value.empty(), values);\n\n                        if (!errorMessage.empty())\n                        {\n#ifndef ARGS_NOEXCEPT\n                            throw ParseError(errorMessage);\n#else\n                            error = Error::Parse;\n                            errorMsg = errorMessage;\n                            return false;\n#endif\n                        }\n\n                        if (!readCompletion)\n                        {\n                            flag->ParseValue(values);\n                        }\n\n                        if (flag->KickOut())\n                        {\n                            ++it;\n                            return false;\n                        }\n\n                        if (!values.empty())\n                        {\n                            break;\n                        }\n                    } else\n                    {\n                        const std::string errorMessage(\"Flag could not be matched: '\" + std::string(1, arg) + \"'\");\n#ifndef ARGS_NOEXCEPT\n                        throw ParseError(errorMessage);\n#else\n                        error = Error::Parse;\n                        errorMsg = errorMessage;\n                        return false;\n#endif\n                    }\n                }\n\n                return true;\n            }\n\n            bool AddCompletionReply(const std::string &cur, const std::string &choice)\n            {\n                if (cur.empty() || choice.find(cur) == 0)\n                {\n                    if (completion->syntax == \"bash\" && ParseOption(choice) == OptionType::LongFlag && choice.find(longseparator) != std::string::npos)\n                    {\n                        completion->reply.push_back(choice.substr(choice.find(longseparator) + 1));\n                    } else\n                    {\n                        completion->reply.push_back(choice);\n                    }\n                    return true;\n                }\n\n                return false;\n            }\n\n            template <typename It>\n            bool Complete(It it, It end)\n            {\n                auto nextIt = it;\n                if (!readCompletion || (++nextIt != end))\n                {\n                    return false;\n                }\n\n                const auto &chunk = *it;\n                auto pos = GetNextPositional();\n                std::vector<Command *> commands = GetCommands();\n                const auto optionType = ParseOption(chunk, true);\n\n                if (!commands.empty() && (chunk.empty() || optionType == OptionType::Positional))\n                {\n                    for (auto &cmd : commands)\n                    {\n                        if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)\n                        {\n                            AddCompletionReply(chunk, cmd->Name());\n                        }\n                    }\n                } else\n                {\n                    bool hasPositionalCompletion = true;\n\n                    if (!commands.empty())\n                    {\n                        for (auto &cmd : commands)\n                        {\n                            if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)\n                            {\n                                AddCompletionReply(chunk, cmd->Name());\n                            }\n                        }\n                    } else if (pos)\n                    {\n                        if ((pos->GetOptions() & Options::HiddenFromCompletion) == Options::None)\n                        {\n                            auto choices = pos->HelpChoices(helpParams);\n                            hasPositionalCompletion = !choices.empty() || optionType != OptionType::Positional;\n                            for (auto &choice : choices)\n                            {\n                                AddCompletionReply(chunk, choice);\n                            }\n                        }\n                    }\n\n                    if (hasPositionalCompletion)\n                    {\n                        auto flags = GetAllFlags();\n                        for (auto flag : flags)\n                        {\n                            if ((flag->GetOptions() & Options::HiddenFromCompletion) != Options::None)\n                            {\n                                continue;\n                            }\n\n                            auto &matcher = flag->GetMatcher();\n                            if (!AddCompletionReply(chunk, matcher.GetShortOrAny().str(shortprefix, longprefix)))\n                            {\n                                for (auto &flagName : matcher.GetFlagStrings())\n                                {\n                                    if (AddCompletionReply(chunk, flagName.str(shortprefix, longprefix)))\n                                    {\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n\n                        if (optionType == OptionType::LongFlag && allowJoinedLongValue)\n                        {\n                            const auto separator = longseparator.empty() ? chunk.npos : chunk.find(longseparator);\n                            if (separator != chunk.npos)\n                            {\n                                std::string arg(chunk, 0, separator);\n                                if (auto flag = this->Match(arg.substr(longprefix.size())))\n                                {\n                                    for (auto &choice : flag->HelpChoices(helpParams))\n                                    {\n                                        AddCompletionReply(chunk, arg + longseparator + choice);\n                                    }\n                                }\n                            }\n                        } else if (optionType == OptionType::ShortFlag && allowJoinedShortValue)\n                        {\n                            if (chunk.size() > shortprefix.size() + 1)\n                            {\n                                auto arg = chunk.at(shortprefix.size());\n                                //TODO: support -abcVALUE where a and b take no value\n                                if (auto flag = this->Match(arg))\n                                {\n                                    for (auto &choice : flag->HelpChoices(helpParams))\n                                    {\n                                        AddCompletionReply(chunk, shortprefix + arg + choice);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n#ifndef ARGS_NOEXCEPT\n                throw Completion(completion->Get());\n#else\n                return true;\n#endif\n            }\n\n            template <typename It>\n            It Parse(It begin, It end)\n            {\n                bool terminated = false;\n                std::vector<Command *> commands = GetCommands();\n\n                // Check all arg chunks\n                for (auto it = begin; it != end; ++it)\n                {\n                    if (Complete(it, end))\n                    {\n                        return end;\n                    }\n\n                    const auto &chunk = *it;\n\n                    if (!terminated && chunk == terminator)\n                    {\n                        terminated = true;\n                    } else if (!terminated && ParseOption(chunk) == OptionType::LongFlag)\n                    {\n                        if (!ParseLong(it, end))\n                        {\n                            return it;\n                        }\n                    } else if (!terminated && ParseOption(chunk) == OptionType::ShortFlag)\n                    {\n                        if (!ParseShort(it, end))\n                        {\n                            return it;\n                        }\n                    } else if (!terminated && !commands.empty())\n                    {\n                        auto itCommand = std::find_if(commands.begin(), commands.end(), [&chunk](Command *c) { return c->Name() == chunk; });\n                        if (itCommand == commands.end())\n                        {\n                            const std::string errorMessage(\"Unknown command: \" + chunk);\n#ifndef ARGS_NOEXCEPT\n                            throw ParseError(errorMessage);\n#else\n                            error = Error::Parse;\n                            errorMsg = errorMessage;\n                            return it;\n#endif\n                        }\n\n                        SelectCommand(*itCommand);\n\n                        if (const auto &coroutine = GetCoroutine())\n                        {\n                            ++it;\n                            RaiiSubparser coro(*this, std::vector<std::string>(it, end));\n                            coroutine(coro.Parser());\n#ifdef ARGS_NOEXCEPT\n                            error = GetError();\n                            if (error != Error::None)\n                            {\n                                return end;\n                            }\n\n                            if (!coro.Parser().IsParsed())\n                            {\n                                error = Error::Usage;\n                                return end;\n                            }\n#else\n                            if (!coro.Parser().IsParsed())\n                            {\n                                throw UsageError(\"Subparser::Parse was not called\");\n                            }\n#endif\n\n                            break;\n                        }\n\n                        commands = GetCommands();\n                    } else\n                    {\n                        auto pos = GetNextPositional();\n                        if (pos)\n                        {\n                            pos->ParseValue(chunk);\n\n                            if (pos->KickOut())\n                            {\n                                return ++it;\n                            }\n                        } else\n                        {\n                            const std::string errorMessage(\"Passed in argument, but no positional arguments were ready to receive it: \" + chunk);\n#ifndef ARGS_NOEXCEPT\n                            throw ParseError(errorMessage);\n#else\n                            error = Error::Parse;\n                            errorMsg = errorMessage;\n                            return it;\n#endif\n                        }\n                    }\n\n                    if (!readCompletion && completion != nullptr && completion->Matched())\n                    {\n#ifdef ARGS_NOEXCEPT\n                        error = Error::Completion;\n#endif\n                        readCompletion = true;\n                        ++it;\n                        size_t argsLeft = std::distance(it, end);\n                        if (completion->cword == 0 || argsLeft <= 1 || completion->cword >= argsLeft)\n                        {\n#ifndef ARGS_NOEXCEPT\n                            throw Completion(\"\");\n#endif\n                        }\n\n                        std::vector<std::string> curArgs(++it, end);\n                        curArgs.resize(completion->cword);\n\n                        if (completion->syntax == \"bash\")\n                        {\n                            // bash tokenizes --flag=value as --flag=value\n                            for (size_t idx = 0; idx < curArgs.size(); )\n                            {\n                                if (idx > 0 && curArgs[idx] == \"=\")\n                                {\n                                    curArgs[idx - 1] += \"=\";\n                                    if (idx + 1 < curArgs.size())\n                                    {\n                                        curArgs[idx - 1] += curArgs[idx + 1];\n                                        curArgs.erase(curArgs.begin() + idx, curArgs.begin() + idx + 2);\n                                    } else\n                                    {\n                                        curArgs.erase(curArgs.begin() + idx);\n                                    }\n                                } else\n                                {\n                                    ++idx;\n                                }\n                            }\n\n                        }\n#ifndef ARGS_NOEXCEPT\n                        try\n                        {\n                            Parse(curArgs.begin(), curArgs.end());\n                            throw Completion(\"\");\n                        }\n                        catch (Completion &)\n                        {\n                            throw;\n                        }\n                        catch (args::Error&)\n                        {\n                            throw Completion(\"\");\n                        }\n#else\n                        return Parse(curArgs.begin(), curArgs.end());\n#endif\n                    }\n                }\n\n                Validate(shortprefix, longprefix);\n                return end;\n            }\n\n        public:\n            HelpParams helpParams;\n\n            ArgumentParser(const std::string &description_, const std::string &epilog_ = std::string())\n            {\n                Description(description_);\n                Epilog(epilog_);\n                LongPrefix(\"--\");\n                ShortPrefix(\"-\");\n                LongSeparator(\"=\");\n                Terminator(\"--\");\n                SetArgumentSeparations(true, true, true, true);\n                matched = true;\n            }\n\n            void AddCompletion(CompletionFlag &completionFlag)\n            {\n                completion = &completionFlag;\n                Add(completionFlag);\n            }\n\n            /** The program name for help generation\n             */\n            const std::string &Prog() const\n            { return helpParams.programName; }\n            /** The program name for help generation\n             */\n            void Prog(const std::string &prog_)\n            { this->helpParams.programName = prog_; }\n\n            /** The prefix for long flags\n             */\n            const std::string &LongPrefix() const\n            { return longprefix; }\n            /** The prefix for long flags\n             */\n            void LongPrefix(const std::string &longprefix_)\n            {\n                this->longprefix = longprefix_;\n                this->helpParams.longPrefix = longprefix_;\n            }\n\n            /** The prefix for short flags\n             */\n            const std::string &ShortPrefix() const\n            { return shortprefix; }\n            /** The prefix for short flags\n             */\n            void ShortPrefix(const std::string &shortprefix_)\n            {\n                this->shortprefix = shortprefix_;\n                this->helpParams.shortPrefix = shortprefix_;\n            }\n\n            /** The separator for long flags\n             */\n            const std::string &LongSeparator() const\n            { return longseparator; }\n            /** The separator for long flags\n             */\n            void LongSeparator(const std::string &longseparator_)\n            {\n                if (longseparator_.empty())\n                {\n                    const std::string errorMessage(\"longseparator can not be set to empty\");\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Usage;\n                    errorMsg = errorMessage;\n#else\n                    throw UsageError(errorMessage);\n#endif\n                } else\n                {\n                    this->longseparator = longseparator_;\n                    this->helpParams.longSeparator = allowJoinedLongValue ? longseparator_ : \" \";\n                }\n            }\n\n            /** The terminator that forcibly separates flags from positionals\n             */\n            const std::string &Terminator() const\n            { return terminator; }\n            /** The terminator that forcibly separates flags from positionals\n             */\n            void Terminator(const std::string &terminator_)\n            { this->terminator = terminator_; }\n\n            /** Get the current argument separation parameters.\n             *\n             * See SetArgumentSeparations for details on what each one means.\n             */\n            void GetArgumentSeparations(\n                bool &allowJoinedShortValue_,\n                bool &allowJoinedLongValue_,\n                bool &allowSeparateShortValue_,\n                bool &allowSeparateLongValue_) const\n            {\n                allowJoinedShortValue_ = this->allowJoinedShortValue;\n                allowJoinedLongValue_ = this->allowJoinedLongValue;\n                allowSeparateShortValue_ = this->allowSeparateShortValue;\n                allowSeparateLongValue_ = this->allowSeparateLongValue;\n            }\n\n            /** Change allowed option separation.\n             *\n             * \\param allowJoinedShortValue_ Allow a short flag that accepts an argument to be passed its argument immediately next to it (ie. in the same argv field)\n             * \\param allowJoinedLongValue_ Allow a long flag that accepts an argument to be passed its argument separated by the longseparator (ie. in the same argv field)\n             * \\param allowSeparateShortValue_ Allow a short flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)\n             * \\param allowSeparateLongValue_ Allow a long flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)\n             */\n            void SetArgumentSeparations(\n                const bool allowJoinedShortValue_,\n                const bool allowJoinedLongValue_,\n                const bool allowSeparateShortValue_,\n                const bool allowSeparateLongValue_)\n            {\n                this->allowJoinedShortValue = allowJoinedShortValue_;\n                this->allowJoinedLongValue = allowJoinedLongValue_;\n                this->allowSeparateShortValue = allowSeparateShortValue_;\n                this->allowSeparateLongValue = allowSeparateLongValue_;\n\n                this->helpParams.longSeparator = allowJoinedLongValue ? longseparator : \" \";\n                this->helpParams.shortSeparator = allowJoinedShortValue ? \"\" : \" \";\n            }\n\n            /** Pass the help menu into an ostream\n             */\n            void Help(std::ostream &help_) const\n            {\n                auto &command = SelectedCommand();\n                const auto &commandDescription = command.Description().empty() ? command.Help() : command.Description();\n                const auto description_text = Wrap(commandDescription, helpParams.width - helpParams.descriptionindent);\n                const auto epilog_text = Wrap(command.Epilog(), helpParams.width - helpParams.descriptionindent);\n\n                const bool hasoptions = command.HasFlag();\n                const bool hasarguments = command.HasPositional();\n\n                std::vector<std::string> prognameline;\n                prognameline.push_back(helpParams.usageString);\n                prognameline.push_back(Prog());\n                auto commandProgLine = command.GetProgramLine(helpParams);\n                prognameline.insert(prognameline.end(), commandProgLine.begin(), commandProgLine.end());\n\n                const auto proglines = Wrap(prognameline.begin(), prognameline.end(),\n                                            helpParams.width - (helpParams.progindent + helpParams.progtailindent),\n                                            helpParams.width - helpParams.progindent);\n                auto progit = std::begin(proglines);\n                if (progit != std::end(proglines))\n                {\n                    help_ << std::string(helpParams.progindent, ' ') << *progit << '\\n';\n                    ++progit;\n                }\n                for (; progit != std::end(proglines); ++progit)\n                {\n                    help_ << std::string(helpParams.progtailindent, ' ') << *progit << '\\n';\n                }\n\n                help_ << '\\n';\n\n                if (!description_text.empty())\n                {\n                    for (const auto &line: description_text)\n                    {\n                        help_ << std::string(helpParams.descriptionindent, ' ') << line << \"\\n\";\n                    }\n                    help_ << \"\\n\";\n                }\n\n                bool lastDescriptionIsNewline = false;\n\n                if (!helpParams.optionsString.empty())\n                {\n                    help_ << std::string(helpParams.progindent, ' ') << helpParams.optionsString << \"\\n\\n\";\n                }\n\n                for (const auto &desc: command.GetDescription(helpParams, 0))\n                {\n                    lastDescriptionIsNewline = std::get<0>(desc).empty() && std::get<1>(desc).empty();\n                    const auto groupindent = std::get<2>(desc) * helpParams.eachgroupindent;\n                    const auto flags = Wrap(std::get<0>(desc), helpParams.width - (helpParams.flagindent + helpParams.helpindent + helpParams.gutter));\n                    const auto info = Wrap(std::get<1>(desc), helpParams.width - (helpParams.helpindent + groupindent));\n\n                    std::string::size_type flagssize = 0;\n                    for (auto flagsit = std::begin(flags); flagsit != std::end(flags); ++flagsit)\n                    {\n                        if (flagsit != std::begin(flags))\n                        {\n                            help_ << '\\n';\n                        }\n                        help_ << std::string(groupindent + helpParams.flagindent, ' ') << *flagsit;\n                        flagssize = Glyphs(*flagsit);\n                    }\n\n                    auto infoit = std::begin(info);\n                    // groupindent is on both sides of this inequality, and therefore can be removed\n                    if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info) || helpParams.addNewlineBeforeDescription)\n                    {\n                        help_ << '\\n';\n                    } else\n                    {\n                        // groupindent is on both sides of the minus sign, and therefore doesn't actually need to be in here\n                        help_ << std::string(helpParams.helpindent - (helpParams.flagindent + flagssize), ' ') << *infoit << '\\n';\n                        ++infoit;\n                    }\n                    for (; infoit != std::end(info); ++infoit)\n                    {\n                        help_ << std::string(groupindent + helpParams.helpindent, ' ') << *infoit << '\\n';\n                    }\n                }\n                if (hasoptions && hasarguments && helpParams.showTerminator)\n                {\n                    lastDescriptionIsNewline = false;\n                    for (const auto &item: Wrap(std::string(\"\\\"\") + terminator + \"\\\" can be used to terminate flag options and force all following arguments to be treated as positional options\", helpParams.width - helpParams.flagindent))\n                    {\n                        help_ << std::string(helpParams.flagindent, ' ') << item << '\\n';\n                    }\n                }\n\n                if (!lastDescriptionIsNewline)\n                {\n                    help_ << \"\\n\";\n                }\n\n                for (const auto &line: epilog_text)\n                {\n                    help_ << std::string(helpParams.descriptionindent, ' ') << line << \"\\n\";\n                }\n            }\n\n            /** Generate a help menu as a string.\n             *\n             * \\return the help text as a single string\n             */\n            std::string Help() const\n            {\n                std::ostringstream help_;\n                Help(help_);\n                return help_.str();\n            }\n\n            virtual void Reset() noexcept override\n            {\n                Command::Reset();\n                matched = true;\n                readCompletion = false;\n            }\n\n            /** Parse all arguments.\n             *\n             * \\param begin an iterator to the beginning of the argument list\n             * \\param end an iterator to the past-the-end element of the argument list\n             * \\return the iterator after the last parsed value.  Only useful for kick-out\n             */\n            template <typename It>\n            It ParseArgs(It begin, It end)\n            {\n                // Reset all Matched statuses and errors\n                Reset();\n#ifdef ARGS_NOEXCEPT\n                error = GetError();\n                if (error != Error::None)\n                {\n                    return end;\n                }\n#endif\n                return Parse(begin, end);\n            }\n\n            /** Parse all arguments.\n             *\n             * \\param args an iterable of the arguments\n             * \\return the iterator after the last parsed value.  Only useful for kick-out\n             */\n            template <typename T>\n            auto ParseArgs(const T &args) -> decltype(std::begin(args))\n            {\n                return ParseArgs(std::begin(args), std::end(args));\n            }\n\n            /** Convenience function to parse the CLI from argc and argv\n             *\n             * Just assigns the program name and vectorizes arguments for passing into ParseArgs()\n             *\n             * \\return whether or not all arguments were parsed.  This works for detecting kick-out, but is generally useless as it can't do anything with it.\n             */\n            bool ParseCLI(const int argc, const char * const * argv)\n            {\n                if (Prog().empty())\n                {\n                    Prog(argv[0]);\n                }\n                const std::vector<std::string> args(argv + 1, argv + argc);\n                return ParseArgs(args) == std::end(args);\n            }\n            \n            template <typename T>\n            bool ParseCLI(const T &args)\n            {\n                return ParseArgs(args) == std::end(args);\n            }\n    };\n\n    inline Command::RaiiSubparser::RaiiSubparser(ArgumentParser &parser_, std::vector<std::string> args_)\n        : command(parser_.SelectedCommand()), parser(std::move(args_), parser_, command, parser_.helpParams), oldSubparser(command.subparser)\n    {\n        command.subparser = &parser;\n    }\n\n    inline Command::RaiiSubparser::RaiiSubparser(const Command &command_, const HelpParams &params_): command(command_), parser(command, params_), oldSubparser(command.subparser)\n    {\n        command.subparser = &parser;\n    }\n\n    inline void Subparser::Parse()\n    {\n        isParsed = true;\n        Reset();\n        command.subparserDescription = GetDescription(helpParams, 0);\n        command.subparserHasFlag = HasFlag();\n        command.subparserHasPositional = HasPositional();\n        command.subparserHasCommand = HasCommand();\n        command.subparserProgramLine = GetProgramLine(helpParams);\n        if (parser == nullptr)\n        {\n#ifndef ARGS_NOEXCEPT\n            throw args::SubparserError();\n#else\n            error = Error::Subparser;\n            return;\n#endif\n        }\n\n        auto it = parser->Parse(args.begin(), args.end());\n        command.Validate(parser->ShortPrefix(), parser->LongPrefix());\n        kicked.assign(it, args.end());\n\n#ifdef ARGS_NOEXCEPT\n        command.subparserError = GetError();\n#endif\n    }\n\n    inline std::ostream &operator<<(std::ostream &os, const ArgumentParser &parser)\n    {\n        parser.Help(os);\n        return os;\n    }\n\n    /** Boolean argument matcher\n     */\n    class Flag : public FlagBase\n    {\n        public:\n            Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): FlagBase(name_, help_, std::move(matcher_), options_)\n            {\n                group_.Add(*this);\n            }\n\n            Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false): Flag(group_, name_, help_, std::move(matcher_), extraError_ ? Options::Single : Options::None)\n            {\n            }\n\n            virtual ~Flag() {}\n\n            /** Get whether this was matched\n             */\n            bool Get() const\n            {\n                return Matched();\n            }\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            {\n                return 0;\n            }\n\n            virtual void ParseValue(const std::vector<std::string>&) override\n            {\n            }\n    };\n\n    /** Help flag class\n     *\n     * Works like a regular flag, but throws an instance of Help when it is matched\n     */\n    class HelpFlag : public Flag\n    {\n        public:\n            HelpFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_ = {}): Flag(group_, name_, help_, std::move(matcher_), options_) {}\n\n            virtual ~HelpFlag() {}\n\n            virtual void ParseValue(const std::vector<std::string> &)\n            {\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Help;\n                    errorMsg = Name();\n#else\n                    throw Help(Name());\n#endif\n            }\n\n            /** Get whether this was matched\n             */\n            bool Get() const noexcept\n            {\n                return Matched();\n            }\n    };\n\n    /** A flag class that simply counts the number of times it's matched\n     */\n    class CounterFlag : public Flag\n    {\n        private:\n            const int startcount;\n            int count;\n\n        public:\n            CounterFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const int startcount_ = 0, Options options_ = {}):\n                Flag(group_, name_, help_, std::move(matcher_), options_), startcount(startcount_), count(startcount_) {}\n\n            virtual ~CounterFlag() {}\n\n            virtual FlagBase *Match(const EitherFlag &arg) override\n            {\n                auto me = FlagBase::Match(arg);\n                if (me)\n                {\n                    ++count;\n                }\n                return me;\n            }\n\n            /** Get the count\n             */\n            int &Get() noexcept\n            {\n                return count;\n            }\n\n            virtual void Reset() noexcept override\n            {\n                FlagBase::Reset();\n                count = startcount;\n            }\n    };\n\n    /** A flag class that calls a function when it's matched\n     */\n    class ActionFlag : public FlagBase\n    {\n        private:\n            std::function<void(const std::vector<std::string> &)> action;\n            Nargs nargs;\n\n        public:\n            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, std::function<void(const std::vector<std::string> &)> action_, Options options_ = {}):\n                FlagBase(name_, help_, std::move(matcher_), options_), action(std::move(action_)), nargs(nargs_)\n            {\n                group_.Add(*this);\n            }\n\n            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function<void(const std::string &)> action_, Options options_ = {}):\n                FlagBase(name_, help_, std::move(matcher_), options_), nargs(1)\n            {\n                group_.Add(*this);\n                action = [action_](const std::vector<std::string> &a) { return action_(a.at(0)); };\n            }\n\n            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function<void()> action_, Options options_ = {}):\n                FlagBase(name_, help_, std::move(matcher_), options_), nargs(0)\n            {\n                group_.Add(*this);\n                action = [action_](const std::vector<std::string> &) { return action_(); };\n            }\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            { return nargs; }\n\n            virtual void ParseValue(const std::vector<std::string> &value) override\n            { action(value); }\n    };\n\n    /** A default Reader class for argument classes\n     *\n     * If destination type is assignable to std::string it uses an assignment to std::string.\n     * Otherwise ValueReader simply uses a std::istringstream to read into the destination type, and\n     * raises a ParseError if there are any characters left.\n     */\n    struct ValueReader\n    {\n        template <typename T>\n        typename std::enable_if<!std::is_assignable<T, std::string>::value, bool>::type\n        operator ()(const std::string &name, const std::string &value, T &destination)\n        {\n            std::istringstream ss(value);\n            ss >> destination >> std::ws;\n\n            if (ss.rdbuf()->in_avail() > 0)\n            {\n#ifdef ARGS_NOEXCEPT\n                (void)name;\n                return false;\n#else\n                std::ostringstream problem;\n                problem << \"Argument '\" << name << \"' received invalid value type '\" << value << \"'\";\n                throw ParseError(problem.str());\n#endif\n            }\n            return true;\n        }\n\n        template <typename T>\n        typename std::enable_if<std::is_assignable<T, std::string>::value, bool>::type\n        operator()(const std::string &, const std::string &value, T &destination)\n        {\n            destination = value;\n            return true;\n        }\n    };\n\n    /** An argument-accepting flag class\n     * \n     * \\tparam T the type to extract the argument as\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        typename Reader = ValueReader>\n    class ValueFlag : public ValueFlagBase\n    {\n        protected:\n            T value;\n            T defaultValue;\n\n            virtual std::string GetDefaultString(const HelpParams&) const override\n            {\n                return detail::ToString(defaultValue);\n            }\n\n        private:\n            Reader reader;\n\n        public:\n\n            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), value(defaultValue_), defaultValue(defaultValue_)\n            {\n                group_.Add(*this);\n            }\n\n            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), const bool extraError_ = false): ValueFlag(group_, name_, help_, std::move(matcher_), defaultValue_, extraError_ ? Options::Single : Options::None)\n            {\n            }\n\n            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): ValueFlag(group_, name_, help_, std::move(matcher_), T(), options_)\n            {\n            }\n\n            virtual ~ValueFlag() {}\n\n            virtual void ParseValue(const std::vector<std::string> &values_) override\n            {\n                const std::string &value_ = values_.at(0);\n\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, this->value))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, this->value);\n#endif\n            }\n\n            virtual void Reset() noexcept override\n            {\n                ValueFlagBase::Reset();\n                value = defaultValue;\n            }\n\n            /** Get the value\n             */\n            T &Get() noexcept\n            {\n                return value;\n            }\n\n            /** Get the default value\n             */\n            const T &GetDefault() noexcept\n            {\n                return defaultValue;\n            }\n    };\n\n    /** An optional argument-accepting flag class\n     *\n     * \\tparam T the type to extract the argument as\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        typename Reader = ValueReader>\n    class ImplicitValueFlag : public ValueFlag<T, Reader>\n    {\n        protected:\n            T implicitValue;\n\n        public:\n\n            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &implicitValue_, const T &defaultValue_ = T(), Options options_ = {})\n                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(implicitValue_)\n            {\n            }\n\n            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), Options options_ = {})\n                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(defaultValue_)\n            {\n            }\n\n            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_)\n                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), {}, options_), implicitValue()\n            {\n            }\n\n            virtual ~ImplicitValueFlag() {}\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            {\n                return {0, 1};\n            }\n\n            virtual void ParseValue(const std::vector<std::string> &value_) override\n            {\n                if (value_.empty())\n                {\n                    this->value = implicitValue;\n                } else\n                {\n                    ValueFlag<T, Reader>::ParseValue(value_);\n                }\n            }\n    };\n\n    /** A variadic arguments accepting flag class\n     *\n     * \\tparam T the type to extract the argument as\n     * \\tparam List the list type that houses the values\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        template <typename...> class List = std::vector,\n        typename Reader = ValueReader>\n    class NargsValueFlag : public FlagBase\n    {\n        protected:\n\n            List<T> values;\n            Nargs nargs;\n            Reader reader;\n\n        public:\n\n            typedef List<T> Container;\n            typedef T value_type;\n            typedef typename Container::allocator_type allocator_type;\n            typedef typename Container::pointer pointer;\n            typedef typename Container::const_pointer const_pointer;\n            typedef T& reference;\n            typedef const T& const_reference;\n            typedef typename Container::size_type size_type;\n            typedef typename Container::difference_type difference_type;\n            typedef typename Container::iterator iterator;\n            typedef typename Container::const_iterator const_iterator;\n            typedef std::reverse_iterator<iterator> reverse_iterator;\n            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n            NargsValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, const List<T> &defaultValues_ = {}, Options options_ = {})\n                : FlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), nargs(nargs_)\n            {\n                group_.Add(*this);\n            }\n\n            virtual ~NargsValueFlag() {}\n\n            virtual Nargs NumberOfArguments() const noexcept override\n            {\n                return nargs;\n            }\n\n            virtual void ParseValue(const std::vector<std::string> &values_) override\n            {\n                values.clear();\n\n                for (const std::string &value : values_)\n                {\n                    T v;\n#ifdef ARGS_NOEXCEPT\n                    if (!reader(name, value, v))\n                    {\n                        error = Error::Parse;\n                    }\n#else\n                    reader(name, value, v);\n#endif\n                    values.insert(std::end(values), v);\n                }\n            }\n\n            List<T> &Get() noexcept\n            {\n                return values;\n            }\n\n            iterator begin() noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator begin() const noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator cbegin() const noexcept\n            {\n                return values.cbegin();\n            }\n\n            iterator end() noexcept\n            {\n                return values.end();\n            }\n\n            const_iterator end() const noexcept \n            {\n                return values.end();\n            }\n\n            const_iterator cend() const noexcept\n            {\n                return values.cend();\n            }\n    };\n\n    /** An argument-accepting flag class that pushes the found values into a list\n     * \n     * \\tparam T the type to extract the argument as\n     * \\tparam List the list type that houses the values\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        template <typename...> class List = std::vector,\n        typename Reader = ValueReader>\n    class ValueFlagList : public ValueFlagBase\n    {\n        private:\n            using Container = List<T>;\n            Container values;\n            Reader reader;\n\n        public:\n\n            typedef T value_type;\n            typedef typename Container::allocator_type allocator_type;\n            typedef typename Container::pointer pointer;\n            typedef typename Container::const_pointer const_pointer;\n            typedef T& reference;\n            typedef const T& const_reference;\n            typedef typename Container::size_type size_type;\n            typedef typename Container::difference_type difference_type;\n            typedef typename Container::iterator iterator;\n            typedef typename Container::const_iterator const_iterator;\n            typedef std::reverse_iterator<iterator> reverse_iterator;\n            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n            ValueFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Container &defaultValues_ = Container(), Options options_ = {}):\n                ValueFlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_)\n            {\n                group_.Add(*this);\n            }\n\n            virtual ~ValueFlagList() {}\n\n            virtual void ParseValue(const std::vector<std::string> &values_) override\n            {\n                const std::string &value_ = values_.at(0);\n\n                T v;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, v))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, v);\n#endif\n                values.insert(std::end(values), v);\n            }\n\n            /** Get the values\n             */\n            Container &Get() noexcept\n            {\n                return values;\n            }\n\n            virtual std::string Name() const override\n            {\n                return name + std::string(\"...\");\n            }\n\n            virtual void Reset() noexcept override\n            {\n                ValueFlagBase::Reset();\n                values.clear();\n            }\n\n            iterator begin() noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator begin() const noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator cbegin() const noexcept\n            {\n                return values.cbegin();\n            }\n\n            iterator end() noexcept\n            {\n                return values.end();\n            }\n\n            const_iterator end() const noexcept \n            {\n                return values.end();\n            }\n\n            const_iterator cend() const noexcept\n            {\n                return values.cend();\n            }\n    };\n\n    /** A mapping value flag class\n     * \n     * \\tparam K the type to extract the argument as\n     * \\tparam T the type to store the result as\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     * \\tparam Map The Map type.  Should operate like std::map or std::unordered_map\n     */\n    template <\n        typename K,\n        typename T,\n        typename Reader = ValueReader,\n        template <typename...> class Map = std::unordered_map>\n    class MapFlag : public ValueFlagBase\n    {\n        private:\n            const Map<K, T> map;\n            T value;\n            Reader reader;\n\n        protected:\n            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override\n            {\n                return detail::MapKeysToStrings(map);\n            }\n\n        public:\n\n            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), map(map_), value(defaultValue_)\n            {\n                group_.Add(*this);\n            }\n\n            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_ = T(), const bool extraError_ = false): MapFlag(group_, name_, help_, std::move(matcher_), map_, defaultValue_, extraError_ ? Options::Single : Options::None)\n            {\n            }\n\n            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, Options options_): MapFlag(group_, name_, help_, std::move(matcher_), map_, T(), options_)\n            {\n            }\n\n            virtual ~MapFlag() {}\n\n            virtual void ParseValue(const std::vector<std::string> &values_) override\n            {\n                const std::string &value_ = values_.at(0);\n\n                K key;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, key))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, key);\n#endif\n                auto it = map.find(key);\n                if (it == std::end(map))\n                {\n                    std::ostringstream problem;\n                    problem << \"Could not find key '\" << key << \"' in map for arg '\" << name << \"'\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Map;\n                    errorMsg = problem.str();\n#else\n                    throw MapError(problem.str());\n#endif\n                } else\n                {\n                    this->value = it->second;\n                }\n            }\n\n            /** Get the value\n             */\n            T &Get() noexcept\n            {\n                return value;\n            }\n    };\n\n    /** A mapping value flag list class\n     * \n     * \\tparam K the type to extract the argument as\n     * \\tparam T the type to store the result as\n     * \\tparam List the list type that houses the values\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     * \\tparam Map The Map type.  Should operate like std::map or std::unordered_map\n     */\n    template <\n        typename K,\n        typename T,\n        template <typename...> class List = std::vector,\n        typename Reader = ValueReader,\n        template <typename...> class Map = std::unordered_map>\n    class MapFlagList : public ValueFlagBase\n    {\n        private:\n            using Container = List<T>;\n            const Map<K, T> map;\n            Container values;\n            Reader reader;\n\n        protected:\n            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override\n            {\n                return detail::MapKeysToStrings(map);\n            }\n\n        public:\n            typedef T value_type;\n            typedef typename Container::allocator_type allocator_type;\n            typedef typename Container::pointer pointer;\n            typedef typename Container::const_pointer const_pointer;\n            typedef T& reference;\n            typedef const T& const_reference;\n            typedef typename Container::size_type size_type;\n            typedef typename Container::difference_type difference_type;\n            typedef typename Container::iterator iterator;\n            typedef typename Container::const_iterator const_iterator;\n            typedef std::reverse_iterator<iterator> reverse_iterator;\n            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n            MapFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const Container &defaultValues_ = Container()): ValueFlagBase(name_, help_, std::move(matcher_)), map(map_), values(defaultValues_)\n            {\n                group_.Add(*this);\n            }\n\n            virtual ~MapFlagList() {}\n\n            virtual void ParseValue(const std::vector<std::string> &values_) override\n            {\n                const std::string &value = values_.at(0);\n\n                K key;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value, key))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value, key);\n#endif\n                auto it = map.find(key);\n                if (it == std::end(map))\n                {\n                    std::ostringstream problem;\n                    problem << \"Could not find key '\" << key << \"' in map for arg '\" << name << \"'\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Map;\n                    errorMsg = problem.str();\n#else\n                    throw MapError(problem.str());\n#endif\n                } else\n                {\n                    this->values.emplace_back(it->second);\n                }\n            }\n\n            /** Get the value\n             */\n            Container &Get() noexcept\n            {\n                return values;\n            }\n\n            virtual std::string Name() const override\n            {\n                return name + std::string(\"...\");\n            }\n\n            virtual void Reset() noexcept override\n            {\n                ValueFlagBase::Reset();\n                values.clear();\n            }\n\n            iterator begin() noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator begin() const noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator cbegin() const noexcept\n            {\n                return values.cbegin();\n            }\n\n            iterator end() noexcept\n            {\n                return values.end();\n            }\n\n            const_iterator end() const noexcept \n            {\n                return values.end();\n            }\n\n            const_iterator cend() const noexcept\n            {\n                return values.cend();\n            }\n    };\n\n    /** A positional argument class\n     *\n     * \\tparam T the type to extract the argument as\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        typename Reader = ValueReader>\n    class Positional : public PositionalBase\n    {\n        private:\n            T value;\n            Reader reader;\n        public:\n            Positional(Group &group_, const std::string &name_, const std::string &help_, const T &defaultValue_ = T(), Options options_ = {}): PositionalBase(name_, help_, options_), value(defaultValue_)\n            {\n                group_.Add(*this);\n            }\n\n            Positional(Group &group_, const std::string &name_, const std::string &help_, Options options_): Positional(group_, name_, help_, T(), options_)\n            {\n            }\n\n            virtual ~Positional() {}\n\n            virtual void ParseValue(const std::string &value_) override\n            {\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, this->value))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, this->value);\n#endif\n                ready = false;\n                matched = true;\n            }\n\n            /** Get the value\n             */\n            T &Get() noexcept\n            {\n                return value;\n            }\n    };\n\n    /** A positional argument class that pushes the found values into a list\n     * \n     * \\tparam T the type to extract the argument as\n     * \\tparam List the list type that houses the values\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     */\n    template <\n        typename T,\n        template <typename...> class List = std::vector,\n        typename Reader = ValueReader>\n    class PositionalList : public PositionalBase\n    {\n        private:\n            using Container = List<T>;\n            Container values;\n            Reader reader;\n\n        public:\n            typedef T value_type;\n            typedef typename Container::allocator_type allocator_type;\n            typedef typename Container::pointer pointer;\n            typedef typename Container::const_pointer const_pointer;\n            typedef T& reference;\n            typedef const T& const_reference;\n            typedef typename Container::size_type size_type;\n            typedef typename Container::difference_type difference_type;\n            typedef typename Container::iterator iterator;\n            typedef typename Container::const_iterator const_iterator;\n            typedef std::reverse_iterator<iterator> reverse_iterator;\n            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n            PositionalList(Group &group_, const std::string &name_, const std::string &help_, const Container &defaultValues_ = Container(), Options options_ = {}): PositionalBase(name_, help_, options_), values(defaultValues_)\n            {\n                group_.Add(*this);\n            }\n\n            PositionalList(Group &group_, const std::string &name_, const std::string &help_, Options options_): PositionalList(group_, name_, help_, {}, options_)\n            {\n            }\n\n            virtual ~PositionalList() {}\n\n            virtual void ParseValue(const std::string &value_) override\n            {\n                T v;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, v))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, v);\n#endif\n                values.insert(std::end(values), v);\n                matched = true;\n            }\n\n            virtual std::string Name() const override\n            {\n                return name + std::string(\"...\");\n            }\n\n            /** Get the values\n             */\n            Container &Get() noexcept\n            {\n                return values;\n            }\n\n            virtual void Reset() noexcept override\n            {\n                PositionalBase::Reset();\n                values.clear();\n            }\n\n            iterator begin() noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator begin() const noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator cbegin() const noexcept\n            {\n                return values.cbegin();\n            }\n\n            iterator end() noexcept\n            {\n                return values.end();\n            }\n\n            const_iterator end() const noexcept \n            {\n                return values.end();\n            }\n\n            const_iterator cend() const noexcept\n            {\n                return values.cend();\n            }\n    };\n\n    /** A positional argument mapping class\n     * \n     * \\tparam K the type to extract the argument as\n     * \\tparam T the type to store the result as\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     * \\tparam Map The Map type.  Should operate like std::map or std::unordered_map\n     */\n    template <\n        typename K,\n        typename T,\n        typename Reader = ValueReader,\n        template <typename...> class Map = std::unordered_map>\n    class MapPositional : public PositionalBase\n    {\n        private:\n            const Map<K, T> map;\n            T value;\n            Reader reader;\n\n        protected:\n            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override\n            {\n                return detail::MapKeysToStrings(map);\n            }\n\n        public:\n\n            MapPositional(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const T &defaultValue_ = T(), Options options_ = {}):\n                PositionalBase(name_, help_, options_), map(map_), value(defaultValue_)\n            {\n                group_.Add(*this);\n            }\n\n            virtual ~MapPositional() {}\n\n            virtual void ParseValue(const std::string &value_) override\n            {\n                K key;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, key))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, key);\n#endif\n                auto it = map.find(key);\n                if (it == std::end(map))\n                {\n                    std::ostringstream problem;\n                    problem << \"Could not find key '\" << key << \"' in map for arg '\" << name << \"'\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Map;\n                    errorMsg = problem.str();\n#else\n                    throw MapError(problem.str());\n#endif\n                } else\n                {\n                    this->value = it->second;\n                    ready = false;\n                    matched = true;\n                }\n            }\n\n            /** Get the value\n             */\n            T &Get() noexcept\n            {\n                return value;\n            }\n    };\n\n    /** A positional argument mapping list class\n     * \n     * \\tparam K the type to extract the argument as\n     * \\tparam T the type to store the result as\n     * \\tparam List the list type that houses the values\n     * \\tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)\n     * \\tparam Map The Map type.  Should operate like std::map or std::unordered_map\n     */\n    template <\n        typename K,\n        typename T,\n        template <typename...> class List = std::vector,\n        typename Reader = ValueReader,\n        template <typename...> class Map = std::unordered_map>\n    class MapPositionalList : public PositionalBase\n    {\n        private:\n            using Container = List<T>;\n\n            const Map<K, T> map;\n            Container values;\n            Reader reader;\n\n        protected:\n            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override\n            {\n                return detail::MapKeysToStrings(map);\n            }\n\n        public:\n            typedef T value_type;\n            typedef typename Container::allocator_type allocator_type;\n            typedef typename Container::pointer pointer;\n            typedef typename Container::const_pointer const_pointer;\n            typedef T& reference;\n            typedef const T& const_reference;\n            typedef typename Container::size_type size_type;\n            typedef typename Container::difference_type difference_type;\n            typedef typename Container::iterator iterator;\n            typedef typename Container::const_iterator const_iterator;\n            typedef std::reverse_iterator<iterator> reverse_iterator;\n            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;\n\n            MapPositionalList(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const Container &defaultValues_ = Container(), Options options_ = {}):\n                PositionalBase(name_, help_, options_), map(map_), values(defaultValues_)\n            {\n                group_.Add(*this);\n            }\n\n            virtual ~MapPositionalList() {}\n\n            virtual void ParseValue(const std::string &value_) override\n            {\n                K key;\n#ifdef ARGS_NOEXCEPT\n                if (!reader(name, value_, key))\n                {\n                    error = Error::Parse;\n                }\n#else\n                reader(name, value_, key);\n#endif\n                auto it = map.find(key);\n                if (it == std::end(map))\n                {\n                    std::ostringstream problem;\n                    problem << \"Could not find key '\" << key << \"' in map for arg '\" << name << \"'\";\n#ifdef ARGS_NOEXCEPT\n                    error = Error::Map;\n                    errorMsg = problem.str();\n#else\n                    throw MapError(problem.str());\n#endif\n                } else\n                {\n                    this->values.emplace_back(it->second);\n                    matched = true;\n                }\n            }\n\n            /** Get the value\n             */\n            Container &Get() noexcept\n            {\n                return values;\n            }\n\n            virtual std::string Name() const override\n            {\n                return name + std::string(\"...\");\n            }\n\n            virtual void Reset() noexcept override\n            {\n                PositionalBase::Reset();\n                values.clear();\n            }\n\n            iterator begin() noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator begin() const noexcept\n            {\n                return values.begin();\n            }\n\n            const_iterator cbegin() const noexcept\n            {\n                return values.cbegin();\n            }\n\n            iterator end() noexcept\n            {\n                return values.end();\n            }\n\n            const_iterator end() const noexcept \n            {\n                return values.end();\n            }\n\n            const_iterator cend() const noexcept\n            {\n                return values.cend();\n            }\n    };\n}\n\n#endif\n"
  },
  {
    "path": "third-party/catch/LICENSE.txt",
    "content": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "third-party/catch/catch.hpp",
    "content": "/*\n *  Catch v1.6.1\n *  Generated: 2017-01-20 12:33:53.497767\n *  ----------------------------------------------------------\n *  This file has been merged from multiple headers. Please don't edit it directly\n *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n *\n *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\n#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n#define TWOBLUECUBES_CATCH_HPP_INCLUDED\n\n#ifdef __clang__\n#    pragma clang system_header\n#elif defined __GNUC__\n#    pragma GCC system_header\n#endif\n\n// #included from: internal/catch_suppress_warnings.h\n\n#ifdef __clang__\n#   ifdef __ICC // icpc defines the __clang__ macro\n#       pragma warning(push)\n#       pragma warning(disable: 161 1682)\n#   else // __ICC\n#       pragma clang diagnostic ignored \"-Wglobal-constructors\"\n#       pragma clang diagnostic ignored \"-Wvariadic-macros\"\n#       pragma clang diagnostic ignored \"-Wc99-extensions\"\n#       pragma clang diagnostic ignored \"-Wunused-variable\"\n#       pragma clang diagnostic push\n#       pragma clang diagnostic ignored \"-Wpadded\"\n#       pragma clang diagnostic ignored \"-Wc++98-compat\"\n#       pragma clang diagnostic ignored \"-Wc++98-compat-pedantic\"\n#       pragma clang diagnostic ignored \"-Wswitch-enum\"\n#       pragma clang diagnostic ignored \"-Wcovered-switch-default\"\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic ignored \"-Wvariadic-macros\"\n#    pragma GCC diagnostic ignored \"-Wunused-variable\"\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wpadded\"\n#endif\n#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)\n#  define CATCH_IMPL\n#endif\n\n#ifdef CATCH_IMPL\n#  ifndef CLARA_CONFIG_MAIN\n#    define CLARA_CONFIG_MAIN_NOT_DEFINED\n#    define CLARA_CONFIG_MAIN\n#  endif\n#endif\n\n// #included from: internal/catch_notimplemented_exception.h\n#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED\n\n// #included from: catch_common.h\n#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED\n\n// #included from: catch_compiler_capabilities.h\n#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED\n\n// Detect a number of compiler features - mostly C++11/14 conformance - by compiler\n// The following features are defined:\n//\n// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?\n// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?\n// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods\n// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?\n// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported\n// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?\n// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?\n// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)\n\n// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?\n\n// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?\n// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?\n// ****************\n// Note to maintainers: if new toggles are added please document them\n// in configuration.md, too\n// ****************\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11\n\n#ifdef __cplusplus\n\n#  if __cplusplus >= 201103L\n#    define CATCH_CPP11_OR_GREATER\n#  endif\n\n#  if __cplusplus >= 201402L\n#    define CATCH_CPP14_OR_GREATER\n#  endif\n\n#endif\n\n#ifdef __clang__\n\n#  if __has_feature(cxx_nullptr)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#  endif\n\n#  if __has_feature(cxx_noexcept)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#  endif\n\n#   if defined(CATCH_CPP11_OR_GREATER)\n#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( \"clang diagnostic ignored \\\"-Wparentheses\\\"\" )\n#   endif\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// Borland\n#ifdef __BORLANDC__\n\n#endif // __BORLANDC__\n\n////////////////////////////////////////////////////////////////////////////////\n// EDG\n#ifdef __EDG_VERSION__\n\n#endif // __EDG_VERSION__\n\n////////////////////////////////////////////////////////////////////////////////\n// Digital Mars\n#ifdef __DMC__\n\n#endif // __DMC__\n\n////////////////////////////////////////////////////////////////////////////////\n// GCC\n#ifdef __GNUC__\n\n#   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)\n#       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#   endif\n\n#   if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)\n#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( \"GCC diagnostic ignored \\\"-Wparentheses\\\"\" )\n#   endif\n\n// - otherwise more recent versions define __cplusplus >= 201103L\n// and will get picked up below\n\n#endif // __GNUC__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#ifdef _MSC_VER\n\n#if (_MSC_VER >= 1600)\n#   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))\n#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE\n#endif\n\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Use variadic macros if the compiler supports them\n#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \\\n    ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \\\n    ( defined __GNUC__ && __GNUC__ >= 3 ) || \\\n    ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )\n\n#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n\n#endif\n\n// Use __COUNTER__ if the compiler supports it\n#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \\\n    ( defined __GNUC__  && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \\\n    ( defined __clang__ && __clang_major__ >= 3 )\n\n#define CATCH_INTERNAL_CONFIG_COUNTER\n\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// C++ language feature support\n\n// catch all support for C++11\n#if defined(CATCH_CPP11_OR_GREATER)\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)\n#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM\n#    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE\n#    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE\n#  endif\n\n#  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n#    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS\n#  endif\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)\n#    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG\n#  endif\n\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)\n#    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE\n#  endif\n#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)\n#    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#  endif\n# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)\n#   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE\n#  endif\n\n#endif // __cplusplus >= 201103L\n\n// Now set the actual defines based on the above + anything the user has configured\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_NULLPTR\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_NOEXCEPT\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_GENERATED_METHODS\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_IS_ENUM\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_TUPLE\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)\n#   define CATCH_CONFIG_VARIADIC_MACROS\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_LONG_LONG\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_OVERRIDE\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_UNIQUE_PTR\n#endif\n// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for\n// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.\n// This does not affect compilation\n#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)\n#   define CATCH_CONFIG_COUNTER\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)\n#   define CATCH_CONFIG_CPP11_SHUFFLE\n#endif\n\n#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS\n#endif\n\n// noexcept support:\n#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)\n#  define CATCH_NOEXCEPT noexcept\n#  define CATCH_NOEXCEPT_IS(x) noexcept(x)\n#else\n#  define CATCH_NOEXCEPT throw()\n#  define CATCH_NOEXCEPT_IS(x)\n#endif\n\n// nullptr support\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n#   define CATCH_NULL nullptr\n#else\n#   define CATCH_NULL NULL\n#endif\n\n// override support\n#ifdef CATCH_CONFIG_CPP11_OVERRIDE\n#   define CATCH_OVERRIDE override\n#else\n#   define CATCH_OVERRIDE\n#endif\n\n// unique_ptr support\n#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR\n#   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>\n#else\n#   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>\n#endif\n\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )\n#ifdef CATCH_CONFIG_COUNTER\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )\n#else\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )\n#endif\n\n#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr\n#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )\n\n#include <sstream>\n#include <stdexcept>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct IConfig;\n\n    struct CaseSensitive { enum Choice {\n        Yes,\n        No\n    }; };\n\n    class NonCopyable {\n#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        NonCopyable( NonCopyable const& )              = delete;\n        NonCopyable( NonCopyable && )                  = delete;\n        NonCopyable& operator = ( NonCopyable const& ) = delete;\n        NonCopyable& operator = ( NonCopyable && )     = delete;\n#else\n        NonCopyable( NonCopyable const& info );\n        NonCopyable& operator = ( NonCopyable const& );\n#endif\n\n    protected:\n        NonCopyable() {}\n        virtual ~NonCopyable();\n    };\n\n    class SafeBool {\n    public:\n        typedef void (SafeBool::*type)() const;\n\n        static type makeSafe( bool value ) {\n            return value ? &SafeBool::trueValue : 0;\n        }\n    private:\n        void trueValue() const {}\n    };\n\n    template<typename ContainerT>\n    inline void deleteAll( ContainerT& container ) {\n        typename ContainerT::const_iterator it = container.begin();\n        typename ContainerT::const_iterator itEnd = container.end();\n        for(; it != itEnd; ++it )\n            delete *it;\n    }\n    template<typename AssociativeContainerT>\n    inline void deleteAllValues( AssociativeContainerT& container ) {\n        typename AssociativeContainerT::const_iterator it = container.begin();\n        typename AssociativeContainerT::const_iterator itEnd = container.end();\n        for(; it != itEnd; ++it )\n            delete it->second;\n    }\n\n    bool startsWith( std::string const& s, std::string const& prefix );\n    bool endsWith( std::string const& s, std::string const& suffix );\n    bool contains( std::string const& s, std::string const& infix );\n    void toLowerInPlace( std::string& s );\n    std::string toLower( std::string const& s );\n    std::string trim( std::string const& str );\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );\n\n    struct pluralise {\n        pluralise( std::size_t count, std::string const& label );\n\n        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );\n\n        std::size_t m_count;\n        std::string m_label;\n    };\n\n    struct SourceLineInfo {\n\n        SourceLineInfo();\n        SourceLineInfo( char const* _file, std::size_t _line );\n        SourceLineInfo( SourceLineInfo const& other );\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        SourceLineInfo( SourceLineInfo && )                  = default;\n        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;\n        SourceLineInfo& operator = ( SourceLineInfo && )     = default;\n#  endif\n        bool empty() const;\n        bool operator == ( SourceLineInfo const& other ) const;\n        bool operator < ( SourceLineInfo const& other ) const;\n\n        std::string file;\n        std::size_t line;\n    };\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );\n\n    // This is just here to avoid compiler warnings with macro constants and boolean literals\n    inline bool alwaysTrue( std::size_t = 0 ) { return true; }\n    inline bool alwaysFalse( std::size_t = 0 ) { return false; }\n\n    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );\n\n    void seedRng( IConfig const& config );\n    unsigned int rngSeed();\n\n    // Use this in variadic streaming macros to allow\n    //    >> +StreamEndStop\n    // as well as\n    //    >> stuff +StreamEndStop\n    struct StreamEndStop {\n        std::string operator+() {\n            return std::string();\n        }\n    };\n    template<typename T>\n    T const& operator + ( T const& value, StreamEndStop ) {\n        return value;\n    }\n}\n\n#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )\n#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );\n\n#include <ostream>\n\nnamespace Catch {\n\n    class NotImplementedException : public std::exception\n    {\n    public:\n        NotImplementedException( SourceLineInfo const& lineInfo );\n        NotImplementedException( NotImplementedException const& ) {}\n\n        virtual ~NotImplementedException() CATCH_NOEXCEPT {}\n\n        virtual const char* what() const CATCH_NOEXCEPT;\n\n    private:\n        std::string m_what;\n        SourceLineInfo m_lineInfo;\n    };\n\n} // end namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )\n\n// #included from: internal/catch_context.h\n#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED\n\n// #included from: catch_interfaces_generators.h\n#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct IGeneratorInfo {\n        virtual ~IGeneratorInfo();\n        virtual bool moveNext() = 0;\n        virtual std::size_t getCurrentIndex() const = 0;\n    };\n\n    struct IGeneratorsForTest {\n        virtual ~IGeneratorsForTest();\n\n        virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;\n        virtual bool moveNext() = 0;\n    };\n\n    IGeneratorsForTest* createGeneratorsForTest();\n\n} // end namespace Catch\n\n// #included from: catch_ptr.hpp\n#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    // An intrusive reference counting smart pointer.\n    // T must implement addRef() and release() methods\n    // typically implementing the IShared interface\n    template<typename T>\n    class Ptr {\n    public:\n        Ptr() : m_p( CATCH_NULL ){}\n        Ptr( T* p ) : m_p( p ){\n            if( m_p )\n                m_p->addRef();\n        }\n        Ptr( Ptr const& other ) : m_p( other.m_p ){\n            if( m_p )\n                m_p->addRef();\n        }\n        ~Ptr(){\n            if( m_p )\n                m_p->release();\n        }\n        void reset() {\n            if( m_p )\n                m_p->release();\n            m_p = CATCH_NULL;\n        }\n        Ptr& operator = ( T* p ){\n            Ptr temp( p );\n            swap( temp );\n            return *this;\n        }\n        Ptr& operator = ( Ptr const& other ){\n            Ptr temp( other );\n            swap( temp );\n            return *this;\n        }\n        void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }\n        T* get() const{ return m_p; }\n        T& operator*() const { return *m_p; }\n        T* operator->() const { return m_p; }\n        bool operator !() const { return m_p == CATCH_NULL; }\n        operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }\n\n    private:\n        T* m_p;\n    };\n\n    struct IShared : NonCopyable {\n        virtual ~IShared();\n        virtual void addRef() const = 0;\n        virtual void release() const = 0;\n    };\n\n    template<typename T = IShared>\n    struct SharedImpl : T {\n\n        SharedImpl() : m_rc( 0 ){}\n\n        virtual void addRef() const {\n            ++m_rc;\n        }\n        virtual void release() const {\n            if( --m_rc == 0 )\n                delete this;\n        }\n\n        mutable unsigned int m_rc;\n    };\n\n} // end namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#include <memory>\n#include <vector>\n#include <stdlib.h>\n\nnamespace Catch {\n\n    class TestCase;\n    class Stream;\n    struct IResultCapture;\n    struct IRunner;\n    struct IGeneratorsForTest;\n    struct IConfig;\n\n    struct IContext\n    {\n        virtual ~IContext();\n\n        virtual IResultCapture* getResultCapture() = 0;\n        virtual IRunner* getRunner() = 0;\n        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;\n        virtual bool advanceGeneratorsForCurrentTest() = 0;\n        virtual Ptr<IConfig const> getConfig() const = 0;\n    };\n\n    struct IMutableContext : IContext\n    {\n        virtual ~IMutableContext();\n        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;\n        virtual void setRunner( IRunner* runner ) = 0;\n        virtual void setConfig( Ptr<IConfig const> const& config ) = 0;\n    };\n\n    IContext& getCurrentContext();\n    IMutableContext& getCurrentMutableContext();\n    void cleanUpContext();\n    Stream createStream( std::string const& streamName );\n\n}\n\n// #included from: internal/catch_test_registry.hpp\n#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED\n\n// #included from: catch_interfaces_testcase.h\n#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED\n\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec;\n\n    struct ITestCase : IShared {\n        virtual void invoke () const = 0;\n    protected:\n        virtual ~ITestCase();\n    };\n\n    class TestCase;\n    struct IConfig;\n\n    struct ITestCaseRegistry {\n        virtual ~ITestCaseRegistry();\n        virtual std::vector<TestCase> const& getAllTests() const = 0;\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;\n    };\n\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n}\n\nnamespace Catch {\n\ntemplate<typename C>\nclass MethodTestCase : public SharedImpl<ITestCase> {\n\npublic:\n    MethodTestCase( void (C::*method)() ) : m_method( method ) {}\n\n    virtual void invoke() const {\n        C obj;\n        (obj.*m_method)();\n    }\n\nprivate:\n    virtual ~MethodTestCase() {}\n\n    void (C::*m_method)();\n};\n\ntypedef void(*TestFunction)();\n\nstruct NameAndDesc {\n    NameAndDesc( const char* _name = \"\", const char* _description= \"\" )\n    : name( _name ), description( _description )\n    {}\n\n    const char* name;\n    const char* description;\n};\n\nvoid registerTestCase\n    (   ITestCase* testCase,\n        char const* className,\n        NameAndDesc const& nameAndDesc,\n        SourceLineInfo const& lineInfo );\n\nstruct AutoReg {\n\n    AutoReg\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc );\n\n    template<typename C>\n    AutoReg\n        (   void (C::*method)(),\n            char const* className,\n            NameAndDesc const& nameAndDesc,\n            SourceLineInfo const& lineInfo ) {\n\n        registerTestCase\n            (   new MethodTestCase<C>( method ),\n                className,\n                nameAndDesc,\n                lineInfo );\n    }\n\n    ~AutoReg();\n\nprivate:\n    AutoReg( AutoReg const& );\n    void operator= ( AutoReg const& );\n};\n\nvoid registerTestCaseFunction\n    (   TestFunction function,\n        SourceLineInfo const& lineInfo,\n        NameAndDesc const& nameAndDesc );\n\n} // end namespace Catch\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \\\n        static void TestName(); \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( ... ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, \"&\" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\\\n        namespace{ \\\n            struct TestName : ClassName{ \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \\\n        } \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \\\n        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );\n\n#else\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \\\n        static void TestName(); \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, \"&\" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\\\n        namespace{ \\\n            struct TestCaseName : ClassName{ \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \\\n        } \\\n        void TestCaseName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \\\n        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );\n#endif\n\n// #included from: internal/catch_capture.hpp\n#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED\n\n// #included from: catch_result_builder.h\n#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED\n\n// #included from: catch_result_type.h\n#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED\n\nnamespace Catch {\n\n    // ResultWas::OfType enum\n    struct ResultWas { enum OfType {\n        Unknown = -1,\n        Ok = 0,\n        Info = 1,\n        Warning = 2,\n\n        FailureBit = 0x10,\n\n        ExpressionFailed = FailureBit | 1,\n        ExplicitFailure = FailureBit | 2,\n\n        Exception = 0x100 | FailureBit,\n\n        ThrewException = Exception | 1,\n        DidntThrowException = Exception | 2,\n\n        FatalErrorCondition = 0x200 | FailureBit\n\n    }; };\n\n    inline bool isOk( ResultWas::OfType resultType ) {\n        return ( resultType & ResultWas::FailureBit ) == 0;\n    }\n    inline bool isJustInfo( int flags ) {\n        return flags == ResultWas::Info;\n    }\n\n    // ResultDisposition::Flags enum\n    struct ResultDisposition { enum Flags {\n        Normal = 0x01,\n\n        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues\n        FalseTest = 0x04,           // Prefix expression with !\n        SuppressFail = 0x08         // Failures are reported but do not fail the test\n    }; };\n\n    inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {\n        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );\n    }\n\n    inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }\n    inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }\n    inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }\n\n} // end namespace Catch\n\n// #included from: catch_assertionresult.h\n#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct AssertionInfo\n    {\n        AssertionInfo() {}\n        AssertionInfo(  std::string const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        std::string const& _capturedExpression,\n                        ResultDisposition::Flags _resultDisposition );\n\n        std::string macroName;\n        SourceLineInfo lineInfo;\n        std::string capturedExpression;\n        ResultDisposition::Flags resultDisposition;\n    };\n\n    struct AssertionResultData\n    {\n        AssertionResultData() : resultType( ResultWas::Unknown ) {}\n\n        std::string reconstructedExpression;\n        std::string message;\n        ResultWas::OfType resultType;\n    };\n\n    class AssertionResult {\n    public:\n        AssertionResult();\n        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );\n        ~AssertionResult();\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n         AssertionResult( AssertionResult const& )              = default;\n         AssertionResult( AssertionResult && )                  = default;\n         AssertionResult& operator = ( AssertionResult const& ) = default;\n         AssertionResult& operator = ( AssertionResult && )     = default;\n#  endif\n\n        bool isOk() const;\n        bool succeeded() const;\n        ResultWas::OfType getResultType() const;\n        bool hasExpression() const;\n        bool hasMessage() const;\n        std::string getExpression() const;\n        std::string getExpressionInMacro() const;\n        bool hasExpandedExpression() const;\n        std::string getExpandedExpression() const;\n        std::string getMessage() const;\n        SourceLineInfo getSourceInfo() const;\n        std::string getTestMacroName() const;\n\n    protected:\n        AssertionInfo m_info;\n        AssertionResultData m_resultData;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_matchers.hpp\n#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n    namespace Generic {\n        template<typename ExpressionT> class AllOf;\n        template<typename ExpressionT> class AnyOf;\n        template<typename ExpressionT> class Not;\n    }\n\n    template<typename ExpressionT>\n    struct Matcher : SharedImpl<IShared>\n    {\n        typedef ExpressionT ExpressionType;\n\n        virtual ~Matcher() {}\n        virtual Ptr<Matcher> clone() const = 0;\n        virtual bool match( ExpressionT const& expr ) const = 0;\n        virtual std::string toString() const = 0;\n\n        Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;\n        Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;\n        Generic::Not<ExpressionT> operator ! () const;\n    };\n\n    template<typename DerivedT, typename ExpressionT>\n    struct MatcherImpl : Matcher<ExpressionT> {\n\n        virtual Ptr<Matcher<ExpressionT> > clone() const {\n            return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );\n        }\n    };\n\n    namespace Generic {\n        template<typename ExpressionT>\n        class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {\n        public:\n            explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}\n            Not( Not const& other ) : m_matcher( other.m_matcher ) {}\n\n            virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {\n                return !m_matcher->match( expr );\n            }\n\n            virtual std::string toString() const CATCH_OVERRIDE {\n                return \"not \" + m_matcher->toString();\n            }\n        private:\n            Ptr< Matcher<ExpressionT> > m_matcher;\n        };\n\n        template<typename ExpressionT>\n        class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {\n        public:\n\n            AllOf() {}\n            AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}\n\n            AllOf& add( Matcher<ExpressionT> const& matcher ) {\n                m_matchers.push_back( matcher.clone() );\n                return *this;\n            }\n            virtual bool match( ExpressionT const& expr ) const\n            {\n                for( std::size_t i = 0; i < m_matchers.size(); ++i )\n                    if( !m_matchers[i]->match( expr ) )\n                        return false;\n                return true;\n            }\n            virtual std::string toString() const {\n                std::ostringstream oss;\n                oss << \"( \";\n                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {\n                    if( i != 0 )\n                        oss << \" and \";\n                    oss << m_matchers[i]->toString();\n                }\n                oss << \" )\";\n                return oss.str();\n            }\n\n            AllOf operator && ( Matcher<ExpressionT> const& other ) const {\n                AllOf allOfExpr( *this );\n                allOfExpr.add( other );\n                return allOfExpr;\n            }\n\n        private:\n            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;\n        };\n\n        template<typename ExpressionT>\n        class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {\n        public:\n\n            AnyOf() {}\n            AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}\n\n            AnyOf& add( Matcher<ExpressionT> const& matcher ) {\n                m_matchers.push_back( matcher.clone() );\n                return *this;\n            }\n            virtual bool match( ExpressionT const& expr ) const\n            {\n                for( std::size_t i = 0; i < m_matchers.size(); ++i )\n                    if( m_matchers[i]->match( expr ) )\n                        return true;\n                return false;\n            }\n            virtual std::string toString() const {\n                std::ostringstream oss;\n                oss << \"( \";\n                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {\n                    if( i != 0 )\n                        oss << \" or \";\n                    oss << m_matchers[i]->toString();\n                }\n                oss << \" )\";\n                return oss.str();\n            }\n\n            AnyOf operator || ( Matcher<ExpressionT> const& other ) const {\n                AnyOf anyOfExpr( *this );\n                anyOfExpr.add( other );\n                return anyOfExpr;\n            }\n\n        private:\n            std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;\n        };\n\n    } // namespace Generic\n\n    template<typename ExpressionT>\n    Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {\n        Generic::AllOf<ExpressionT> allOfExpr;\n        allOfExpr.add( *this );\n        allOfExpr.add( other );\n        return allOfExpr;\n    }\n\n    template<typename ExpressionT>\n    Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {\n        Generic::AnyOf<ExpressionT> anyOfExpr;\n        anyOfExpr.add( *this );\n        anyOfExpr.add( other );\n        return anyOfExpr;\n    }\n\n    template<typename ExpressionT>\n    Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {\n        return Generic::Not<ExpressionT>( *this );\n    }\n\n    namespace StdString {\n\n        inline std::string makeString( std::string const& str ) { return str; }\n        inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }\n\n        struct CasedString\n        {\n            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )\n            :   m_caseSensitivity( caseSensitivity ),\n                m_str( adjustString( str ) )\n            {}\n            std::string adjustString( std::string const& str ) const {\n                return m_caseSensitivity == CaseSensitive::No\n                    ? toLower( str )\n                    : str;\n\n            }\n            std::string toStringSuffix() const\n            {\n                return m_caseSensitivity == CaseSensitive::No\n                    ? \" (case insensitive)\"\n                    : \"\";\n            }\n            CaseSensitive::Choice m_caseSensitivity;\n            std::string m_str;\n        };\n\n        struct Equals : MatcherImpl<Equals, std::string> {\n            Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            :   m_data( str, caseSensitivity )\n            {}\n            Equals( Equals const& other ) : m_data( other.m_data ){}\n\n            virtual ~Equals();\n\n            virtual bool match( std::string const& expr ) const {\n                return m_data.m_str == m_data.adjustString( expr );;\n            }\n            virtual std::string toString() const {\n                return \"equals: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct Contains : MatcherImpl<Contains, std::string> {\n            Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n            Contains( Contains const& other ) : m_data( other.m_data ){}\n\n            virtual ~Contains();\n\n            virtual bool match( std::string const& expr ) const {\n                return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;\n            }\n            virtual std::string toString() const {\n                return \"contains: \\\"\" + m_data.m_str  + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct StartsWith : MatcherImpl<StartsWith, std::string> {\n            StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n\n            StartsWith( StartsWith const& other ) : m_data( other.m_data ){}\n\n            virtual ~StartsWith();\n\n            virtual bool match( std::string const& expr ) const {\n                return startsWith( m_data.adjustString( expr ), m_data.m_str );\n            }\n            virtual std::string toString() const {\n                return \"starts with: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n\n        struct EndsWith : MatcherImpl<EndsWith, std::string> {\n            EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )\n            : m_data( substr, caseSensitivity ){}\n            EndsWith( EndsWith const& other ) : m_data( other.m_data ){}\n\n            virtual ~EndsWith();\n\n            virtual bool match( std::string const& expr ) const {\n                return endsWith( m_data.adjustString( expr ), m_data.m_str );\n            }\n            virtual std::string toString() const {\n                return \"ends with: \\\"\" + m_data.m_str + \"\\\"\" + m_data.toStringSuffix();\n            }\n\n            CasedString m_data;\n        };\n    } // namespace StdString\n    } // namespace Impl\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n    template<typename ExpressionT>\n    inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {\n        return Impl::Generic::Not<ExpressionT>( m );\n    }\n\n    template<typename ExpressionT>\n    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2 ) {\n        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2,\n                                                    Impl::Matcher<ExpressionT> const& m3 ) {\n        return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2 ) {\n        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );\n    }\n    template<typename ExpressionT>\n    inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,\n                                                    Impl::Matcher<ExpressionT> const& m2,\n                                                    Impl::Matcher<ExpressionT> const& m3 ) {\n        return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );\n    }\n\n    inline Impl::StdString::Equals      Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Equals( str, caseSensitivity );\n    }\n    inline Impl::StdString::Equals      Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );\n    }\n    inline Impl::StdString::Contains    Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Contains( substr, caseSensitivity );\n    }\n    inline Impl::StdString::Contains    Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {\n        return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );\n    }\n    inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {\n        return Impl::StdString::StartsWith( substr );\n    }\n    inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {\n        return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );\n    }\n    inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {\n        return Impl::StdString::EndsWith( substr );\n    }\n    inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {\n        return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );\n    }\n\n} // namespace Matchers\n\nusing namespace Matchers;\n\n} // namespace Catch\n\nnamespace Catch {\n\n    struct TestFailureException{};\n\n    template<typename T> class ExpressionLhs;\n\n    struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;\n\n    struct CopyableStream {\n        CopyableStream() {}\n        CopyableStream( CopyableStream const& other ) {\n            oss << other.oss.str();\n        }\n        CopyableStream& operator=( CopyableStream const& other ) {\n            oss.str(\"\");\n            oss << other.oss.str();\n            return *this;\n        }\n        std::ostringstream oss;\n    };\n\n    class ResultBuilder {\n    public:\n        ResultBuilder(  char const* macroName,\n                        SourceLineInfo const& lineInfo,\n                        char const* capturedExpression,\n                        ResultDisposition::Flags resultDisposition,\n                        char const* secondArg = \"\" );\n\n        template<typename T>\n        ExpressionLhs<T const&> operator <= ( T const& operand );\n        ExpressionLhs<bool> operator <= ( bool value );\n\n        template<typename T>\n        ResultBuilder& operator << ( T const& value ) {\n            m_stream.oss << value;\n            return *this;\n        }\n\n        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );\n        template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );\n\n        ResultBuilder& setResultType( ResultWas::OfType result );\n        ResultBuilder& setResultType( bool result );\n        ResultBuilder& setLhs( std::string const& lhs );\n        ResultBuilder& setRhs( std::string const& rhs );\n        ResultBuilder& setOp( std::string const& op );\n\n        void endExpression();\n\n        std::string reconstructExpression() const;\n        AssertionResult build() const;\n\n        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );\n        void captureResult( ResultWas::OfType resultType );\n        void captureExpression();\n        void captureExpectedException( std::string const& expectedMessage );\n        void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );\n        void handleResult( AssertionResult const& result );\n        void react();\n        bool shouldDebugBreak() const;\n        bool allowThrows() const;\n\n    private:\n        AssertionInfo m_assertionInfo;\n        AssertionResultData m_data;\n        struct ExprComponents {\n            ExprComponents() : testFalse( false ) {}\n            bool testFalse;\n            std::string lhs, rhs, op;\n        } m_exprComponents;\n        CopyableStream m_stream;\n\n        bool m_shouldDebugBreak;\n        bool m_shouldThrow;\n    };\n\n} // namespace Catch\n\n// Include after due to circular dependency:\n// #included from: catch_expression_lhs.hpp\n#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED\n\n// #included from: catch_evaluate.hpp\n#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4389) // '==' : signed/unsigned mismatch\n#endif\n\n#include <cstddef>\n\nnamespace Catch {\nnamespace Internal {\n\n    enum Operator {\n        IsEqualTo,\n        IsNotEqualTo,\n        IsLessThan,\n        IsGreaterThan,\n        IsLessThanOrEqualTo,\n        IsGreaterThanOrEqualTo\n    };\n\n    template<Operator Op> struct OperatorTraits             { static const char* getName(){ return \"*error*\"; } };\n    template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return \"==\"; } };\n    template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return \"!=\"; } };\n    template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return \"<\"; } };\n    template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return \">\"; } };\n    template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return \"<=\"; } };\n    template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return \">=\"; } };\n\n    template<typename T>\n    inline T& opCast(T const& t) { return const_cast<T&>(t); }\n\n// nullptr_t support based on pull request #154 from Konstantin Baumann\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }\n#endif // CATCH_CONFIG_CPP11_NULLPTR\n\n    // So the compare overloads can be operator agnostic we convey the operator as a template\n    // enum, which is used to specialise an Evaluator for doing the comparison.\n    template<typename T1, typename T2, Operator Op>\n    class Evaluator{};\n\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs) {\n            return bool( opCast( lhs ) ==  opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsNotEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) != opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsLessThan> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) < opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsGreaterThan> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) > opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) >= opCast( rhs ) );\n        }\n    };\n    template<typename T1, typename T2>\n    struct Evaluator<T1, T2, IsLessThanOrEqualTo> {\n        static bool evaluate( T1 const& lhs, T2 const& rhs ) {\n            return bool( opCast( lhs ) <= opCast( rhs ) );\n        }\n    };\n\n    template<Operator Op, typename T1, typename T2>\n    bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {\n        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );\n    }\n\n    // This level of indirection allows us to specialise for integer types\n    // to avoid signed/ unsigned warnings\n\n    // \"base\" overload\n    template<Operator Op, typename T1, typename T2>\n    bool compare( T1 const& lhs, T2 const& rhs ) {\n        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );\n    }\n\n    // unsigned X to int\n    template<Operator Op> bool compare( unsigned int lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned long lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned char lhs, int rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );\n    }\n\n    // unsigned X to long\n    template<Operator Op> bool compare( unsigned int lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned long lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n    template<Operator Op> bool compare( unsigned char lhs, long rhs ) {\n        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );\n    }\n\n    // int to unsigned X\n    template<Operator Op> bool compare( int lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( int lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( int lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );\n    }\n\n    // long to unsigned X\n    template<Operator Op> bool compare( long lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n\n    // pointer to long (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n\n    // pointer to int (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\n    // long long to unsigned X\n    template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {\n        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );\n    }\n\n    // unsigned long long to X\n    template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n    template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {\n        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );\n    }\n\n    // pointer to long long (when comparing against NULL)\n    template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );\n    }\n#endif // CATCH_CONFIG_CPP11_LONG_LONG\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\n    // pointer to nullptr_t (when comparing against nullptr)\n    template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {\n        return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );\n    }\n    template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {\n        return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );\n    }\n#endif // CATCH_CONFIG_CPP11_NULLPTR\n\n} // end of namespace Internal\n} // end of namespace Catch\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// #included from: catch_tostring.h\n#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED\n\n#include <sstream>\n#include <iomanip>\n#include <limits>\n#include <vector>\n#include <cstddef>\n\n#ifdef __OBJC__\n// #included from: catch_objc_arc.hpp\n#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED\n\n#import <Foundation/Foundation.h>\n\n#ifdef __has_feature\n#define CATCH_ARC_ENABLED __has_feature(objc_arc)\n#else\n#define CATCH_ARC_ENABLED 0\n#endif\n\nvoid arcSafeRelease( NSObject* obj );\nid performOptionalSelector( id obj, SEL sel );\n\n#if !CATCH_ARC_ENABLED\ninline void arcSafeRelease( NSObject* obj ) {\n    [obj release];\n}\ninline id performOptionalSelector( id obj, SEL sel ) {\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED\n#define CATCH_ARC_STRONG\n#else\ninline void arcSafeRelease( NSObject* ){}\ninline id performOptionalSelector( id obj, SEL sel ) {\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#endif\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained\n#define CATCH_ARC_STRONG __strong\n#endif\n\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_TUPLE\n#include <tuple>\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_IS_ENUM\n#include <type_traits>\n#endif\n\nnamespace Catch {\n\n// Why we're here.\ntemplate<typename T>\nstd::string toString( T const& value );\n\n// Built in overloads\n\nstd::string toString( std::string const& value );\nstd::string toString( std::wstring const& value );\nstd::string toString( const char* const value );\nstd::string toString( char* const value );\nstd::string toString( const wchar_t* const value );\nstd::string toString( wchar_t* const value );\nstd::string toString( int value );\nstd::string toString( unsigned long value );\nstd::string toString( unsigned int value );\nstd::string toString( const double value );\nstd::string toString( const float value );\nstd::string toString( bool value );\nstd::string toString( char value );\nstd::string toString( signed char value );\nstd::string toString( unsigned char value );\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\nstd::string toString( long long value );\nstd::string toString( unsigned long long value );\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\nstd::string toString( std::nullptr_t );\n#endif\n\n#ifdef __OBJC__\n    std::string toString( NSString const * const& nsstring );\n    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );\n    std::string toString( NSObject* const& nsObject );\n#endif\n\nnamespace Detail {\n\n    extern const std::string unprintableString;\n\n    struct BorgType {\n        template<typename T> BorgType( T const& );\n    };\n\n    struct TrueType { char sizer[1]; };\n    struct FalseType { char sizer[2]; };\n\n    TrueType& testStreamable( std::ostream& );\n    FalseType testStreamable( FalseType );\n\n    FalseType operator<<( std::ostream const&, BorgType const& );\n\n    template<typename T>\n    struct IsStreamInsertable {\n        static std::ostream &s;\n        static T  const&t;\n        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };\n    };\n\n#if defined(CATCH_CONFIG_CPP11_IS_ENUM)\n    template<typename T,\n             bool IsEnum = std::is_enum<T>::value\n             >\n    struct EnumStringMaker\n    {\n        static std::string convert( T const& ) { return unprintableString; }\n    };\n\n    template<typename T>\n    struct EnumStringMaker<T,true>\n    {\n        static std::string convert( T const& v )\n        {\n            return ::Catch::toString(\n                static_cast<typename std::underlying_type<T>::type>(v)\n                );\n        }\n    };\n#endif\n    template<bool C>\n    struct StringMakerBase {\n#if defined(CATCH_CONFIG_CPP11_IS_ENUM)\n        template<typename T>\n        static std::string convert( T const& v )\n        {\n            return EnumStringMaker<T>::convert( v );\n        }\n#else\n        template<typename T>\n        static std::string convert( T const& ) { return unprintableString; }\n#endif\n    };\n\n    template<>\n    struct StringMakerBase<true> {\n        template<typename T>\n        static std::string convert( T const& _value ) {\n            std::ostringstream oss;\n            oss << _value;\n            return oss.str();\n        }\n    };\n\n    std::string rawMemoryToString( const void *object, std::size_t size );\n\n    template<typename T>\n    inline std::string rawMemoryToString( const T& object ) {\n      return rawMemoryToString( &object, sizeof(object) );\n    }\n\n} // end namespace Detail\n\ntemplate<typename T>\nstruct StringMaker :\n    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};\n\ntemplate<typename T>\nstruct StringMaker<T*> {\n    template<typename U>\n    static std::string convert( U* p ) {\n        if( !p )\n            return \"NULL\";\n        else\n            return Detail::rawMemoryToString( p );\n    }\n};\n\ntemplate<typename R, typename C>\nstruct StringMaker<R C::*> {\n    static std::string convert( R C::* p ) {\n        if( !p )\n            return \"NULL\";\n        else\n            return Detail::rawMemoryToString( p );\n    }\n};\n\nnamespace Detail {\n    template<typename InputIterator>\n    std::string rangeToString( InputIterator first, InputIterator last );\n}\n\n//template<typename T, typename Allocator>\n//struct StringMaker<std::vector<T, Allocator> > {\n//    static std::string convert( std::vector<T,Allocator> const& v ) {\n//        return Detail::rangeToString( v.begin(), v.end() );\n//    }\n//};\n\ntemplate<typename T, typename Allocator>\nstd::string toString( std::vector<T,Allocator> const& v ) {\n    return Detail::rangeToString( v.begin(), v.end() );\n}\n\n#ifdef CATCH_CONFIG_CPP11_TUPLE\n\n// toString for tuples\nnamespace TupleDetail {\n  template<\n      typename Tuple,\n      std::size_t N = 0,\n      bool = (N < std::tuple_size<Tuple>::value)\n      >\n  struct ElementPrinter {\n      static void print( const Tuple& tuple, std::ostream& os )\n      {\n          os << ( N ? \", \" : \" \" )\n             << Catch::toString(std::get<N>(tuple));\n          ElementPrinter<Tuple,N+1>::print(tuple,os);\n      }\n  };\n\n  template<\n      typename Tuple,\n      std::size_t N\n      >\n  struct ElementPrinter<Tuple,N,false> {\n      static void print( const Tuple&, std::ostream& ) {}\n  };\n\n}\n\ntemplate<typename ...Types>\nstruct StringMaker<std::tuple<Types...>> {\n\n    static std::string convert( const std::tuple<Types...>& tuple )\n    {\n        std::ostringstream os;\n        os << '{';\n        TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );\n        os << \" }\";\n        return os.str();\n    }\n};\n#endif // CATCH_CONFIG_CPP11_TUPLE\n\nnamespace Detail {\n    template<typename T>\n    std::string makeString( T const& value ) {\n        return StringMaker<T>::convert( value );\n    }\n} // end namespace Detail\n\n/// \\brief converts any type to a string\n///\n/// The default template forwards on to ostringstream - except when an\n/// ostringstream overload does not exist - in which case it attempts to detect\n/// that and writes {?}.\n/// Overload (not specialise) this template for custom typs that you don't want\n/// to provide an ostream overload for.\ntemplate<typename T>\nstd::string toString( T const& value ) {\n    return StringMaker<T>::convert( value );\n}\n\n    namespace Detail {\n    template<typename InputIterator>\n    std::string rangeToString( InputIterator first, InputIterator last ) {\n        std::ostringstream oss;\n        oss << \"{ \";\n        if( first != last ) {\n            oss << Catch::toString( *first );\n            for( ++first ; first != last ; ++first )\n                oss << \", \" << Catch::toString( *first );\n        }\n        oss << \" }\";\n        return oss.str();\n    }\n}\n\n} // end namespace Catch\n\nnamespace Catch {\n\n// Wraps the LHS of an expression and captures the operator and RHS (if any) -\n// wrapping them all in a ResultBuilder object\ntemplate<typename T>\nclass ExpressionLhs {\n    ExpressionLhs& operator = ( ExpressionLhs const& );\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n    ExpressionLhs& operator = ( ExpressionLhs && ) = delete;\n#  endif\n\npublic:\n    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n    ExpressionLhs( ExpressionLhs const& ) = default;\n    ExpressionLhs( ExpressionLhs && )     = default;\n#  endif\n\n    template<typename RhsT>\n    ResultBuilder& operator == ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator != ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsNotEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator < ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsLessThan>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator > ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsGreaterThan>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator <= ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );\n    }\n\n    template<typename RhsT>\n    ResultBuilder& operator >= ( RhsT const& rhs ) {\n        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );\n    }\n\n    ResultBuilder& operator == ( bool rhs ) {\n        return captureExpression<Internal::IsEqualTo>( rhs );\n    }\n\n    ResultBuilder& operator != ( bool rhs ) {\n        return captureExpression<Internal::IsNotEqualTo>( rhs );\n    }\n\n    void endExpression() {\n        bool value = m_lhs ? true : false;\n        m_rb\n            .setLhs( Catch::toString( value ) )\n            .setResultType( value )\n            .endExpression();\n    }\n\n    // Only simple binary expressions are allowed on the LHS.\n    // If more complex compositions are required then place the sub expression in parentheses\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );\n    template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );\n\nprivate:\n    template<Internal::Operator Op, typename RhsT>\n    ResultBuilder& captureExpression( RhsT const& rhs ) {\n        return m_rb\n            .setResultType( Internal::compare<Op>( m_lhs, rhs ) )\n            .setLhs( Catch::toString( m_lhs ) )\n            .setRhs( Catch::toString( rhs ) )\n            .setOp( Internal::OperatorTraits<Op>::getName() );\n    }\n\nprivate:\n    ResultBuilder& m_rb;\n    T m_lhs;\n};\n\n} // end namespace Catch\n\n\nnamespace Catch {\n\n    template<typename T>\n    inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {\n        return ExpressionLhs<T const&>( *this, operand );\n    }\n\n    inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {\n        return ExpressionLhs<bool>( *this, value );\n    }\n\n} // namespace Catch\n\n// #included from: catch_message.h\n#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct MessageInfo {\n        MessageInfo(    std::string const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        ResultWas::OfType _type );\n\n        std::string macroName;\n        SourceLineInfo lineInfo;\n        ResultWas::OfType type;\n        std::string message;\n        unsigned int sequence;\n\n        bool operator == ( MessageInfo const& other ) const {\n            return sequence == other.sequence;\n        }\n        bool operator < ( MessageInfo const& other ) const {\n            return sequence < other.sequence;\n        }\n    private:\n        static unsigned int globalCount;\n    };\n\n    struct MessageBuilder {\n        MessageBuilder( std::string const& macroName,\n                        SourceLineInfo const& lineInfo,\n                        ResultWas::OfType type )\n        : m_info( macroName, lineInfo, type )\n        {}\n\n        template<typename T>\n        MessageBuilder& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        MessageInfo m_info;\n        std::ostringstream m_stream;\n    };\n\n    class ScopedMessage {\n    public:\n        ScopedMessage( MessageBuilder const& builder );\n        ScopedMessage( ScopedMessage const& other );\n        ~ScopedMessage();\n\n        MessageInfo m_info;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_interfaces_capture.h\n#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    class TestCase;\n    class AssertionResult;\n    struct AssertionInfo;\n    struct SectionInfo;\n    struct SectionEndInfo;\n    struct MessageInfo;\n    class ScopedMessageBuilder;\n    struct Counts;\n\n    struct IResultCapture {\n\n        virtual ~IResultCapture();\n\n        virtual void assertionEnded( AssertionResult const& result ) = 0;\n        virtual bool sectionStarted(    SectionInfo const& sectionInfo,\n                                        Counts& assertions ) = 0;\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;\n        virtual void pushScopedMessage( MessageInfo const& message ) = 0;\n        virtual void popScopedMessage( MessageInfo const& message ) = 0;\n\n        virtual std::string getCurrentTestName() const = 0;\n        virtual const AssertionResult* getLastResult() const = 0;\n\n        virtual void handleFatalErrorCondition( std::string const& message ) = 0;\n    };\n\n    IResultCapture& getResultCapture();\n}\n\n// #included from: catch_debugger.h\n#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED\n\n// #included from: catch_platform.h\n#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED\n\n#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)\n#  define CATCH_PLATFORM_MAC\n#elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)\n#  define CATCH_PLATFORM_IPHONE\n#elif defined(linux) || defined(__linux) || defined(__linux__)\n#  define CATCH_PLATFORM_LINUX\n#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)\n#  define CATCH_PLATFORM_WINDOWS\n#  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)\n#    define CATCH_DEFINES_NOMINMAX\n#  endif\n#  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)\n#    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  endif\n#endif\n\n#include <string>\n\nnamespace Catch{\n\n    bool isDebuggerActive();\n    void writeToDebugConsole( std::string const& text );\n}\n\n#ifdef CATCH_PLATFORM_MAC\n\n    // The following code snippet based on:\n    // http://cocoawithlove.com/2008/03/break-into-debugger.html\n    #ifdef DEBUG\n        #if defined(__ppc64__) || defined(__ppc__)\n            #define CATCH_TRAP() \\\n                    __asm__(\"li r0, 20\\nsc\\nnop\\nli r0, 37\\nli r4, 2\\nsc\\nnop\\n\" \\\n                    : : : \"memory\",\"r0\",\"r3\",\"r4\" )\n        #else\n            #define CATCH_TRAP() _asm__(\"int $3\\n\" : : )\n        #endif\n    #endif\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    // If we can use inline assembler, do it because this allows us to break\n    // directly at the location of the failing check instead of breaking inside\n    // raise() called from it, i.e. one stack frame below.\n    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n        #define CATCH_TRAP() asm volatile (\"int $3\")\n    #else // Fall back to the generic way.\n        #include <signal.h>\n\n        #define CATCH_TRAP() raise(SIGTRAP)\n    #endif\n#elif defined(_MSC_VER)\n    #define CATCH_TRAP() __debugbreak()\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\n    #define CATCH_TRAP() DebugBreak()\n#endif\n\n#ifdef CATCH_TRAP\n    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }\n#else\n    #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();\n#endif\n\n// #included from: catch_interfaces_runner.h\n#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED\n\nnamespace Catch {\n    class TestCase;\n\n    struct IRunner {\n        virtual ~IRunner();\n        virtual bool aborting() const = 0;\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// In the event of a failure works out if the debugger needs to be invoked\n// and/or an exception thrown and takes appropriate action.\n// This needs to be done as a macro so the debugger will stop in the user\n// source code rather than in Catch library code\n#define INTERNAL_CATCH_REACT( resultBuilder ) \\\n    if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \\\n    resultBuilder.react();\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        try { \\\n            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n            ( __catchResult <= expr ).endExpression(); \\\n        } \\\n        catch( ... ) { \\\n            __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \\\n    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \\\n    if( Catch::getResultCapture().getLastResult()->succeeded() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \\\n    INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \\\n    if( !Catch::getResultCapture().getLastResult()->succeeded() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        try { \\\n            expr; \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        } \\\n        catch( ... ) { \\\n            __catchResult.useActiveException( resultDisposition ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \\\n        if( __catchResult.allowThrows() ) \\\n            try { \\\n                expr; \\\n                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \\\n            } \\\n            catch( ... ) { \\\n                __catchResult.captureExpectedException( matcher ); \\\n            } \\\n        else \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \\\n        if( __catchResult.allowThrows() ) \\\n            try { \\\n                expr; \\\n                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \\\n            } \\\n            catch( exceptionType ) { \\\n                __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n            } \\\n            catch( ... ) { \\\n                __catchResult.useActiveException( resultDisposition ); \\\n            } \\\n        else \\\n            __catchResult.captureResult( Catch::ResultWas::Ok ); \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n///////////////////////////////////////////////////////////////////////////////\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \\\n        do { \\\n            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, \"\", resultDisposition ); \\\n            __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \\\n            __catchResult.captureResult( messageType ); \\\n            INTERNAL_CATCH_REACT( __catchResult ) \\\n        } while( Catch::alwaysFalse() )\n#else\n    #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \\\n        do { \\\n            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, \"\", resultDisposition ); \\\n            __catchResult << log + ::Catch::StreamEndStop(); \\\n            __catchResult.captureResult( messageType ); \\\n            INTERNAL_CATCH_REACT( __catchResult ) \\\n        } while( Catch::alwaysFalse() )\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_INFO( log, macroName ) \\\n    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \\\n    do { \\\n        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg \", \" #matcher, resultDisposition ); \\\n        try { \\\n            std::string matcherAsString = (matcher).toString(); \\\n            __catchResult \\\n                .setLhs( Catch::toString( arg ) ) \\\n                .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \\\n                .setOp( \"matches\" ) \\\n                .setResultType( (matcher).match( arg ) ); \\\n            __catchResult.captureExpression(); \\\n        } catch( ... ) { \\\n            __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \\\n        } \\\n        INTERNAL_CATCH_REACT( __catchResult ) \\\n    } while( Catch::alwaysFalse() )\n\n// #included from: internal/catch_section.h\n#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED\n\n// #included from: catch_section_info.h\n#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED\n\n// #included from: catch_totals.hpp\n#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED\n\n#include <cstddef>\n\nnamespace Catch {\n\n    struct Counts {\n        Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}\n\n        Counts operator - ( Counts const& other ) const {\n            Counts diff;\n            diff.passed = passed - other.passed;\n            diff.failed = failed - other.failed;\n            diff.failedButOk = failedButOk - other.failedButOk;\n            return diff;\n        }\n        Counts& operator += ( Counts const& other ) {\n            passed += other.passed;\n            failed += other.failed;\n            failedButOk += other.failedButOk;\n            return *this;\n        }\n\n        std::size_t total() const {\n            return passed + failed + failedButOk;\n        }\n        bool allPassed() const {\n            return failed == 0 && failedButOk == 0;\n        }\n        bool allOk() const {\n            return failed == 0;\n        }\n\n        std::size_t passed;\n        std::size_t failed;\n        std::size_t failedButOk;\n    };\n\n    struct Totals {\n\n        Totals operator - ( Totals const& other ) const {\n            Totals diff;\n            diff.assertions = assertions - other.assertions;\n            diff.testCases = testCases - other.testCases;\n            return diff;\n        }\n\n        Totals delta( Totals const& prevTotals ) const {\n            Totals diff = *this - prevTotals;\n            if( diff.assertions.failed > 0 )\n                ++diff.testCases.failed;\n            else if( diff.assertions.failedButOk > 0 )\n                ++diff.testCases.failedButOk;\n            else\n                ++diff.testCases.passed;\n            return diff;\n        }\n\n        Totals& operator += ( Totals const& other ) {\n            assertions += other.assertions;\n            testCases += other.testCases;\n            return *this;\n        }\n\n        Counts assertions;\n        Counts testCases;\n    };\n}\n\nnamespace Catch {\n\n    struct SectionInfo {\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name,\n                std::string const& _description = std::string() );\n\n        std::string name;\n        std::string description;\n        SourceLineInfo lineInfo;\n    };\n\n    struct SectionEndInfo {\n        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )\n        : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )\n        {}\n\n        SectionInfo sectionInfo;\n        Counts prevAssertions;\n        double durationInSeconds;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_timer.h\n#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED\n\n#ifdef CATCH_PLATFORM_WINDOWS\ntypedef unsigned long long uint64_t;\n#else\n#include <stdint.h>\n#endif\n\nnamespace Catch {\n\n    class Timer {\n    public:\n        Timer() : m_ticks( 0 ) {}\n        void start();\n        unsigned int getElapsedMicroseconds() const;\n        unsigned int getElapsedMilliseconds() const;\n        double getElapsedSeconds() const;\n\n    private:\n        uint64_t m_ticks;\n    };\n\n} // namespace Catch\n\n#include <string>\n\nnamespace Catch {\n\n    class Section : NonCopyable {\n    public:\n        Section( SectionInfo const& info );\n        ~Section();\n\n        // This indicates whether the section should be executed or not\n        operator bool() const;\n\n    private:\n        SectionInfo m_info;\n\n        std::string m_name;\n        Counts m_assertions;\n        bool m_sectionIncluded;\n        Timer m_timer;\n    };\n\n} // end namespace Catch\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define INTERNAL_CATCH_SECTION( ... ) \\\n        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )\n#else\n    #define INTERNAL_CATCH_SECTION( name, desc ) \\\n        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )\n#endif\n\n// #included from: internal/catch_generators.hpp\n#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED\n\n#include <iterator>\n#include <vector>\n#include <string>\n#include <stdlib.h>\n\nnamespace Catch {\n\ntemplate<typename T>\nstruct IGenerator {\n    virtual ~IGenerator() {}\n    virtual T getValue( std::size_t index ) const = 0;\n    virtual std::size_t size () const = 0;\n};\n\ntemplate<typename T>\nclass BetweenGenerator : public IGenerator<T> {\npublic:\n    BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}\n\n    virtual T getValue( std::size_t index ) const {\n        return m_from+static_cast<int>( index );\n    }\n\n    virtual std::size_t size() const {\n        return static_cast<std::size_t>( 1+m_to-m_from );\n    }\n\nprivate:\n\n    T m_from;\n    T m_to;\n};\n\ntemplate<typename T>\nclass ValuesGenerator : public IGenerator<T> {\npublic:\n    ValuesGenerator(){}\n\n    void add( T value ) {\n        m_values.push_back( value );\n    }\n\n    virtual T getValue( std::size_t index ) const {\n        return m_values[index];\n    }\n\n    virtual std::size_t size() const {\n        return m_values.size();\n    }\n\nprivate:\n    std::vector<T> m_values;\n};\n\ntemplate<typename T>\nclass CompositeGenerator {\npublic:\n    CompositeGenerator() : m_totalSize( 0 ) {}\n\n    // *** Move semantics, similar to auto_ptr ***\n    CompositeGenerator( CompositeGenerator& other )\n    :   m_fileInfo( other.m_fileInfo ),\n        m_totalSize( 0 )\n    {\n        move( other );\n    }\n\n    CompositeGenerator& setFileInfo( const char* fileInfo ) {\n        m_fileInfo = fileInfo;\n        return *this;\n    }\n\n    ~CompositeGenerator() {\n        deleteAll( m_composed );\n    }\n\n    operator T () const {\n        size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );\n\n        typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();\n        typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();\n        for( size_t index = 0; it != itEnd; ++it )\n        {\n            const IGenerator<T>* generator = *it;\n            if( overallIndex >= index && overallIndex < index + generator->size() )\n            {\n                return generator->getValue( overallIndex-index );\n            }\n            index += generator->size();\n        }\n        CATCH_INTERNAL_ERROR( \"Indexed past end of generated range\" );\n        return T(); // Suppress spurious \"not all control paths return a value\" warning in Visual Studio - if you know how to fix this please do so\n    }\n\n    void add( const IGenerator<T>* generator ) {\n        m_totalSize += generator->size();\n        m_composed.push_back( generator );\n    }\n\n    CompositeGenerator& then( CompositeGenerator& other ) {\n        move( other );\n        return *this;\n    }\n\n    CompositeGenerator& then( T value ) {\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( value );\n        add( valuesGen );\n        return *this;\n    }\n\nprivate:\n\n    void move( CompositeGenerator& other ) {\n        std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );\n        m_totalSize += other.m_totalSize;\n        other.m_composed.clear();\n    }\n\n    std::vector<const IGenerator<T>*> m_composed;\n    std::string m_fileInfo;\n    size_t m_totalSize;\n};\n\nnamespace Generators\n{\n    template<typename T>\n    CompositeGenerator<T> between( T from, T to ) {\n        CompositeGenerator<T> generators;\n        generators.add( new BetweenGenerator<T>( from, to ) );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2 ) {\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2, T val3 ){\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        valuesGen->add( val3 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n    template<typename T>\n    CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {\n        CompositeGenerator<T> generators;\n        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();\n        valuesGen->add( val1 );\n        valuesGen->add( val2 );\n        valuesGen->add( val3 );\n        valuesGen->add( val4 );\n        generators.add( valuesGen );\n        return generators;\n    }\n\n} // end namespace Generators\n\nusing namespace Generators;\n\n} // end namespace Catch\n\n#define INTERNAL_CATCH_LINESTR2( line ) #line\n#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )\n\n#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ \"(\" INTERNAL_CATCH_LINESTR( __LINE__ ) \")\" )\n\n// #included from: internal/catch_interfaces_exception.h\n#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED\n\n#include <string>\n#include <vector>\n\n// #included from: catch_interfaces_registry_hub.h\n#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    class TestCase;\n    struct ITestCaseRegistry;\n    struct IExceptionTranslatorRegistry;\n    struct IExceptionTranslator;\n    struct IReporterRegistry;\n    struct IReporterFactory;\n\n    struct IRegistryHub {\n        virtual ~IRegistryHub();\n\n        virtual IReporterRegistry const& getReporterRegistry() const = 0;\n        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;\n        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;\n    };\n\n    struct IMutableRegistryHub {\n        virtual ~IMutableRegistryHub();\n        virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;\n        virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;\n        virtual void registerTest( TestCase const& testInfo ) = 0;\n        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;\n    };\n\n    IRegistryHub& getRegistryHub();\n    IMutableRegistryHub& getMutableRegistryHub();\n    void cleanUp();\n    std::string translateActiveException();\n\n}\n\nnamespace Catch {\n\n    typedef std::string(*exceptionTranslateFunction)();\n\n    struct IExceptionTranslator;\n    typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;\n\n    struct IExceptionTranslator {\n        virtual ~IExceptionTranslator();\n        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;\n    };\n\n    struct IExceptionTranslatorRegistry {\n        virtual ~IExceptionTranslatorRegistry();\n\n        virtual std::string translateActiveException() const = 0;\n    };\n\n    class ExceptionTranslatorRegistrar {\n        template<typename T>\n        class ExceptionTranslator : public IExceptionTranslator {\n        public:\n\n            ExceptionTranslator( std::string(*translateFunction)( T& ) )\n            : m_translateFunction( translateFunction )\n            {}\n\n            virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {\n                try {\n                    if( it == itEnd )\n                        throw;\n                    else\n                        return (*it)->translate( it+1, itEnd );\n                }\n                catch( T& ex ) {\n                    return m_translateFunction( ex );\n                }\n            }\n\n        protected:\n            std::string(*m_translateFunction)( T& );\n        };\n\n    public:\n        template<typename T>\n        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {\n            getMutableRegistryHub().registerTranslator\n                ( new ExceptionTranslator<T>( translateFunction ) );\n        }\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \\\n    static std::string translatorName( signature ); \\\n    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\\\n    static std::string translatorName( signature )\n\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// #included from: internal/catch_approx.hpp\n#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED\n\n#include <cmath>\n#include <limits>\n\nnamespace Catch {\nnamespace Detail {\n\n    class Approx {\n    public:\n        explicit Approx ( double value )\n        :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),\n            m_scale( 1.0 ),\n            m_value( value )\n        {}\n\n        Approx( Approx const& other )\n        :   m_epsilon( other.m_epsilon ),\n            m_scale( other.m_scale ),\n            m_value( other.m_value )\n        {}\n\n        static Approx custom() {\n            return Approx( 0 );\n        }\n\n        Approx operator()( double value ) {\n            Approx approx( value );\n            approx.epsilon( m_epsilon );\n            approx.scale( m_scale );\n            return approx;\n        }\n\n        friend bool operator == ( double lhs, Approx const& rhs ) {\n            // Thanks to Richard Harris for his help refining this formula\n            return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );\n        }\n\n        friend bool operator == ( Approx const& lhs, double rhs ) {\n            return operator==( rhs, lhs );\n        }\n\n        friend bool operator != ( double lhs, Approx const& rhs ) {\n            return !operator==( lhs, rhs );\n        }\n\n        friend bool operator != ( Approx const& lhs, double rhs ) {\n            return !operator==( rhs, lhs );\n        }\n\n        friend bool operator <= ( double lhs, Approx const& rhs )\n        {\n          return lhs < rhs.m_value || lhs == rhs;\n        }\n\n        friend bool operator <= ( Approx const& lhs, double rhs )\n        {\n          return lhs.m_value < rhs || lhs == rhs;\n        }\n\n        friend bool operator >= ( double lhs, Approx const& rhs )\n        {\n          return lhs > rhs.m_value || lhs == rhs;\n        }\n\n        friend bool operator >= ( Approx const& lhs, double rhs )\n        {\n          return lhs.m_value > rhs || lhs == rhs;\n        }\n\n        Approx& epsilon( double newEpsilon ) {\n            m_epsilon = newEpsilon;\n            return *this;\n        }\n\n        Approx& scale( double newScale ) {\n            m_scale = newScale;\n            return *this;\n        }\n\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << \"Approx( \" << Catch::toString( m_value ) << \" )\";\n            return oss.str();\n        }\n\n    private:\n        double m_epsilon;\n        double m_scale;\n        double m_value;\n    };\n}\n\ntemplate<>\ninline std::string toString<Detail::Approx>( Detail::Approx const& value ) {\n    return value.toString();\n}\n\n} // end namespace Catch\n\n// #included from: internal/catch_interfaces_tag_alias_registry.h\n#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED\n\n// #included from: catch_tag_alias.h\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias {\n        TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}\n\n        std::string tag;\n        SourceLineInfo lineInfo;\n    };\n\n    struct RegistrarForTagAliases {\n        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n    };\n\n} // end namespace Catch\n\n#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }\n// #included from: catch_option.hpp\n#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED\n\nnamespace Catch {\n\n    // An optional type\n    template<typename T>\n    class Option {\n    public:\n        Option() : nullableValue( CATCH_NULL ) {}\n        Option( T const& _value )\n        : nullableValue( new( storage ) T( _value ) )\n        {}\n        Option( Option const& _other )\n        : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )\n        {}\n\n        ~Option() {\n            reset();\n        }\n\n        Option& operator= ( Option const& _other ) {\n            if( &_other != this ) {\n                reset();\n                if( _other )\n                    nullableValue = new( storage ) T( *_other );\n            }\n            return *this;\n        }\n        Option& operator = ( T const& _value ) {\n            reset();\n            nullableValue = new( storage ) T( _value );\n            return *this;\n        }\n\n        void reset() {\n            if( nullableValue )\n                nullableValue->~T();\n            nullableValue = CATCH_NULL;\n        }\n\n        T& operator*() { return *nullableValue; }\n        T const& operator*() const { return *nullableValue; }\n        T* operator->() { return nullableValue; }\n        const T* operator->() const { return nullableValue; }\n\n        T valueOr( T const& defaultValue ) const {\n            return nullableValue ? *nullableValue : defaultValue;\n        }\n\n        bool some() const { return nullableValue != CATCH_NULL; }\n        bool none() const { return nullableValue == CATCH_NULL; }\n\n        bool operator !() const { return nullableValue == CATCH_NULL; }\n        operator SafeBool::type() const {\n            return SafeBool::makeSafe( some() );\n        }\n\n    private:\n        T* nullableValue;\n        char storage[sizeof(T)];\n    };\n\n} // end namespace Catch\n\nnamespace Catch {\n\n    struct ITagAliasRegistry {\n        virtual ~ITagAliasRegistry();\n        virtual Option<TagAlias> find( std::string const& alias ) const = 0;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;\n\n        static ITagAliasRegistry const& get();\n    };\n\n} // end namespace Catch\n\n// These files are included here so the single_include script doesn't put them\n// in the conditionally compiled sections\n// #included from: internal/catch_test_case_info.h\n#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED\n\n#include <string>\n#include <set>\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    struct ITestCase;\n\n    struct TestCaseInfo {\n        enum SpecialProperties{\n            None = 0,\n            IsHidden = 1 << 1,\n            ShouldFail = 1 << 2,\n            MayFail = 1 << 3,\n            Throws = 1 << 4\n        };\n\n        TestCaseInfo(   std::string const& _name,\n                        std::string const& _className,\n                        std::string const& _description,\n                        std::set<std::string> const& _tags,\n                        SourceLineInfo const& _lineInfo );\n\n        TestCaseInfo( TestCaseInfo const& other );\n\n        friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );\n\n        bool isHidden() const;\n        bool throws() const;\n        bool okToFail() const;\n        bool expectedToFail() const;\n\n        std::string name;\n        std::string className;\n        std::string description;\n        std::set<std::string> tags;\n        std::set<std::string> lcaseTags;\n        std::string tagsAsString;\n        SourceLineInfo lineInfo;\n        SpecialProperties properties;\n    };\n\n    class TestCase : public TestCaseInfo {\n    public:\n\n        TestCase( ITestCase* testCase, TestCaseInfo const& info );\n        TestCase( TestCase const& other );\n\n        TestCase withName( std::string const& _newName ) const;\n\n        void invoke() const;\n\n        TestCaseInfo const& getTestCaseInfo() const;\n\n        void swap( TestCase& other );\n        bool operator == ( TestCase const& other ) const;\n        bool operator < ( TestCase const& other ) const;\n        TestCase& operator = ( TestCase const& other );\n\n    private:\n        Ptr<ITestCase> test;\n    };\n\n    TestCase makeTestCase(  ITestCase* testCase,\n                            std::string const& className,\n                            std::string const& name,\n                            std::string const& description,\n                            SourceLineInfo const& lineInfo );\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n\n#ifdef __OBJC__\n// #included from: internal/catch_objc.hpp\n#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED\n\n#import <objc/runtime.h>\n\n#include <string>\n\n// NB. Any general catch headers included here must be included\n// in catch.hpp first to make sure they are included by the single\n// header for non obj-usage\n\n///////////////////////////////////////////////////////////////////////////////\n// This protocol is really only here for (self) documenting purposes, since\n// all its methods are optional.\n@protocol OcFixture\n\n@optional\n\n-(void) setUp;\n-(void) tearDown;\n\n@end\n\nnamespace Catch {\n\n    class OcMethod : public SharedImpl<ITestCase> {\n\n    public:\n        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}\n\n        virtual void invoke() const {\n            id obj = [[m_cls alloc] init];\n\n            performOptionalSelector( obj, @selector(setUp)  );\n            performOptionalSelector( obj, m_sel );\n            performOptionalSelector( obj, @selector(tearDown)  );\n\n            arcSafeRelease( obj );\n        }\n    private:\n        virtual ~OcMethod() {}\n\n        Class m_cls;\n        SEL m_sel;\n    };\n\n    namespace Detail{\n\n        inline std::string getAnnotation(   Class cls,\n                                            std::string const& annotationName,\n                                            std::string const& testCaseName ) {\n            NSString* selStr = [[NSString alloc] initWithFormat:@\"Catch_%s_%s\", annotationName.c_str(), testCaseName.c_str()];\n            SEL sel = NSSelectorFromString( selStr );\n            arcSafeRelease( selStr );\n            id value = performOptionalSelector( cls, sel );\n            if( value )\n                return [(NSString*)value UTF8String];\n            return \"\";\n        }\n    }\n\n    inline size_t registerTestMethods() {\n        size_t noTestMethods = 0;\n        int noClasses = objc_getClassList( CATCH_NULL, 0 );\n\n        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);\n        objc_getClassList( classes, noClasses );\n\n        for( int c = 0; c < noClasses; c++ ) {\n            Class cls = classes[c];\n            {\n                u_int count;\n                Method* methods = class_copyMethodList( cls, &count );\n                for( u_int m = 0; m < count ; m++ ) {\n                    SEL selector = method_getName(methods[m]);\n                    std::string methodName = sel_getName(selector);\n                    if( startsWith( methodName, \"Catch_TestCase_\" ) ) {\n                        std::string testCaseName = methodName.substr( 15 );\n                        std::string name = Detail::getAnnotation( cls, \"Name\", testCaseName );\n                        std::string desc = Detail::getAnnotation( cls, \"Description\", testCaseName );\n                        const char* className = class_getName( cls );\n\n                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );\n                        noTestMethods++;\n                    }\n                }\n                free(methods);\n            }\n        }\n        return noTestMethods;\n    }\n\n    namespace Matchers {\n        namespace Impl {\n        namespace NSStringMatchers {\n\n            template<typename MatcherT>\n            struct StringHolder : MatcherImpl<MatcherT, NSString*>{\n                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}\n                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}\n                StringHolder() {\n                    arcSafeRelease( m_substr );\n                }\n\n                NSString* m_substr;\n            };\n\n            struct Equals : StringHolder<Equals> {\n                Equals( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str isEqualToString:m_substr];\n                }\n\n                virtual std::string toString() const {\n                    return \"equals string: \" + Catch::toString( m_substr );\n                }\n            };\n\n            struct Contains : StringHolder<Contains> {\n                Contains( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location != NSNotFound;\n                }\n\n                virtual std::string toString() const {\n                    return \"contains string: \" + Catch::toString( m_substr );\n                }\n            };\n\n            struct StartsWith : StringHolder<StartsWith> {\n                StartsWith( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == 0;\n                }\n\n                virtual std::string toString() const {\n                    return \"starts with: \" + Catch::toString( m_substr );\n                }\n            };\n            struct EndsWith : StringHolder<EndsWith> {\n                EndsWith( NSString* substr ) : StringHolder( substr ){}\n\n                virtual bool match( ExpressionType const& str ) const {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];\n                }\n\n                virtual std::string toString() const {\n                    return \"ends with: \" + Catch::toString( m_substr );\n                }\n            };\n\n        } // namespace NSStringMatchers\n        } // namespace Impl\n\n        inline Impl::NSStringMatchers::Equals\n            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }\n\n        inline Impl::NSStringMatchers::Contains\n            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }\n\n        inline Impl::NSStringMatchers::StartsWith\n            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }\n\n        inline Impl::NSStringMatchers::EndsWith\n            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }\n\n    } // namespace Matchers\n\n    using namespace Matchers;\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define OC_TEST_CASE( name, desc )\\\n+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \\\n{\\\nreturn @ name; \\\n}\\\n+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \\\n{ \\\nreturn @ desc; \\\n} \\\n-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )\n\n#endif\n\n#ifdef CATCH_IMPL\n// #included from: internal/catch_impl.hpp\n#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED\n\n// Collect all the implementation files together here\n// These are the equivalent of what would usually be cpp files\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#endif\n\n// #included from: ../catch_session.hpp\n#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED\n\n// #included from: internal/catch_commandline.hpp\n#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED\n\n// #included from: catch_config.hpp\n#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED\n\n// #included from: catch_test_spec_parser.hpp\n#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// #included from: catch_test_spec.hpp\n#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// #included from: catch_wildcard_pattern.hpp\n#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED\n\nnamespace Catch\n{\n    class WildcardPattern {\n        enum WildcardPosition {\n            NoWildcard = 0,\n            WildcardAtStart = 1,\n            WildcardAtEnd = 2,\n            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd\n        };\n\n    public:\n\n        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )\n        :   m_caseSensitivity( caseSensitivity ),\n            m_wildcard( NoWildcard ),\n            m_pattern( adjustCase( pattern ) )\n        {\n            if( startsWith( m_pattern, \"*\" ) ) {\n                m_pattern = m_pattern.substr( 1 );\n                m_wildcard = WildcardAtStart;\n            }\n            if( endsWith( m_pattern, \"*\" ) ) {\n                m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );\n                m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );\n            }\n        }\n        virtual ~WildcardPattern();\n        virtual bool matches( std::string const& str ) const {\n            switch( m_wildcard ) {\n                case NoWildcard:\n                    return m_pattern == adjustCase( str );\n                case WildcardAtStart:\n                    return endsWith( adjustCase( str ), m_pattern );\n                case WildcardAtEnd:\n                    return startsWith( adjustCase( str ), m_pattern );\n                case WildcardAtBothEnds:\n                    return contains( adjustCase( str ), m_pattern );\n            }\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunreachable-code\"\n#endif\n            throw std::logic_error( \"Unknown enum\" );\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n        }\n    private:\n        std::string adjustCase( std::string const& str ) const {\n            return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;\n        }\n        CaseSensitive::Choice m_caseSensitivity;\n        WildcardPosition m_wildcard;\n        std::string m_pattern;\n    };\n}\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec {\n        struct Pattern : SharedImpl<> {\n            virtual ~Pattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const = 0;\n        };\n        class NamePattern : public Pattern {\n        public:\n            NamePattern( std::string const& name )\n            : m_wildcardPattern( toLower( name ), CaseSensitive::No )\n            {}\n            virtual ~NamePattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const {\n                return m_wildcardPattern.matches( toLower( testCase.name ) );\n            }\n        private:\n            WildcardPattern m_wildcardPattern;\n        };\n\n        class TagPattern : public Pattern {\n        public:\n            TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}\n            virtual ~TagPattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const {\n                return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();\n            }\n        private:\n            std::string m_tag;\n        };\n\n        class ExcludedPattern : public Pattern {\n        public:\n            ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}\n            virtual ~ExcludedPattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }\n        private:\n            Ptr<Pattern> m_underlyingPattern;\n        };\n\n        struct Filter {\n            std::vector<Ptr<Pattern> > m_patterns;\n\n            bool matches( TestCaseInfo const& testCase ) const {\n                // All patterns in a filter must match for the filter to be a match\n                for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {\n                    if( !(*it)->matches( testCase ) )\n                        return false;\n                }\n                return true;\n            }\n        };\n\n    public:\n        bool hasFilters() const {\n            return !m_filters.empty();\n        }\n        bool matches( TestCaseInfo const& testCase ) const {\n            // A TestSpec matches if any filter matches\n            for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )\n                if( it->matches( testCase ) )\n                    return true;\n            return false;\n        }\n\n    private:\n        std::vector<Filter> m_filters;\n\n        friend class TestSpecParser;\n    };\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\nnamespace Catch {\n\n    class TestSpecParser {\n        enum Mode{ None, Name, QuotedName, Tag, EscapedName };\n        Mode m_mode;\n        bool m_exclusion;\n        std::size_t m_start, m_pos;\n        std::string m_arg;\n        std::vector<std::size_t> m_escapeChars;\n        TestSpec::Filter m_currentFilter;\n        TestSpec m_testSpec;\n        ITagAliasRegistry const* m_tagAliases;\n\n    public:\n        TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}\n\n        TestSpecParser& parse( std::string const& arg ) {\n            m_mode = None;\n            m_exclusion = false;\n            m_start = std::string::npos;\n            m_arg = m_tagAliases->expandAliases( arg );\n            m_escapeChars.clear();\n            for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )\n                visitChar( m_arg[m_pos] );\n            if( m_mode == Name )\n                addPattern<TestSpec::NamePattern>();\n            return *this;\n        }\n        TestSpec testSpec() {\n            addFilter();\n            return m_testSpec;\n        }\n    private:\n        void visitChar( char c ) {\n            if( m_mode == None ) {\n                switch( c ) {\n                case ' ': return;\n                case '~': m_exclusion = true; return;\n                case '[': return startNewMode( Tag, ++m_pos );\n                case '\"': return startNewMode( QuotedName, ++m_pos );\n                case '\\\\': return escape();\n                default: startNewMode( Name, m_pos ); break;\n                }\n            }\n            if( m_mode == Name ) {\n                if( c == ',' ) {\n                    addPattern<TestSpec::NamePattern>();\n                    addFilter();\n                }\n                else if( c == '[' ) {\n                    if( subString() == \"exclude:\" )\n                        m_exclusion = true;\n                    else\n                        addPattern<TestSpec::NamePattern>();\n                    startNewMode( Tag, ++m_pos );\n                }\n                else if( c == '\\\\' )\n                    escape();\n            }\n            else if( m_mode == EscapedName )\n                m_mode = Name;\n            else if( m_mode == QuotedName && c == '\"' )\n                addPattern<TestSpec::NamePattern>();\n            else if( m_mode == Tag && c == ']' )\n                addPattern<TestSpec::TagPattern>();\n        }\n        void startNewMode( Mode mode, std::size_t start ) {\n            m_mode = mode;\n            m_start = start;\n        }\n        void escape() {\n            m_mode = EscapedName;\n            m_escapeChars.push_back( m_pos );\n        }\n        std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }\n        template<typename T>\n        void addPattern() {\n            std::string token = subString();\n            for( size_t i = 0; i < m_escapeChars.size(); ++i )\n                token = token.substr( 0, m_escapeChars[i] ) + token.substr( m_escapeChars[i]+1 );\n            m_escapeChars.clear();\n            if( startsWith( token, \"exclude:\" ) ) {\n                m_exclusion = true;\n                token = token.substr( 8 );\n            }\n            if( !token.empty() ) {\n                Ptr<TestSpec::Pattern> pattern = new T( token );\n                if( m_exclusion )\n                    pattern = new TestSpec::ExcludedPattern( pattern );\n                m_currentFilter.m_patterns.push_back( pattern );\n            }\n            m_exclusion = false;\n            m_mode = None;\n        }\n        void addFilter() {\n            if( !m_currentFilter.m_patterns.empty() ) {\n                m_testSpec.m_filters.push_back( m_currentFilter );\n                m_currentFilter = TestSpec::Filter();\n            }\n        }\n    };\n    inline TestSpec parseTestSpec( std::string const& arg ) {\n        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();\n    }\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// #included from: catch_interfaces_config.h\n#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED\n\n#include <iostream>\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    struct Verbosity { enum Level {\n        NoOutput = 0,\n        Quiet,\n        Normal\n    }; };\n\n    struct WarnAbout { enum What {\n        Nothing = 0x00,\n        NoAssertions = 0x01\n    }; };\n\n    struct ShowDurations { enum OrNot {\n        DefaultForReporter,\n        Always,\n        Never\n    }; };\n    struct RunTests { enum InWhatOrder {\n        InDeclarationOrder,\n        InLexicographicalOrder,\n        InRandomOrder\n    }; };\n    struct UseColour { enum YesOrNo {\n        Auto,\n        Yes,\n        No\n    }; };\n\n    class TestSpec;\n\n    struct IConfig : IShared {\n\n        virtual ~IConfig();\n\n        virtual bool allowThrows() const = 0;\n        virtual std::ostream& stream() const = 0;\n        virtual std::string name() const = 0;\n        virtual bool includeSuccessfulResults() const = 0;\n        virtual bool shouldDebugBreak() const = 0;\n        virtual bool warnAboutMissingAssertions() const = 0;\n        virtual int abortAfter() const = 0;\n        virtual bool showInvisibles() const = 0;\n        virtual ShowDurations::OrNot showDurations() const = 0;\n        virtual TestSpec const& testSpec() const = 0;\n        virtual RunTests::InWhatOrder runOrder() const = 0;\n        virtual unsigned int rngSeed() const = 0;\n        virtual UseColour::YesOrNo useColour() const = 0;\n    };\n}\n\n// #included from: catch_stream.h\n#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED\n\n// #included from: catch_streambuf.h\n#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED\n\n#include <streambuf>\n\nnamespace Catch {\n\n    class StreamBufBase : public std::streambuf {\n    public:\n        virtual ~StreamBufBase() CATCH_NOEXCEPT;\n    };\n}\n\n#include <streambuf>\n#include <ostream>\n#include <fstream>\n#include <memory>\n\nnamespace Catch {\n\n    std::ostream& cout();\n    std::ostream& cerr();\n\n    struct IStream {\n        virtual ~IStream() CATCH_NOEXCEPT;\n        virtual std::ostream& stream() const = 0;\n    };\n\n    class FileStream : public IStream {\n        mutable std::ofstream m_ofs;\n    public:\n        FileStream( std::string const& filename );\n        virtual ~FileStream() CATCH_NOEXCEPT;\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n\n    class CoutStream : public IStream {\n        mutable std::ostream m_os;\n    public:\n        CoutStream();\n        virtual ~CoutStream() CATCH_NOEXCEPT;\n\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n\n    class DebugOutStream : public IStream {\n        CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;\n        mutable std::ostream m_os;\n    public:\n        DebugOutStream();\n        virtual ~DebugOutStream() CATCH_NOEXCEPT;\n\n    public: // IStream\n        virtual std::ostream& stream() const CATCH_OVERRIDE;\n    };\n}\n\n#include <memory>\n#include <vector>\n#include <string>\n#include <iostream>\n#include <ctime>\n\n#ifndef CATCH_CONFIG_CONSOLE_WIDTH\n#define CATCH_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\n\n    struct ConfigData {\n\n        ConfigData()\n        :   listTests( false ),\n            listTags( false ),\n            listReporters( false ),\n            listTestNamesOnly( false ),\n            showSuccessfulTests( false ),\n            shouldDebugBreak( false ),\n            noThrow( false ),\n            showHelp( false ),\n            showInvisibles( false ),\n            filenamesAsTags( false ),\n            abortAfter( -1 ),\n            rngSeed( 0 ),\n            verbosity( Verbosity::Normal ),\n            warnings( WarnAbout::Nothing ),\n            showDurations( ShowDurations::DefaultForReporter ),\n            runOrder( RunTests::InDeclarationOrder ),\n            useColour( UseColour::Auto )\n        {}\n\n        bool listTests;\n        bool listTags;\n        bool listReporters;\n        bool listTestNamesOnly;\n\n        bool showSuccessfulTests;\n        bool shouldDebugBreak;\n        bool noThrow;\n        bool showHelp;\n        bool showInvisibles;\n        bool filenamesAsTags;\n\n        int abortAfter;\n        unsigned int rngSeed;\n\n        Verbosity::Level verbosity;\n        WarnAbout::What warnings;\n        ShowDurations::OrNot showDurations;\n        RunTests::InWhatOrder runOrder;\n        UseColour::YesOrNo useColour;\n\n        std::string outputFilename;\n        std::string name;\n        std::string processName;\n\n        std::vector<std::string> reporterNames;\n        std::vector<std::string> testsOrTags;\n    };\n\n    class Config : public SharedImpl<IConfig> {\n    private:\n        Config( Config const& other );\n        Config& operator = ( Config const& other );\n        virtual void dummy();\n    public:\n\n        Config()\n        {}\n\n        Config( ConfigData const& data )\n        :   m_data( data ),\n            m_stream( openStream() )\n        {\n            if( !data.testsOrTags.empty() ) {\n                TestSpecParser parser( ITagAliasRegistry::get() );\n                for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )\n                    parser.parse( data.testsOrTags[i] );\n                m_testSpec = parser.testSpec();\n            }\n        }\n\n        virtual ~Config() {\n        }\n\n        std::string const& getFilename() const {\n            return m_data.outputFilename ;\n        }\n\n        bool listTests() const { return m_data.listTests; }\n        bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }\n        bool listTags() const { return m_data.listTags; }\n        bool listReporters() const { return m_data.listReporters; }\n\n        std::string getProcessName() const { return m_data.processName; }\n\n        bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }\n\n        std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }\n\n        int abortAfter() const { return m_data.abortAfter; }\n\n        TestSpec const& testSpec() const { return m_testSpec; }\n\n        bool showHelp() const { return m_data.showHelp; }\n        bool showInvisibles() const { return m_data.showInvisibles; }\n\n        // IConfig interface\n        virtual bool allowThrows() const        { return !m_data.noThrow; }\n        virtual std::ostream& stream() const    { return m_stream->stream(); }\n        virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }\n        virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }\n        virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }\n        virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }\n        virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }\n        virtual unsigned int rngSeed() const    { return m_data.rngSeed; }\n        virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }\n\n    private:\n\n        IStream const* openStream() {\n            if( m_data.outputFilename.empty() )\n                return new CoutStream();\n            else if( m_data.outputFilename[0] == '%' ) {\n                if( m_data.outputFilename == \"%debug\" )\n                    return new DebugOutStream();\n                else\n                    throw std::domain_error( \"Unrecognised stream: \" + m_data.outputFilename );\n            }\n            else\n                return new FileStream( m_data.outputFilename );\n        }\n        ConfigData m_data;\n\n        CATCH_AUTO_PTR( IStream const ) m_stream;\n        TestSpec m_testSpec;\n    };\n\n} // end namespace Catch\n\n// #included from: catch_clara.h\n#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED\n\n// Use Catch's value for console width (store Clara's off to the side, if present)\n#ifdef CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH\n#undef CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH\n\n// Declare Clara inside the Catch namespace\n#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {\n// #included from: ../external/clara.h\n\n// Version 0.0.2.4\n\n// Only use header guard if we are not using an outer namespace\n#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)\n\n#ifndef STITCH_CLARA_OPEN_NAMESPACE\n#define TWOBLUECUBES_CLARA_H_INCLUDED\n#define STITCH_CLARA_OPEN_NAMESPACE\n#define STITCH_CLARA_CLOSE_NAMESPACE\n#else\n#define STITCH_CLARA_CLOSE_NAMESPACE }\n#endif\n\n#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE\n\n// ----------- #included from tbc_text_format.h -----------\n\n// Only use header guard if we are not using an outer namespace\n#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)\n#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n#define TBC_TEXT_FORMAT_H_INCLUDED\n#endif\n\n#include <string>\n#include <vector>\n#include <sstream>\n#include <algorithm>\n\n// Use optional outer namespace\n#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\nnamespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {\n#endif\n\nnamespace Tbc {\n\n#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH\n    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n    struct TextAttributes {\n        TextAttributes()\n        :   initialIndent( std::string::npos ),\n            indent( 0 ),\n            width( consoleWidth-1 ),\n            tabChar( '\\t' )\n        {}\n\n        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }\n        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }\n        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }\n        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }\n\n        std::size_t initialIndent;  // indent of first line, or npos\n        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos\n        std::size_t width;          // maximum width of text, including indent. Longer text will wrap\n        char tabChar;               // If this char is seen the indent is changed to current pos\n    };\n\n    class Text {\n    public:\n        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )\n        : attr( _attr )\n        {\n            std::string wrappableChars = \" [({.,/|\\\\-\";\n            std::size_t indent = _attr.initialIndent != std::string::npos\n                ? _attr.initialIndent\n                : _attr.indent;\n            std::string remainder = _str;\n\n            while( !remainder.empty() ) {\n                if( lines.size() >= 1000 ) {\n                    lines.push_back( \"... message truncated due to excessive size\" );\n                    return;\n                }\n                std::size_t tabPos = std::string::npos;\n                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );\n                std::size_t pos = remainder.find_first_of( '\\n' );\n                if( pos <= width ) {\n                    width = pos;\n                }\n                pos = remainder.find_last_of( _attr.tabChar, width );\n                if( pos != std::string::npos ) {\n                    tabPos = pos;\n                    if( remainder[width] == '\\n' )\n                        width--;\n                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );\n                }\n\n                if( width == remainder.size() ) {\n                    spliceLine( indent, remainder, width );\n                }\n                else if( remainder[width] == '\\n' ) {\n                    spliceLine( indent, remainder, width );\n                    if( width <= 1 || remainder.size() != 1 )\n                        remainder = remainder.substr( 1 );\n                    indent = _attr.indent;\n                }\n                else {\n                    pos = remainder.find_last_of( wrappableChars, width );\n                    if( pos != std::string::npos && pos > 0 ) {\n                        spliceLine( indent, remainder, pos );\n                        if( remainder[0] == ' ' )\n                            remainder = remainder.substr( 1 );\n                    }\n                    else {\n                        spliceLine( indent, remainder, width-1 );\n                        lines.back() += \"-\";\n                    }\n                    if( lines.size() == 1 )\n                        indent = _attr.indent;\n                    if( tabPos != std::string::npos )\n                        indent += tabPos;\n                }\n            }\n        }\n\n        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {\n            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );\n            _remainder = _remainder.substr( _pos );\n        }\n\n        typedef std::vector<std::string>::const_iterator const_iterator;\n\n        const_iterator begin() const { return lines.begin(); }\n        const_iterator end() const { return lines.end(); }\n        std::string const& last() const { return lines.back(); }\n        std::size_t size() const { return lines.size(); }\n        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << *this;\n            return oss.str();\n        }\n\n        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {\n            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();\n                it != itEnd; ++it ) {\n                if( it != _text.begin() )\n                    _stream << \"\\n\";\n                _stream << *it;\n            }\n            return _stream;\n        }\n\n    private:\n        std::string str;\n        TextAttributes attr;\n        std::vector<std::string> lines;\n    };\n\n} // end namespace Tbc\n\n#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n} // end outer namespace\n#endif\n\n#endif // TBC_TEXT_FORMAT_H_INCLUDED\n\n// ----------- end of #include from tbc_text_format.h -----------\n// ........... back in clara.h\n\n#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE\n\n// ----------- #included from clara_compilers.h -----------\n\n#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n\n// Detect a number of compiler features - mostly C++11/14 conformance - by compiler\n// The following features are defined:\n//\n// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?\n// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?\n// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods\n// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?\n// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)\n\n// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?\n\n// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11\n\n#ifdef __clang__\n\n#if __has_feature(cxx_nullptr)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n#if __has_feature(cxx_noexcept)\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#endif\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// GCC\n#ifdef __GNUC__\n\n#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n// - otherwise more recent versions define __cplusplus >= 201103L\n// and will get picked up below\n\n#endif // __GNUC__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#ifdef _MSC_VER\n\n#if (_MSC_VER >= 1600)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#endif\n\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n// C++ language feature support\n\n// catch all support for C++11\n#if defined(__cplusplus) && __cplusplus >= 201103L\n\n#define CLARA_CPP11_OR_GREATER\n\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)\n#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR\n#endif\n\n#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT\n#endif\n\n#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS\n#endif\n\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)\n#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE\n#endif\n#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)\n#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n#endif // __cplusplus >= 201103L\n\n// Now set the actual defines based on the above + anything the user has configured\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_NULLPTR\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_NOEXCEPT\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_GENERATED_METHODS\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_OVERRIDE\n#endif\n#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)\n#define CLARA_CONFIG_CPP11_UNIQUE_PTR\n#endif\n\n// noexcept support:\n#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)\n#define CLARA_NOEXCEPT noexcept\n#  define CLARA_NOEXCEPT_IS(x) noexcept(x)\n#else\n#define CLARA_NOEXCEPT throw()\n#  define CLARA_NOEXCEPT_IS(x)\n#endif\n\n// nullptr support\n#ifdef CLARA_CONFIG_CPP11_NULLPTR\n#define CLARA_NULL nullptr\n#else\n#define CLARA_NULL NULL\n#endif\n\n// override support\n#ifdef CLARA_CONFIG_CPP11_OVERRIDE\n#define CLARA_OVERRIDE override\n#else\n#define CLARA_OVERRIDE\n#endif\n\n// unique_ptr support\n#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR\n#   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>\n#else\n#   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>\n#endif\n\n#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED\n\n// ----------- end of #include from clara_compilers.h -----------\n// ........... back in clara.h\n\n#include <map>\n#include <stdexcept>\n#include <memory>\n\n#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)\n#define CLARA_PLATFORM_WINDOWS\n#endif\n\n// Use optional outer namespace\n#ifdef STITCH_CLARA_OPEN_NAMESPACE\nSTITCH_CLARA_OPEN_NAMESPACE\n#endif\n\nnamespace Clara {\n\n    struct UnpositionalTag {};\n\n    extern UnpositionalTag _;\n\n#ifdef CLARA_CONFIG_MAIN\n    UnpositionalTag _;\n#endif\n\n    namespace Detail {\n\n#ifdef CLARA_CONSOLE_WIDTH\n    const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n        using namespace Tbc;\n\n        inline bool startsWith( std::string const& str, std::string const& prefix ) {\n            return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;\n        }\n\n        template<typename T> struct RemoveConstRef{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T&>{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };\n        template<typename T> struct RemoveConstRef<T const>{ typedef T type; };\n\n        template<typename T>    struct IsBool       { static const bool value = false; };\n        template<>              struct IsBool<bool> { static const bool value = true; };\n\n        template<typename T>\n        void convertInto( std::string const& _source, T& _dest ) {\n            std::stringstream ss;\n            ss << _source;\n            ss >> _dest;\n            if( ss.fail() )\n                throw std::runtime_error( \"Unable to convert \" + _source + \" to destination type\" );\n        }\n        inline void convertInto( std::string const& _source, std::string& _dest ) {\n            _dest = _source;\n        }\n        char toLowerCh(char c) {\n            return static_cast<char>( ::tolower( c ) );\n        }\n        inline void convertInto( std::string const& _source, bool& _dest ) {\n            std::string sourceLC = _source;\n            std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );\n            if( sourceLC == \"y\" || sourceLC == \"1\" || sourceLC == \"true\" || sourceLC == \"yes\" || sourceLC == \"on\" )\n                _dest = true;\n            else if( sourceLC == \"n\" || sourceLC == \"0\" || sourceLC == \"false\" || sourceLC == \"no\" || sourceLC == \"off\" )\n                _dest = false;\n            else\n                throw std::runtime_error( \"Expected a boolean value but did not recognise:\\n  '\" + _source + \"'\" );\n        }\n\n        template<typename ConfigT>\n        struct IArgFunction {\n            virtual ~IArgFunction() {}\n#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS\n            IArgFunction()                      = default;\n            IArgFunction( IArgFunction const& ) = default;\n#endif\n            virtual void set( ConfigT& config, std::string const& value ) const = 0;\n            virtual bool takesArg() const = 0;\n            virtual IArgFunction* clone() const = 0;\n        };\n\n        template<typename ConfigT>\n        class BoundArgFunction {\n        public:\n            BoundArgFunction() : functionObj( CLARA_NULL ) {}\n            BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}\n            BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}\n            BoundArgFunction& operator = ( BoundArgFunction const& other ) {\n                IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;\n                delete functionObj;\n                functionObj = newFunctionObj;\n                return *this;\n            }\n            ~BoundArgFunction() { delete functionObj; }\n\n            void set( ConfigT& config, std::string const& value ) const {\n                functionObj->set( config, value );\n            }\n            bool takesArg() const { return functionObj->takesArg(); }\n\n            bool isSet() const {\n                return functionObj != CLARA_NULL;\n            }\n        private:\n            IArgFunction<ConfigT>* functionObj;\n        };\n\n        template<typename C>\n        struct NullBinder : IArgFunction<C>{\n            virtual void set( C&, std::string const& ) const {}\n            virtual bool takesArg() const { return true; }\n            virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }\n        };\n\n        template<typename C, typename M>\n        struct BoundDataMember : IArgFunction<C>{\n            BoundDataMember( M C::* _member ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                convertInto( stringValue, p.*member );\n            }\n            virtual bool takesArg() const { return !IsBool<M>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }\n            M C::* member;\n        };\n        template<typename C, typename M>\n        struct BoundUnaryMethod : IArgFunction<C>{\n            BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                typename RemoveConstRef<M>::type value;\n                convertInto( stringValue, value );\n                (p.*member)( value );\n            }\n            virtual bool takesArg() const { return !IsBool<M>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }\n            void (C::*member)( M );\n        };\n        template<typename C>\n        struct BoundNullaryMethod : IArgFunction<C>{\n            BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}\n            virtual void set( C& p, std::string const& stringValue ) const {\n                bool value;\n                convertInto( stringValue, value );\n                if( value )\n                    (p.*member)();\n            }\n            virtual bool takesArg() const { return false; }\n            virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }\n            void (C::*member)();\n        };\n\n        template<typename C>\n        struct BoundUnaryFunction : IArgFunction<C>{\n            BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}\n            virtual void set( C& obj, std::string const& stringValue ) const {\n                bool value;\n                convertInto( stringValue, value );\n                if( value )\n                    function( obj );\n            }\n            virtual bool takesArg() const { return false; }\n            virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }\n            void (*function)( C& );\n        };\n\n        template<typename C, typename T>\n        struct BoundBinaryFunction : IArgFunction<C>{\n            BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}\n            virtual void set( C& obj, std::string const& stringValue ) const {\n                typename RemoveConstRef<T>::type value;\n                convertInto( stringValue, value );\n                function( obj, value );\n            }\n            virtual bool takesArg() const { return !IsBool<T>::value; }\n            virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }\n            void (*function)( C&, T );\n        };\n\n    } // namespace Detail\n\n    inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {\n        std::vector<std::string> args( static_cast<std::size_t>( argc ) );\n        for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )\n            args[i] = argv[i];\n\n        return args;\n    }\n\n    class Parser {\n        enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };\n        Mode mode;\n        std::size_t from;\n        bool inQuotes;\n    public:\n\n        struct Token {\n            enum Type { Positional, ShortOpt, LongOpt };\n            Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}\n            Type type;\n            std::string data;\n        };\n\n        Parser() : mode( None ), from( 0 ), inQuotes( false ){}\n\n        void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {\n            const std::string doubleDash = \"--\";\n            for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )\n                parseIntoTokens( args[i], tokens);\n        }\n\n        void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {\n            for( std::size_t i = 0; i <= arg.size(); ++i ) {\n                char c = arg[i];\n                if( c == '\"' )\n                    inQuotes = !inQuotes;\n                mode = handleMode( i, c, arg, tokens );\n            }\n        }\n        Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            switch( mode ) {\n                case None: return handleNone( i, c );\n                case MaybeShortOpt: return handleMaybeShortOpt( i, c );\n                case ShortOpt:\n                case LongOpt:\n                case SlashOpt: return handleOpt( i, c, arg, tokens );\n                case Positional: return handlePositional( i, c, arg, tokens );\n                default: throw std::logic_error( \"Unknown mode\" );\n            }\n        }\n\n        Mode handleNone( std::size_t i, char c ) {\n            if( inQuotes ) {\n                from = i;\n                return Positional;\n            }\n            switch( c ) {\n                case '-': return MaybeShortOpt;\n#ifdef CLARA_PLATFORM_WINDOWS\n                case '/': from = i+1; return SlashOpt;\n#endif\n                default: from = i; return Positional;\n            }\n        }\n        Mode handleMaybeShortOpt( std::size_t i, char c ) {\n            switch( c ) {\n                case '-': from = i+1; return LongOpt;\n                default: from = i; return ShortOpt;\n            }\n        }\n        Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            if( std::string( \":=\\0\", 3 ).find( c ) == std::string::npos )\n                return mode;\n\n            std::string optName = arg.substr( from, i-from );\n            if( mode == ShortOpt )\n                for( std::size_t j = 0; j < optName.size(); ++j )\n                    tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );\n            else if( mode == SlashOpt && optName.size() == 1 )\n                tokens.push_back( Token( Token::ShortOpt, optName ) );\n            else\n                tokens.push_back( Token( Token::LongOpt, optName ) );\n            return None;\n        }\n        Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {\n            if( inQuotes || std::string( \"\\0\", 1 ).find( c ) == std::string::npos )\n                return mode;\n\n            std::string data = arg.substr( from, i-from );\n            tokens.push_back( Token( Token::Positional, data ) );\n            return None;\n        }\n    };\n\n    template<typename ConfigT>\n    struct CommonArgProperties {\n        CommonArgProperties() {}\n        CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}\n\n        Detail::BoundArgFunction<ConfigT> boundField;\n        std::string description;\n        std::string detail;\n        std::string placeholder; // Only value if boundField takes an arg\n\n        bool takesArg() const {\n            return !placeholder.empty();\n        }\n        void validate() const {\n            if( !boundField.isSet() )\n                throw std::logic_error( \"option not bound\" );\n        }\n    };\n    struct OptionArgProperties {\n        std::vector<std::string> shortNames;\n        std::string longName;\n\n        bool hasShortName( std::string const& shortName ) const {\n            return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();\n        }\n        bool hasLongName( std::string const& _longName ) const {\n            return _longName == longName;\n        }\n    };\n    struct PositionalArgProperties {\n        PositionalArgProperties() : position( -1 ) {}\n        int position; // -1 means non-positional (floating)\n\n        bool isFixedPositional() const {\n            return position != -1;\n        }\n    };\n\n    template<typename ConfigT>\n    class CommandLine {\n\n        struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {\n            Arg() {}\n            Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}\n\n            using CommonArgProperties<ConfigT>::placeholder; // !TBD\n\n            std::string dbgName() const {\n                if( !longName.empty() )\n                    return \"--\" + longName;\n                if( !shortNames.empty() )\n                    return \"-\" + shortNames[0];\n                return \"positional args\";\n            }\n            std::string commands() const {\n                std::ostringstream oss;\n                bool first = true;\n                std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();\n                for(; it != itEnd; ++it ) {\n                    if( first )\n                        first = false;\n                    else\n                        oss << \", \";\n                    oss << \"-\" << *it;\n                }\n                if( !longName.empty() ) {\n                    if( !first )\n                        oss << \", \";\n                    oss << \"--\" << longName;\n                }\n                if( !placeholder.empty() )\n                    oss << \" <\" << placeholder << \">\";\n                return oss.str();\n            }\n        };\n\n        typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;\n\n        friend void addOptName( Arg& arg, std::string const& optName )\n        {\n            if( optName.empty() )\n                return;\n            if( Detail::startsWith( optName, \"--\" ) ) {\n                if( !arg.longName.empty() )\n                    throw std::logic_error( \"Only one long opt may be specified. '\"\n                        + arg.longName\n                        + \"' already specified, now attempting to add '\"\n                        + optName + \"'\" );\n                arg.longName = optName.substr( 2 );\n            }\n            else if( Detail::startsWith( optName, \"-\" ) )\n                arg.shortNames.push_back( optName.substr( 1 ) );\n            else\n                throw std::logic_error( \"option must begin with - or --. Option was: '\" + optName + \"'\" );\n        }\n        friend void setPositionalArg( Arg& arg, int position )\n        {\n            arg.position = position;\n        }\n\n        class ArgBuilder {\n        public:\n            ArgBuilder( Arg* arg ) : m_arg( arg ) {}\n\n            // Bind a non-boolean data member (requires placeholder string)\n            template<typename C, typename M>\n            void bind( M C::* field, std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundDataMember<C,M>( field );\n                m_arg->placeholder = placeholder;\n            }\n            // Bind a boolean data member (no placeholder required)\n            template<typename C>\n            void bind( bool C::* field ) {\n                m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );\n            }\n\n            // Bind a method taking a single, non-boolean argument (requires a placeholder string)\n            template<typename C, typename M>\n            void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );\n                m_arg->placeholder = placeholder;\n            }\n\n            // Bind a method taking a single, boolean argument (no placeholder string required)\n            template<typename C>\n            void bind( void (C::* unaryMethod)( bool ) ) {\n                m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );\n            }\n\n            // Bind a method that takes no arguments (will be called if opt is present)\n            template<typename C>\n            void bind( void (C::* nullaryMethod)() ) {\n                m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );\n            }\n\n            // Bind a free function taking a single argument - the object to operate on (no placeholder string required)\n            template<typename C>\n            void bind( void (* unaryFunction)( C& ) ) {\n                m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );\n            }\n\n            // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)\n            template<typename C, typename T>\n            void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {\n                m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );\n                m_arg->placeholder = placeholder;\n            }\n\n            ArgBuilder& describe( std::string const& description ) {\n                m_arg->description = description;\n                return *this;\n            }\n            ArgBuilder& detail( std::string const& detail ) {\n                m_arg->detail = detail;\n                return *this;\n            }\n\n        protected:\n            Arg* m_arg;\n        };\n\n        class OptBuilder : public ArgBuilder {\n        public:\n            OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}\n            OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}\n\n            OptBuilder& operator[]( std::string const& optName ) {\n                addOptName( *ArgBuilder::m_arg, optName );\n                return *this;\n            }\n        };\n\n    public:\n\n        CommandLine()\n        :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),\n            m_highestSpecifiedArgPosition( 0 ),\n            m_throwOnUnrecognisedTokens( false )\n        {}\n        CommandLine( CommandLine const& other )\n        :   m_boundProcessName( other.m_boundProcessName ),\n            m_options ( other.m_options ),\n            m_positionalArgs( other.m_positionalArgs ),\n            m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),\n            m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )\n        {\n            if( other.m_floatingArg.get() )\n                m_floatingArg.reset( new Arg( *other.m_floatingArg ) );\n        }\n\n        CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {\n            m_throwOnUnrecognisedTokens = shouldThrow;\n            return *this;\n        }\n\n        OptBuilder operator[]( std::string const& optName ) {\n            m_options.push_back( Arg() );\n            addOptName( m_options.back(), optName );\n            OptBuilder builder( &m_options.back() );\n            return builder;\n        }\n\n        ArgBuilder operator[]( int position ) {\n            m_positionalArgs.insert( std::make_pair( position, Arg() ) );\n            if( position > m_highestSpecifiedArgPosition )\n                m_highestSpecifiedArgPosition = position;\n            setPositionalArg( m_positionalArgs[position], position );\n            ArgBuilder builder( &m_positionalArgs[position] );\n            return builder;\n        }\n\n        // Invoke this with the _ instance\n        ArgBuilder operator[]( UnpositionalTag ) {\n            if( m_floatingArg.get() )\n                throw std::logic_error( \"Only one unpositional argument can be added\" );\n            m_floatingArg.reset( new Arg() );\n            ArgBuilder builder( m_floatingArg.get() );\n            return builder;\n        }\n\n        template<typename C, typename M>\n        void bindProcessName( M C::* field ) {\n            m_boundProcessName = new Detail::BoundDataMember<C,M>( field );\n        }\n        template<typename C, typename M>\n        void bindProcessName( void (C::*_unaryMethod)( M ) ) {\n            m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );\n        }\n\n        void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {\n            typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;\n            std::size_t maxWidth = 0;\n            for( it = itBegin; it != itEnd; ++it )\n                maxWidth = (std::max)( maxWidth, it->commands().size() );\n\n            for( it = itBegin; it != itEnd; ++it ) {\n                Detail::Text usage( it->commands(), Detail::TextAttributes()\n                                                        .setWidth( maxWidth+indent )\n                                                        .setIndent( indent ) );\n                Detail::Text desc( it->description, Detail::TextAttributes()\n                                                        .setWidth( width - maxWidth - 3 ) );\n\n                for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {\n                    std::string usageCol = i < usage.size() ? usage[i] : \"\";\n                    os << usageCol;\n\n                    if( i < desc.size() && !desc[i].empty() )\n                        os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )\n                            << desc[i];\n                    os << \"\\n\";\n                }\n            }\n        }\n        std::string optUsage() const {\n            std::ostringstream oss;\n            optUsage( oss );\n            return oss.str();\n        }\n\n        void argSynopsis( std::ostream& os ) const {\n            for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {\n                if( i > 1 )\n                    os << \" \";\n                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );\n                if( it != m_positionalArgs.end() )\n                    os << \"<\" << it->second.placeholder << \">\";\n                else if( m_floatingArg.get() )\n                    os << \"<\" << m_floatingArg->placeholder << \">\";\n                else\n                    throw std::logic_error( \"non consecutive positional arguments with no floating args\" );\n            }\n            // !TBD No indication of mandatory args\n            if( m_floatingArg.get() ) {\n                if( m_highestSpecifiedArgPosition > 1 )\n                    os << \" \";\n                os << \"[<\" << m_floatingArg->placeholder << \"> ...]\";\n            }\n        }\n        std::string argSynopsis() const {\n            std::ostringstream oss;\n            argSynopsis( oss );\n            return oss.str();\n        }\n\n        void usage( std::ostream& os, std::string const& procName ) const {\n            validate();\n            os << \"usage:\\n  \" << procName << \" \";\n            argSynopsis( os );\n            if( !m_options.empty() ) {\n                os << \" [options]\\n\\nwhere options are: \\n\";\n                optUsage( os, 2 );\n            }\n            os << \"\\n\";\n        }\n        std::string usage( std::string const& procName ) const {\n            std::ostringstream oss;\n            usage( oss, procName );\n            return oss.str();\n        }\n\n        ConfigT parse( std::vector<std::string> const& args ) const {\n            ConfigT config;\n            parseInto( args, config );\n            return config;\n        }\n\n        std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {\n            std::string processName = args[0];\n            std::size_t lastSlash = processName.find_last_of( \"/\\\\\" );\n            if( lastSlash != std::string::npos )\n                processName = processName.substr( lastSlash+1 );\n            m_boundProcessName.set( config, processName );\n            std::vector<Parser::Token> tokens;\n            Parser parser;\n            parser.parseIntoTokens( args, tokens );\n            return populate( tokens, config );\n        }\n\n        std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            validate();\n            std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );\n            unusedTokens = populateFixedArgs( unusedTokens, config );\n            unusedTokens = populateFloatingArgs( unusedTokens, config );\n            return unusedTokens;\n        }\n\n        std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            std::vector<Parser::Token> unusedTokens;\n            std::vector<std::string> errors;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();\n                for(; it != itEnd; ++it ) {\n                    Arg const& arg = *it;\n\n                    try {\n                        if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||\n                            ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {\n                            if( arg.takesArg() ) {\n                                if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )\n                                    errors.push_back( \"Expected argument to option: \" + token.data );\n                                else\n                                    arg.boundField.set( config, tokens[++i].data );\n                            }\n                            else {\n                                arg.boundField.set( config, \"true\" );\n                            }\n                            break;\n                        }\n                    }\n                    catch( std::exception& ex ) {\n                        errors.push_back( std::string( ex.what() ) + \"\\n- while parsing: (\" + arg.commands() + \")\" );\n                    }\n                }\n                if( it == itEnd ) {\n                    if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )\n                        unusedTokens.push_back( token );\n                    else if( errors.empty() && m_throwOnUnrecognisedTokens )\n                        errors.push_back( \"unrecognised option: \" + token.data );\n                }\n            }\n            if( !errors.empty() ) {\n                std::ostringstream oss;\n                for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();\n                        it != itEnd;\n                        ++it ) {\n                    if( it != errors.begin() )\n                        oss << \"\\n\";\n                    oss << *it;\n                }\n                throw std::runtime_error( oss.str() );\n            }\n            return unusedTokens;\n        }\n        std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            std::vector<Parser::Token> unusedTokens;\n            int position = 1;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );\n                if( it != m_positionalArgs.end() )\n                    it->second.boundField.set( config, token.data );\n                else\n                    unusedTokens.push_back( token );\n                if( token.type == Parser::Token::Positional )\n                    position++;\n            }\n            return unusedTokens;\n        }\n        std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {\n            if( !m_floatingArg.get() )\n                return tokens;\n            std::vector<Parser::Token> unusedTokens;\n            for( std::size_t i = 0; i < tokens.size(); ++i ) {\n                Parser::Token const& token = tokens[i];\n                if( token.type == Parser::Token::Positional )\n                    m_floatingArg->boundField.set( config, token.data );\n                else\n                    unusedTokens.push_back( token );\n            }\n            return unusedTokens;\n        }\n\n        void validate() const\n        {\n            if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )\n                throw std::logic_error( \"No options or arguments specified\" );\n\n            for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),\n                                                            itEnd = m_options.end();\n                    it != itEnd; ++it )\n                it->validate();\n        }\n\n    private:\n        Detail::BoundArgFunction<ConfigT> m_boundProcessName;\n        std::vector<Arg> m_options;\n        std::map<int, Arg> m_positionalArgs;\n        ArgAutoPtr m_floatingArg;\n        int m_highestSpecifiedArgPosition;\n        bool m_throwOnUnrecognisedTokens;\n    };\n\n} // end namespace Clara\n\nSTITCH_CLARA_CLOSE_NAMESPACE\n#undef STITCH_CLARA_OPEN_NAMESPACE\n#undef STITCH_CLARA_CLOSE_NAMESPACE\n\n#endif // TWOBLUECUBES_CLARA_H_INCLUDED\n#undef STITCH_CLARA_OPEN_NAMESPACE\n\n// Restore Clara's value for console width, if present\n#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n#include <fstream>\n\nnamespace Catch {\n\n    inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }\n    inline void abortAfterX( ConfigData& config, int x ) {\n        if( x < 1 )\n            throw std::runtime_error( \"Value after -x or --abortAfter must be greater than zero\" );\n        config.abortAfter = x;\n    }\n    inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }\n    inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }\n\n    inline void addWarning( ConfigData& config, std::string const& _warning ) {\n        if( _warning == \"NoAssertions\" )\n            config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );\n        else\n            throw std::runtime_error( \"Unrecognised warning: '\" + _warning + \"'\" );\n    }\n    inline void setOrder( ConfigData& config, std::string const& order ) {\n        if( startsWith( \"declared\", order ) )\n            config.runOrder = RunTests::InDeclarationOrder;\n        else if( startsWith( \"lexical\", order ) )\n            config.runOrder = RunTests::InLexicographicalOrder;\n        else if( startsWith( \"random\", order ) )\n            config.runOrder = RunTests::InRandomOrder;\n        else\n            throw std::runtime_error( \"Unrecognised ordering: '\" + order + \"'\" );\n    }\n    inline void setRngSeed( ConfigData& config, std::string const& seed ) {\n        if( seed == \"time\" ) {\n            config.rngSeed = static_cast<unsigned int>( std::time(0) );\n        }\n        else {\n            std::stringstream ss;\n            ss << seed;\n            ss >> config.rngSeed;\n            if( ss.fail() )\n                throw std::runtime_error( \"Argment to --rng-seed should be the word 'time' or a number\" );\n        }\n    }\n    inline void setVerbosity( ConfigData& config, int level ) {\n        // !TBD: accept strings?\n        config.verbosity = static_cast<Verbosity::Level>( level );\n    }\n    inline void setShowDurations( ConfigData& config, bool _showDurations ) {\n        config.showDurations = _showDurations\n            ? ShowDurations::Always\n            : ShowDurations::Never;\n    }\n    inline void setUseColour( ConfigData& config, std::string const& value ) {\n        std::string mode = toLower( value );\n\n        if( mode == \"yes\" )\n            config.useColour = UseColour::Yes;\n        else if( mode == \"no\" )\n            config.useColour = UseColour::No;\n        else if( mode == \"auto\" )\n            config.useColour = UseColour::Auto;\n        else\n            throw std::runtime_error( \"colour mode must be one of: auto, yes or no\" );\n    }\n    inline void forceColour( ConfigData& config ) {\n        config.useColour = UseColour::Yes;\n    }\n    inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {\n        std::ifstream f( _filename.c_str() );\n        if( !f.is_open() )\n            throw std::domain_error( \"Unable to load input file: \" + _filename );\n\n        std::string line;\n        while( std::getline( f, line ) ) {\n            line = trim(line);\n            if( !line.empty() && !startsWith( line, \"#\" ) ) {\n                if( !startsWith( line, \"\\\"\" ) )\n                    line = \"\\\"\" + line + \"\\\"\";\n                addTestOrTags( config, line + \",\" );\n            }\n        }\n    }\n\n    inline Clara::CommandLine<ConfigData> makeCommandLineParser() {\n\n        using namespace Clara;\n        CommandLine<ConfigData> cli;\n\n        cli.bindProcessName( &ConfigData::processName );\n\n        cli[\"-?\"][\"-h\"][\"--help\"]\n            .describe( \"display usage information\" )\n            .bind( &ConfigData::showHelp );\n\n        cli[\"-l\"][\"--list-tests\"]\n            .describe( \"list all/matching test cases\" )\n            .bind( &ConfigData::listTests );\n\n        cli[\"-t\"][\"--list-tags\"]\n            .describe( \"list all/matching tags\" )\n            .bind( &ConfigData::listTags );\n\n        cli[\"-s\"][\"--success\"]\n            .describe( \"include successful tests in output\" )\n            .bind( &ConfigData::showSuccessfulTests );\n\n        cli[\"-b\"][\"--break\"]\n            .describe( \"break into debugger on failure\" )\n            .bind( &ConfigData::shouldDebugBreak );\n\n        cli[\"-e\"][\"--nothrow\"]\n            .describe( \"skip exception tests\" )\n            .bind( &ConfigData::noThrow );\n\n        cli[\"-i\"][\"--invisibles\"]\n            .describe( \"show invisibles (tabs, newlines)\" )\n            .bind( &ConfigData::showInvisibles );\n\n        cli[\"-o\"][\"--out\"]\n            .describe( \"output filename\" )\n            .bind( &ConfigData::outputFilename, \"filename\" );\n\n        cli[\"-r\"][\"--reporter\"]\n//            .placeholder( \"name[:filename]\" )\n            .describe( \"reporter to use (defaults to console)\" )\n            .bind( &addReporterName, \"name\" );\n\n        cli[\"-n\"][\"--name\"]\n            .describe( \"suite name\" )\n            .bind( &ConfigData::name, \"name\" );\n\n        cli[\"-a\"][\"--abort\"]\n            .describe( \"abort at first failure\" )\n            .bind( &abortAfterFirst );\n\n        cli[\"-x\"][\"--abortx\"]\n            .describe( \"abort after x failures\" )\n            .bind( &abortAfterX, \"no. failures\" );\n\n        cli[\"-w\"][\"--warn\"]\n            .describe( \"enable warnings\" )\n            .bind( &addWarning, \"warning name\" );\n\n// - needs updating if reinstated\n//        cli.into( &setVerbosity )\n//            .describe( \"level of verbosity (0=no output)\" )\n//            .shortOpt( \"v\")\n//            .longOpt( \"verbosity\" )\n//            .placeholder( \"level\" );\n\n        cli[_]\n            .describe( \"which test or tests to use\" )\n            .bind( &addTestOrTags, \"test name, pattern or tags\" );\n\n        cli[\"-d\"][\"--durations\"]\n            .describe( \"show test durations\" )\n            .bind( &setShowDurations, \"yes|no\" );\n\n        cli[\"-f\"][\"--input-file\"]\n            .describe( \"load test names to run from a file\" )\n            .bind( &loadTestNamesFromFile, \"filename\" );\n\n        cli[\"-#\"][\"--filenames-as-tags\"]\n            .describe( \"adds a tag for the filename\" )\n            .bind( &ConfigData::filenamesAsTags );\n\n        // Less common commands which don't have a short form\n        cli[\"--list-test-names-only\"]\n            .describe( \"list all/matching test cases names only\" )\n            .bind( &ConfigData::listTestNamesOnly );\n\n        cli[\"--list-reporters\"]\n            .describe( \"list all reporters\" )\n            .bind( &ConfigData::listReporters );\n\n        cli[\"--order\"]\n            .describe( \"test case order (defaults to decl)\" )\n            .bind( &setOrder, \"decl|lex|rand\" );\n\n        cli[\"--rng-seed\"]\n            .describe( \"set a specific seed for random numbers\" )\n            .bind( &setRngSeed, \"'time'|number\" );\n\n        cli[\"--force-colour\"]\n            .describe( \"force colourised output (deprecated)\" )\n            .bind( &forceColour );\n\n        cli[\"--use-colour\"]\n            .describe( \"should output be colourised\" )\n            .bind( &setUseColour, \"yes|no\" );\n\n        return cli;\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_list.hpp\n#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED\n\n// #included from: catch_text.h\n#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED\n\n#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH\n\n#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch\n// #included from: ../external/tbc_text_format.h\n// Only use header guard if we are not using an outer namespace\n#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED\n#  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#  endif\n# else\n#  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED\n# endif\n#endif\n#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#include <string>\n#include <vector>\n#include <sstream>\n\n// Use optional outer namespace\n#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\nnamespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {\n#endif\n\nnamespace Tbc {\n\n#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH\n    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;\n#else\n    const unsigned int consoleWidth = 80;\n#endif\n\n    struct TextAttributes {\n        TextAttributes()\n        :   initialIndent( std::string::npos ),\n            indent( 0 ),\n            width( consoleWidth-1 ),\n            tabChar( '\\t' )\n        {}\n\n        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }\n        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }\n        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }\n        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }\n\n        std::size_t initialIndent;  // indent of first line, or npos\n        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos\n        std::size_t width;          // maximum width of text, including indent. Longer text will wrap\n        char tabChar;               // If this char is seen the indent is changed to current pos\n    };\n\n    class Text {\n    public:\n        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )\n        : attr( _attr )\n        {\n            std::string wrappableChars = \" [({.,/|\\\\-\";\n            std::size_t indent = _attr.initialIndent != std::string::npos\n                ? _attr.initialIndent\n                : _attr.indent;\n            std::string remainder = _str;\n\n            while( !remainder.empty() ) {\n                if( lines.size() >= 1000 ) {\n                    lines.push_back( \"... message truncated due to excessive size\" );\n                    return;\n                }\n                std::size_t tabPos = std::string::npos;\n                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );\n                std::size_t pos = remainder.find_first_of( '\\n' );\n                if( pos <= width ) {\n                    width = pos;\n                }\n                pos = remainder.find_last_of( _attr.tabChar, width );\n                if( pos != std::string::npos ) {\n                    tabPos = pos;\n                    if( remainder[width] == '\\n' )\n                        width--;\n                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );\n                }\n\n                if( width == remainder.size() ) {\n                    spliceLine( indent, remainder, width );\n                }\n                else if( remainder[width] == '\\n' ) {\n                    spliceLine( indent, remainder, width );\n                    if( width <= 1 || remainder.size() != 1 )\n                        remainder = remainder.substr( 1 );\n                    indent = _attr.indent;\n                }\n                else {\n                    pos = remainder.find_last_of( wrappableChars, width );\n                    if( pos != std::string::npos && pos > 0 ) {\n                        spliceLine( indent, remainder, pos );\n                        if( remainder[0] == ' ' )\n                            remainder = remainder.substr( 1 );\n                    }\n                    else {\n                        spliceLine( indent, remainder, width-1 );\n                        lines.back() += \"-\";\n                    }\n                    if( lines.size() == 1 )\n                        indent = _attr.indent;\n                    if( tabPos != std::string::npos )\n                        indent += tabPos;\n                }\n            }\n        }\n\n        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {\n            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );\n            _remainder = _remainder.substr( _pos );\n        }\n\n        typedef std::vector<std::string>::const_iterator const_iterator;\n\n        const_iterator begin() const { return lines.begin(); }\n        const_iterator end() const { return lines.end(); }\n        std::string const& last() const { return lines.back(); }\n        std::size_t size() const { return lines.size(); }\n        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }\n        std::string toString() const {\n            std::ostringstream oss;\n            oss << *this;\n            return oss.str();\n        }\n\n        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {\n            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();\n                it != itEnd; ++it ) {\n                if( it != _text.begin() )\n                    _stream << \"\\n\";\n                _stream << *it;\n            }\n            return _stream;\n        }\n\n    private:\n        std::string str;\n        TextAttributes attr;\n        std::vector<std::string> lines;\n    };\n\n} // end namespace Tbc\n\n#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n} // end outer namespace\n#endif\n\n#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED\n#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE\n\nnamespace Catch {\n    using Tbc::Text;\n    using Tbc::TextAttributes;\n}\n\n// #included from: catch_console_colour.hpp\n#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct Colour {\n        enum Code {\n            None = 0,\n\n            White,\n            Red,\n            Green,\n            Blue,\n            Cyan,\n            Yellow,\n            Grey,\n\n            Bright = 0x10,\n\n            BrightRed = Bright | Red,\n            BrightGreen = Bright | Green,\n            LightGrey = Bright | Grey,\n            BrightWhite = Bright | White,\n\n            // By intention\n            FileName = LightGrey,\n            Warning = Yellow,\n            ResultError = BrightRed,\n            ResultSuccess = BrightGreen,\n            ResultExpectedFailure = Warning,\n\n            Error = BrightRed,\n            Success = Green,\n\n            OriginalExpression = Cyan,\n            ReconstructedExpression = Yellow,\n\n            SecondaryText = LightGrey,\n            Headers = White\n        };\n\n        // Use constructed object for RAII guard\n        Colour( Code _colourCode );\n        Colour( Colour const& other );\n        ~Colour();\n\n        // Use static method for one-shot changes\n        static void use( Code _colourCode );\n\n    private:\n        bool m_moved;\n    };\n\n    inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }\n\n} // end namespace Catch\n\n// #included from: catch_interfaces_reporter.h\n#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED\n\n#include <string>\n#include <ostream>\n#include <map>\n#include <assert.h>\n\nnamespace Catch\n{\n    struct ReporterConfig {\n        explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )\n        :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}\n\n        ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )\n        :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}\n\n        std::ostream& stream() const    { return *m_stream; }\n        Ptr<IConfig const> fullConfig() const { return m_fullConfig; }\n\n    private:\n        std::ostream* m_stream;\n        Ptr<IConfig const> m_fullConfig;\n    };\n\n    struct ReporterPreferences {\n        ReporterPreferences()\n        : shouldRedirectStdOut( false )\n        {}\n\n        bool shouldRedirectStdOut;\n    };\n\n    template<typename T>\n    struct LazyStat : Option<T> {\n        LazyStat() : used( false ) {}\n        LazyStat& operator=( T const& _value ) {\n            Option<T>::operator=( _value );\n            used = false;\n            return *this;\n        }\n        void reset() {\n            Option<T>::reset();\n            used = false;\n        }\n        bool used;\n    };\n\n    struct TestRunInfo {\n        TestRunInfo( std::string const& _name ) : name( _name ) {}\n        std::string name;\n    };\n    struct GroupInfo {\n        GroupInfo(  std::string const& _name,\n                    std::size_t _groupIndex,\n                    std::size_t _groupsCount )\n        :   name( _name ),\n            groupIndex( _groupIndex ),\n            groupsCounts( _groupsCount )\n        {}\n\n        std::string name;\n        std::size_t groupIndex;\n        std::size_t groupsCounts;\n    };\n\n    struct AssertionStats {\n        AssertionStats( AssertionResult const& _assertionResult,\n                        std::vector<MessageInfo> const& _infoMessages,\n                        Totals const& _totals )\n        :   assertionResult( _assertionResult ),\n            infoMessages( _infoMessages ),\n            totals( _totals )\n        {\n            if( assertionResult.hasMessage() ) {\n                // Copy message into messages list.\n                // !TBD This should have been done earlier, somewhere\n                MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );\n                builder << assertionResult.getMessage();\n                builder.m_info.message = builder.m_stream.str();\n\n                infoMessages.push_back( builder.m_info );\n            }\n        }\n        virtual ~AssertionStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        AssertionStats( AssertionStats const& )              = default;\n        AssertionStats( AssertionStats && )                  = default;\n        AssertionStats& operator = ( AssertionStats const& ) = default;\n        AssertionStats& operator = ( AssertionStats && )     = default;\n#  endif\n\n        AssertionResult assertionResult;\n        std::vector<MessageInfo> infoMessages;\n        Totals totals;\n    };\n\n    struct SectionStats {\n        SectionStats(   SectionInfo const& _sectionInfo,\n                        Counts const& _assertions,\n                        double _durationInSeconds,\n                        bool _missingAssertions )\n        :   sectionInfo( _sectionInfo ),\n            assertions( _assertions ),\n            durationInSeconds( _durationInSeconds ),\n            missingAssertions( _missingAssertions )\n        {}\n        virtual ~SectionStats();\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        SectionStats( SectionStats const& )              = default;\n        SectionStats( SectionStats && )                  = default;\n        SectionStats& operator = ( SectionStats const& ) = default;\n        SectionStats& operator = ( SectionStats && )     = default;\n#  endif\n\n        SectionInfo sectionInfo;\n        Counts assertions;\n        double durationInSeconds;\n        bool missingAssertions;\n    };\n\n    struct TestCaseStats {\n        TestCaseStats(  TestCaseInfo const& _testInfo,\n                        Totals const& _totals,\n                        std::string const& _stdOut,\n                        std::string const& _stdErr,\n                        bool _aborting )\n        : testInfo( _testInfo ),\n            totals( _totals ),\n            stdOut( _stdOut ),\n            stdErr( _stdErr ),\n            aborting( _aborting )\n        {}\n        virtual ~TestCaseStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestCaseStats( TestCaseStats const& )              = default;\n        TestCaseStats( TestCaseStats && )                  = default;\n        TestCaseStats& operator = ( TestCaseStats const& ) = default;\n        TestCaseStats& operator = ( TestCaseStats && )     = default;\n#  endif\n\n        TestCaseInfo testInfo;\n        Totals totals;\n        std::string stdOut;\n        std::string stdErr;\n        bool aborting;\n    };\n\n    struct TestGroupStats {\n        TestGroupStats( GroupInfo const& _groupInfo,\n                        Totals const& _totals,\n                        bool _aborting )\n        :   groupInfo( _groupInfo ),\n            totals( _totals ),\n            aborting( _aborting )\n        {}\n        TestGroupStats( GroupInfo const& _groupInfo )\n        :   groupInfo( _groupInfo ),\n            aborting( false )\n        {}\n        virtual ~TestGroupStats();\n\n#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestGroupStats( TestGroupStats const& )              = default;\n        TestGroupStats( TestGroupStats && )                  = default;\n        TestGroupStats& operator = ( TestGroupStats const& ) = default;\n        TestGroupStats& operator = ( TestGroupStats && )     = default;\n#  endif\n\n        GroupInfo groupInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    struct TestRunStats {\n        TestRunStats(   TestRunInfo const& _runInfo,\n                        Totals const& _totals,\n                        bool _aborting )\n        :   runInfo( _runInfo ),\n            totals( _totals ),\n            aborting( _aborting )\n        {}\n        virtual ~TestRunStats();\n\n#  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS\n        TestRunStats( TestRunStats const& _other )\n        :   runInfo( _other.runInfo ),\n            totals( _other.totals ),\n            aborting( _other.aborting )\n        {}\n#  else\n        TestRunStats( TestRunStats const& )              = default;\n        TestRunStats( TestRunStats && )                  = default;\n        TestRunStats& operator = ( TestRunStats const& ) = default;\n        TestRunStats& operator = ( TestRunStats && )     = default;\n#  endif\n\n        TestRunInfo runInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    class MultipleReporters;\n\n    struct IStreamingReporter : IShared {\n        virtual ~IStreamingReporter();\n\n        // Implementing class must also provide the following static method:\n        // static std::string getDescription();\n\n        virtual ReporterPreferences getPreferences() const = 0;\n\n        virtual void noMatchingTestCases( std::string const& spec ) = 0;\n\n        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;\n\n        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;\n\n        // The return value indicates if the messages buffer should be cleared:\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;\n        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;\n\n        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;\n\n        virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }\n    };\n\n    struct IReporterFactory : IShared {\n        virtual ~IReporterFactory();\n        virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;\n        virtual std::string getDescription() const = 0;\n    };\n\n    struct IReporterRegistry {\n        typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;\n        typedef std::vector<Ptr<IReporterFactory> > Listeners;\n\n        virtual ~IReporterRegistry();\n        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;\n        virtual FactoryMap const& getFactories() const = 0;\n        virtual Listeners const& getListeners() const = 0;\n    };\n\n    Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );\n\n}\n\n#include <limits>\n#include <algorithm>\n\nnamespace Catch {\n\n    inline std::size_t listTests( Config const& config ) {\n\n        TestSpec testSpec = config.testSpec();\n        if( config.testSpec().hasFilters() )\n            Catch::cout() << \"Matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available test cases:\\n\";\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        }\n\n        std::size_t matchedTests = 0;\n        TextAttributes nameAttr, tagsAttr;\n        nameAttr.setInitialIndent( 2 ).setIndent( 4 );\n        tagsAttr.setIndent( 6 );\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            matchedTests++;\n            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();\n            Colour::Code colour = testCaseInfo.isHidden()\n                ? Colour::SecondaryText\n                : Colour::None;\n            Colour colourGuard( colour );\n\n            Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;\n            if( !testCaseInfo.tags.empty() )\n                Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;\n        }\n\n        if( !config.testSpec().hasFilters() )\n            Catch::cout() << pluralise( matchedTests, \"test case\" ) << \"\\n\" << std::endl;\n        else\n            Catch::cout() << pluralise( matchedTests, \"matching test case\" ) << \"\\n\" << std::endl;\n        return matchedTests;\n    }\n\n    inline std::size_t listTestsNamesOnly( Config const& config ) {\n        TestSpec testSpec = config.testSpec();\n        if( !config.testSpec().hasFilters() )\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        std::size_t matchedTests = 0;\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            matchedTests++;\n            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();\n            if( startsWith( testCaseInfo.name, \"#\" ) )\n               Catch::cout() << \"\\\"\" << testCaseInfo.name << \"\\\"\" << std::endl;\n            else\n               Catch::cout() << testCaseInfo.name << std::endl;\n        }\n        return matchedTests;\n    }\n\n    struct TagInfo {\n        TagInfo() : count ( 0 ) {}\n        void add( std::string const& spelling ) {\n            ++count;\n            spellings.insert( spelling );\n        }\n        std::string all() const {\n            std::string out;\n            for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();\n                        it != itEnd;\n                        ++it )\n                out += \"[\" + *it + \"]\";\n            return out;\n        }\n        std::set<std::string> spellings;\n        std::size_t count;\n    };\n\n    inline std::size_t listTags( Config const& config ) {\n        TestSpec testSpec = config.testSpec();\n        if( config.testSpec().hasFilters() )\n            Catch::cout() << \"Tags for matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available tags:\\n\";\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"*\" ).testSpec();\n        }\n\n        std::map<std::string, TagInfo> tagCounts;\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();\n                it != itEnd;\n                ++it ) {\n            for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),\n                                                        tagItEnd = it->getTestCaseInfo().tags.end();\n                    tagIt != tagItEnd;\n                    ++tagIt ) {\n                std::string tagName = *tagIt;\n                std::string lcaseTagName = toLower( tagName );\n                std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );\n                if( countIt == tagCounts.end() )\n                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;\n                countIt->second.add( tagName );\n            }\n        }\n\n        for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),\n                                                            countItEnd = tagCounts.end();\n                countIt != countItEnd;\n                ++countIt ) {\n            std::ostringstream oss;\n            oss << \"  \" << std::setw(2) << countIt->second.count << \"  \";\n            Text wrapper( countIt->second.all(), TextAttributes()\n                                                    .setInitialIndent( 0 )\n                                                    .setIndent( oss.str().size() )\n                                                    .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );\n            Catch::cout() << oss.str() << wrapper << \"\\n\";\n        }\n        Catch::cout() << pluralise( tagCounts.size(), \"tag\" ) << \"\\n\" << std::endl;\n        return tagCounts.size();\n    }\n\n    inline std::size_t listReporters( Config const& /*config*/ ) {\n        Catch::cout() << \"Available reporters:\\n\";\n        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n        IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;\n        std::size_t maxNameLen = 0;\n        for(it = itBegin; it != itEnd; ++it )\n            maxNameLen = (std::max)( maxNameLen, it->first.size() );\n\n        for(it = itBegin; it != itEnd; ++it ) {\n            Text wrapper( it->second->getDescription(), TextAttributes()\n                                                        .setInitialIndent( 0 )\n                                                        .setIndent( 7+maxNameLen )\n                                                        .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );\n            Catch::cout() << \"  \"\n                    << it->first\n                    << \":\"\n                    << std::string( maxNameLen - it->first.size() + 2, ' ' )\n                    << wrapper << \"\\n\";\n        }\n        Catch::cout() << std::endl;\n        return factories.size();\n    }\n\n    inline Option<std::size_t> list( Config const& config ) {\n        Option<std::size_t> listedCount;\n        if( config.listTests() )\n            listedCount = listedCount.valueOr(0) + listTests( config );\n        if( config.listTestNamesOnly() )\n            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );\n        if( config.listTags() )\n            listedCount = listedCount.valueOr(0) + listTags( config );\n        if( config.listReporters() )\n            listedCount = listedCount.valueOr(0) + listReporters( config );\n        return listedCount;\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_run_context.hpp\n#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED\n\n// #included from: catch_test_case_tracker.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED\n\n#include <map>\n#include <string>\n#include <assert.h>\n#include <vector>\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    struct ITracker : SharedImpl<> {\n        virtual ~ITracker();\n\n        // static queries\n        virtual std::string name() const = 0;\n\n        // dynamic queries\n        virtual bool isComplete() const = 0; // Successfully completed or failed\n        virtual bool isSuccessfullyCompleted() const = 0;\n        virtual bool isOpen() const = 0; // Started but not complete\n        virtual bool hasChildren() const = 0;\n\n        virtual ITracker& parent() = 0;\n\n        // actions\n        virtual void close() = 0; // Successfully complete\n        virtual void fail() = 0;\n        virtual void markAsNeedingAnotherRun() = 0;\n\n        virtual void addChild( Ptr<ITracker> const& child ) = 0;\n        virtual ITracker* findChild( std::string const& name ) = 0;\n        virtual void openChild() = 0;\n\n        // Debug/ checking\n        virtual bool isSectionTracker() const = 0;\n        virtual bool isIndexTracker() const = 0;\n    };\n\n    class TrackerContext {\n\n        enum RunState {\n            NotStarted,\n            Executing,\n            CompletedCycle\n        };\n\n        Ptr<ITracker> m_rootTracker;\n        ITracker* m_currentTracker;\n        RunState m_runState;\n\n    public:\n\n        static TrackerContext& instance() {\n            static TrackerContext s_instance;\n            return s_instance;\n        }\n\n        TrackerContext()\n        :   m_currentTracker( CATCH_NULL ),\n            m_runState( NotStarted )\n        {}\n\n        ITracker& startRun();\n\n        void endRun() {\n            m_rootTracker.reset();\n            m_currentTracker = CATCH_NULL;\n            m_runState = NotStarted;\n        }\n\n        void startCycle() {\n            m_currentTracker = m_rootTracker.get();\n            m_runState = Executing;\n        }\n        void completeCycle() {\n            m_runState = CompletedCycle;\n        }\n\n        bool completedCycle() const {\n            return m_runState == CompletedCycle;\n        }\n        ITracker& currentTracker() {\n            return *m_currentTracker;\n        }\n        void setCurrentTracker( ITracker* tracker ) {\n            m_currentTracker = tracker;\n        }\n    };\n\n    class TrackerBase : public ITracker {\n    protected:\n        enum CycleState {\n            NotStarted,\n            Executing,\n            ExecutingChildren,\n            NeedsAnotherRun,\n            CompletedSuccessfully,\n            Failed\n        };\n        class TrackerHasName {\n            std::string m_name;\n        public:\n            TrackerHasName( std::string const& name ) : m_name( name ) {}\n            bool operator ()( Ptr<ITracker> const& tracker ) {\n                return tracker->name() == m_name;\n            }\n        };\n        typedef std::vector<Ptr<ITracker> > Children;\n        std::string m_name;\n        TrackerContext& m_ctx;\n        ITracker* m_parent;\n        Children m_children;\n        CycleState m_runState;\n    public:\n        TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )\n        :   m_name( name ),\n            m_ctx( ctx ),\n            m_parent( parent ),\n            m_runState( NotStarted )\n        {}\n        virtual ~TrackerBase();\n\n        virtual std::string name() const CATCH_OVERRIDE {\n            return m_name;\n        }\n        virtual bool isComplete() const CATCH_OVERRIDE {\n            return m_runState == CompletedSuccessfully || m_runState == Failed;\n        }\n        virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {\n            return m_runState == CompletedSuccessfully;\n        }\n        virtual bool isOpen() const CATCH_OVERRIDE {\n            return m_runState != NotStarted && !isComplete();\n        }\n        virtual bool hasChildren() const CATCH_OVERRIDE {\n            return !m_children.empty();\n        }\n\n        virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {\n            m_children.push_back( child );\n        }\n\n        virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {\n            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );\n            return( it != m_children.end() )\n                ? it->get()\n                : CATCH_NULL;\n        }\n        virtual ITracker& parent() CATCH_OVERRIDE {\n            assert( m_parent ); // Should always be non-null except for root\n            return *m_parent;\n        }\n\n        virtual void openChild() CATCH_OVERRIDE {\n            if( m_runState != ExecutingChildren ) {\n                m_runState = ExecutingChildren;\n                if( m_parent )\n                    m_parent->openChild();\n            }\n        }\n\n        virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }\n        virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }\n\n        void open() {\n            m_runState = Executing;\n            moveToThis();\n            if( m_parent )\n                m_parent->openChild();\n        }\n\n        virtual void close() CATCH_OVERRIDE {\n\n            // Close any still open children (e.g. generators)\n            while( &m_ctx.currentTracker() != this )\n                m_ctx.currentTracker().close();\n\n            switch( m_runState ) {\n                case NotStarted:\n                case CompletedSuccessfully:\n                case Failed:\n                    throw std::logic_error( \"Illogical state\" );\n\n                case NeedsAnotherRun:\n                    break;;\n\n                case Executing:\n                    m_runState = CompletedSuccessfully;\n                    break;\n                case ExecutingChildren:\n                    if( m_children.empty() || m_children.back()->isComplete() )\n                        m_runState = CompletedSuccessfully;\n                    break;\n\n                default:\n                    throw std::logic_error( \"Unexpected state\" );\n            }\n            moveToParent();\n            m_ctx.completeCycle();\n        }\n        virtual void fail() CATCH_OVERRIDE {\n            m_runState = Failed;\n            if( m_parent )\n                m_parent->markAsNeedingAnotherRun();\n            moveToParent();\n            m_ctx.completeCycle();\n        }\n        virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {\n            m_runState = NeedsAnotherRun;\n        }\n    private:\n        void moveToParent() {\n            assert( m_parent );\n            m_ctx.setCurrentTracker( m_parent );\n        }\n        void moveToThis() {\n            m_ctx.setCurrentTracker( this );\n        }\n    };\n\n    class SectionTracker : public TrackerBase {\n    public:\n        SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )\n        :   TrackerBase( name, ctx, parent )\n        {}\n        virtual ~SectionTracker();\n\n        virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }\n\n        static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {\n            SectionTracker* section = CATCH_NULL;\n\n            ITracker& currentTracker = ctx.currentTracker();\n            if( ITracker* childTracker = currentTracker.findChild( name ) ) {\n                assert( childTracker );\n                assert( childTracker->isSectionTracker() );\n                section = static_cast<SectionTracker*>( childTracker );\n            }\n            else {\n                section = new SectionTracker( name, ctx, &currentTracker );\n                currentTracker.addChild( section );\n            }\n            if( !ctx.completedCycle() && !section->isComplete() ) {\n\n                section->open();\n            }\n            return *section;\n        }\n    };\n\n    class IndexTracker : public TrackerBase {\n        int m_size;\n        int m_index;\n    public:\n        IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )\n        :   TrackerBase( name, ctx, parent ),\n            m_size( size ),\n            m_index( -1 )\n        {}\n        virtual ~IndexTracker();\n\n        virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }\n\n        static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {\n            IndexTracker* tracker = CATCH_NULL;\n\n            ITracker& currentTracker = ctx.currentTracker();\n            if( ITracker* childTracker = currentTracker.findChild( name ) ) {\n                assert( childTracker );\n                assert( childTracker->isIndexTracker() );\n                tracker = static_cast<IndexTracker*>( childTracker );\n            }\n            else {\n                tracker = new IndexTracker( name, ctx, &currentTracker, size );\n                currentTracker.addChild( tracker );\n            }\n\n            if( !ctx.completedCycle() && !tracker->isComplete() ) {\n                if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )\n                    tracker->moveNext();\n                tracker->open();\n            }\n\n            return *tracker;\n        }\n\n        int index() const { return m_index; }\n\n        void moveNext() {\n            m_index++;\n            m_children.clear();\n        }\n\n        virtual void close() CATCH_OVERRIDE {\n            TrackerBase::close();\n            if( m_runState == CompletedSuccessfully && m_index < m_size-1 )\n                m_runState = Executing;\n        }\n    };\n\n    inline ITracker& TrackerContext::startRun() {\n        m_rootTracker = new SectionTracker( \"{root}\", *this, CATCH_NULL );\n        m_currentTracker = CATCH_NULL;\n        m_runState = Executing;\n        return *m_rootTracker;\n    }\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\nusing TestCaseTracking::IndexTracker;\n\n} // namespace Catch\n\n// #included from: catch_fatal_condition.hpp\n#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED\n\nnamespace Catch {\n\n    // Report the error condition then exit the process\n    inline void fatal( std::string const& message, int exitCode ) {\n        IContext& context = Catch::getCurrentContext();\n        IResultCapture* resultCapture = context.getResultCapture();\n        resultCapture->handleFatalErrorCondition( message );\n\n\t\tif( Catch::alwaysTrue() ) // avoids \"no return\" warnings\n            exit( exitCode );\n    }\n\n} // namespace Catch\n\n#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////\n\nnamespace Catch {\n\n    struct FatalConditionHandler {\n\t\tvoid reset() {}\n\t};\n\n} // namespace Catch\n\n#else // Not Windows - assumed to be POSIX compatible //////////////////////////\n\n#include <signal.h>\n\nnamespace Catch {\n\n    struct SignalDefs { int id; const char* name; };\n    extern SignalDefs signalDefs[];\n    SignalDefs signalDefs[] = {\n            { SIGINT,  \"SIGINT - Terminal interrupt signal\" },\n            { SIGILL,  \"SIGILL - Illegal instruction signal\" },\n            { SIGFPE,  \"SIGFPE - Floating point error signal\" },\n            { SIGSEGV, \"SIGSEGV - Segmentation violation signal\" },\n            { SIGTERM, \"SIGTERM - Termination request signal\" },\n            { SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\" }\n        };\n\n    struct FatalConditionHandler {\n\n        static void handleSignal( int sig ) {\n            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                if( sig == signalDefs[i].id )\n                    fatal( signalDefs[i].name, -sig );\n            fatal( \"<unknown signal>\", -sig );\n        }\n\n        FatalConditionHandler() : m_isSet( true ) {\n            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                signal( signalDefs[i].id, handleSignal );\n        }\n        ~FatalConditionHandler() {\n            reset();\n        }\n        void reset() {\n            if( m_isSet ) {\n                for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )\n                    signal( signalDefs[i].id, SIG_DFL );\n                m_isSet = false;\n            }\n        }\n\n        bool m_isSet;\n    };\n\n} // namespace Catch\n\n#endif // not Windows\n\n#include <set>\n#include <string>\n\nnamespace Catch {\n\n    class StreamRedirect {\n\n    public:\n        StreamRedirect( std::ostream& stream, std::string& targetString )\n        :   m_stream( stream ),\n            m_prevBuf( stream.rdbuf() ),\n            m_targetString( targetString )\n        {\n            stream.rdbuf( m_oss.rdbuf() );\n        }\n\n        ~StreamRedirect() {\n            m_targetString += m_oss.str();\n            m_stream.rdbuf( m_prevBuf );\n        }\n\n    private:\n        std::ostream& m_stream;\n        std::streambuf* m_prevBuf;\n        std::ostringstream m_oss;\n        std::string& m_targetString;\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class RunContext : public IResultCapture, public IRunner {\n\n        RunContext( RunContext const& );\n        void operator =( RunContext const& );\n\n    public:\n\n        explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )\n        :   m_runInfo( _config->name() ),\n            m_context( getCurrentMutableContext() ),\n            m_activeTestCase( CATCH_NULL ),\n            m_config( _config ),\n            m_reporter( reporter )\n        {\n            m_context.setRunner( this );\n            m_context.setConfig( m_config );\n            m_context.setResultCapture( this );\n            m_reporter->testRunStarting( m_runInfo );\n        }\n\n        virtual ~RunContext() {\n            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );\n        }\n\n        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {\n            m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );\n        }\n        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {\n            m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );\n        }\n\n        Totals runTest( TestCase const& testCase ) {\n            Totals prevTotals = m_totals;\n\n            std::string redirectedCout;\n            std::string redirectedCerr;\n\n            TestCaseInfo testInfo = testCase.getTestCaseInfo();\n\n            m_reporter->testCaseStarting( testInfo );\n\n            m_activeTestCase = &testCase;\n\n            do {\n                m_trackerContext.startRun();\n                do {\n                    m_trackerContext.startCycle();\n                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );\n                    runCurrentTest( redirectedCout, redirectedCerr );\n                }\n                while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );\n            }\n            // !TBD: deprecated - this will be replaced by indexed trackers\n            while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );\n\n            Totals deltaTotals = m_totals.delta( prevTotals );\n            if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {\n                deltaTotals.assertions.failed++;\n                deltaTotals.testCases.passed--;\n                deltaTotals.testCases.failed++;\n            }\n            m_totals.testCases += deltaTotals.testCases;\n            m_reporter->testCaseEnded( TestCaseStats(   testInfo,\n                                                        deltaTotals,\n                                                        redirectedCout,\n                                                        redirectedCerr,\n                                                        aborting() ) );\n\n            m_activeTestCase = CATCH_NULL;\n            m_testCaseTracker = CATCH_NULL;\n\n            return deltaTotals;\n        }\n\n        Ptr<IConfig const> config() const {\n            return m_config;\n        }\n\n    private: // IResultCapture\n\n        virtual void assertionEnded( AssertionResult const& result ) {\n            if( result.getResultType() == ResultWas::Ok ) {\n                m_totals.assertions.passed++;\n            }\n            else if( !result.isOk() ) {\n                m_totals.assertions.failed++;\n            }\n\n            if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )\n                m_messages.clear();\n\n            // Reset working state\n            m_lastAssertionInfo = AssertionInfo( \"\", m_lastAssertionInfo.lineInfo, \"{Unknown expression after the reported line}\" , m_lastAssertionInfo.resultDisposition );\n            m_lastResult = result;\n        }\n\n        virtual bool sectionStarted (\n            SectionInfo const& sectionInfo,\n            Counts& assertions\n        )\n        {\n            std::ostringstream oss;\n            oss << sectionInfo.name << \"@\" << sectionInfo.lineInfo;\n\n            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );\n            if( !sectionTracker.isOpen() )\n                return false;\n            m_activeSections.push_back( &sectionTracker );\n\n            m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;\n\n            m_reporter->sectionStarting( sectionInfo );\n\n            assertions = m_totals.assertions;\n\n            return true;\n        }\n        bool testForMissingAssertions( Counts& assertions ) {\n            if( assertions.total() != 0 )\n                return false;\n            if( !m_config->warnAboutMissingAssertions() )\n                return false;\n            if( m_trackerContext.currentTracker().hasChildren() )\n                return false;\n            m_totals.assertions.failed++;\n            assertions.failed++;\n            return true;\n        }\n\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) {\n            Counts assertions = m_totals.assertions - endInfo.prevAssertions;\n            bool missingAssertions = testForMissingAssertions( assertions );\n\n            if( !m_activeSections.empty() ) {\n                m_activeSections.back()->close();\n                m_activeSections.pop_back();\n            }\n\n            m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );\n            m_messages.clear();\n        }\n\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {\n            if( m_unfinishedSections.empty() )\n                m_activeSections.back()->fail();\n            else\n                m_activeSections.back()->close();\n            m_activeSections.pop_back();\n\n            m_unfinishedSections.push_back( endInfo );\n        }\n\n        virtual void pushScopedMessage( MessageInfo const& message ) {\n            m_messages.push_back( message );\n        }\n\n        virtual void popScopedMessage( MessageInfo const& message ) {\n            m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );\n        }\n\n        virtual std::string getCurrentTestName() const {\n            return m_activeTestCase\n                ? m_activeTestCase->getTestCaseInfo().name\n                : \"\";\n        }\n\n        virtual const AssertionResult* getLastResult() const {\n            return &m_lastResult;\n        }\n\n        virtual void handleFatalErrorCondition( std::string const& message ) {\n            ResultBuilder resultBuilder = makeUnexpectedResultBuilder();\n            resultBuilder.setResultType( ResultWas::FatalErrorCondition );\n            resultBuilder << message;\n            resultBuilder.captureExpression();\n\n            handleUnfinishedSections();\n\n            // Recreate section for test case (as we will lose the one that was in scope)\n            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );\n\n            Counts assertions;\n            assertions.failed = 1;\n            SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );\n            m_reporter->sectionEnded( testCaseSectionStats );\n\n            TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();\n\n            Totals deltaTotals;\n            deltaTotals.testCases.failed = 1;\n            m_reporter->testCaseEnded( TestCaseStats(   testInfo,\n                                                        deltaTotals,\n                                                        \"\",\n                                                        \"\",\n                                                        false ) );\n            m_totals.testCases.failed++;\n            testGroupEnded( \"\", m_totals, 1, 1 );\n            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );\n        }\n\n    public:\n        // !TBD We need to do this another way!\n        bool aborting() const {\n            return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );\n        }\n\n    private:\n\n        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {\n            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );\n            m_reporter->sectionStarting( testCaseSection );\n            Counts prevAssertions = m_totals.assertions;\n            double duration = 0;\n            try {\n                m_lastAssertionInfo = AssertionInfo( \"TEST_CASE\", testCaseInfo.lineInfo, \"\", ResultDisposition::Normal );\n\n                seedRng( *m_config );\n\n                Timer timer;\n                timer.start();\n                if( m_reporter->getPreferences().shouldRedirectStdOut ) {\n                    StreamRedirect coutRedir( Catch::cout(), redirectedCout );\n                    StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );\n                    invokeActiveTestCase();\n                }\n                else {\n                    invokeActiveTestCase();\n                }\n                duration = timer.getElapsedSeconds();\n            }\n            catch( TestFailureException& ) {\n                // This just means the test was aborted due to failure\n            }\n            catch(...) {\n                makeUnexpectedResultBuilder().useActiveException();\n            }\n            m_testCaseTracker->close();\n            handleUnfinishedSections();\n            m_messages.clear();\n\n            Counts assertions = m_totals.assertions - prevAssertions;\n            bool missingAssertions = testForMissingAssertions( assertions );\n\n            if( testCaseInfo.okToFail() ) {\n                std::swap( assertions.failedButOk, assertions.failed );\n                m_totals.assertions.failed -= assertions.failedButOk;\n                m_totals.assertions.failedButOk += assertions.failedButOk;\n            }\n\n            SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );\n            m_reporter->sectionEnded( testCaseSectionStats );\n        }\n\n        void invokeActiveTestCase() {\n            FatalConditionHandler fatalConditionHandler; // Handle signals\n            m_activeTestCase->invoke();\n            fatalConditionHandler.reset();\n        }\n\n    private:\n\n        ResultBuilder makeUnexpectedResultBuilder() const {\n            return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),\n                                    m_lastAssertionInfo.lineInfo,\n                                    m_lastAssertionInfo.capturedExpression.c_str(),\n                                    m_lastAssertionInfo.resultDisposition );\n        }\n\n        void handleUnfinishedSections() {\n            // If sections ended prematurely due to an exception we stored their\n            // infos here so we can tear them down outside the unwind process.\n            for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),\n                        itEnd = m_unfinishedSections.rend();\n                    it != itEnd;\n                    ++it )\n                sectionEnded( *it );\n            m_unfinishedSections.clear();\n        }\n\n        TestRunInfo m_runInfo;\n        IMutableContext& m_context;\n        TestCase const* m_activeTestCase;\n        ITracker* m_testCaseTracker;\n        ITracker* m_currentSectionTracker;\n        AssertionResult m_lastResult;\n\n        Ptr<IConfig const> m_config;\n        Totals m_totals;\n        Ptr<IStreamingReporter> m_reporter;\n        std::vector<MessageInfo> m_messages;\n        AssertionInfo m_lastAssertionInfo;\n        std::vector<SectionEndInfo> m_unfinishedSections;\n        std::vector<ITracker*> m_activeSections;\n        TrackerContext m_trackerContext;\n    };\n\n    IResultCapture& getResultCapture() {\n        if( IResultCapture* capture = getCurrentContext().getResultCapture() )\n            return *capture;\n        else\n            throw std::logic_error( \"No result capture instance\" );\n    }\n\n} // end namespace Catch\n\n// #included from: internal/catch_version.h\n#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED\n\nnamespace Catch {\n\n    // Versioning information\n    struct Version {\n        Version(    unsigned int _majorVersion,\n                    unsigned int _minorVersion,\n                    unsigned int _patchNumber,\n                    std::string const& _branchName,\n                    unsigned int _buildNumber );\n\n        unsigned int const majorVersion;\n        unsigned int const minorVersion;\n        unsigned int const patchNumber;\n\n        // buildNumber is only used if branchName is not null\n        std::string const branchName;\n        unsigned int const buildNumber;\n\n        friend std::ostream& operator << ( std::ostream& os, Version const& version );\n\n    private:\n        void operator=( Version const& );\n    };\n\n    extern Version libraryVersion;\n}\n\n#include <fstream>\n#include <stdlib.h>\n#include <limits>\n\nnamespace Catch {\n\n    Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {\n        Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );\n        if( !reporter ) {\n            std::ostringstream oss;\n            oss << \"No reporter registered with name: '\" << reporterName << \"'\";\n            throw std::domain_error( oss.str() );\n        }\n        return reporter;\n    }\n\n    Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {\n        std::vector<std::string> reporters = config->getReporterNames();\n        if( reporters.empty() )\n            reporters.push_back( \"console\" );\n\n        Ptr<IStreamingReporter> reporter;\n        for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();\n                it != itEnd;\n                ++it )\n            reporter = addReporter( reporter, createReporter( *it, config ) );\n        return reporter;\n    }\n    Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {\n        IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();\n        for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();\n                it != itEnd;\n                ++it )\n            reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );\n        return reporters;\n    }\n\n    Totals runTests( Ptr<Config> const& config ) {\n\n        Ptr<IConfig const> iconfig = config.get();\n\n        Ptr<IStreamingReporter> reporter = makeReporter( config );\n        reporter = addListeners( iconfig, reporter );\n\n        RunContext context( iconfig, reporter );\n\n        Totals totals;\n\n        context.testGroupStarting( config->name(), 1, 1 );\n\n        TestSpec testSpec = config->testSpec();\n        if( !testSpec.hasFilters() )\n            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( \"~[.]\" ).testSpec(); // All not hidden tests\n\n        std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );\n        for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();\n                it != itEnd;\n                ++it ) {\n            if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )\n                totals += context.runTest( *it );\n            else\n                reporter->skipTest( *it );\n        }\n\n        context.testGroupEnded( iconfig->name(), totals, 1, 1 );\n        return totals;\n    }\n\n    void applyFilenamesAsTags( IConfig const& config ) {\n        std::vector<TestCase> const& tests = getAllTestCasesSorted( config );\n        for(std::size_t i = 0; i < tests.size(); ++i ) {\n            TestCase& test = const_cast<TestCase&>( tests[i] );\n            std::set<std::string> tags = test.tags;\n\n            std::string filename = test.lineInfo.file;\n            std::string::size_type lastSlash = filename.find_last_of( \"\\\\/\" );\n            if( lastSlash != std::string::npos )\n                filename = filename.substr( lastSlash+1 );\n\n            std::string::size_type lastDot = filename.find_last_of( \".\" );\n            if( lastDot != std::string::npos )\n                filename = filename.substr( 0, lastDot );\n\n            tags.insert( \"#\" + filename );\n            setTags( test, tags );\n        }\n    }\n\n    class Session : NonCopyable {\n        static bool alreadyInstantiated;\n\n    public:\n\n        struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };\n\n        Session()\n        : m_cli( makeCommandLineParser() ) {\n            if( alreadyInstantiated ) {\n                std::string msg = \"Only one instance of Catch::Session can ever be used\";\n                Catch::cerr() << msg << std::endl;\n                throw std::logic_error( msg );\n            }\n            alreadyInstantiated = true;\n        }\n        ~Session() {\n            Catch::cleanUp();\n        }\n\n        void showHelp( std::string const& processName ) {\n            Catch::cout() << \"\\nCatch v\" << libraryVersion << \"\\n\";\n\n            m_cli.usage( Catch::cout(), processName );\n            Catch::cout() << \"For more detail usage please see the project docs\\n\" << std::endl;\n        }\n\n        int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {\n            try {\n                m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );\n                m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );\n                if( m_configData.showHelp )\n                    showHelp( m_configData.processName );\n                m_config.reset();\n            }\n            catch( std::exception& ex ) {\n                {\n                    Colour colourGuard( Colour::Red );\n                    Catch::cerr()\n                        << \"\\nError(s) in input:\\n\"\n                        << Text( ex.what(), TextAttributes().setIndent(2) )\n                        << \"\\n\\n\";\n                }\n                m_cli.usage( Catch::cout(), m_configData.processName );\n                return (std::numeric_limits<int>::max)();\n            }\n            return 0;\n        }\n\n        void useConfigData( ConfigData const& _configData ) {\n            m_configData = _configData;\n            m_config.reset();\n        }\n\n        int run( int argc, char const* const* const argv ) {\n\n            int returnCode = applyCommandLine( argc, argv );\n            if( returnCode == 0 )\n                returnCode = run();\n            return returnCode;\n        }\n\n        int run() {\n            if( m_configData.showHelp )\n                return 0;\n\n            try\n            {\n                config(); // Force config to be constructed\n\n                seedRng( *m_config );\n\n                if( m_configData.filenamesAsTags )\n                    applyFilenamesAsTags( *m_config );\n\n                // Handle list request\n                if( Option<std::size_t> listed = list( config() ) )\n                    return static_cast<int>( *listed );\n\n                return static_cast<int>( runTests( m_config ).assertions.failed );\n            }\n            catch( std::exception& ex ) {\n                Catch::cerr() << ex.what() << std::endl;\n                return (std::numeric_limits<int>::max)();\n            }\n        }\n\n        Clara::CommandLine<ConfigData> const& cli() const {\n            return m_cli;\n        }\n        std::vector<Clara::Parser::Token> const& unusedTokens() const {\n            return m_unusedTokens;\n        }\n        ConfigData& configData() {\n            return m_configData;\n        }\n        Config& config() {\n            if( !m_config )\n                m_config = new Config( m_configData );\n            return *m_config;\n        }\n    private:\n        Clara::CommandLine<ConfigData> m_cli;\n        std::vector<Clara::Parser::Token> m_unusedTokens;\n        ConfigData m_configData;\n        Ptr<Config> m_config;\n    };\n\n    bool Session::alreadyInstantiated = false;\n\n} // end namespace Catch\n\n// #included from: catch_registry_hub.hpp\n#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED\n\n// #included from: catch_test_case_registry_impl.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED\n\n#include <vector>\n#include <set>\n#include <sstream>\n#include <iostream>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct RandomNumberGenerator {\n        typedef std::ptrdiff_t result_type;\n\n        result_type operator()( result_type n ) const { return std::rand() % n; }\n\n#ifdef CATCH_CONFIG_CPP11_SHUFFLE\n        static constexpr result_type min() { return 0; }\n        static constexpr result_type max() { return 1000000; }\n        result_type operator()() const { return std::rand() % max(); }\n#endif\n        template<typename V>\n        static void shuffle( V& vector ) {\n            RandomNumberGenerator rng;\n#ifdef CATCH_CONFIG_CPP11_SHUFFLE\n            std::shuffle( vector.begin(), vector.end(), rng );\n#else\n            std::random_shuffle( vector.begin(), vector.end(), rng );\n#endif\n        }\n    };\n\n    inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {\n\n        std::vector<TestCase> sorted = unsortedTestCases;\n\n        switch( config.runOrder() ) {\n            case RunTests::InLexicographicalOrder:\n                std::sort( sorted.begin(), sorted.end() );\n                break;\n            case RunTests::InRandomOrder:\n                {\n                    seedRng( config );\n                    RandomNumberGenerator::shuffle( sorted );\n                }\n                break;\n            case RunTests::InDeclarationOrder:\n                // already in declaration order\n                break;\n        }\n        return sorted;\n    }\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {\n        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );\n    }\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {\n        std::set<TestCase> seenFunctions;\n        for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();\n            it != itEnd;\n            ++it ) {\n            std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );\n            if( !prev.second ) {\n                std::ostringstream ss;\n\n                ss  << Colour( Colour::Red )\n                    << \"error: TEST_CASE( \\\"\" << it->name << \"\\\" ) already defined.\\n\"\n                    << \"\\tFirst seen at \" << prev.first->getTestCaseInfo().lineInfo << \"\\n\"\n                    << \"\\tRedefined at \" << it->getTestCaseInfo().lineInfo << std::endl;\n\n                throw std::runtime_error(ss.str());\n            }\n        }\n    }\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {\n        std::vector<TestCase> filtered;\n        filtered.reserve( testCases.size() );\n        for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();\n                it != itEnd;\n                ++it )\n            if( matchTest( *it, testSpec, config ) )\n                filtered.push_back( *it );\n        return filtered;\n    }\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {\n        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );\n    }\n\n    class TestRegistry : public ITestCaseRegistry {\n    public:\n        TestRegistry()\n        :   m_currentSortOrder( RunTests::InDeclarationOrder ),\n            m_unnamedCount( 0 )\n        {}\n        virtual ~TestRegistry();\n\n        virtual void registerTest( TestCase const& testCase ) {\n            std::string name = testCase.getTestCaseInfo().name;\n            if( name == \"\" ) {\n                std::ostringstream oss;\n                oss << \"Anonymous test case \" << ++m_unnamedCount;\n                return registerTest( testCase.withName( oss.str() ) );\n            }\n            m_functions.push_back( testCase );\n        }\n\n        virtual std::vector<TestCase> const& getAllTests() const {\n            return m_functions;\n        }\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {\n            if( m_sortedFunctions.empty() )\n                enforceNoDuplicateTestCases( m_functions );\n\n            if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {\n                m_sortedFunctions = sortTests( config, m_functions );\n                m_currentSortOrder = config.runOrder();\n            }\n            return m_sortedFunctions;\n        }\n\n    private:\n        std::vector<TestCase> m_functions;\n        mutable RunTests::InWhatOrder m_currentSortOrder;\n        mutable std::vector<TestCase> m_sortedFunctions;\n        size_t m_unnamedCount;\n        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class FreeFunctionTestCase : public SharedImpl<ITestCase> {\n    public:\n\n        FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}\n\n        virtual void invoke() const {\n            m_fun();\n        }\n\n    private:\n        virtual ~FreeFunctionTestCase();\n\n        TestFunction m_fun;\n    };\n\n    inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {\n        std::string className = classOrQualifiedMethodName;\n        if( startsWith( className, \"&\" ) )\n        {\n            std::size_t lastColons = className.rfind( \"::\" );\n            std::size_t penultimateColons = className.rfind( \"::\", lastColons-1 );\n            if( penultimateColons == std::string::npos )\n                penultimateColons = 1;\n            className = className.substr( penultimateColons, lastColons-penultimateColons );\n        }\n        return className;\n    }\n\n    void registerTestCase\n        (   ITestCase* testCase,\n            char const* classOrQualifiedMethodName,\n            NameAndDesc const& nameAndDesc,\n            SourceLineInfo const& lineInfo ) {\n\n        getMutableRegistryHub().registerTest\n            ( makeTestCase\n                (   testCase,\n                    extractClassName( classOrQualifiedMethodName ),\n                    nameAndDesc.name,\n                    nameAndDesc.description,\n                    lineInfo ) );\n    }\n    void registerTestCaseFunction\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc ) {\n        registerTestCase( new FreeFunctionTestCase( function ), \"\", nameAndDesc, lineInfo );\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    AutoReg::AutoReg\n        (   TestFunction function,\n            SourceLineInfo const& lineInfo,\n            NameAndDesc const& nameAndDesc ) {\n        registerTestCaseFunction( function, lineInfo, nameAndDesc );\n    }\n\n    AutoReg::~AutoReg() {}\n\n} // end namespace Catch\n\n// #included from: catch_reporter_registry.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED\n\n#include <map>\n\nnamespace Catch {\n\n    class ReporterRegistry : public IReporterRegistry {\n\n    public:\n\n        virtual ~ReporterRegistry() CATCH_OVERRIDE {}\n\n        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {\n            FactoryMap::const_iterator it =  m_factories.find( name );\n            if( it == m_factories.end() )\n                return CATCH_NULL;\n            return it->second->create( ReporterConfig( config ) );\n        }\n\n        void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {\n            m_factories.insert( std::make_pair( name, factory ) );\n        }\n        void registerListener( Ptr<IReporterFactory> const& factory ) {\n            m_listeners.push_back( factory );\n        }\n\n        virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {\n            return m_factories;\n        }\n        virtual Listeners const& getListeners() const CATCH_OVERRIDE {\n            return m_listeners;\n        }\n\n    private:\n        FactoryMap m_factories;\n        Listeners m_listeners;\n    };\n}\n\n// #included from: catch_exception_translator_registry.hpp\n#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED\n\n#ifdef __OBJC__\n#import \"Foundation/Foundation.h\"\n#endif\n\nnamespace Catch {\n\n    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {\n    public:\n        ~ExceptionTranslatorRegistry() {\n            deleteAll( m_translators );\n        }\n\n        virtual void registerTranslator( const IExceptionTranslator* translator ) {\n            m_translators.push_back( translator );\n        }\n\n        virtual std::string translateActiveException() const {\n            try {\n#ifdef __OBJC__\n                // In Objective-C try objective-c exceptions first\n                @try {\n                    return tryTranslators();\n                }\n                @catch (NSException *exception) {\n                    return Catch::toString( [exception description] );\n                }\n#else\n                return tryTranslators();\n#endif\n            }\n            catch( TestFailureException& ) {\n                throw;\n            }\n            catch( std::exception& ex ) {\n                return ex.what();\n            }\n            catch( std::string& msg ) {\n                return msg;\n            }\n            catch( const char* msg ) {\n                return msg;\n            }\n            catch(...) {\n                return \"Unknown exception\";\n            }\n        }\n\n        std::string tryTranslators() const {\n            if( m_translators.empty() )\n                throw;\n            else\n                return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );\n        }\n\n    private:\n        std::vector<const IExceptionTranslator*> m_translators;\n    };\n}\n\nnamespace Catch {\n\n    namespace {\n\n        class RegistryHub : public IRegistryHub, public IMutableRegistryHub {\n\n            RegistryHub( RegistryHub const& );\n            void operator=( RegistryHub const& );\n\n        public: // IRegistryHub\n            RegistryHub() {\n            }\n            virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {\n                return m_reporterRegistry;\n            }\n            virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {\n                return m_testCaseRegistry;\n            }\n            virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {\n                return m_exceptionTranslatorRegistry;\n            }\n\n        public: // IMutableRegistryHub\n            virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {\n                m_reporterRegistry.registerReporter( name, factory );\n            }\n            virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {\n                m_reporterRegistry.registerListener( factory );\n            }\n            virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {\n                m_testCaseRegistry.registerTest( testInfo );\n            }\n            virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {\n                m_exceptionTranslatorRegistry.registerTranslator( translator );\n            }\n\n        private:\n            TestRegistry m_testCaseRegistry;\n            ReporterRegistry m_reporterRegistry;\n            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;\n        };\n\n        // Single, global, instance\n        inline RegistryHub*& getTheRegistryHub() {\n            static RegistryHub* theRegistryHub = CATCH_NULL;\n            if( !theRegistryHub )\n                theRegistryHub = new RegistryHub();\n            return theRegistryHub;\n        }\n    }\n\n    IRegistryHub& getRegistryHub() {\n        return *getTheRegistryHub();\n    }\n    IMutableRegistryHub& getMutableRegistryHub() {\n        return *getTheRegistryHub();\n    }\n    void cleanUp() {\n        delete getTheRegistryHub();\n        getTheRegistryHub() = CATCH_NULL;\n        cleanUpContext();\n    }\n    std::string translateActiveException() {\n        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_notimplemented_exception.hpp\n#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED\n\n#include <ostream>\n\nnamespace Catch {\n\n    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )\n    :   m_lineInfo( lineInfo ) {\n        std::ostringstream oss;\n        oss << lineInfo << \": function \";\n        oss << \"not implemented\";\n        m_what = oss.str();\n    }\n\n    const char* NotImplementedException::what() const CATCH_NOEXCEPT {\n        return m_what.c_str();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_context_impl.hpp\n#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED\n\n// #included from: catch_stream.hpp\n#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED\n\n#include <stdexcept>\n#include <cstdio>\n#include <iostream>\n\nnamespace Catch {\n\n    template<typename WriterF, size_t bufferSize=256>\n    class StreamBufImpl : public StreamBufBase {\n        char data[bufferSize];\n        WriterF m_writer;\n\n    public:\n        StreamBufImpl() {\n            setp( data, data + sizeof(data) );\n        }\n\n        ~StreamBufImpl() CATCH_NOEXCEPT {\n            sync();\n        }\n\n    private:\n        int overflow( int c ) {\n            sync();\n\n            if( c != EOF ) {\n                if( pbase() == epptr() )\n                    m_writer( std::string( 1, static_cast<char>( c ) ) );\n                else\n                    sputc( static_cast<char>( c ) );\n            }\n            return 0;\n        }\n\n        int sync() {\n            if( pbase() != pptr() ) {\n                m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );\n                setp( pbase(), epptr() );\n            }\n            return 0;\n        }\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    FileStream::FileStream( std::string const& filename ) {\n        m_ofs.open( filename.c_str() );\n        if( m_ofs.fail() ) {\n            std::ostringstream oss;\n            oss << \"Unable to open file: '\" << filename << \"'\";\n            throw std::domain_error( oss.str() );\n        }\n    }\n\n    std::ostream& FileStream::stream() const {\n        return m_ofs;\n    }\n\n    struct OutputDebugWriter {\n\n        void operator()( std::string const&str ) {\n            writeToDebugConsole( str );\n        }\n    };\n\n    DebugOutStream::DebugOutStream()\n    :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),\n        m_os( m_streamBuf.get() )\n    {}\n\n    std::ostream& DebugOutStream::stream() const {\n        return m_os;\n    }\n\n    // Store the streambuf from cout up-front because\n    // cout may get redirected when running tests\n    CoutStream::CoutStream()\n    :   m_os( Catch::cout().rdbuf() )\n    {}\n\n    std::ostream& CoutStream::stream() const {\n        return m_os;\n    }\n\n#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions\n    std::ostream& cout() {\n        return std::cout;\n    }\n    std::ostream& cerr() {\n        return std::cerr;\n    }\n#endif\n}\n\nnamespace Catch {\n\n    class Context : public IMutableContext {\n\n        Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}\n        Context( Context const& );\n        void operator=( Context const& );\n\n    public:\n        virtual ~Context() {\n            deleteAllValues( m_generatorsByTestName );\n        }\n\n    public: // IContext\n        virtual IResultCapture* getResultCapture() {\n            return m_resultCapture;\n        }\n        virtual IRunner* getRunner() {\n            return m_runner;\n        }\n        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {\n            return getGeneratorsForCurrentTest()\n            .getGeneratorInfo( fileInfo, totalSize )\n            .getCurrentIndex();\n        }\n        virtual bool advanceGeneratorsForCurrentTest() {\n            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();\n            return generators && generators->moveNext();\n        }\n\n        virtual Ptr<IConfig const> getConfig() const {\n            return m_config;\n        }\n\n    public: // IMutableContext\n        virtual void setResultCapture( IResultCapture* resultCapture ) {\n            m_resultCapture = resultCapture;\n        }\n        virtual void setRunner( IRunner* runner ) {\n            m_runner = runner;\n        }\n        virtual void setConfig( Ptr<IConfig const> const& config ) {\n            m_config = config;\n        }\n\n        friend IMutableContext& getCurrentMutableContext();\n\n    private:\n        IGeneratorsForTest* findGeneratorsForCurrentTest() {\n            std::string testName = getResultCapture()->getCurrentTestName();\n\n            std::map<std::string, IGeneratorsForTest*>::const_iterator it =\n                m_generatorsByTestName.find( testName );\n            return it != m_generatorsByTestName.end()\n                ? it->second\n                : CATCH_NULL;\n        }\n\n        IGeneratorsForTest& getGeneratorsForCurrentTest() {\n            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();\n            if( !generators ) {\n                std::string testName = getResultCapture()->getCurrentTestName();\n                generators = createGeneratorsForTest();\n                m_generatorsByTestName.insert( std::make_pair( testName, generators ) );\n            }\n            return *generators;\n        }\n\n    private:\n        Ptr<IConfig const> m_config;\n        IRunner* m_runner;\n        IResultCapture* m_resultCapture;\n        std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;\n    };\n\n    namespace {\n        Context* currentContext = CATCH_NULL;\n    }\n    IMutableContext& getCurrentMutableContext() {\n        if( !currentContext )\n            currentContext = new Context();\n        return *currentContext;\n    }\n    IContext& getCurrentContext() {\n        return getCurrentMutableContext();\n    }\n\n    void cleanUpContext() {\n        delete currentContext;\n        currentContext = CATCH_NULL;\n    }\n}\n\n// #included from: catch_console_colour_impl.hpp\n#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED\n\nnamespace Catch {\n    namespace {\n\n        struct IColourImpl {\n            virtual ~IColourImpl() {}\n            virtual void use( Colour::Code _colourCode ) = 0;\n        };\n\n        struct NoColourImpl : IColourImpl {\n            void use( Colour::Code ) {}\n\n            static IColourImpl* instance() {\n                static NoColourImpl s_instance;\n                return &s_instance;\n            }\n        };\n\n    } // anon namespace\n} // namespace Catch\n\n#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )\n#   ifdef CATCH_PLATFORM_WINDOWS\n#       define CATCH_CONFIG_COLOUR_WINDOWS\n#   else\n#       define CATCH_CONFIG_COLOUR_ANSI\n#   endif\n#endif\n\n#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////\n\n// #included from: catch_windows_h_proxy.h\n\n#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED\n\n#ifdef CATCH_DEFINES_NOMINMAX\n#  define NOMINMAX\n#endif\n#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef CATCH_DEFINES_NOMINMAX\n#  undef NOMINMAX\n#endif\n#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN\n#  undef WIN32_LEAN_AND_MEAN\n#endif\n\nnamespace Catch {\nnamespace {\n\n    class Win32ColourImpl : public IColourImpl {\n    public:\n        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )\n        {\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );\n            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );\n            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );\n        }\n\n        virtual void use( Colour::Code _colourCode ) {\n            switch( _colourCode ) {\n                case Colour::None:      return setTextAttribute( originalForegroundAttributes );\n                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );\n                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );\n                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );\n                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );\n                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );\n                case Colour::Grey:      return setTextAttribute( 0 );\n\n                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );\n                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );\n                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );\n                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n\n                case Colour::Bright: throw std::logic_error( \"not a colour\" );\n            }\n        }\n\n    private:\n        void setTextAttribute( WORD _textAttribute ) {\n            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );\n        }\n        HANDLE stdoutHandle;\n        WORD originalForegroundAttributes;\n        WORD originalBackgroundAttributes;\n    };\n\n    IColourImpl* platformColourInstance() {\n        static Win32ColourImpl s_instance;\n\n        Ptr<IConfig const> config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = !isDebuggerActive()\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? &s_instance\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////\n\n#include <unistd.h>\n\nnamespace Catch {\nnamespace {\n\n    // use POSIX/ ANSI console terminal codes\n    // Thanks to Adam Strzelecki for original contribution\n    // (http://github.com/nanoant)\n    // https://github.com/philsquared/Catch/pull/131\n    class PosixColourImpl : public IColourImpl {\n    public:\n        virtual void use( Colour::Code _colourCode ) {\n            switch( _colourCode ) {\n                case Colour::None:\n                case Colour::White:     return setColour( \"[0m\" );\n                case Colour::Red:       return setColour( \"[0;31m\" );\n                case Colour::Green:     return setColour( \"[0;32m\" );\n                case Colour::Blue:      return setColour( \"[0;34m\" );\n                case Colour::Cyan:      return setColour( \"[0;36m\" );\n                case Colour::Yellow:    return setColour( \"[0;33m\" );\n                case Colour::Grey:      return setColour( \"[1;30m\" );\n\n                case Colour::LightGrey:     return setColour( \"[0;37m\" );\n                case Colour::BrightRed:     return setColour( \"[1;31m\" );\n                case Colour::BrightGreen:   return setColour( \"[1;32m\" );\n                case Colour::BrightWhite:   return setColour( \"[1;37m\" );\n\n                case Colour::Bright: throw std::logic_error( \"not a colour\" );\n            }\n        }\n        static IColourImpl* instance() {\n            static PosixColourImpl s_instance;\n            return &s_instance;\n        }\n\n    private:\n        void setColour( const char* _escapeCode ) {\n            Catch::cout() << '\\033' << _escapeCode;\n        }\n    };\n\n    IColourImpl* platformColourInstance() {\n        Ptr<IConfig const> config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? PosixColourImpl::instance()\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#else  // not Windows or ANSI ///////////////////////////////////////////////\n\nnamespace Catch {\n\n    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }\n\n} // end namespace Catch\n\n#endif // Windows/ ANSI/ None\n\nnamespace Catch {\n\n    Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }\n    Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }\n    Colour::~Colour(){ if( !m_moved ) use( None ); }\n\n    void Colour::use( Code _colourCode ) {\n        static IColourImpl* impl = platformColourInstance();\n        impl->use( _colourCode );\n    }\n\n} // end namespace Catch\n\n// #included from: catch_generators_impl.hpp\n#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED\n\n#include <vector>\n#include <string>\n#include <map>\n\nnamespace Catch {\n\n    struct GeneratorInfo : IGeneratorInfo {\n\n        GeneratorInfo( std::size_t size )\n        :   m_size( size ),\n            m_currentIndex( 0 )\n        {}\n\n        bool moveNext() {\n            if( ++m_currentIndex == m_size ) {\n                m_currentIndex = 0;\n                return false;\n            }\n            return true;\n        }\n\n        std::size_t getCurrentIndex() const {\n            return m_currentIndex;\n        }\n\n        std::size_t m_size;\n        std::size_t m_currentIndex;\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class GeneratorsForTest : public IGeneratorsForTest {\n\n    public:\n        ~GeneratorsForTest() {\n            deleteAll( m_generatorsInOrder );\n        }\n\n        IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {\n            std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );\n            if( it == m_generatorsByName.end() ) {\n                IGeneratorInfo* info = new GeneratorInfo( size );\n                m_generatorsByName.insert( std::make_pair( fileInfo, info ) );\n                m_generatorsInOrder.push_back( info );\n                return *info;\n            }\n            return *it->second;\n        }\n\n        bool moveNext() {\n            std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();\n            std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();\n            for(; it != itEnd; ++it ) {\n                if( (*it)->moveNext() )\n                    return true;\n            }\n            return false;\n        }\n\n    private:\n        std::map<std::string, IGeneratorInfo*> m_generatorsByName;\n        std::vector<IGeneratorInfo*> m_generatorsInOrder;\n    };\n\n    IGeneratorsForTest* createGeneratorsForTest()\n    {\n        return new GeneratorsForTest();\n    }\n\n} // end namespace Catch\n\n// #included from: catch_assertionresult.hpp\n#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED\n\nnamespace Catch {\n\n    AssertionInfo::AssertionInfo(   std::string const& _macroName,\n                                    SourceLineInfo const& _lineInfo,\n                                    std::string const& _capturedExpression,\n                                    ResultDisposition::Flags _resultDisposition )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        capturedExpression( _capturedExpression ),\n        resultDisposition( _resultDisposition )\n    {}\n\n    AssertionResult::AssertionResult() {}\n\n    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )\n    :   m_info( info ),\n        m_resultData( data )\n    {}\n\n    AssertionResult::~AssertionResult() {}\n\n    // Result was a success\n    bool AssertionResult::succeeded() const {\n        return Catch::isOk( m_resultData.resultType );\n    }\n\n    // Result was a success, or failure is suppressed\n    bool AssertionResult::isOk() const {\n        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );\n    }\n\n    ResultWas::OfType AssertionResult::getResultType() const {\n        return m_resultData.resultType;\n    }\n\n    bool AssertionResult::hasExpression() const {\n        return !m_info.capturedExpression.empty();\n    }\n\n    bool AssertionResult::hasMessage() const {\n        return !m_resultData.message.empty();\n    }\n\n    std::string AssertionResult::getExpression() const {\n        if( isFalseTest( m_info.resultDisposition ) )\n            return \"!\" + m_info.capturedExpression;\n        else\n            return m_info.capturedExpression;\n    }\n    std::string AssertionResult::getExpressionInMacro() const {\n        if( m_info.macroName.empty() )\n            return m_info.capturedExpression;\n        else\n            return m_info.macroName + \"( \" + m_info.capturedExpression + \" )\";\n    }\n\n    bool AssertionResult::hasExpandedExpression() const {\n        return hasExpression() && getExpandedExpression() != getExpression();\n    }\n\n    std::string AssertionResult::getExpandedExpression() const {\n        return m_resultData.reconstructedExpression;\n    }\n\n    std::string AssertionResult::getMessage() const {\n        return m_resultData.message;\n    }\n    SourceLineInfo AssertionResult::getSourceInfo() const {\n        return m_info.lineInfo;\n    }\n\n    std::string AssertionResult::getTestMacroName() const {\n        return m_info.macroName;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_test_case_info.hpp\n#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED\n\nnamespace Catch {\n\n    inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {\n        if( startsWith( tag, \".\" ) ||\n            tag == \"hide\" ||\n            tag == \"!hide\" )\n            return TestCaseInfo::IsHidden;\n        else if( tag == \"!throws\" )\n            return TestCaseInfo::Throws;\n        else if( tag == \"!shouldfail\" )\n            return TestCaseInfo::ShouldFail;\n        else if( tag == \"!mayfail\" )\n            return TestCaseInfo::MayFail;\n        else\n            return TestCaseInfo::None;\n    }\n    inline bool isReservedTag( std::string const& tag ) {\n        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );\n    }\n    inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {\n        if( isReservedTag( tag ) ) {\n            {\n                Colour colourGuard( Colour::Red );\n                Catch::cerr()\n                    << \"Tag name [\" << tag << \"] not allowed.\\n\"\n                    << \"Tag names starting with non alpha-numeric characters are reserved\\n\";\n            }\n            {\n                Colour colourGuard( Colour::FileName );\n                Catch::cerr() << _lineInfo << std::endl;\n            }\n            exit(1);\n        }\n    }\n\n    TestCase makeTestCase(  ITestCase* _testCase,\n                            std::string const& _className,\n                            std::string const& _name,\n                            std::string const& _descOrTags,\n                            SourceLineInfo const& _lineInfo )\n    {\n        bool isHidden( startsWith( _name, \"./\" ) ); // Legacy support\n\n        // Parse out tags\n        std::set<std::string> tags;\n        std::string desc, tag;\n        bool inTag = false;\n        for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {\n            char c = _descOrTags[i];\n            if( !inTag ) {\n                if( c == '[' )\n                    inTag = true;\n                else\n                    desc += c;\n            }\n            else {\n                if( c == ']' ) {\n                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );\n                    if( prop == TestCaseInfo::IsHidden )\n                        isHidden = true;\n                    else if( prop == TestCaseInfo::None )\n                        enforceNotReservedTag( tag, _lineInfo );\n\n                    tags.insert( tag );\n                    tag.clear();\n                    inTag = false;\n                }\n                else\n                    tag += c;\n            }\n        }\n        if( isHidden ) {\n            tags.insert( \"hide\" );\n            tags.insert( \".\" );\n        }\n\n        TestCaseInfo info( _name, _className, desc, tags, _lineInfo );\n        return TestCase( _testCase, info );\n    }\n\n    void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )\n    {\n        testCaseInfo.tags = tags;\n        testCaseInfo.lcaseTags.clear();\n\n        std::ostringstream oss;\n        for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {\n            oss << \"[\" << *it << \"]\";\n            std::string lcaseTag = toLower( *it );\n            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );\n            testCaseInfo.lcaseTags.insert( lcaseTag );\n        }\n        testCaseInfo.tagsAsString = oss.str();\n    }\n\n    TestCaseInfo::TestCaseInfo( std::string const& _name,\n                                std::string const& _className,\n                                std::string const& _description,\n                                std::set<std::string> const& _tags,\n                                SourceLineInfo const& _lineInfo )\n    :   name( _name ),\n        className( _className ),\n        description( _description ),\n        lineInfo( _lineInfo ),\n        properties( None )\n    {\n        setTags( *this, _tags );\n    }\n\n    TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )\n    :   name( other.name ),\n        className( other.className ),\n        description( other.description ),\n        tags( other.tags ),\n        lcaseTags( other.lcaseTags ),\n        tagsAsString( other.tagsAsString ),\n        lineInfo( other.lineInfo ),\n        properties( other.properties )\n    {}\n\n    bool TestCaseInfo::isHidden() const {\n        return ( properties & IsHidden ) != 0;\n    }\n    bool TestCaseInfo::throws() const {\n        return ( properties & Throws ) != 0;\n    }\n    bool TestCaseInfo::okToFail() const {\n        return ( properties & (ShouldFail | MayFail ) ) != 0;\n    }\n    bool TestCaseInfo::expectedToFail() const {\n        return ( properties & (ShouldFail ) ) != 0;\n    }\n\n    TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}\n\n    TestCase::TestCase( TestCase const& other )\n    :   TestCaseInfo( other ),\n        test( other.test )\n    {}\n\n    TestCase TestCase::withName( std::string const& _newName ) const {\n        TestCase other( *this );\n        other.name = _newName;\n        return other;\n    }\n\n    void TestCase::swap( TestCase& other ) {\n        test.swap( other.test );\n        name.swap( other.name );\n        className.swap( other.className );\n        description.swap( other.description );\n        tags.swap( other.tags );\n        lcaseTags.swap( other.lcaseTags );\n        tagsAsString.swap( other.tagsAsString );\n        std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );\n        std::swap( lineInfo, other.lineInfo );\n    }\n\n    void TestCase::invoke() const {\n        test->invoke();\n    }\n\n    bool TestCase::operator == ( TestCase const& other ) const {\n        return  test.get() == other.test.get() &&\n                name == other.name &&\n                className == other.className;\n    }\n\n    bool TestCase::operator < ( TestCase const& other ) const {\n        return name < other.name;\n    }\n    TestCase& TestCase::operator = ( TestCase const& other ) {\n        TestCase temp( other );\n        swap( temp );\n        return *this;\n    }\n\n    TestCaseInfo const& TestCase::getTestCaseInfo() const\n    {\n        return *this;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_version.hpp\n#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED\n\nnamespace Catch {\n\n    Version::Version\n        (   unsigned int _majorVersion,\n            unsigned int _minorVersion,\n            unsigned int _patchNumber,\n            std::string const& _branchName,\n            unsigned int _buildNumber )\n    :   majorVersion( _majorVersion ),\n        minorVersion( _minorVersion ),\n        patchNumber( _patchNumber ),\n        branchName( _branchName ),\n        buildNumber( _buildNumber )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, Version const& version ) {\n        os  << version.majorVersion << \".\"\n            << version.minorVersion << \".\"\n            << version.patchNumber;\n\n        if( !version.branchName.empty() ) {\n            os  << \"-\" << version.branchName\n                << \".\" << version.buildNumber;\n        }\n        return os;\n    }\n\n    Version libraryVersion( 1, 6, 1, \"\", 0 );\n\n}\n\n// #included from: catch_message.hpp\n#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED\n\nnamespace Catch {\n\n    MessageInfo::MessageInfo(   std::string const& _macroName,\n                                SourceLineInfo const& _lineInfo,\n                                ResultWas::OfType _type )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        type( _type ),\n        sequence( ++globalCount )\n    {}\n\n    // This may need protecting if threading support is added\n    unsigned int MessageInfo::globalCount = 0;\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    ScopedMessage::ScopedMessage( MessageBuilder const& builder )\n    : m_info( builder.m_info )\n    {\n        m_info.message = builder.m_stream.str();\n        getResultCapture().pushScopedMessage( m_info );\n    }\n    ScopedMessage::ScopedMessage( ScopedMessage const& other )\n    : m_info( other.m_info )\n    {}\n\n    ScopedMessage::~ScopedMessage() {\n        getResultCapture().popScopedMessage( m_info );\n    }\n\n} // end namespace Catch\n\n// #included from: catch_legacy_reporter_adapter.hpp\n#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED\n\n// #included from: catch_legacy_reporter_adapter.h\n#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED\n\nnamespace Catch\n{\n    // Deprecated\n    struct IReporter : IShared {\n        virtual ~IReporter();\n\n        virtual bool shouldRedirectStdout() const = 0;\n\n        virtual void StartTesting() = 0;\n        virtual void EndTesting( Totals const& totals ) = 0;\n        virtual void StartGroup( std::string const& groupName ) = 0;\n        virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;\n        virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;\n        virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;\n        virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;\n        virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;\n        virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;\n        virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;\n        virtual void Aborted() = 0;\n        virtual void Result( AssertionResult const& result ) = 0;\n    };\n\n    class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>\n    {\n    public:\n        LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );\n        virtual ~LegacyReporterAdapter();\n\n        virtual ReporterPreferences getPreferences() const;\n        virtual void noMatchingTestCases( std::string const& );\n        virtual void testRunStarting( TestRunInfo const& );\n        virtual void testGroupStarting( GroupInfo const& groupInfo );\n        virtual void testCaseStarting( TestCaseInfo const& testInfo );\n        virtual void sectionStarting( SectionInfo const& sectionInfo );\n        virtual void assertionStarting( AssertionInfo const& );\n        virtual bool assertionEnded( AssertionStats const& assertionStats );\n        virtual void sectionEnded( SectionStats const& sectionStats );\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats );\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats );\n        virtual void testRunEnded( TestRunStats const& testRunStats );\n        virtual void skipTest( TestCaseInfo const& );\n\n    private:\n        Ptr<IReporter> m_legacyReporter;\n    };\n}\n\nnamespace Catch\n{\n    LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )\n    :   m_legacyReporter( legacyReporter )\n    {}\n    LegacyReporterAdapter::~LegacyReporterAdapter() {}\n\n    ReporterPreferences LegacyReporterAdapter::getPreferences() const {\n        ReporterPreferences prefs;\n        prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();\n        return prefs;\n    }\n\n    void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}\n    void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {\n        m_legacyReporter->StartTesting();\n    }\n    void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {\n        m_legacyReporter->StartGroup( groupInfo.name );\n    }\n    void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        m_legacyReporter->StartTestCase( testInfo );\n    }\n    void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {\n        m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );\n    }\n    void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {\n        // Not on legacy interface\n    }\n\n    bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {\n        if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {\n            for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();\n                    it != itEnd;\n                    ++it ) {\n                if( it->type == ResultWas::Info ) {\n                    ResultBuilder rb( it->macroName.c_str(), it->lineInfo, \"\", ResultDisposition::Normal );\n                    rb << it->message;\n                    rb.setResultType( ResultWas::Info );\n                    AssertionResult result = rb.build();\n                    m_legacyReporter->Result( result );\n                }\n            }\n        }\n        m_legacyReporter->Result( assertionStats.assertionResult );\n        return true;\n    }\n    void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {\n        if( sectionStats.missingAssertions )\n            m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );\n        m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );\n    }\n    void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        m_legacyReporter->EndTestCase\n            (   testCaseStats.testInfo,\n                testCaseStats.totals,\n                testCaseStats.stdOut,\n                testCaseStats.stdErr );\n    }\n    void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        if( testGroupStats.aborting )\n            m_legacyReporter->Aborted();\n        m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );\n    }\n    void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {\n        m_legacyReporter->EndTesting( testRunStats.totals );\n    }\n    void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {\n    }\n}\n\n// #included from: catch_timer.hpp\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wc++11-long-long\"\n#endif\n\n#ifdef CATCH_PLATFORM_WINDOWS\n#else\n#include <sys/time.h>\n#endif\n\nnamespace Catch {\n\n    namespace {\n#ifdef CATCH_PLATFORM_WINDOWS\n        uint64_t getCurrentTicks() {\n            static uint64_t hz=0, hzo=0;\n            if (!hz) {\n                QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );\n                QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );\n            }\n            uint64_t t;\n            QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );\n            return ((t-hzo)*1000000)/hz;\n        }\n#else\n        uint64_t getCurrentTicks() {\n            timeval t;\n            gettimeofday(&t,CATCH_NULL);\n            return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );\n        }\n#endif\n    }\n\n    void Timer::start() {\n        m_ticks = getCurrentTicks();\n    }\n    unsigned int Timer::getElapsedMicroseconds() const {\n        return static_cast<unsigned int>(getCurrentTicks() - m_ticks);\n    }\n    unsigned int Timer::getElapsedMilliseconds() const {\n        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);\n    }\n    double Timer::getElapsedSeconds() const {\n        return getElapsedMicroseconds()/1000000.0;\n    }\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n// #included from: catch_common.hpp\n#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED\n\nnamespace Catch {\n\n    bool startsWith( std::string const& s, std::string const& prefix ) {\n        return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;\n    }\n    bool endsWith( std::string const& s, std::string const& suffix ) {\n        return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;\n    }\n    bool contains( std::string const& s, std::string const& infix ) {\n        return s.find( infix ) != std::string::npos;\n    }\n    char toLowerCh(char c) {\n        return static_cast<char>( ::tolower( c ) );\n    }\n    void toLowerInPlace( std::string& s ) {\n        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );\n    }\n    std::string toLower( std::string const& s ) {\n        std::string lc = s;\n        toLowerInPlace( lc );\n        return lc;\n    }\n    std::string trim( std::string const& str ) {\n        static char const* whitespaceChars = \"\\n\\r\\t \";\n        std::string::size_type start = str.find_first_not_of( whitespaceChars );\n        std::string::size_type end = str.find_last_not_of( whitespaceChars );\n\n        return start != std::string::npos ? str.substr( start, 1+end-start ) : \"\";\n    }\n\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {\n        bool replaced = false;\n        std::size_t i = str.find( replaceThis );\n        while( i != std::string::npos ) {\n            replaced = true;\n            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );\n            if( i < str.size()-withThis.size() )\n                i = str.find( replaceThis, i+withThis.size() );\n            else\n                i = std::string::npos;\n        }\n        return replaced;\n    }\n\n    pluralise::pluralise( std::size_t count, std::string const& label )\n    :   m_count( count ),\n        m_label( label )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {\n        os << pluraliser.m_count << \" \" << pluraliser.m_label;\n        if( pluraliser.m_count != 1 )\n            os << \"s\";\n        return os;\n    }\n\n    SourceLineInfo::SourceLineInfo() : line( 0 ){}\n    SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )\n    :   file( _file ),\n        line( _line )\n    {}\n    SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )\n    :   file( other.file ),\n        line( other.line )\n    {}\n    bool SourceLineInfo::empty() const {\n        return file.empty();\n    }\n    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {\n        return line == other.line && file == other.file;\n    }\n    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {\n        return line < other.line || ( line == other.line  && file < other.file );\n    }\n\n    void seedRng( IConfig const& config ) {\n        if( config.rngSeed() != 0 )\n            std::srand( config.rngSeed() );\n    }\n    unsigned int rngSeed() {\n        return getCurrentContext().getConfig()->rngSeed();\n    }\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {\n#ifndef __GNUG__\n        os << info.file << \"(\" << info.line << \")\";\n#else\n        os << info.file << \":\" << info.line;\n#endif\n        return os;\n    }\n\n    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {\n        std::ostringstream oss;\n        oss << locationInfo << \": Internal Catch error: '\" << message << \"'\";\n        if( alwaysTrue() )\n            throw std::logic_error( oss.str() );\n    }\n}\n\n// #included from: catch_section.hpp\n#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED\n\nnamespace Catch {\n\n    SectionInfo::SectionInfo\n        (   SourceLineInfo const& _lineInfo,\n            std::string const& _name,\n            std::string const& _description )\n    :   name( _name ),\n        description( _description ),\n        lineInfo( _lineInfo )\n    {}\n\n    Section::Section( SectionInfo const& info )\n    :   m_info( info ),\n        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )\n    {\n        m_timer.start();\n    }\n\n    Section::~Section() {\n        if( m_sectionIncluded ) {\n            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );\n            if( std::uncaught_exception() )\n                getResultCapture().sectionEndedEarly( endInfo );\n            else\n                getResultCapture().sectionEnded( endInfo );\n        }\n    }\n\n    // This indicates whether the section should be executed or not\n    Section::operator bool() const {\n        return m_sectionIncluded;\n    }\n\n} // end namespace Catch\n\n// #included from: catch_debugger.hpp\n#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED\n\n#include <iostream>\n\n#ifdef CATCH_PLATFORM_MAC\n\n    #include <assert.h>\n    #include <stdbool.h>\n    #include <sys/types.h>\n    #include <unistd.h>\n    #include <sys/sysctl.h>\n\n    namespace Catch{\n\n        // The following function is taken directly from the following technical note:\n        // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html\n\n        // Returns true if the current process is being debugged (either\n        // running under the debugger or has a debugger attached post facto).\n        bool isDebuggerActive(){\n\n            int                 mib[4];\n            struct kinfo_proc   info;\n            size_t              size;\n\n            // Initialize the flags so that, if sysctl fails for some bizarre\n            // reason, we get a predictable result.\n\n            info.kp_proc.p_flag = 0;\n\n            // Initialize mib, which tells sysctl the info we want, in this case\n            // we're looking for information about a specific process ID.\n\n            mib[0] = CTL_KERN;\n            mib[1] = KERN_PROC;\n            mib[2] = KERN_PROC_PID;\n            mib[3] = getpid();\n\n            // Call sysctl.\n\n            size = sizeof(info);\n            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {\n                Catch::cerr() << \"\\n** Call to sysctl failed - unable to determine if debugger is active **\\n\" << std::endl;\n                return false;\n            }\n\n            // We're being debugged if the P_TRACED flag is set.\n\n            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n        }\n    } // namespace Catch\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    #include <fstream>\n    #include <string>\n\n    namespace Catch{\n        // The standard POSIX way of detecting a debugger is to attempt to\n        // ptrace() the process, but this needs to be done from a child and not\n        // this process itself to still allow attaching to this process later\n        // if wanted, so is rather heavy. Under Linux we have the PID of the\n        // \"debugger\" (which doesn't need to be gdb, of course, it could also\n        // be strace, for example) in /proc/$PID/status, so just get it from\n        // there instead.\n        bool isDebuggerActive(){\n            std::ifstream in(\"/proc/self/status\");\n            for( std::string line; std::getline(in, line); ) {\n                static const int PREFIX_LEN = 11;\n                if( line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0 ) {\n                    // We're traced if the PID is not 0 and no other PID starts\n                    // with 0 digit, so it's enough to check for just a single\n                    // character.\n                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n                }\n            }\n\n            return false;\n        }\n    } // namespace Catch\n#elif defined(_MSC_VER)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#else\n    namespace Catch {\n       inline bool isDebuggerActive() { return false; }\n    }\n#endif // Platform\n\n#ifdef CATCH_PLATFORM_WINDOWS\n    extern \"C\" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            ::OutputDebugStringA( text.c_str() );\n        }\n    }\n#else\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            // !TBD: Need a version for Mac/ XCode and other IDEs\n            Catch::cout() << text;\n        }\n    }\n#endif // Platform\n\n// #included from: catch_tostring.hpp\n#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED\n\nnamespace Catch {\n\nnamespace Detail {\n\n    const std::string unprintableString = \"{?}\";\n\n    namespace {\n        const int hexThreshold = 255;\n\n        struct Endianness {\n            enum Arch { Big, Little };\n\n            static Arch which() {\n                union _{\n                    int asInt;\n                    char asChar[sizeof (int)];\n                } u;\n\n                u.asInt = 1;\n                return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;\n            }\n        };\n    }\n\n    std::string rawMemoryToString( const void *object, std::size_t size )\n    {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>( size ), inc = 1;\n        if( Endianness::which() == Endianness::Little ) {\n            i = end-1;\n            end = inc = -1;\n        }\n\n        unsigned char const *bytes = static_cast<unsigned char const *>(object);\n        std::ostringstream os;\n        os << \"0x\" << std::setfill('0') << std::hex;\n        for( ; i != end; i += inc )\n             os << std::setw(2) << static_cast<unsigned>(bytes[i]);\n       return os.str();\n    }\n}\n\nstd::string toString( std::string const& value ) {\n    std::string s = value;\n    if( getCurrentContext().getConfig()->showInvisibles() ) {\n        for(size_t i = 0; i < s.size(); ++i ) {\n            std::string subs;\n            switch( s[i] ) {\n            case '\\n': subs = \"\\\\n\"; break;\n            case '\\t': subs = \"\\\\t\"; break;\n            default: break;\n            }\n            if( !subs.empty() ) {\n                s = s.substr( 0, i ) + subs + s.substr( i+1 );\n                ++i;\n            }\n        }\n    }\n    return \"\\\"\" + s + \"\\\"\";\n}\nstd::string toString( std::wstring const& value ) {\n\n    std::string s;\n    s.reserve( value.size() );\n    for(size_t i = 0; i < value.size(); ++i )\n        s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';\n    return Catch::toString( s );\n}\n\nstd::string toString( const char* const value ) {\n    return value ? Catch::toString( std::string( value ) ) : std::string( \"{null string}\" );\n}\n\nstd::string toString( char* const value ) {\n    return Catch::toString( static_cast<const char*>( value ) );\n}\n\nstd::string toString( const wchar_t* const value )\n{\n\treturn value ? Catch::toString( std::wstring(value) ) : std::string( \"{null string}\" );\n}\n\nstd::string toString( wchar_t* const value )\n{\n\treturn Catch::toString( static_cast<const wchar_t*>( value ) );\n}\n\nstd::string toString( int value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n\nstd::string toString( unsigned long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n\nstd::string toString( unsigned int value ) {\n    return Catch::toString( static_cast<unsigned long>( value ) );\n}\n\ntemplate<typename T>\nstd::string fpToString( T value, int precision ) {\n    std::ostringstream oss;\n    oss << std::setprecision( precision )\n        << std::fixed\n        << value;\n    std::string d = oss.str();\n    std::size_t i = d.find_last_not_of( '0' );\n    if( i != std::string::npos && i != d.size()-1 ) {\n        if( d[i] == '.' )\n            i++;\n        d = d.substr( 0, i+1 );\n    }\n    return d;\n}\n\nstd::string toString( const double value ) {\n    return fpToString( value, 10 );\n}\nstd::string toString( const float value ) {\n    return fpToString( value, 5 ) + \"f\";\n}\n\nstd::string toString( bool value ) {\n    return value ? \"true\" : \"false\";\n}\n\nstd::string toString( char value ) {\n    return value < ' '\n        ? toString( static_cast<unsigned int>( value ) )\n        : Detail::makeString( value );\n}\n\nstd::string toString( signed char value ) {\n    return toString( static_cast<char>( value ) );\n}\n\nstd::string toString( unsigned char value ) {\n    return toString( static_cast<char>( value ) );\n}\n\n#ifdef CATCH_CONFIG_CPP11_LONG_LONG\nstd::string toString( long long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\nstd::string toString( unsigned long long value ) {\n    std::ostringstream oss;\n    oss << value;\n    if( value > Detail::hexThreshold )\n        oss << \" (0x\" << std::hex << value << \")\";\n    return oss.str();\n}\n#endif\n\n#ifdef CATCH_CONFIG_CPP11_NULLPTR\nstd::string toString( std::nullptr_t ) {\n    return \"nullptr\";\n}\n#endif\n\n#ifdef __OBJC__\n    std::string toString( NSString const * const& nsstring ) {\n        if( !nsstring )\n            return \"nil\";\n        return \"@\" + toString([nsstring UTF8String]);\n    }\n    std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {\n        if( !nsstring )\n            return \"nil\";\n        return \"@\" + toString([nsstring UTF8String]);\n    }\n    std::string toString( NSObject* const& nsObject ) {\n        return toString( [nsObject description] );\n    }\n#endif\n\n} // end namespace Catch\n\n// #included from: catch_result_builder.hpp\n#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED\n\nnamespace Catch {\n\n    std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {\n        return secondArg.empty() || secondArg == \"\\\"\\\"\"\n            ? capturedExpression\n            : capturedExpression + \", \" + secondArg;\n    }\n    ResultBuilder::ResultBuilder(   char const* macroName,\n                                    SourceLineInfo const& lineInfo,\n                                    char const* capturedExpression,\n                                    ResultDisposition::Flags resultDisposition,\n                                    char const* secondArg )\n    :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),\n        m_shouldDebugBreak( false ),\n        m_shouldThrow( false )\n    {}\n\n    ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {\n        m_data.resultType = result;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setResultType( bool result ) {\n        m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {\n        m_exprComponents.lhs = lhs;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {\n        m_exprComponents.rhs = rhs;\n        return *this;\n    }\n    ResultBuilder& ResultBuilder::setOp( std::string const& op ) {\n        m_exprComponents.op = op;\n        return *this;\n    }\n\n    void ResultBuilder::endExpression() {\n        m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );\n        captureExpression();\n    }\n\n    void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {\n        m_assertionInfo.resultDisposition = resultDisposition;\n        m_stream.oss << Catch::translateActiveException();\n        captureResult( ResultWas::ThrewException );\n    }\n\n    void ResultBuilder::captureResult( ResultWas::OfType resultType ) {\n        setResultType( resultType );\n        captureExpression();\n    }\n    void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {\n        if( expectedMessage.empty() )\n            captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );\n        else\n            captureExpectedException( Matchers::Equals( expectedMessage ) );\n    }\n\n    void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {\n\n        assert( m_exprComponents.testFalse == false );\n        AssertionResultData data = m_data;\n        data.resultType = ResultWas::Ok;\n        data.reconstructedExpression = m_assertionInfo.capturedExpression;\n\n        std::string actualMessage = Catch::translateActiveException();\n        if( !matcher.match( actualMessage ) ) {\n            data.resultType = ResultWas::ExpressionFailed;\n            data.reconstructedExpression = actualMessage;\n        }\n        AssertionResult result( m_assertionInfo, data );\n        handleResult( result );\n    }\n\n    void ResultBuilder::captureExpression() {\n        AssertionResult result = build();\n        handleResult( result );\n    }\n    void ResultBuilder::handleResult( AssertionResult const& result )\n    {\n        getResultCapture().assertionEnded( result );\n\n        if( !result.isOk() ) {\n            if( getCurrentContext().getConfig()->shouldDebugBreak() )\n                m_shouldDebugBreak = true;\n            if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )\n                m_shouldThrow = true;\n        }\n    }\n    void ResultBuilder::react() {\n        if( m_shouldThrow )\n            throw Catch::TestFailureException();\n    }\n\n    bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }\n    bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }\n\n    AssertionResult ResultBuilder::build() const\n    {\n        assert( m_data.resultType != ResultWas::Unknown );\n\n        AssertionResultData data = m_data;\n\n        // Flip bool results if testFalse is set\n        if( m_exprComponents.testFalse ) {\n            if( data.resultType == ResultWas::Ok )\n                data.resultType = ResultWas::ExpressionFailed;\n            else if( data.resultType == ResultWas::ExpressionFailed )\n                data.resultType = ResultWas::Ok;\n        }\n\n        data.message = m_stream.oss.str();\n        data.reconstructedExpression = reconstructExpression();\n        if( m_exprComponents.testFalse ) {\n            if( m_exprComponents.op == \"\" )\n                data.reconstructedExpression = \"!\" + data.reconstructedExpression;\n            else\n                data.reconstructedExpression = \"!(\" + data.reconstructedExpression + \")\";\n        }\n        return AssertionResult( m_assertionInfo, data );\n    }\n    std::string ResultBuilder::reconstructExpression() const {\n        if( m_exprComponents.op == \"\" )\n            return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs;\n        else if( m_exprComponents.op == \"matches\" )\n            return m_exprComponents.lhs + \" \" + m_exprComponents.rhs;\n        else if( m_exprComponents.op != \"!\" ) {\n            if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&\n                m_exprComponents.lhs.find(\"\\n\") == std::string::npos &&\n                m_exprComponents.rhs.find(\"\\n\") == std::string::npos )\n                return m_exprComponents.lhs + \" \" + m_exprComponents.op + \" \" + m_exprComponents.rhs;\n            else\n                return m_exprComponents.lhs + \"\\n\" + m_exprComponents.op + \"\\n\" + m_exprComponents.rhs;\n        }\n        else\n            return \"{can't expand - use \" + m_assertionInfo.macroName + \"_FALSE( \" + m_assertionInfo.capturedExpression.substr(1) + \" ) instead of \" + m_assertionInfo.macroName + \"( \" + m_assertionInfo.capturedExpression + \" ) for better diagnostics}\";\n    }\n\n} // end namespace Catch\n\n// #included from: catch_tag_alias_registry.hpp\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED\n\n// #included from: catch_tag_alias_registry.h\n#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED\n\n#include <map>\n\nnamespace Catch {\n\n    class TagAliasRegistry : public ITagAliasRegistry {\n    public:\n        virtual ~TagAliasRegistry();\n        virtual Option<TagAlias> find( std::string const& alias ) const;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;\n        void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n        static TagAliasRegistry& get();\n\n    private:\n        std::map<std::string, TagAlias> m_registry;\n    };\n\n} // end namespace Catch\n\n#include <map>\n#include <iostream>\n\nnamespace Catch {\n\n    TagAliasRegistry::~TagAliasRegistry() {}\n\n    Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {\n        std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );\n        if( it != m_registry.end() )\n            return it->second;\n        else\n            return Option<TagAlias>();\n    }\n\n    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {\n        std::string expandedTestSpec = unexpandedTestSpec;\n        for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();\n                it != itEnd;\n                ++it ) {\n            std::size_t pos = expandedTestSpec.find( it->first );\n            if( pos != std::string::npos ) {\n                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +\n                                    it->second.tag +\n                                    expandedTestSpec.substr( pos + it->first.size() );\n            }\n        }\n        return expandedTestSpec;\n    }\n\n    void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {\n\n        if( !startsWith( alias, \"[@\" ) || !endsWith( alias, \"]\" ) ) {\n            std::ostringstream oss;\n            oss << \"error: tag alias, \\\"\" << alias << \"\\\" is not of the form [@alias name].\\n\" << lineInfo;\n            throw std::domain_error( oss.str().c_str() );\n        }\n        if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {\n            std::ostringstream oss;\n            oss << \"error: tag alias, \\\"\" << alias << \"\\\" already registered.\\n\"\n                << \"\\tFirst seen at \" << find(alias)->lineInfo << \"\\n\"\n                << \"\\tRedefined at \" << lineInfo;\n            throw std::domain_error( oss.str().c_str() );\n        }\n    }\n\n    TagAliasRegistry& TagAliasRegistry::get() {\n        static TagAliasRegistry instance;\n        return instance;\n\n    }\n\n    ITagAliasRegistry::~ITagAliasRegistry() {}\n    ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }\n\n    RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {\n        try {\n            TagAliasRegistry::get().add( alias, tag, lineInfo );\n        }\n        catch( std::exception& ex ) {\n            Colour colourGuard( Colour::Red );\n            Catch::cerr() << ex.what() << std::endl;\n            exit(1);\n        }\n    }\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_multi.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED\n\nnamespace Catch {\n\nclass MultipleReporters : public SharedImpl<IStreamingReporter> {\n    typedef std::vector<Ptr<IStreamingReporter> > Reporters;\n    Reporters m_reporters;\n\npublic:\n    void add( Ptr<IStreamingReporter> const& reporter ) {\n        m_reporters.push_back( reporter );\n    }\n\npublic: // IStreamingReporter\n\n    virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n        return m_reporters[0]->getPreferences();\n    }\n\n    virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->noMatchingTestCases( spec );\n    }\n\n    virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testRunStarting( testRunInfo );\n    }\n\n    virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testGroupStarting( groupInfo );\n    }\n\n    virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testCaseStarting( testInfo );\n    }\n\n    virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->sectionStarting( sectionInfo );\n    }\n\n    virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->assertionStarting( assertionInfo );\n    }\n\n    // The return value indicates if the messages buffer should be cleared:\n    virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n        bool clearBuffer = false;\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            clearBuffer |= (*it)->assertionEnded( assertionStats );\n        return clearBuffer;\n    }\n\n    virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->sectionEnded( sectionStats );\n    }\n\n    virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testCaseEnded( testCaseStats );\n    }\n\n    virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testGroupEnded( testGroupStats );\n    }\n\n    virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->testRunEnded( testRunStats );\n    }\n\n    virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();\n                it != itEnd;\n                ++it )\n            (*it)->skipTest( testInfo );\n    }\n\n    virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {\n        return this;\n    }\n\n};\n\nPtr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {\n    Ptr<IStreamingReporter> resultingReporter;\n\n    if( existingReporter ) {\n        MultipleReporters* multi = existingReporter->tryAsMulti();\n        if( !multi ) {\n            multi = new MultipleReporters;\n            resultingReporter = Ptr<IStreamingReporter>( multi );\n            if( existingReporter )\n                multi->add( existingReporter );\n        }\n        else\n            resultingReporter = existingReporter;\n        multi->add( additionalReporter );\n    }\n    else\n        resultingReporter = additionalReporter;\n\n    return resultingReporter;\n}\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_xml.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED\n\n// #included from: catch_reporter_bases.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED\n\n#include <cstring>\n\nnamespace Catch {\n\n    struct StreamingReporterBase : SharedImpl<IStreamingReporter> {\n\n        StreamingReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n        }\n\n        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n            return m_reporterPrefs;\n        }\n\n        virtual ~StreamingReporterBase() CATCH_OVERRIDE;\n\n        virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}\n\n        virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {\n            currentTestRunInfo = _testRunInfo;\n        }\n        virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {\n            currentGroupInfo = _groupInfo;\n        }\n\n        virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {\n            currentTestCaseInfo = _testInfo;\n        }\n        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {\n            m_sectionStack.push_back( _sectionInfo );\n        }\n\n        virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {\n            m_sectionStack.pop_back();\n        }\n        virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {\n            currentTestCaseInfo.reset();\n        }\n        virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {\n            currentGroupInfo.reset();\n        }\n        virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {\n            currentTestCaseInfo.reset();\n            currentGroupInfo.reset();\n            currentTestRunInfo.reset();\n        }\n\n        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {\n            // Don't do anything with this by default.\n            // It can optionally be overridden in the derived class.\n        }\n\n        Ptr<IConfig const> m_config;\n        std::ostream& stream;\n\n        LazyStat<TestRunInfo> currentTestRunInfo;\n        LazyStat<GroupInfo> currentGroupInfo;\n        LazyStat<TestCaseInfo> currentTestCaseInfo;\n\n        std::vector<SectionInfo> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {\n        template<typename T, typename ChildNodeT>\n        struct Node : SharedImpl<> {\n            explicit Node( T const& _value ) : value( _value ) {}\n            virtual ~Node() {}\n\n            typedef std::vector<Ptr<ChildNodeT> > ChildNodes;\n            T value;\n            ChildNodes children;\n        };\n        struct SectionNode : SharedImpl<> {\n            explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}\n            virtual ~SectionNode();\n\n            bool operator == ( SectionNode const& other ) const {\n                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;\n            }\n            bool operator == ( Ptr<SectionNode> const& other ) const {\n                return operator==( *other );\n            }\n\n            SectionStats stats;\n            typedef std::vector<Ptr<SectionNode> > ChildSections;\n            typedef std::vector<AssertionStats> Assertions;\n            ChildSections childSections;\n            Assertions assertions;\n            std::string stdOut;\n            std::string stdErr;\n        };\n\n        struct BySectionInfo {\n            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}\n\t\t\tBySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}\n            bool operator() ( Ptr<SectionNode> const& node ) const {\n                return node->stats.sectionInfo.lineInfo == m_other.lineInfo;\n            }\n        private:\n\t\t\tvoid operator=( BySectionInfo const& );\n            SectionInfo const& m_other;\n        };\n\n        typedef Node<TestCaseStats, SectionNode> TestCaseNode;\n        typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;\n        typedef Node<TestRunStats, TestGroupNode> TestRunNode;\n\n        CumulativeReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n        }\n        ~CumulativeReporterBase();\n\n        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {\n            return m_reporterPrefs;\n        }\n\n        virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}\n        virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}\n\n        virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}\n\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );\n            Ptr<SectionNode> node;\n            if( m_sectionStack.empty() ) {\n                if( !m_rootSection )\n                    m_rootSection = new SectionNode( incompleteStats );\n                node = m_rootSection;\n            }\n            else {\n                SectionNode& parentNode = *m_sectionStack.back();\n                SectionNode::ChildSections::const_iterator it =\n                    std::find_if(   parentNode.childSections.begin(),\n                                    parentNode.childSections.end(),\n                                    BySectionInfo( sectionInfo ) );\n                if( it == parentNode.childSections.end() ) {\n                    node = new SectionNode( incompleteStats );\n                    parentNode.childSections.push_back( node );\n                }\n                else\n                    node = *it;\n            }\n            m_sectionStack.push_back( node );\n            m_deepestSection = node;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            assert( !m_sectionStack.empty() );\n            SectionNode& sectionNode = *m_sectionStack.back();\n            sectionNode.assertions.push_back( assertionStats );\n            return true;\n        }\n        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n            assert( !m_sectionStack.empty() );\n            SectionNode& node = *m_sectionStack.back();\n            node.stats = sectionStats;\n            m_sectionStack.pop_back();\n        }\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );\n            assert( m_sectionStack.size() == 0 );\n            node->children.push_back( m_rootSection );\n            m_testCases.push_back( node );\n            m_rootSection.reset();\n\n            assert( m_deepestSection );\n            m_deepestSection->stdOut = testCaseStats.stdOut;\n            m_deepestSection->stdErr = testCaseStats.stdErr;\n        }\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );\n            node->children.swap( m_testCases );\n            m_testGroups.push_back( node );\n        }\n        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n            Ptr<TestRunNode> node = new TestRunNode( testRunStats );\n            node->children.swap( m_testGroups );\n            m_testRuns.push_back( node );\n            testRunEndedCumulative();\n        }\n        virtual void testRunEndedCumulative() = 0;\n\n        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}\n\n        Ptr<IConfig const> m_config;\n        std::ostream& stream;\n        std::vector<AssertionStats> m_assertions;\n        std::vector<std::vector<Ptr<SectionNode> > > m_sections;\n        std::vector<Ptr<TestCaseNode> > m_testCases;\n        std::vector<Ptr<TestGroupNode> > m_testGroups;\n\n        std::vector<Ptr<TestRunNode> > m_testRuns;\n\n        Ptr<SectionNode> m_rootSection;\n        Ptr<SectionNode> m_deepestSection;\n        std::vector<Ptr<SectionNode> > m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n\n    };\n\n    template<char C>\n    char const* getLineOfChars() {\n        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};\n        if( !*line ) {\n            memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );\n            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;\n        }\n        return line;\n    }\n\n    struct TestEventListenerBase : StreamingReporterBase {\n        TestEventListenerBase( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config )\n        {}\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}\n        virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {\n            return false;\n        }\n    };\n\n} // end namespace Catch\n\n// #included from: ../internal/catch_reporter_registrars.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED\n\nnamespace Catch {\n\n    template<typename T>\n    class LegacyReporterRegistrar {\n\n        class ReporterFactory : public IReporterFactory {\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new LegacyReporterAdapter( new T( config ) );\n            }\n\n            virtual std::string getDescription() const {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        LegacyReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );\n        }\n    };\n\n    template<typename T>\n    class ReporterRegistrar {\n\n        class ReporterFactory : public SharedImpl<IReporterFactory> {\n\n            // *** Please Note ***:\n            // - If you end up here looking at a compiler error because it's trying to register\n            // your custom reporter class be aware that the native reporter interface has changed\n            // to IStreamingReporter. The \"legacy\" interface, IReporter, is still supported via\n            // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.\n            // However please consider updating to the new interface as the old one is now\n            // deprecated and will probably be removed quite soon!\n            // Please contact me via github if you have any questions at all about this.\n            // In fact, ideally, please contact me anyway to let me know you've hit this - as I have\n            // no idea who is actually using custom reporters at all (possibly no-one!).\n            // The new interface is designed to minimise exposure to interface changes in the future.\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new T( config );\n            }\n\n            virtual std::string getDescription() const {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        ReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );\n        }\n    };\n\n    template<typename T>\n    class ListenerRegistrar {\n\n        class ListenerFactory : public SharedImpl<IReporterFactory> {\n\n            virtual IStreamingReporter* create( ReporterConfig const& config ) const {\n                return new T( config );\n            }\n            virtual std::string getDescription() const {\n                return \"\";\n            }\n        };\n\n    public:\n\n        ListenerRegistrar() {\n            getMutableRegistryHub().registerListener( new ListenerFactory() );\n        }\n    };\n}\n\n#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \\\n    namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }\n\n#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \\\n    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }\n\n#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \\\n    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }\n\n// #included from: ../internal/catch_xmlwriter.hpp\n#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED\n\n#include <sstream>\n#include <string>\n#include <vector>\n#include <iomanip>\n\nnamespace Catch {\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )\n        :   m_str( str ),\n            m_forWhat( forWhat )\n        {}\n\n        void encodeTo( std::ostream& os ) const {\n\n            // Apostrophe escaping not necessary if we always use \" to write attributes\n            // (see: http://www.w3.org/TR/xml/#syntax)\n\n            for( std::size_t i = 0; i < m_str.size(); ++ i ) {\n                char c = m_str[i];\n                switch( c ) {\n                    case '<':   os << \"&lt;\"; break;\n                    case '&':   os << \"&amp;\"; break;\n\n                    case '>':\n                        // See: http://www.w3.org/TR/xml/#syntax\n                        if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )\n                            os << \"&gt;\";\n                        else\n                            os << c;\n                        break;\n\n                    case '\\\"':\n                        if( m_forWhat == ForAttributes )\n                            os << \"&quot;\";\n                        else\n                            os << c;\n                        break;\n\n                    default:\n                        // Escape control chars - based on contribution by @espenalb in PR #465 and\n                        // by @mrpi PR #588\n                        if ( ( c >= 0 && c < '\\x09' ) || ( c > '\\x0D' && c < '\\x20') || c=='\\x7F' )\n                            os << \"&#x\" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';\n                        else\n                            os << c;\n                }\n            }\n        }\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n            xmlEncode.encodeTo( os );\n            return os;\n        }\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer )\n            :   m_writer( writer )\n            {}\n\n            ScopedElement( ScopedElement const& other )\n            :   m_writer( other.m_writer ){\n                other.m_writer = CATCH_NULL;\n            }\n\n            ~ScopedElement() {\n                if( m_writer )\n                    m_writer->endElement();\n            }\n\n            ScopedElement& writeText( std::string const& text, bool indent = true ) {\n                m_writer->writeText( text, indent );\n                return *this;\n            }\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer;\n        };\n\n        XmlWriter()\n        :   m_tagIsOpen( false ),\n            m_needsNewline( false ),\n            m_os( &Catch::cout() )\n        {\n            // We encode control characters, which requires\n            // XML 1.1\n            // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n            *m_os << \"<?xml version=\\\"1.1\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n        }\n\n        XmlWriter( std::ostream& os )\n        :   m_tagIsOpen( false ),\n            m_needsNewline( false ),\n            m_os( &os )\n        {\n            *m_os << \"<?xml version=\\\"1.1\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n        }\n\n        ~XmlWriter() {\n            while( !m_tags.empty() )\n                endElement();\n        }\n\n        XmlWriter& startElement( std::string const& name ) {\n            ensureTagClosed();\n            newlineIfNecessary();\n            stream() << m_indent << \"<\" << name;\n            m_tags.push_back( name );\n            m_indent += \"  \";\n            m_tagIsOpen = true;\n            return *this;\n        }\n\n        ScopedElement scopedElement( std::string const& name ) {\n            ScopedElement scoped( this );\n            startElement( name );\n            return scoped;\n        }\n\n        XmlWriter& endElement() {\n            newlineIfNecessary();\n            m_indent = m_indent.substr( 0, m_indent.size()-2 );\n            if( m_tagIsOpen ) {\n                stream() << \"/>\\n\";\n                m_tagIsOpen = false;\n            }\n            else {\n                stream() << m_indent << \"</\" << m_tags.back() << \">\\n\";\n            }\n            m_tags.pop_back();\n            return *this;\n        }\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {\n            if( !name.empty() && !attribute.empty() )\n                stream() << \" \" << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << \"\\\"\";\n            return *this;\n        }\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute ) {\n            stream() << \" \" << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << \"\\\"\";\n            return *this;\n        }\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n            std::ostringstream oss;\n            oss << attribute;\n            return writeAttribute( name, oss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, bool indent = true ) {\n            if( !text.empty() ){\n                bool tagWasOpen = m_tagIsOpen;\n                ensureTagClosed();\n                if( tagWasOpen && indent )\n                    stream() << m_indent;\n                stream() << XmlEncode( text );\n                m_needsNewline = true;\n            }\n            return *this;\n        }\n\n        XmlWriter& writeComment( std::string const& text ) {\n            ensureTagClosed();\n            stream() << m_indent << \"<!--\" << text << \"-->\";\n            m_needsNewline = true;\n            return *this;\n        }\n\n        XmlWriter& writeBlankLine() {\n            ensureTagClosed();\n            stream() << \"\\n\";\n            return *this;\n        }\n\n        void setStream( std::ostream& os ) {\n            m_os = &os;\n        }\n\n    private:\n        XmlWriter( XmlWriter const& );\n        void operator=( XmlWriter const& );\n\n        std::ostream& stream() {\n            return *m_os;\n        }\n\n        void ensureTagClosed() {\n            if( m_tagIsOpen ) {\n                stream() << \">\\n\";\n                m_tagIsOpen = false;\n            }\n        }\n\n        void newlineIfNecessary() {\n            if( m_needsNewline ) {\n                stream() << \"\\n\";\n                m_needsNewline = false;\n            }\n        }\n\n        bool m_tagIsOpen;\n        bool m_needsNewline;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream* m_os;\n    };\n\n}\n// #included from: catch_reenable_warnings.h\n\n#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED\n\n#ifdef __clang__\n#    ifdef __ICC // icpc defines the __clang__ macro\n#        pragma warning(pop)\n#    else\n#        pragma clang diagnostic pop\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic pop\n#endif\n\n\nnamespace Catch {\n    class XmlReporter : public StreamingReporterBase {\n    public:\n        XmlReporter( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config ),\n            m_xml(_config.stream()),\n            m_sectionDepth( 0 )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n        }\n\n        virtual ~XmlReporter() CATCH_OVERRIDE;\n\n        static std::string getDescription() {\n            return \"Reports test results as an XML document\";\n        }\n\n    public: // StreamingReporterBase\n\n        virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {\n            StreamingReporterBase::noMatchingTestCases( s );\n        }\n\n        virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testRunStarting( testInfo );\n            m_xml.startElement( \"Catch\" );\n            if( !m_config->name().empty() )\n                m_xml.writeAttribute( \"name\", m_config->name() );\n        }\n\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testGroupStarting( groupInfo );\n            m_xml.startElement( \"Group\" )\n                .writeAttribute( \"name\", groupInfo.name );\n        }\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseStarting(testInfo);\n            m_xml.startElement( \"TestCase\" ).writeAttribute( \"name\", testInfo.name );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                m_testCaseTimer.start();\n        }\n\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {\n            StreamingReporterBase::sectionStarting( sectionInfo );\n            if( m_sectionDepth++ > 0 ) {\n                m_xml.startElement( \"Section\" )\n                    .writeAttribute( \"name\", trim( sectionInfo.name ) )\n                    .writeAttribute( \"description\", sectionInfo.description );\n            }\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            const AssertionResult& assertionResult = assertionStats.assertionResult;\n\n            // Print any info messages in <Info> tags.\n            if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {\n                for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();\n                        it != itEnd;\n                        ++it ) {\n                    if( it->type == ResultWas::Info ) {\n                        m_xml.scopedElement( \"Info\" )\n                            .writeText( it->message );\n                    } else if ( it->type == ResultWas::Warning ) {\n                        m_xml.scopedElement( \"Warning\" )\n                            .writeText( it->message );\n                    }\n                }\n            }\n\n            // Drop out if result was successful but we're not printing them.\n            if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )\n                return true;\n\n            // Print the expression if there is one.\n            if( assertionResult.hasExpression() ) {\n                m_xml.startElement( \"Expression\" )\n                    .writeAttribute( \"success\", assertionResult.succeeded() )\n\t\t\t\t\t.writeAttribute( \"type\", assertionResult.getTestMacroName() )\n                    .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                    .writeAttribute( \"line\", assertionResult.getSourceInfo().line );\n\n                m_xml.scopedElement( \"Original\" )\n                    .writeText( assertionResult.getExpression() );\n                m_xml.scopedElement( \"Expanded\" )\n                    .writeText( assertionResult.getExpandedExpression() );\n            }\n\n            // And... Print a result applicable to each result type.\n            switch( assertionResult.getResultType() ) {\n                case ResultWas::ThrewException:\n                    m_xml.scopedElement( \"Exception\" )\n                        .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                        .writeAttribute( \"line\", assertionResult.getSourceInfo().line )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::FatalErrorCondition:\n                    m_xml.scopedElement( \"FatalErrorCondition\" )\n                        .writeAttribute( \"filename\", assertionResult.getSourceInfo().file )\n                        .writeAttribute( \"line\", assertionResult.getSourceInfo().line )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::Info:\n                    m_xml.scopedElement( \"Info\" )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                case ResultWas::Warning:\n                    // Warning will already have been written\n                    break;\n                case ResultWas::ExplicitFailure:\n                    m_xml.scopedElement( \"Failure\" )\n                        .writeText( assertionResult.getMessage() );\n                    break;\n                default:\n                    break;\n            }\n\n            if( assertionResult.hasExpression() )\n                m_xml.endElement();\n\n            return true;\n        }\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::sectionEnded( sectionStats );\n            if( --m_sectionDepth > 0 ) {\n                XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResults\" );\n                e.writeAttribute( \"successes\", sectionStats.assertions.passed );\n                e.writeAttribute( \"failures\", sectionStats.assertions.failed );\n                e.writeAttribute( \"expectedFailures\", sectionStats.assertions.failedButOk );\n\n                if ( m_config->showDurations() == ShowDurations::Always )\n                    e.writeAttribute( \"durationInSeconds\", sectionStats.durationInSeconds );\n\n                m_xml.endElement();\n            }\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseEnded( testCaseStats );\n            XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResult\" );\n            e.writeAttribute( \"success\", testCaseStats.totals.assertions.allOk() );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                e.writeAttribute( \"durationInSeconds\", m_testCaseTimer.getElapsedSeconds() );\n\n            m_xml.endElement();\n        }\n\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testGroupEnded( testGroupStats );\n            // TODO: Check testGroupStats.aborting and act accordingly.\n            m_xml.scopedElement( \"OverallResults\" )\n                .writeAttribute( \"successes\", testGroupStats.totals.assertions.passed )\n                .writeAttribute( \"failures\", testGroupStats.totals.assertions.failed )\n                .writeAttribute( \"expectedFailures\", testGroupStats.totals.assertions.failedButOk );\n            m_xml.endElement();\n        }\n\n        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testRunEnded( testRunStats );\n            m_xml.scopedElement( \"OverallResults\" )\n                .writeAttribute( \"successes\", testRunStats.totals.assertions.passed )\n                .writeAttribute( \"failures\", testRunStats.totals.assertions.failed )\n                .writeAttribute( \"expectedFailures\", testRunStats.totals.assertions.failedButOk );\n            m_xml.endElement();\n        }\n\n    private:\n        Timer m_testCaseTimer;\n        XmlWriter m_xml;\n        int m_sectionDepth;\n    };\n\n     INTERNAL_CATCH_REGISTER_REPORTER( \"xml\", XmlReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_junit.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED\n\n#include <assert.h>\n\nnamespace Catch {\n\n    namespace {\n        std::string getCurrentTimestamp() {\n            // Beware, this is not reentrant because of backward compatibility issues\n            // Also, UTC only, again because of backward compatibility (%z is C++11)\n            time_t rawtime;\n            std::time(&rawtime);\n            const size_t timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n#ifdef CATCH_PLATFORM_WINDOWS\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &rawtime);\n#else\n            std::tm* timeInfo;\n            timeInfo = std::gmtime(&rawtime);\n#endif\n\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef CATCH_PLATFORM_WINDOWS\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp);\n        }\n\n    }\n\n    class JunitReporter : public CumulativeReporterBase {\n    public:\n        JunitReporter( ReporterConfig const& _config )\n        :   CumulativeReporterBase( _config ),\n            xml( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n        }\n\n        virtual ~JunitReporter() CATCH_OVERRIDE;\n\n        static std::string getDescription() {\n            return \"Reports test results in an XML format that looks like Ant's junitreport target\";\n        }\n\n        virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}\n\n        virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {\n            CumulativeReporterBase::testRunStarting( runInfo );\n            xml.startElement( \"testsuites\" );\n        }\n\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {\n            suiteTimer.start();\n            stdOutForSuite.str(\"\");\n            stdErrForSuite.str(\"\");\n            unexpectedExceptions = 0;\n            CumulativeReporterBase::testGroupStarting( groupInfo );\n        }\n\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {\n            if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )\n                unexpectedExceptions++;\n            return CumulativeReporterBase::assertionEnded( assertionStats );\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {\n            stdOutForSuite << testCaseStats.stdOut;\n            stdErrForSuite << testCaseStats.stdErr;\n            CumulativeReporterBase::testCaseEnded( testCaseStats );\n        }\n\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {\n            double suiteTime = suiteTimer.getElapsedSeconds();\n            CumulativeReporterBase::testGroupEnded( testGroupStats );\n            writeGroup( *m_testGroups.back(), suiteTime );\n        }\n\n        virtual void testRunEndedCumulative() CATCH_OVERRIDE {\n            xml.endElement();\n        }\n\n        void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {\n            XmlWriter::ScopedElement e = xml.scopedElement( \"testsuite\" );\n            TestGroupStats const& stats = groupNode.value;\n            xml.writeAttribute( \"name\", stats.groupInfo.name );\n            xml.writeAttribute( \"errors\", unexpectedExceptions );\n            xml.writeAttribute( \"failures\", stats.totals.assertions.failed-unexpectedExceptions );\n            xml.writeAttribute( \"tests\", stats.totals.assertions.total() );\n            xml.writeAttribute( \"hostname\", \"tbd\" ); // !TBD\n            if( m_config->showDurations() == ShowDurations::Never )\n                xml.writeAttribute( \"time\", \"\" );\n            else\n                xml.writeAttribute( \"time\", suiteTime );\n            xml.writeAttribute( \"timestamp\", getCurrentTimestamp() );\n\n            // Write test cases\n            for( TestGroupNode::ChildNodes::const_iterator\n                    it = groupNode.children.begin(), itEnd = groupNode.children.end();\n                    it != itEnd;\n                    ++it )\n                writeTestCase( **it );\n\n            xml.scopedElement( \"system-out\" ).writeText( trim( stdOutForSuite.str() ), false );\n            xml.scopedElement( \"system-err\" ).writeText( trim( stdErrForSuite.str() ), false );\n        }\n\n        void writeTestCase( TestCaseNode const& testCaseNode ) {\n            TestCaseStats const& stats = testCaseNode.value;\n\n            // All test cases have exactly one section - which represents the\n            // test case itself. That section may have 0-n nested sections\n            assert( testCaseNode.children.size() == 1 );\n            SectionNode const& rootSection = *testCaseNode.children.front();\n\n            std::string className = stats.testInfo.className;\n\n            if( className.empty() ) {\n                if( rootSection.childSections.empty() )\n                    className = \"global\";\n            }\n            writeSection( className, \"\", rootSection );\n        }\n\n        void writeSection(  std::string const& className,\n                            std::string const& rootName,\n                            SectionNode const& sectionNode ) {\n            std::string name = trim( sectionNode.stats.sectionInfo.name );\n            if( !rootName.empty() )\n                name = rootName + \"/\" + name;\n\n            if( !sectionNode.assertions.empty() ||\n                !sectionNode.stdOut.empty() ||\n                !sectionNode.stdErr.empty() ) {\n                XmlWriter::ScopedElement e = xml.scopedElement( \"testcase\" );\n                if( className.empty() ) {\n                    xml.writeAttribute( \"classname\", name );\n                    xml.writeAttribute( \"name\", \"root\" );\n                }\n                else {\n                    xml.writeAttribute( \"classname\", className );\n                    xml.writeAttribute( \"name\", name );\n                }\n                xml.writeAttribute( \"time\", Catch::toString( sectionNode.stats.durationInSeconds ) );\n\n                writeAssertions( sectionNode );\n\n                if( !sectionNode.stdOut.empty() )\n                    xml.scopedElement( \"system-out\" ).writeText( trim( sectionNode.stdOut ), false );\n                if( !sectionNode.stdErr.empty() )\n                    xml.scopedElement( \"system-err\" ).writeText( trim( sectionNode.stdErr ), false );\n            }\n            for( SectionNode::ChildSections::const_iterator\n                    it = sectionNode.childSections.begin(),\n                    itEnd = sectionNode.childSections.end();\n                    it != itEnd;\n                    ++it )\n                if( className.empty() )\n                    writeSection( name, \"\", **it );\n                else\n                    writeSection( className, name, **it );\n        }\n\n        void writeAssertions( SectionNode const& sectionNode ) {\n            for( SectionNode::Assertions::const_iterator\n                    it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();\n                    it != itEnd;\n                    ++it )\n                writeAssertion( *it );\n        }\n        void writeAssertion( AssertionStats const& stats ) {\n            AssertionResult const& result = stats.assertionResult;\n            if( !result.isOk() ) {\n                std::string elementName;\n                switch( result.getResultType() ) {\n                    case ResultWas::ThrewException:\n                    case ResultWas::FatalErrorCondition:\n                        elementName = \"error\";\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        elementName = \"failure\";\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        elementName = \"failure\";\n                        break;\n                    case ResultWas::DidntThrowException:\n                        elementName = \"failure\";\n                        break;\n\n                    // We should never see these here:\n                    case ResultWas::Info:\n                    case ResultWas::Warning:\n                    case ResultWas::Ok:\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        elementName = \"internalError\";\n                        break;\n                }\n\n                XmlWriter::ScopedElement e = xml.scopedElement( elementName );\n\n                xml.writeAttribute( \"message\", result.getExpandedExpression() );\n                xml.writeAttribute( \"type\", result.getTestMacroName() );\n\n                std::ostringstream oss;\n                if( !result.getMessage().empty() )\n                    oss << result.getMessage() << \"\\n\";\n                for( std::vector<MessageInfo>::const_iterator\n                        it = stats.infoMessages.begin(),\n                        itEnd = stats.infoMessages.end();\n                            it != itEnd;\n                            ++it )\n                    if( it->type == ResultWas::Info )\n                        oss << it->message << \"\\n\";\n\n                oss << \"at \" << result.getSourceInfo();\n                xml.writeText( oss.str(), false );\n            }\n        }\n\n        XmlWriter xml;\n        Timer suiteTimer;\n        std::ostringstream stdOutForSuite;\n        std::ostringstream stdErrForSuite;\n        unsigned int unexpectedExceptions;\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"junit\", JunitReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_console.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct ConsoleReporter : StreamingReporterBase {\n        ConsoleReporter( ReporterConfig const& _config )\n        :   StreamingReporterBase( _config ),\n            m_headerPrinted( false )\n        {}\n\n        virtual ~ConsoleReporter() CATCH_OVERRIDE;\n        static std::string getDescription() {\n            return \"Reports test results as plain lines of text\";\n        }\n\n        virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {\n            stream << \"No test cases matched '\" << spec << \"'\" << std::endl;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {\n        }\n\n        virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            lazyPrint();\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n            stream << std::endl;\n            return true;\n        }\n\n        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {\n            m_headerPrinted = false;\n            StreamingReporterBase::sectionStarting( _sectionInfo );\n        }\n        virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {\n            if( _sectionStats.missingAssertions ) {\n                lazyPrint();\n                Colour colour( Colour::ResultError );\n                if( m_sectionStack.size() > 1 )\n                    stream << \"\\nNo assertions in section\";\n                else\n                    stream << \"\\nNo assertions in test case\";\n                stream << \" '\" << _sectionStats.sectionInfo.name << \"'\\n\" << std::endl;\n            }\n            if( m_headerPrinted ) {\n                if( m_config->showDurations() == ShowDurations::Always )\n                    stream << \"Completed in \" << _sectionStats.durationInSeconds << \"s\" << std::endl;\n                m_headerPrinted = false;\n            }\n            else {\n                if( m_config->showDurations() == ShowDurations::Always )\n                    stream << _sectionStats.sectionInfo.name << \" completed in \" << _sectionStats.durationInSeconds << \"s\" << std::endl;\n            }\n            StreamingReporterBase::sectionEnded( _sectionStats );\n        }\n\n        virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {\n            StreamingReporterBase::testCaseEnded( _testCaseStats );\n            m_headerPrinted = false;\n        }\n        virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {\n            if( currentGroupInfo.used ) {\n                printSummaryDivider();\n                stream << \"Summary for group '\" << _testGroupStats.groupInfo.name << \"':\\n\";\n                printTotals( _testGroupStats.totals );\n                stream << \"\\n\" << std::endl;\n            }\n            StreamingReporterBase::testGroupEnded( _testGroupStats );\n        }\n        virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {\n            printTotalsDivider( _testRunStats.totals );\n            printTotals( _testRunStats.totals );\n            stream << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n    private:\n\n        class AssertionPrinter {\n            void operator= ( AssertionPrinter const& );\n        public:\n            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )\n            :   stream( _stream ),\n                stats( _stats ),\n                result( _stats.assertionResult ),\n                colour( Colour::None ),\n                message( result.getMessage() ),\n                messages( _stats.infoMessages ),\n                printInfoMessages( _printInfoMessages )\n            {\n                switch( result.getResultType() ) {\n                    case ResultWas::Ok:\n                        colour = Colour::Success;\n                        passOrFail = \"PASSED\";\n                        //if( result.hasMessage() )\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"with messages\";\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        if( result.isOk() ) {\n                            colour = Colour::Success;\n                            passOrFail = \"FAILED - but was ok\";\n                        }\n                        else {\n                            colour = Colour::Error;\n                            passOrFail = \"FAILED\";\n                        }\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"with messages\";\n                        break;\n                    case ResultWas::ThrewException:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"due to unexpected exception with message\";\n                        break;\n                    case ResultWas::FatalErrorCondition:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"due to a fatal error condition\";\n                        break;\n                    case ResultWas::DidntThrowException:\n                        colour = Colour::Error;\n                        passOrFail = \"FAILED\";\n                        messageLabel = \"because no exception was thrown where one was expected\";\n                        break;\n                    case ResultWas::Info:\n                        messageLabel = \"info\";\n                        break;\n                    case ResultWas::Warning:\n                        messageLabel = \"warning\";\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        passOrFail = \"FAILED\";\n                        colour = Colour::Error;\n                        if( _stats.infoMessages.size() == 1 )\n                            messageLabel = \"explicitly with message\";\n                        if( _stats.infoMessages.size() > 1 )\n                            messageLabel = \"explicitly with messages\";\n                        break;\n                    // These cases are here to prevent compiler warnings\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        passOrFail = \"** internal error **\";\n                        colour = Colour::Error;\n                        break;\n                }\n            }\n\n            void print() const {\n                printSourceInfo();\n                if( stats.totals.assertions.total() > 0 ) {\n                    if( result.isOk() )\n                        stream << \"\\n\";\n                    printResultType();\n                    printOriginalExpression();\n                    printReconstructedExpression();\n                }\n                else {\n                    stream << \"\\n\";\n                }\n                printMessage();\n            }\n\n        private:\n            void printResultType() const {\n                if( !passOrFail.empty() ) {\n                    Colour colourGuard( colour );\n                    stream << passOrFail << \":\\n\";\n                }\n            }\n            void printOriginalExpression() const {\n                if( result.hasExpression() ) {\n                    Colour colourGuard( Colour::OriginalExpression );\n                    stream  << \"  \";\n                    stream << result.getExpressionInMacro();\n                    stream << \"\\n\";\n                }\n            }\n            void printReconstructedExpression() const {\n                if( result.hasExpandedExpression() ) {\n                    stream << \"with expansion:\\n\";\n                    Colour colourGuard( Colour::ReconstructedExpression );\n                    stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << \"\\n\";\n                }\n            }\n            void printMessage() const {\n                if( !messageLabel.empty() )\n                    stream << messageLabel << \":\" << \"\\n\";\n                for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();\n                        it != itEnd;\n                        ++it ) {\n                    // If this assertion is a warning ignore any INFO messages\n                    if( printInfoMessages || it->type != ResultWas::Info )\n                        stream << Text( it->message, TextAttributes().setIndent(2) ) << \"\\n\";\n                }\n            }\n            void printSourceInfo() const {\n                Colour colourGuard( Colour::FileName );\n                stream << result.getSourceInfo() << \": \";\n            }\n\n            std::ostream& stream;\n            AssertionStats const& stats;\n            AssertionResult const& result;\n            Colour::Code colour;\n            std::string passOrFail;\n            std::string messageLabel;\n            std::string message;\n            std::vector<MessageInfo> messages;\n            bool printInfoMessages;\n        };\n\n        void lazyPrint() {\n\n            if( !currentTestRunInfo.used )\n                lazyPrintRunInfo();\n            if( !currentGroupInfo.used )\n                lazyPrintGroupInfo();\n\n            if( !m_headerPrinted ) {\n                printTestCaseAndSectionHeader();\n                m_headerPrinted = true;\n            }\n        }\n        void lazyPrintRunInfo() {\n            stream  << \"\\n\" << getLineOfChars<'~'>() << \"\\n\";\n            Colour colour( Colour::SecondaryText );\n            stream  << currentTestRunInfo->name\n                    << \" is a Catch v\"  << libraryVersion << \" host application.\\n\"\n                    << \"Run with -? for options\\n\\n\";\n\n            if( m_config->rngSeed() != 0 )\n                stream << \"Randomness seeded to: \" << m_config->rngSeed() << \"\\n\\n\";\n\n            currentTestRunInfo.used = true;\n        }\n        void lazyPrintGroupInfo() {\n            if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {\n                printClosedHeader( \"Group: \" + currentGroupInfo->name );\n                currentGroupInfo.used = true;\n            }\n        }\n        void printTestCaseAndSectionHeader() {\n            assert( !m_sectionStack.empty() );\n            printOpenHeader( currentTestCaseInfo->name );\n\n            if( m_sectionStack.size() > 1 ) {\n                Colour colourGuard( Colour::Headers );\n\n                std::vector<SectionInfo>::const_iterator\n                    it = m_sectionStack.begin()+1, // Skip first section (test case)\n                    itEnd = m_sectionStack.end();\n                for( ; it != itEnd; ++it )\n                    printHeaderString( it->name, 2 );\n            }\n\n            SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;\n\n            if( !lineInfo.empty() ){\n                stream << getLineOfChars<'-'>() << \"\\n\";\n                Colour colourGuard( Colour::FileName );\n                stream << lineInfo << \"\\n\";\n            }\n            stream << getLineOfChars<'.'>() << \"\\n\" << std::endl;\n        }\n\n        void printClosedHeader( std::string const& _name ) {\n            printOpenHeader( _name );\n            stream << getLineOfChars<'.'>() << \"\\n\";\n        }\n        void printOpenHeader( std::string const& _name ) {\n            stream  << getLineOfChars<'-'>() << \"\\n\";\n            {\n                Colour colourGuard( Colour::Headers );\n                printHeaderString( _name );\n            }\n        }\n\n        // if string has a : in first line will set indent to follow it on\n        // subsequent lines\n        void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {\n            std::size_t i = _string.find( \": \" );\n            if( i != std::string::npos )\n                i+=2;\n            else\n                i = 0;\n            stream << Text( _string, TextAttributes()\n                                        .setIndent( indent+i)\n                                        .setInitialIndent( indent ) ) << \"\\n\";\n        }\n\n        struct SummaryColumn {\n\n            SummaryColumn( std::string const& _label, Colour::Code _colour )\n            :   label( _label ),\n                colour( _colour )\n            {}\n            SummaryColumn addRow( std::size_t count ) {\n                std::ostringstream oss;\n                oss << count;\n                std::string row = oss.str();\n                for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {\n                    while( it->size() < row.size() )\n                        *it = \" \" + *it;\n                    while( it->size() > row.size() )\n                        row = \" \" + row;\n                }\n                rows.push_back( row );\n                return *this;\n            }\n\n            std::string label;\n            Colour::Code colour;\n            std::vector<std::string> rows;\n\n        };\n\n        void printTotals( Totals const& totals ) {\n            if( totals.testCases.total() == 0 ) {\n                stream << Colour( Colour::Warning ) << \"No tests ran\\n\";\n            }\n            else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {\n                stream << Colour( Colour::ResultSuccess ) << \"All tests passed\";\n                stream << \" (\"\n                        << pluralise( totals.assertions.passed, \"assertion\" ) << \" in \"\n                        << pluralise( totals.testCases.passed, \"test case\" ) << \")\"\n                        << \"\\n\";\n            }\n            else {\n\n                std::vector<SummaryColumn> columns;\n                columns.push_back( SummaryColumn( \"\", Colour::None )\n                                        .addRow( totals.testCases.total() )\n                                        .addRow( totals.assertions.total() ) );\n                columns.push_back( SummaryColumn( \"passed\", Colour::Success )\n                                        .addRow( totals.testCases.passed )\n                                        .addRow( totals.assertions.passed ) );\n                columns.push_back( SummaryColumn( \"failed\", Colour::ResultError )\n                                        .addRow( totals.testCases.failed )\n                                        .addRow( totals.assertions.failed ) );\n                columns.push_back( SummaryColumn( \"failed as expected\", Colour::ResultExpectedFailure )\n                                        .addRow( totals.testCases.failedButOk )\n                                        .addRow( totals.assertions.failedButOk ) );\n\n                printSummaryRow( \"test cases\", columns, 0 );\n                printSummaryRow( \"assertions\", columns, 1 );\n            }\n        }\n        void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {\n            for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {\n                std::string value = it->rows[row];\n                if( it->label.empty() ) {\n                    stream << label << \": \";\n                    if( value != \"0\" )\n                        stream << value;\n                    else\n                        stream << Colour( Colour::Warning ) << \"- none -\";\n                }\n                else if( value != \"0\" ) {\n                    stream  << Colour( Colour::LightGrey ) << \" | \";\n                    stream  << Colour( it->colour )\n                            << value << \" \" << it->label;\n                }\n            }\n            stream << \"\\n\";\n        }\n\n        static std::size_t makeRatio( std::size_t number, std::size_t total ) {\n            std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;\n            return ( ratio == 0 && number > 0 ) ? 1 : ratio;\n        }\n        static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {\n            if( i > j && i > k )\n                return i;\n            else if( j > k )\n                return j;\n            else\n                return k;\n        }\n\n        void printTotalsDivider( Totals const& totals ) {\n            if( totals.testCases.total() > 0 ) {\n                std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );\n                std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );\n                std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );\n                while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )\n                    findMax( failedRatio, failedButOkRatio, passedRatio )++;\n                while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )\n                    findMax( failedRatio, failedButOkRatio, passedRatio )--;\n\n                stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );\n                stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );\n                if( totals.testCases.allPassed() )\n                    stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );\n                else\n                    stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );\n            }\n            else {\n                stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );\n            }\n            stream << \"\\n\";\n        }\n        void printSummaryDivider() {\n            stream << getLineOfChars<'-'>() << \"\\n\";\n        }\n\n    private:\n        bool m_headerPrinted;\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"console\", ConsoleReporter )\n\n} // end namespace Catch\n\n// #included from: ../reporters/catch_reporter_compact.hpp\n#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED\n\nnamespace Catch {\n\n    struct CompactReporter : StreamingReporterBase {\n\n        CompactReporter( ReporterConfig const& _config )\n        : StreamingReporterBase( _config )\n        {}\n\n        virtual ~CompactReporter();\n\n        static std::string getDescription() {\n            return \"Reports test results on a single line, suitable for IDEs\";\n        }\n\n        virtual ReporterPreferences getPreferences() const {\n            ReporterPreferences prefs;\n            prefs.shouldRedirectStdOut = false;\n            return prefs;\n        }\n\n        virtual void noMatchingTestCases( std::string const& spec ) {\n            stream << \"No test cases matched '\" << spec << \"'\" << std::endl;\n        }\n\n        virtual void assertionStarting( AssertionInfo const& ) {\n        }\n\n        virtual bool assertionEnded( AssertionStats const& _assertionStats ) {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n\n            stream << std::endl;\n            return true;\n        }\n\n        virtual void testRunEnded( TestRunStats const& _testRunStats ) {\n            printTotals( _testRunStats.totals );\n            stream << \"\\n\" << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n    private:\n        class AssertionPrinter {\n            void operator= ( AssertionPrinter const& );\n        public:\n            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )\n            : stream( _stream )\n            , stats( _stats )\n            , result( _stats.assertionResult )\n            , messages( _stats.infoMessages )\n            , itMessage( _stats.infoMessages.begin() )\n            , printInfoMessages( _printInfoMessages )\n            {}\n\n            void print() {\n                printSourceInfo();\n\n                itMessage = messages.begin();\n\n                switch( result.getResultType() ) {\n                    case ResultWas::Ok:\n                        printResultType( Colour::ResultSuccess, passedString() );\n                        printOriginalExpression();\n                        printReconstructedExpression();\n                        if ( ! result.hasExpression() )\n                            printRemainingMessages( Colour::None );\n                        else\n                            printRemainingMessages();\n                        break;\n                    case ResultWas::ExpressionFailed:\n                        if( result.isOk() )\n                            printResultType( Colour::ResultSuccess, failedString() + std::string( \" - but was ok\" ) );\n                        else\n                            printResultType( Colour::Error, failedString() );\n                        printOriginalExpression();\n                        printReconstructedExpression();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::ThrewException:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"unexpected exception with message:\" );\n                        printMessage();\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::FatalErrorCondition:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"fatal error condition with message:\" );\n                        printMessage();\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::DidntThrowException:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"expected exception, got none\" );\n                        printExpressionWas();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::Info:\n                        printResultType( Colour::None, \"info\" );\n                        printMessage();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::Warning:\n                        printResultType( Colour::None, \"warning\" );\n                        printMessage();\n                        printRemainingMessages();\n                        break;\n                    case ResultWas::ExplicitFailure:\n                        printResultType( Colour::Error, failedString() );\n                        printIssue( \"explicitly\" );\n                        printRemainingMessages( Colour::None );\n                        break;\n                    // These cases are here to prevent compiler warnings\n                    case ResultWas::Unknown:\n                    case ResultWas::FailureBit:\n                    case ResultWas::Exception:\n                        printResultType( Colour::Error, \"** internal error **\" );\n                        break;\n                }\n            }\n\n        private:\n            // Colour::LightGrey\n\n            static Colour::Code dimColour() { return Colour::FileName; }\n\n#ifdef CATCH_PLATFORM_MAC\n            static const char* failedString() { return \"FAILED\"; }\n            static const char* passedString() { return \"PASSED\"; }\n#else\n            static const char* failedString() { return \"failed\"; }\n            static const char* passedString() { return \"passed\"; }\n#endif\n\n            void printSourceInfo() const {\n                Colour colourGuard( Colour::FileName );\n                stream << result.getSourceInfo() << \":\";\n            }\n\n            void printResultType( Colour::Code colour, std::string passOrFail ) const {\n                if( !passOrFail.empty() ) {\n                    {\n                        Colour colourGuard( colour );\n                        stream << \" \" << passOrFail;\n                    }\n                    stream << \":\";\n                }\n            }\n\n            void printIssue( std::string issue ) const {\n                stream << \" \" << issue;\n            }\n\n            void printExpressionWas() {\n                if( result.hasExpression() ) {\n                    stream << \";\";\n                    {\n                        Colour colour( dimColour() );\n                        stream << \" expression was:\";\n                    }\n                    printOriginalExpression();\n                }\n            }\n\n            void printOriginalExpression() const {\n                if( result.hasExpression() ) {\n                    stream << \" \" << result.getExpression();\n                }\n            }\n\n            void printReconstructedExpression() const {\n                if( result.hasExpandedExpression() ) {\n                    {\n                        Colour colour( dimColour() );\n                        stream << \" for: \";\n                    }\n                    stream << result.getExpandedExpression();\n                }\n            }\n\n            void printMessage() {\n                if ( itMessage != messages.end() ) {\n                    stream << \" '\" << itMessage->message << \"'\";\n                    ++itMessage;\n                }\n            }\n\n            void printRemainingMessages( Colour::Code colour = dimColour() ) {\n                if ( itMessage == messages.end() )\n                    return;\n\n                // using messages.end() directly yields compilation error:\n                std::vector<MessageInfo>::const_iterator itEnd = messages.end();\n                const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );\n\n                {\n                    Colour colourGuard( colour );\n                    stream << \" with \" << pluralise( N, \"message\" ) << \":\";\n                }\n\n                for(; itMessage != itEnd; ) {\n                    // If this assertion is a warning ignore any INFO messages\n                    if( printInfoMessages || itMessage->type != ResultWas::Info ) {\n                        stream << \" '\" << itMessage->message << \"'\";\n                        if ( ++itMessage != itEnd ) {\n                            Colour colourGuard( dimColour() );\n                            stream << \" and\";\n                        }\n                    }\n                }\n            }\n\n        private:\n            std::ostream& stream;\n            AssertionStats const& stats;\n            AssertionResult const& result;\n            std::vector<MessageInfo> messages;\n            std::vector<MessageInfo>::const_iterator itMessage;\n            bool printInfoMessages;\n        };\n\n        // Colour, message variants:\n        // - white: No tests ran.\n        // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.\n        // - white: Passed [both/all] N test cases (no assertions).\n        // -   red: Failed N tests cases, failed M assertions.\n        // - green: Passed [both/all] N tests cases with M assertions.\n\n        std::string bothOrAll( std::size_t count ) const {\n            return count == 1 ? \"\" : count == 2 ? \"both \" : \"all \" ;\n        }\n\n        void printTotals( const Totals& totals ) const {\n            if( totals.testCases.total() == 0 ) {\n                stream << \"No tests ran.\";\n            }\n            else if( totals.testCases.failed == totals.testCases.total() ) {\n                Colour colour( Colour::ResultError );\n                const std::string qualify_assertions_failed =\n                    totals.assertions.failed == totals.assertions.total() ?\n                        bothOrAll( totals.assertions.failed ) : \"\";\n                stream <<\n                    \"Failed \" << bothOrAll( totals.testCases.failed )\n                              << pluralise( totals.testCases.failed, \"test case\"  ) << \", \"\n                    \"failed \" << qualify_assertions_failed <<\n                                 pluralise( totals.assertions.failed, \"assertion\" ) << \".\";\n            }\n            else if( totals.assertions.total() == 0 ) {\n                stream <<\n                    \"Passed \" << bothOrAll( totals.testCases.total() )\n                              << pluralise( totals.testCases.total(), \"test case\" )\n                              << \" (no assertions).\";\n            }\n            else if( totals.assertions.failed ) {\n                Colour colour( Colour::ResultError );\n                stream <<\n                    \"Failed \" << pluralise( totals.testCases.failed, \"test case\"  ) << \", \"\n                    \"failed \" << pluralise( totals.assertions.failed, \"assertion\" ) << \".\";\n            }\n            else {\n                Colour colour( Colour::ResultSuccess );\n                stream <<\n                    \"Passed \" << bothOrAll( totals.testCases.passed )\n                              << pluralise( totals.testCases.passed, \"test case\"  ) <<\n                    \" with \"  << pluralise( totals.assertions.passed, \"assertion\" ) << \".\";\n            }\n        }\n    };\n\n    INTERNAL_CATCH_REGISTER_REPORTER( \"compact\", CompactReporter )\n\n} // end namespace Catch\n\nnamespace Catch {\n    // These are all here to avoid warnings about not having any out of line\n    // virtual methods\n    NonCopyable::~NonCopyable() {}\n    IShared::~IShared() {}\n    IStream::~IStream() CATCH_NOEXCEPT {}\n    FileStream::~FileStream() CATCH_NOEXCEPT {}\n    CoutStream::~CoutStream() CATCH_NOEXCEPT {}\n    DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}\n    StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}\n    IContext::~IContext() {}\n    IResultCapture::~IResultCapture() {}\n    ITestCase::~ITestCase() {}\n    ITestCaseRegistry::~ITestCaseRegistry() {}\n    IRegistryHub::~IRegistryHub() {}\n    IMutableRegistryHub::~IMutableRegistryHub() {}\n    IExceptionTranslator::~IExceptionTranslator() {}\n    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}\n    IReporter::~IReporter() {}\n    IReporterFactory::~IReporterFactory() {}\n    IReporterRegistry::~IReporterRegistry() {}\n    IStreamingReporter::~IStreamingReporter() {}\n    AssertionStats::~AssertionStats() {}\n    SectionStats::~SectionStats() {}\n    TestCaseStats::~TestCaseStats() {}\n    TestGroupStats::~TestGroupStats() {}\n    TestRunStats::~TestRunStats() {}\n    CumulativeReporterBase::SectionNode::~SectionNode() {}\n    CumulativeReporterBase::~CumulativeReporterBase() {}\n\n    StreamingReporterBase::~StreamingReporterBase() {}\n    ConsoleReporter::~ConsoleReporter() {}\n    CompactReporter::~CompactReporter() {}\n    IRunner::~IRunner() {}\n    IMutableContext::~IMutableContext() {}\n    IConfig::~IConfig() {}\n    XmlReporter::~XmlReporter() {}\n    JunitReporter::~JunitReporter() {}\n    TestRegistry::~TestRegistry() {}\n    FreeFunctionTestCase::~FreeFunctionTestCase() {}\n    IGeneratorInfo::~IGeneratorInfo() {}\n    IGeneratorsForTest::~IGeneratorsForTest() {}\n    WildcardPattern::~WildcardPattern() {}\n    TestSpec::Pattern::~Pattern() {}\n    TestSpec::NamePattern::~NamePattern() {}\n    TestSpec::TagPattern::~TagPattern() {}\n    TestSpec::ExcludedPattern::~ExcludedPattern() {}\n\n    Matchers::Impl::StdString::Equals::~Equals() {}\n    Matchers::Impl::StdString::Contains::~Contains() {}\n    Matchers::Impl::StdString::StartsWith::~StartsWith() {}\n    Matchers::Impl::StdString::EndsWith::~EndsWith() {}\n\n    void Config::dummy() {}\n\n    namespace TestCaseTracking {\n        ITracker::~ITracker() {}\n        TrackerBase::~TrackerBase() {}\n        SectionTracker::~SectionTracker() {}\n        IndexTracker::~IndexTracker() {}\n    }\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n#endif\n\n#ifdef CATCH_CONFIG_MAIN\n// #included from: internal/catch_default_main.hpp\n#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED\n\n#ifndef __OBJC__\n\n// Standard C/C++ main entry point\nint main (int argc, char * argv[]) {\n    return Catch::Session().run( argc, argv );\n}\n\n#else // __OBJC__\n\n// Objective-C entry point\nint main (int argc, char * const argv[]) {\n#if !CATCH_ARC_ENABLED\n    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n#endif\n\n    Catch::registerTestMethods();\n    int result = Catch::Session().run( argc, (char* const*)argv );\n\n#if !CATCH_ARC_ENABLED\n    [pool drain];\n#endif\n\n    return result;\n}\n\n#endif // __OBJC__\n\n#endif\n\n#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED\n#  undef CLARA_CONFIG_MAIN\n#endif\n\n//////\n\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE\" )\n#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \"CATCH_REQUIRE_FALSE\" )\n\n#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, \"\", \"CATCH_REQUIRE_THROWS\" )\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_THROWS_AS\" )\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, \"CATCH_REQUIRE_THROWS_WITH\" )\n#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_NOTHROW\" )\n\n#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK\" )\n#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, \"CATCH_CHECK_FALSE\" )\n#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECKED_IF\" )\n#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECKED_ELSE\" )\n#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \"CATCH_CHECK_NOFAIL\" )\n\n#define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, \"\", \"CATCH_CHECK_THROWS\" )\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_THROWS_AS\" )\n#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, \"CATCH_CHECK_THROWS_WITH\" )\n#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_NOTHROW\" )\n\n#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_CHECK_THAT\" )\n#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, \"CATCH_REQUIRE_THAT\" )\n\n#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"CATCH_INFO\" )\n#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_WARN\", msg )\n#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"CATCH_INFO\" )\n#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CATCH_CAPTURE\" )\n#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CATCH_CAPTURE\" )\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n    #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n    #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n    #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n    #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n    #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"CATCH_FAIL\", __VA_ARGS__ )\n    #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_SUCCEED\", __VA_ARGS__ )\n#else\n    #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )\n    #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )\n    #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )\n    #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )\n    #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )\n    #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"CATCH_FAIL\", msg )\n    #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"CATCH_SUCCEED\", msg )\n#endif\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( \"\", \"\" )\n\n#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )\n#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )\n\n#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )\n\n// \"BDD-style\" convenience wrappers\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#else\n#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( \"Scenario: \" name, tags )\n#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" name, tags )\n#endif\n#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( \"Given: \") + desc, \"\" )\n#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( \" When: \") + desc, \"\" )\n#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( \"  And: \") + desc, \"\" )\n#define CATCH_THEN( desc )     CATCH_SECTION( std::string( \" Then: \") + desc, \"\" )\n#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( \"  And: \") + desc, \"\" )\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, \"REQUIRE\" )\n#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \"REQUIRE_FALSE\" )\n\n#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, \"\", \"REQUIRE_THROWS\" )\n#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, \"REQUIRE_THROWS_AS\" )\n#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, \"REQUIRE_THROWS_WITH\" )\n#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, \"REQUIRE_NOTHROW\" )\n\n#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECK\" )\n#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, \"CHECK_FALSE\" )\n#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECKED_IF\" )\n#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECKED_ELSE\" )\n#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \"CHECK_NOFAIL\" )\n\n#define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, \"\", \"CHECK_THROWS\" )\n#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_THROWS_AS\" )\n#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, \"CHECK_THROWS_WITH\" )\n#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_NOTHROW\" )\n\n#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, \"CHECK_THAT\" )\n#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, \"REQUIRE_THAT\" )\n\n#define INFO( msg ) INTERNAL_CATCH_INFO( msg, \"INFO\" )\n#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, \"WARN\", msg )\n#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, \"INFO\" )\n#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CAPTURE\" )\n#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg \" := \" << msg, \"CAPTURE\" )\n\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n    #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n    #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n    #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n    #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n    #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n    #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"FAIL\", __VA_ARGS__ )\n    #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"SUCCEED\", __VA_ARGS__ )\n#else\n    #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )\n    #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )\n    #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )\n    #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )\n    #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )\n    #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, \"FAIL\", msg )\n    #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, \"SUCCEED\", msg )\n#endif\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( \"\", \"\" )\n\n#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )\n#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )\n\n#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )\n\n// \"BDD-style\" convenience wrappers\n#ifdef CATCH_CONFIG_VARIADIC_MACROS\n#define SCENARIO( ... ) TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#else\n#define SCENARIO( name, tags ) TEST_CASE( \"Scenario: \" name, tags )\n#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" name, tags )\n#endif\n#define GIVEN( desc )    SECTION( std::string(\"   Given: \") + desc, \"\" )\n#define WHEN( desc )     SECTION( std::string(\"    When: \") + desc, \"\" )\n#define AND_WHEN( desc ) SECTION( std::string(\"And when: \") + desc, \"\" )\n#define THEN( desc )     SECTION( std::string(\"    Then: \") + desc, \"\" )\n#define AND_THEN( desc ) SECTION( std::string(\"     And: \") + desc, \"\" )\n\nusing Catch::Detail::Approx;\n\n#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n"
  },
  {
    "path": "third-party/rapidjson/LICENSE.txt",
    "content": "Tencent is pleased to support the open source community by making RapidJSON available. \n \nCopyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.  All rights reserved.\n\nIf you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.\nIf you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms.  Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license.\nA copy of the MIT License is included in this file.\n\nOther dependencies and licenses:\n\nOpen Source Software Licensed Under the BSD License:\n--------------------------------------------------------------------\n\nThe msinttypes r29 \nCopyright (c) 2006-2013 Alexander Chemeris \nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n* Neither the name of  copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nOpen Source Software Licensed Under the JSON License:\n--------------------------------------------------------------------\n\njson.org \nCopyright (c) 2002 JSON.org\nAll Rights Reserved.\n\nJSON_checker\nCopyright (c) 2002 JSON.org\nAll Rights Reserved.\n\n\t\nTerms of the JSON License:\n---------------------------------------------------\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nThe Software shall be used for Good, not Evil.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\nTerms of the MIT License:\n--------------------------------------------------------------------\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "third-party/rapidjson/allocators.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ALLOCATORS_H_\n#define RAPIDJSON_ALLOCATORS_H_\n\n#include \"rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Allocator\n\n/*! \\class rapidjson::Allocator\n    \\brief Concept for allocating, resizing and freeing memory block.\n    \n    Note that Malloc() and Realloc() are non-static but Free() is static.\n    \n    So if an allocator need to support Free(), it needs to put its pointer in \n    the header of memory block.\n\n\\code\nconcept Allocator {\n    static const bool kNeedFree;    //!< Whether this allocator needs to call Free().\n\n    // Allocate a memory block.\n    // \\param size of the memory block in bytes.\n    // \\returns pointer to the memory block.\n    void* Malloc(size_t size);\n\n    // Resize a memory block.\n    // \\param originalPtr The pointer to current memory block. Null pointer is permitted.\n    // \\param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)\n    // \\param newSize the new size in bytes.\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);\n\n    // Free a memory block.\n    // \\param pointer to the memory block. Null pointer is permitted.\n    static void Free(void *ptr);\n};\n\\endcode\n*/\n\n///////////////////////////////////////////////////////////////////////////////\n// CrtAllocator\n\n//! C-runtime library allocator.\n/*! This class is just wrapper for standard C library memory routines.\n    \\note implements Allocator concept\n*/\nclass CrtAllocator {\npublic:\n    static const bool kNeedFree = true;\n    void* Malloc(size_t size) { \n        if (size) //  behavior of malloc(0) is implementation defined.\n            return std::malloc(size);\n        else\n            return NULL; // standardize to returning NULL.\n    }\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {\n        (void)originalSize;\n        if (newSize == 0) {\n            std::free(originalPtr);\n            return NULL;\n        }\n        return std::realloc(originalPtr, newSize);\n    }\n    static void Free(void *ptr) { std::free(ptr); }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// MemoryPoolAllocator\n\n//! Default memory allocator used by the parser and DOM.\n/*! This allocator allocate memory blocks from pre-allocated memory chunks. \n\n    It does not free memory blocks. And Realloc() only allocate new memory.\n\n    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.\n\n    User may also supply a buffer as the first chunk.\n\n    If the user-buffer is full then additional chunks are allocated by BaseAllocator.\n\n    The user-buffer is not deallocated by this allocator.\n\n    \\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.\n    \\note implements Allocator concept\n*/\ntemplate <typename BaseAllocator = CrtAllocator>\nclass MemoryPoolAllocator {\npublic:\n    static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator)\n\n    //! Constructor with chunkSize.\n    /*! \\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\n        \\param baseAllocator The allocator for allocating memory chunks.\n    */\n    MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : \n        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\n    {\n    }\n\n    //! Constructor with user-supplied buffer.\n    /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.\n\n        The user buffer will not be deallocated when this allocator is destructed.\n\n        \\param buffer User supplied buffer.\n        \\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).\n        \\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.\n        \\param baseAllocator The allocator for allocating memory chunks.\n    */\n    MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :\n        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)\n    {\n        RAPIDJSON_ASSERT(buffer != 0);\n        RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));\n        chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);\n        chunkHead_->capacity = size - sizeof(ChunkHeader);\n        chunkHead_->size = 0;\n        chunkHead_->next = 0;\n    }\n\n    //! Destructor.\n    /*! This deallocates all memory chunks, excluding the user-supplied buffer.\n    */\n    ~MemoryPoolAllocator() {\n        Clear();\n        RAPIDJSON_DELETE(ownBaseAllocator_);\n    }\n\n    //! Deallocates all memory chunks, excluding the user-supplied buffer.\n    void Clear() {\n        while (chunkHead_ && chunkHead_ != userBuffer_) {\n            ChunkHeader* next = chunkHead_->next;\n            baseAllocator_->Free(chunkHead_);\n            chunkHead_ = next;\n        }\n        if (chunkHead_ && chunkHead_ == userBuffer_)\n            chunkHead_->size = 0; // Clear user buffer\n    }\n\n    //! Computes the total capacity of allocated memory chunks.\n    /*! \\return total capacity in bytes.\n    */\n    size_t Capacity() const {\n        size_t capacity = 0;\n        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\n            capacity += c->capacity;\n        return capacity;\n    }\n\n    //! Computes the memory blocks allocated.\n    /*! \\return total used bytes.\n    */\n    size_t Size() const {\n        size_t size = 0;\n        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)\n            size += c->size;\n        return size;\n    }\n\n    //! Allocates a memory block. (concept Allocator)\n    void* Malloc(size_t size) {\n        if (!size)\n            return NULL;\n\n        size = RAPIDJSON_ALIGN(size);\n        if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)\n            if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))\n                return NULL;\n\n        void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;\n        chunkHead_->size += size;\n        return buffer;\n    }\n\n    //! Resizes a memory block (concept Allocator)\n    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {\n        if (originalPtr == 0)\n            return Malloc(newSize);\n\n        if (newSize == 0)\n            return NULL;\n\n        originalSize = RAPIDJSON_ALIGN(originalSize);\n        newSize = RAPIDJSON_ALIGN(newSize);\n\n        // Do not shrink if new size is smaller than original\n        if (originalSize >= newSize)\n            return originalPtr;\n\n        // Simply expand it if it is the last allocation and there is sufficient space\n        if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {\n            size_t increment = static_cast<size_t>(newSize - originalSize);\n            if (chunkHead_->size + increment <= chunkHead_->capacity) {\n                chunkHead_->size += increment;\n                return originalPtr;\n            }\n        }\n\n        // Realloc process: allocate and copy memory, do not free original buffer.\n        if (void* newBuffer = Malloc(newSize)) {\n            if (originalSize)\n                std::memcpy(newBuffer, originalPtr, originalSize);\n            return newBuffer;\n        }\n        else\n            return NULL;\n    }\n\n    //! Frees a memory block (concept Allocator)\n    static void Free(void *ptr) { (void)ptr; } // Do nothing\n\nprivate:\n    //! Copy constructor is not permitted.\n    MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;\n    //! Copy assignment operator is not permitted.\n    MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;\n\n    //! Creates a new chunk.\n    /*! \\param capacity Capacity of the chunk in bytes.\n        \\return true if success.\n    */\n    bool AddChunk(size_t capacity) {\n        if (!baseAllocator_)\n            ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();\n        if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {\n            chunk->capacity = capacity;\n            chunk->size = 0;\n            chunk->next = chunkHead_;\n            chunkHead_ =  chunk;\n            return true;\n        }\n        else\n            return false;\n    }\n\n    static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.\n\n    //! Chunk header for perpending to each chunk.\n    /*! Chunks are stored as a singly linked list.\n    */\n    struct ChunkHeader {\n        size_t capacity;    //!< Capacity of the chunk in bytes (excluding the header itself).\n        size_t size;        //!< Current size of allocated memory in bytes.\n        ChunkHeader *next;  //!< Next chunk in the linked list.\n    };\n\n    ChunkHeader *chunkHead_;    //!< Head of the chunk linked-list. Only the head chunk serves allocation.\n    size_t chunk_capacity_;     //!< The minimum capacity of chunk when they are allocated.\n    void *userBuffer_;          //!< User supplied buffer.\n    BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks.\n    BaseAllocator* ownBaseAllocator_;   //!< base allocator created by this object.\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ENCODINGS_H_\n"
  },
  {
    "path": "third-party/rapidjson/document.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_DOCUMENT_H_\n#define RAPIDJSON_DOCUMENT_H_\n\n/*! \\file document.h */\n\n#include \"reader.h\"\n#include \"internal/meta.h\"\n#include \"internal/strfunc.h\"\n#include \"memorystream.h\"\n#include \"encodedstream.h\"\n#include <new>      // placement new\n#include <limits>\n\nRAPIDJSON_DIAG_PUSH\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_OFF(4127) // conditional expression is constant\nRAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data\n#ifdef _MINWINDEF_       // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max\n#ifndef NOMINMAX\n#pragma push_macro(\"min\")\n#pragma push_macro(\"max\")\n#undef min\n#undef max\n#endif\n#endif\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_OFF(effc++)\n#if __GNUC__ >= 6\nRAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions\n#endif\n#endif // __GNUC__\n\n#ifndef RAPIDJSON_NOMEMBERITERATORCLASS\n#include <iterator> // std::iterator, std::random_access_iterator_tag\n#endif\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#include <utility> // std::move\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n// Forward declaration.\ntemplate <typename Encoding, typename Allocator>\nclass GenericValue;\n\ntemplate <typename Encoding, typename Allocator, typename StackAllocator>\nclass GenericDocument;\n\n//! Name-value pair in a JSON object value.\n/*!\n    This class was internal to GenericValue. It used to be a inner struct.\n    But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.\n    https://code.google.com/p/rapidjson/issues/detail?id=64\n*/\ntemplate <typename Encoding, typename Allocator> \nstruct GenericMember { \n    GenericValue<Encoding, Allocator> name;     //!< name of member (must be a string)\n    GenericValue<Encoding, Allocator> value;    //!< value of member.\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericMemberIterator\n\n#ifndef RAPIDJSON_NOMEMBERITERATORCLASS\n\n//! (Constant) member iterator for a JSON object value\n/*!\n    \\tparam Const Is this a constant iterator?\n    \\tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)\n    \\tparam Allocator   Allocator type for allocating memory of object, array and string.\n\n    This class implements a Random Access Iterator for GenericMember elements\n    of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].\n\n    \\note This iterator implementation is mainly intended to avoid implicit\n        conversions from iterator values to \\c NULL,\n        e.g. from GenericValue::FindMember.\n\n    \\note Define \\c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a\n        pointer-based implementation, if your platform doesn't provide\n        the C++ <iterator> header.\n\n    \\see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator\n */\ntemplate <bool Const, typename Encoding, typename Allocator>\nclass GenericMemberIterator\n    : public std::iterator<std::random_access_iterator_tag\n        , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {\n\n    friend class GenericValue<Encoding,Allocator>;\n    template <bool, typename, typename> friend class GenericMemberIterator;\n\n    typedef GenericMember<Encoding,Allocator> PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;\n\npublic:\n    //! Iterator type itself\n    typedef GenericMemberIterator Iterator;\n    //! Constant iterator type\n    typedef GenericMemberIterator<true,Encoding,Allocator>  ConstIterator;\n    //! Non-constant iterator type\n    typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;\n\n    //! Pointer to (const) GenericMember\n    typedef typename BaseType::pointer         Pointer;\n    //! Reference to (const) GenericMember\n    typedef typename BaseType::reference       Reference;\n    //! Signed integer type (e.g. \\c ptrdiff_t)\n    typedef typename BaseType::difference_type DifferenceType;\n\n    //! Default constructor (singular value)\n    /*! Creates an iterator pointing to no element.\n        \\note All operations, except for comparisons, are undefined on such values.\n     */\n    GenericMemberIterator() : ptr_() {}\n\n    //! Iterator conversions to more const\n    /*!\n        \\param it (Non-const) iterator to copy from\n\n        Allows the creation of an iterator from another GenericMemberIterator\n        that is \"less const\".  Especially, creating a non-constant iterator\n        from a constant iterator are disabled:\n        \\li const -> non-const (not ok)\n        \\li const -> const (ok)\n        \\li non-const -> const (ok)\n        \\li non-const -> non-const (ok)\n\n        \\note If the \\c Const template parameter is already \\c false, this\n            constructor effectively defines a regular copy-constructor.\n            Otherwise, the copy constructor is implicitly defined.\n    */\n    GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}\n    Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }\n\n    //! @name stepping\n    //@{\n    Iterator& operator++(){ ++ptr_; return *this; }\n    Iterator& operator--(){ --ptr_; return *this; }\n    Iterator  operator++(int){ Iterator old(*this); ++ptr_; return old; }\n    Iterator  operator--(int){ Iterator old(*this); --ptr_; return old; }\n    //@}\n\n    //! @name increment/decrement\n    //@{\n    Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }\n    Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }\n\n    Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }\n    Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }\n    //@}\n\n    //! @name relations\n    //@{\n    bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }\n    bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }\n    bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }\n    bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }\n    bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }\n    bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }\n    //@}\n\n    //! @name dereference\n    //@{\n    Reference operator*() const { return *ptr_; }\n    Pointer   operator->() const { return ptr_; }\n    Reference operator[](DifferenceType n) const { return ptr_[n]; }\n    //@}\n\n    //! Distance\n    DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }\n\nprivate:\n    //! Internal constructor from plain pointer\n    explicit GenericMemberIterator(Pointer p) : ptr_(p) {}\n\n    Pointer ptr_; //!< raw pointer\n};\n\n#else // RAPIDJSON_NOMEMBERITERATORCLASS\n\n// class-based member iterator implementation disabled, use plain pointers\n\ntemplate <bool Const, typename Encoding, typename Allocator>\nstruct GenericMemberIterator;\n\n//! non-const GenericMemberIterator\ntemplate <typename Encoding, typename Allocator>\nstruct GenericMemberIterator<false,Encoding,Allocator> {\n    //! use plain pointer as iterator type\n    typedef GenericMember<Encoding,Allocator>* Iterator;\n};\n//! const GenericMemberIterator\ntemplate <typename Encoding, typename Allocator>\nstruct GenericMemberIterator<true,Encoding,Allocator> {\n    //! use plain const pointer as iterator type\n    typedef const GenericMember<Encoding,Allocator>* Iterator;\n};\n\n#endif // RAPIDJSON_NOMEMBERITERATORCLASS\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericStringRef\n\n//! Reference to a constant string (not taking a copy)\n/*!\n    \\tparam CharType character type of the string\n\n    This helper class is used to automatically infer constant string\n    references for string literals, especially from \\c const \\b (!)\n    character arrays.\n\n    The main use is for creating JSON string values without copying the\n    source string via an \\ref Allocator.  This requires that the referenced\n    string pointers have a sufficient lifetime, which exceeds the lifetime\n    of the associated GenericValue.\n\n    \\b Example\n    \\code\n    Value v(\"foo\");   // ok, no need to copy & calculate length\n    const char foo[] = \"foo\";\n    v.SetString(foo); // ok\n\n    const char* bar = foo;\n    // Value x(bar); // not ok, can't rely on bar's lifetime\n    Value x(StringRef(bar)); // lifetime explicitly guaranteed by user\n    Value y(StringRef(bar, 3));  // ok, explicitly pass length\n    \\endcode\n\n    \\see StringRef, GenericValue::SetString\n*/\ntemplate<typename CharType>\nstruct GenericStringRef {\n    typedef CharType Ch; //!< character type of the string\n\n    //! Create string reference from \\c const character array\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        This constructor implicitly creates a constant string reference from\n        a \\c const character array.  It has better performance than\n        \\ref StringRef(const CharType*) by inferring the string \\ref length\n        from the array length, and also supports strings containing null\n        characters.\n\n        \\tparam N length of the string, automatically inferred\n\n        \\param str Constant character array, lifetime assumed to be longer\n            than the use of the string in e.g. a GenericValue\n\n        \\post \\ref s == str\n\n        \\note Constant complexity.\n        \\note There is a hidden, private overload to disallow references to\n            non-const character arrays to be created via this constructor.\n            By this, e.g. function-scope arrays used to be filled via\n            \\c snprintf are excluded from consideration.\n            In such cases, the referenced string should be \\b copied to the\n            GenericValue instead.\n     */\n#endif\n    template<SizeType N>\n    GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT\n        : s(str), length(N-1) {}\n\n    //! Explicitly create string reference from \\c const character pointer\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        This constructor can be used to \\b explicitly  create a reference to\n        a constant string pointer.\n\n        \\see StringRef(const CharType*)\n\n        \\param str Constant character pointer, lifetime assumed to be longer\n            than the use of the string in e.g. a GenericValue\n\n        \\post \\ref s == str\n\n        \\note There is a hidden, private overload to disallow references to\n            non-const character arrays to be created via this constructor.\n            By this, e.g. function-scope arrays used to be filled via\n            \\c snprintf are excluded from consideration.\n            In such cases, the referenced string should be \\b copied to the\n            GenericValue instead.\n     */\n#endif\n    explicit GenericStringRef(const CharType* str)\n        : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }\n\n    //! Create constant string reference from pointer and length\n#ifndef __clang__ // -Wdocumentation\n    /*! \\param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n        \\param len length of the string, excluding the trailing NULL terminator\n\n        \\post \\ref s == str && \\ref length == len\n        \\note Constant complexity.\n     */\n#endif\n    GenericStringRef(const CharType* str, SizeType len)\n        : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }\n\n    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}\n\n    //! implicit conversion to plain CharType pointer\n    operator const Ch *() const { return s; }\n\n    const Ch* const s; //!< plain CharType pointer\n    const SizeType length; //!< length of the string (excluding the trailing NULL terminator)\n\nprivate:\n    //! Disallow construction from non-const array\n    template<SizeType N>\n    GenericStringRef(CharType (&str)[N]) /* = delete */;\n    //! Copy assignment operator not permitted - immutable type\n    GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;\n};\n\n//! Mark a character pointer as constant string\n/*! Mark a plain character pointer as a \"string literal\".  This function\n    can be used to avoid copying a character string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n    \\tparam CharType Character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n\n    \\see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const CharType* str) {\n    return GenericStringRef<CharType>(str, internal::StrLen(str));\n}\n\n//! Mark a character pointer as constant string\n/*! Mark a plain character pointer as a \"string literal\".  This function\n    can be used to avoid copying a character string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n\n    This version has better performance with supplied length, and also\n    supports string containing null characters.\n\n    \\tparam CharType character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\param length The length of source string.\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {\n    return GenericStringRef<CharType>(str, SizeType(length));\n}\n\n#if RAPIDJSON_HAS_STDSTRING\n//! Mark a string object as constant string\n/*! Mark a string object (e.g. \\c std::string) as a \"string literal\".\n    This function can be used to avoid copying a string to be referenced as a\n    value in a JSON GenericValue object, if the string's lifetime is known\n    to be valid long enough.\n\n    \\tparam CharType character type of the string\n    \\param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue\n    \\return GenericStringRef string reference object\n    \\relatesalso GenericStringRef\n    \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n*/\ntemplate<typename CharType>\ninline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {\n    return GenericStringRef<CharType>(str.data(), SizeType(str.size()));\n}\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericValue type traits\nnamespace internal {\n\ntemplate <typename T, typename Encoding = void, typename Allocator = void>\nstruct IsGenericValueImpl : FalseType {};\n\n// select candidates according to nested encoding and allocator types\ntemplate <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>\n    : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};\n\n// helper to match arbitrary GenericValue instantiations, including derived classes\ntemplate <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// TypeHelper\n\nnamespace internal {\n\ntemplate <typename ValueType, typename T>\nstruct TypeHelper {};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, bool> {\n    static bool Is(const ValueType& v) { return v.IsBool(); }\n    static bool Get(const ValueType& v) { return v.GetBool(); }\n    static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }\n    static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, int> {\n    static bool Is(const ValueType& v) { return v.IsInt(); }\n    static int Get(const ValueType& v) { return v.GetInt(); }\n    static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }\n    static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, unsigned> {\n    static bool Is(const ValueType& v) { return v.IsUint(); }\n    static unsigned Get(const ValueType& v) { return v.GetUint(); }\n    static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }\n    static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, int64_t> {\n    static bool Is(const ValueType& v) { return v.IsInt64(); }\n    static int64_t Get(const ValueType& v) { return v.GetInt64(); }\n    static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }\n    static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, uint64_t> {\n    static bool Is(const ValueType& v) { return v.IsUint64(); }\n    static uint64_t Get(const ValueType& v) { return v.GetUint64(); }\n    static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }\n    static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, double> {\n    static bool Is(const ValueType& v) { return v.IsDouble(); }\n    static double Get(const ValueType& v) { return v.GetDouble(); }\n    static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }\n    static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, float> {\n    static bool Is(const ValueType& v) { return v.IsFloat(); }\n    static float Get(const ValueType& v) { return v.GetFloat(); }\n    static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }\n    static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, const typename ValueType::Ch*> {\n    typedef const typename ValueType::Ch* StringType;\n    static bool Is(const ValueType& v) { return v.IsString(); }\n    static StringType Get(const ValueType& v) { return v.GetString(); }\n    static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }\n    static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }\n};\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {\n    typedef std::basic_string<typename ValueType::Ch> StringType;\n    static bool Is(const ValueType& v) { return v.IsString(); }\n    static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }\n    static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }\n};\n#endif\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::Array> {\n    typedef typename ValueType::Array ArrayType;\n    static bool Is(const ValueType& v) { return v.IsArray(); }\n    static ArrayType Get(ValueType& v) { return v.GetArray(); }\n    static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }\n    static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::ConstArray> {\n    typedef typename ValueType::ConstArray ArrayType;\n    static bool Is(const ValueType& v) { return v.IsArray(); }\n    static ArrayType Get(const ValueType& v) { return v.GetArray(); }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::Object> {\n    typedef typename ValueType::Object ObjectType;\n    static bool Is(const ValueType& v) { return v.IsObject(); }\n    static ObjectType Get(ValueType& v) { return v.GetObject(); }\n    static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }\n    static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }\n};\n\ntemplate<typename ValueType> \nstruct TypeHelper<ValueType, typename ValueType::ConstObject> {\n    typedef typename ValueType::ConstObject ObjectType;\n    static bool Is(const ValueType& v) { return v.IsObject(); }\n    static ObjectType Get(const ValueType& v) { return v.GetObject(); }\n};\n\n} // namespace internal\n\n// Forward declarations\ntemplate <bool, typename> class GenericArray;\ntemplate <bool, typename> class GenericObject;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericValue\n\n//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.\n/*!\n    A JSON value can be one of 7 types. This class is a variant type supporting\n    these types.\n\n    Use the Value if UTF8 and default allocator\n\n    \\tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)\n    \\tparam Allocator   Allocator type for allocating memory of object, array and string.\n*/\ntemplate <typename Encoding, typename Allocator = MemoryPoolAllocator<> > \nclass GenericValue {\npublic:\n    //! Name-value pair in an object.\n    typedef GenericMember<Encoding, Allocator> Member;\n    typedef Encoding EncodingType;                  //!< Encoding type from template parameter.\n    typedef Allocator AllocatorType;                //!< Allocator type from template parameter.\n    typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.\n    typedef GenericStringRef<Ch> StringRefType;     //!< Reference to a constant string\n    typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;  //!< Member iterator for iterating in object.\n    typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.\n    typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.\n    typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.\n    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.\n    typedef GenericArray<false, ValueType> Array;\n    typedef GenericArray<true, ValueType> ConstArray;\n    typedef GenericObject<false, ValueType> Object;\n    typedef GenericObject<true, ValueType> ConstObject;\n\n    //!@name Constructors and destructor.\n    //@{\n\n    //! Default constructor creates a null value.\n    GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {\n        rhs.data_.f.flags = kNullFlag; // give up contents\n    }\n#endif\n\nprivate:\n    //! Copy constructor is not permitted.\n    GenericValue(const GenericValue& rhs);\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Moving from a GenericDocument is not permitted.\n    template <typename StackAllocator>\n    GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);\n\n    //! Move assignment from a GenericDocument is not permitted.\n    template <typename StackAllocator>\n    GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);\n#endif\n\npublic:\n\n    //! Constructor with JSON value type.\n    /*! This creates a Value of specified type with default content.\n        \\param type Type of the value.\n        \\note Default content for number is zero.\n    */\n    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {\n        static const uint16_t defaultFlags[7] = {\n            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,\n            kNumberAnyFlag\n        };\n        RAPIDJSON_ASSERT(type <= kNumberType);\n        data_.f.flags = defaultFlags[type];\n\n        // Use ShortString to store empty string.\n        if (type == kStringType)\n            data_.ss.SetLength(0);\n    }\n\n    //! Explicit copy constructor (with allocator)\n    /*! Creates a copy of a Value by using the given Allocator\n        \\tparam SourceAllocator allocator of \\c rhs\n        \\param rhs Value to copy from (read-only)\n        \\param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().\n        \\param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)\n        \\see CopyFrom()\n    */\n    template <typename SourceAllocator>\n    GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {\n        switch (rhs.GetType()) {\n        case kObjectType: {\n                SizeType count = rhs.data_.o.size;\n                Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));\n                const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();\n                for (SizeType i = 0; i < count; i++) {\n                    new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);\n                    new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);\n                }\n                data_.f.flags = kObjectFlag;\n                data_.o.size = data_.o.capacity = count;\n                SetMembersPointer(lm);\n            }\n            break;\n        case kArrayType: {\n                SizeType count = rhs.data_.a.size;\n                GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));\n                const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();\n                for (SizeType i = 0; i < count; i++)\n                    new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);\n                data_.f.flags = kArrayFlag;\n                data_.a.size = data_.a.capacity = count;\n                SetElementsPointer(le);\n            }\n            break;\n        case kStringType:\n            if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {\n                data_.f.flags = rhs.data_.f.flags;\n                data_  = *reinterpret_cast<const Data*>(&rhs.data_);\n            }\n            else\n                SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);\n            break;\n        default:\n            data_.f.flags = rhs.data_.f.flags;\n            data_  = *reinterpret_cast<const Data*>(&rhs.data_);\n            break;\n        }\n    }\n\n    //! Constructor for boolean value.\n    /*! \\param b Boolean value\n        \\note This constructor is limited to \\em real boolean values and rejects\n            implicitly converted types like arbitrary pointers.  Use an explicit cast\n            to \\c bool, if you want to construct a boolean JSON value in such cases.\n     */\n#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen\n    template <typename T>\n    explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT  // See #472\n#else\n    explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT\n#endif\n        : data_() {\n            // safe-guard against failing SFINAE\n            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));\n            data_.f.flags = b ? kTrueFlag : kFalseFlag;\n    }\n\n    //! Constructor for int value.\n    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.i64 = i;\n        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;\n    }\n\n    //! Constructor for unsigned value.\n    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.u64 = u; \n        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);\n    }\n\n    //! Constructor for int64_t value.\n    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.i64 = i64;\n        data_.f.flags = kNumberInt64Flag;\n        if (i64 >= 0) {\n            data_.f.flags |= kNumberUint64Flag;\n            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))\n                data_.f.flags |= kUintFlag;\n            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n                data_.f.flags |= kIntFlag;\n        }\n        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n            data_.f.flags |= kIntFlag;\n    }\n\n    //! Constructor for uint64_t value.\n    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {\n        data_.n.u64 = u64;\n        data_.f.flags = kNumberUint64Flag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))\n            data_.f.flags |= kInt64Flag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))\n            data_.f.flags |= kUintFlag;\n        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))\n            data_.f.flags |= kIntFlag;\n    }\n\n    //! Constructor for double value.\n    explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }\n\n    //! Constructor for float value.\n    explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }\n\n    //! Constructor for constant string (i.e. do not make a copy of string)\n    GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }\n\n    //! Constructor for constant string (i.e. do not make a copy of string)\n    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }\n\n    //! Constructor for copy-string (i.e. do make a copy of string)\n    GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }\n\n    //! Constructor for copy-string (i.e. do make a copy of string)\n    GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Constructor for copy-string from a string object (i.e. do make a copy of string)\n    /*! \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n     */\n    GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }\n#endif\n\n    //! Constructor for Array.\n    /*!\n        \\param a An array obtained by \\c GetArray().\n        \\note \\c Array is always pass-by-value.\n        \\note the source array is moved into this value and the sourec array becomes empty.\n    */\n    GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {\n        a.value_.data_ = Data();\n        a.value_.data_.f.flags = kArrayFlag;\n    }\n\n    //! Constructor for Object.\n    /*!\n        \\param o An object obtained by \\c GetObject().\n        \\note \\c Object is always pass-by-value.\n        \\note the source object is moved into this value and the sourec object becomes empty.\n    */\n    GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {\n        o.value_.data_ = Data();\n        o.value_.data_.f.flags = kObjectFlag;\n    }\n\n    //! Destructor.\n    /*! Need to destruct elements of array, members of object, or copy-string.\n    */\n    ~GenericValue() {\n        if (Allocator::kNeedFree) { // Shortcut by Allocator's trait\n            switch(data_.f.flags) {\n            case kArrayFlag:\n                {\n                    GenericValue* e = GetElementsPointer();\n                    for (GenericValue* v = e; v != e + data_.a.size; ++v)\n                        v->~GenericValue();\n                    Allocator::Free(e);\n                }\n                break;\n\n            case kObjectFlag:\n                for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)\n                    m->~Member();\n                Allocator::Free(GetMembersPointer());\n                break;\n\n            case kCopyStringFlag:\n                Allocator::Free(const_cast<Ch*>(GetStringPointer()));\n                break;\n\n            default:\n                break;  // Do nothing for other types.\n            }\n        }\n    }\n\n    //@}\n\n    //!@name Assignment operators\n    //@{\n\n    //! Assignment with move semantics.\n    /*! \\param rhs Source of the assignment. It will become a null value after assignment.\n    */\n    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {\n        RAPIDJSON_ASSERT(this != &rhs);\n        this->~GenericValue();\n        RawAssign(rhs);\n        return *this;\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move assignment in C++11\n    GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {\n        return *this = rhs.Move();\n    }\n#endif\n\n    //! Assignment of constant string reference (no copy)\n    /*! \\param str Constant string reference to be assigned\n        \\note This overload is needed to avoid clashes with the generic primitive type assignment overload below.\n        \\see GenericStringRef, operator=(T)\n    */\n    GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {\n        GenericValue s(str);\n        return *this = s;\n    }\n\n    //! Assignment with primitive types.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param value The value to be assigned.\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref SetString(const Ch*, Allocator&) (for copying) or\n            \\ref StringRef() (to explicitly mark the pointer as constant) instead.\n            All other pointer types would implicitly convert to \\c bool,\n            use \\ref SetBool() instead.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))\n    operator=(T value) {\n        GenericValue v(value);\n        return *this = v;\n    }\n\n    //! Deep-copy assignment from Value\n    /*! Assigns a \\b copy of the Value to the current Value object\n        \\tparam SourceAllocator Allocator type of \\c rhs\n        \\param rhs Value to copy from (read-only)\n        \\param allocator Allocator to use for copying\n        \\param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)\n     */\n    template <typename SourceAllocator>\n    GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {\n        RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));\n        this->~GenericValue();\n        new (this) GenericValue(rhs, allocator, copyConstStrings);\n        return *this;\n    }\n\n    //! Exchange the contents of this value with those of other.\n    /*!\n        \\param other Another value.\n        \\note Constant complexity.\n    */\n    GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {\n        GenericValue temp;\n        temp.RawAssign(*this);\n        RawAssign(other);\n        other.RawAssign(temp);\n        return *this;\n    }\n\n    //! free-standing swap function helper\n    /*!\n        Helper function to enable support for common swap implementation pattern based on \\c std::swap:\n        \\code\n        void swap(MyClass& a, MyClass& b) {\n            using std::swap;\n            swap(a.value, b.value);\n            // ...\n        }\n        \\endcode\n        \\see Swap()\n     */\n    friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }\n\n    //! Prepare Value for move semantics\n    /*! \\return *this */\n    GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }\n    //@}\n\n    //!@name Equal-to and not-equal-to operators\n    //@{\n    //! Equal-to operator\n    /*!\n        \\note If an object contains duplicated named member, comparing equality with any object is always \\c false.\n        \\note Linear time complexity (number of all values in the subtree and total lengths of all strings).\n    */\n    template <typename SourceAllocator>\n    bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {\n        typedef GenericValue<Encoding, SourceAllocator> RhsType;\n        if (GetType() != rhs.GetType())\n            return false;\n\n        switch (GetType()) {\n        case kObjectType: // Warning: O(n^2) inner-loop\n            if (data_.o.size != rhs.data_.o.size)\n                return false;           \n            for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {\n                typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);\n                if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)\n                    return false;\n            }\n            return true;\n            \n        case kArrayType:\n            if (data_.a.size != rhs.data_.a.size)\n                return false;\n            for (SizeType i = 0; i < data_.a.size; i++)\n                if ((*this)[i] != rhs[i])\n                    return false;\n            return true;\n\n        case kStringType:\n            return StringEqual(rhs);\n\n        case kNumberType:\n            if (IsDouble() || rhs.IsDouble()) {\n                double a = GetDouble();     // May convert from integer to double.\n                double b = rhs.GetDouble(); // Ditto\n                return a >= b && a <= b;    // Prevent -Wfloat-equal\n            }\n            else\n                return data_.n.u64 == rhs.data_.n.u64;\n\n        default:\n            return true;\n        }\n    }\n\n    //! Equal-to operator with const C-string pointer\n    bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Equal-to operator with string object\n    /*! \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n     */\n    bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }\n#endif\n\n    //! Equal-to operator with primitive types\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c double, \\c true, \\c false\n    */\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }\n\n    //! Not-equal-to operator\n    /*! \\return !(*this == rhs)\n     */\n    template <typename SourceAllocator>\n    bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }\n\n    //! Not-equal-to operator with const C-string pointer\n    bool operator!=(const Ch* rhs) const { return !(*this == rhs); }\n\n    //! Not-equal-to operator with arbitrary types\n    /*! \\return !(*this == rhs)\n     */\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }\n\n    //! Equal-to operator with arbitrary types (symmetric version)\n    /*! \\return (rhs == lhs)\n     */\n    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }\n\n    //! Not-Equal-to operator with arbitrary types (symmetric version)\n    /*! \\return !(rhs == lhs)\n     */\n    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }\n    //@}\n\n    //!@name Type\n    //@{\n\n    Type GetType()  const { return static_cast<Type>(data_.f.flags & kTypeMask); }\n    bool IsNull()   const { return data_.f.flags == kNullFlag; }\n    bool IsFalse()  const { return data_.f.flags == kFalseFlag; }\n    bool IsTrue()   const { return data_.f.flags == kTrueFlag; }\n    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }\n    bool IsObject() const { return data_.f.flags == kObjectFlag; }\n    bool IsArray()  const { return data_.f.flags == kArrayFlag; }\n    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }\n    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }\n    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }\n    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }\n    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }\n    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }\n    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }\n\n    // Checks whether a number can be losslessly converted to a double.\n    bool IsLosslessDouble() const {\n        if (!IsNumber()) return false;\n        if (IsUint64()) {\n            uint64_t u = GetUint64();\n            volatile double d = static_cast<double>(u);\n            return (d >= 0.0)\n                && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))\n                && (u == static_cast<uint64_t>(d));\n        }\n        if (IsInt64()) {\n            int64_t i = GetInt64();\n            volatile double d = static_cast<double>(i);\n            return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))\n                && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))\n                && (i == static_cast<int64_t>(d));\n        }\n        return true; // double, int, uint are always lossless\n    }\n\n    // Checks whether a number is a float (possible lossy).\n    bool IsFloat() const  {\n        if ((data_.f.flags & kDoubleFlag) == 0)\n            return false;\n        double d = GetDouble();\n        return d >= -3.4028234e38 && d <= 3.4028234e38;\n    }\n    // Checks whether a number can be losslessly converted to a float.\n    bool IsLosslessFloat() const {\n        if (!IsNumber()) return false;\n        double a = GetDouble();\n        if (a < static_cast<double>(-std::numeric_limits<float>::max())\n                || a > static_cast<double>(std::numeric_limits<float>::max()))\n            return false;\n        double b = static_cast<double>(static_cast<float>(a));\n        return a >= b && a <= b;    // Prevent -Wfloat-equal\n    }\n\n    //@}\n\n    //!@name Null\n    //@{\n\n    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }\n\n    //@}\n\n    //!@name Bool\n    //@{\n\n    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }\n    //!< Set boolean value\n    /*! \\post IsBool() == true */\n    GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }\n\n    //@}\n\n    //!@name Object\n    //@{\n\n    //! Set this value as an empty object.\n    /*! \\post IsObject() == true */\n    GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }\n\n    //! Get the number of members in the object.\n    SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }\n\n    //! Check whether the object is empty.\n    bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }\n\n    //! Get a value from an object associated with the name.\n    /*! \\pre IsObject() == true\n        \\tparam T Either \\c Ch or \\c const \\c Ch (template used for disambiguation with \\ref operator[](SizeType))\n        \\note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.\n        Since 0.2, if the name is not correct, it will assert.\n        If user is unsure whether a member exists, user should use HasMember() first.\n        A better approach is to use FindMember().\n        \\note Linear time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {\n        GenericValue n(StringRef(name));\n        return (*this)[n];\n    }\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }\n\n    //! Get a value from an object associated with the name.\n    /*! \\pre IsObject() == true\n        \\tparam SourceAllocator Allocator of the \\c name value\n\n        \\note Compared to \\ref operator[](T*), this version is faster because it does not need a StrLen().\n        And it can also handle strings with embedded null characters.\n\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator member = FindMember(name);\n        if (member != MemberEnd())\n            return member->value;\n        else {\n            RAPIDJSON_ASSERT(false);    // see above note\n\n            // This will generate -Wexit-time-destructors in clang\n            // static GenericValue NullValue;\n            // return NullValue;\n\n            // Use static buffer and placement-new to prevent destruction\n            static char buffer[sizeof(GenericValue)];\n            return *new (buffer) GenericValue();\n        }\n    }\n    template <typename SourceAllocator>\n    const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Get a value from an object associated with name (string object).\n    GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }\n    const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }\n#endif\n\n    //! Const member iterator\n    /*! \\pre IsObject() == true */\n    ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }\n    //! Const \\em past-the-end member iterator\n    /*! \\pre IsObject() == true */\n    ConstMemberIterator MemberEnd() const   { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }\n    //! Member iterator\n    /*! \\pre IsObject() == true */\n    MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }\n    //! \\em Past-the-end member iterator\n    /*! \\pre IsObject() == true */\n    MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }\n\n    //! Check whether a member exists in the object.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Check whether a member exists in the object with string object.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }\n#endif\n\n    //! Check whether a member exists in the object with GenericValue name.\n    /*!\n        This version is faster because it does not need a StrLen(). It can also handle string with null character.\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Whether a member with that name exists.\n        \\note It is better to use FindMember() directly if you need the obtain the value as well.\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }\n\n    //! Find member by name.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n\n        \\note Earlier versions of Rapidjson returned a \\c NULL pointer, in case\n            the requested member doesn't exist. For consistency with e.g.\n            \\c std::map, this has been changed to MemberEnd() now.\n        \\note Linear time complexity.\n    */\n    MemberIterator FindMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return FindMember(n);\n    }\n\n    ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }\n\n    //! Find member by name.\n    /*!\n        This version is faster because it does not need a StrLen(). It can also handle string with null character.\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n\n        \\note Earlier versions of Rapidjson returned a \\c NULL pointer, in case\n            the requested member doesn't exist. For consistency with e.g.\n            \\c std::map, this has been changed to MemberEnd() now.\n        \\note Linear time complexity.\n    */\n    template <typename SourceAllocator>\n    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(name.IsString());\n        MemberIterator member = MemberBegin();\n        for ( ; member != MemberEnd(); ++member)\n            if (name.StringEqual(member->name))\n                break;\n        return member;\n    }\n    template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Find member by string object name.\n    /*!\n        \\param name Member name to be searched.\n        \\pre IsObject() == true\n        \\return Iterator to member, if it exists.\n            Otherwise returns \\ref MemberEnd().\n    */\n    MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }\n    ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }\n#endif\n\n    //! Add a member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value Value of any type.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c name and \\c value will be transferred to this object on success.\n        \\pre  IsObject() && name.IsString()\n        \\post name.IsNull() && value.IsNull()\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(name.IsString());\n\n        ObjectData& o = data_.o;\n        if (o.size >= o.capacity) {\n            if (o.capacity == 0) {\n                o.capacity = kDefaultObjectCapacity;\n                SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));\n            }\n            else {\n                SizeType oldCapacity = o.capacity;\n                o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5\n                SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));\n            }\n        }\n        Member* members = GetMembersPointer();\n        members[o.size].name.RawAssign(name);\n        members[o.size].value.RawAssign(value);\n        o.size++;\n        return *this;\n    }\n\n    //! Add a constant string value as member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Add a string object as member (name-value pair) to the object.\n    /*! \\param name A string value as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {\n        GenericValue v(value, allocator);\n        return AddMember(name, v, allocator);\n    }\n#endif\n\n    //! Add any primitive value as member (name-value pair) to the object.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param name A string value as name of member.\n        \\param value Value of primitive type \\c T as value of member\n        \\param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref AddMember(StringRefType, GenericValue&, Allocator&) or \\ref\n            AddMember(StringRefType, StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized Constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    AddMember(GenericValue& name, T value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {\n        return AddMember(name, value, allocator);\n    }\n    GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n\n    //! Add a member (name-value pair) to the object.\n    /*! \\param name A constant string reference as name of member.\n        \\param value Value of any type.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c value will be transferred to this object on success.\n        \\pre  IsObject()\n        \\post value.IsNull()\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n\n    //! Add a constant string value as member (name-value pair) to the object.\n    /*! \\param name A constant string reference as name of member.\n        \\param value constant string reference as value of member.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n        \\note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.\n        \\note Amortized Constant time complexity.\n    */\n    GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {\n        GenericValue v(value);\n        return AddMember(name, v, allocator);\n    }\n\n    //! Add any primitive value as member (name-value pair) to the object.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param name A constant string reference as name of member.\n        \\param value Value of primitive type \\c T as value of member\n        \\param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\pre  IsObject()\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref AddMember(StringRefType, GenericValue&, Allocator&) or \\ref\n            AddMember(StringRefType, StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized Constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    AddMember(StringRefType name, T value, Allocator& allocator) {\n        GenericValue n(name);\n        return AddMember(n, value, allocator);\n    }\n\n    //! Remove all members in the object.\n    /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.\n        \\note Linear time complexity.\n    */\n    void RemoveAllMembers() {\n        RAPIDJSON_ASSERT(IsObject()); \n        for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)\n            m->~Member();\n        data_.o.size = 0;\n    }\n\n    //! Remove a member in object by its name.\n    /*! \\param name Name of member to be removed.\n        \\return Whether the member existed.\n        \\note This function may reorder the object members. Use \\ref\n            EraseMember(ConstMemberIterator) if you need to preserve the\n            relative order of the remaining members.\n        \\note Linear time complexity.\n    */\n    bool RemoveMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return RemoveMember(n);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }\n#endif\n\n    template <typename SourceAllocator>\n    bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator m = FindMember(name);\n        if (m != MemberEnd()) {\n            RemoveMember(m);\n            return true;\n        }\n        else\n            return false;\n    }\n\n    //! Remove a member in object by iterator.\n    /*! \\param m member iterator (obtained by FindMember() or MemberBegin()).\n        \\return the new iterator after removal.\n        \\note This function may reorder the object members. Use \\ref\n            EraseMember(ConstMemberIterator) if you need to preserve the\n            relative order of the remaining members.\n        \\note Constant time complexity.\n    */\n    MemberIterator RemoveMember(MemberIterator m) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(data_.o.size > 0);\n        RAPIDJSON_ASSERT(GetMembersPointer() != 0);\n        RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());\n\n        MemberIterator last(GetMembersPointer() + (data_.o.size - 1));\n        if (data_.o.size > 1 && m != last)\n            *m = *last; // Move the last one to this place\n        else\n            m->~Member(); // Only one left, just destroy\n        --data_.o.size;\n        return m;\n    }\n\n    //! Remove a member from an object by iterator.\n    /*! \\param pos iterator to the member to remove\n        \\pre IsObject() == true && \\ref MemberBegin() <= \\c pos < \\ref MemberEnd()\n        \\return Iterator following the removed element.\n            If the iterator \\c pos refers to the last element, the \\ref MemberEnd() iterator is returned.\n        \\note This function preserves the relative order of the remaining object\n            members. If you do not need this, use the more efficient \\ref RemoveMember(MemberIterator).\n        \\note Linear time complexity.\n    */\n    MemberIterator EraseMember(ConstMemberIterator pos) {\n        return EraseMember(pos, pos +1);\n    }\n\n    //! Remove members in the range [first, last) from an object.\n    /*! \\param first iterator to the first member to remove\n        \\param last  iterator following the last member to remove\n        \\pre IsObject() == true && \\ref MemberBegin() <= \\c first <= \\c last <= \\ref MemberEnd()\n        \\return Iterator following the last removed element.\n        \\note This function preserves the relative order of the remaining object\n            members.\n        \\note Linear time complexity.\n    */\n    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {\n        RAPIDJSON_ASSERT(IsObject());\n        RAPIDJSON_ASSERT(data_.o.size > 0);\n        RAPIDJSON_ASSERT(GetMembersPointer() != 0);\n        RAPIDJSON_ASSERT(first >= MemberBegin());\n        RAPIDJSON_ASSERT(first <= last);\n        RAPIDJSON_ASSERT(last <= MemberEnd());\n\n        MemberIterator pos = MemberBegin() + (first - MemberBegin());\n        for (MemberIterator itr = pos; itr != last; ++itr)\n            itr->~Member();\n        std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));\n        data_.o.size -= static_cast<SizeType>(last - first);\n        return pos;\n    }\n\n    //! Erase a member in object by its name.\n    /*! \\param name Name of member to be removed.\n        \\return Whether the member existed.\n        \\note Linear time complexity.\n    */\n    bool EraseMember(const Ch* name) {\n        GenericValue n(StringRef(name));\n        return EraseMember(n);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }\n#endif\n\n    template <typename SourceAllocator>\n    bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {\n        MemberIterator m = FindMember(name);\n        if (m != MemberEnd()) {\n            EraseMember(m);\n            return true;\n        }\n        else\n            return false;\n    }\n\n    Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }\n    ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }\n\n    //@}\n\n    //!@name Array\n    //@{\n\n    //! Set this value as an empty array.\n    /*! \\post IsArray == true */\n    GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }\n\n    //! Get the number of elements in array.\n    SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }\n\n    //! Get the capacity of array.\n    SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }\n\n    //! Check whether the array is empty.\n    bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }\n\n    //! Remove all elements in the array.\n    /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.\n        \\note Linear time complexity.\n    */\n    void Clear() {\n        RAPIDJSON_ASSERT(IsArray()); \n        GenericValue* e = GetElementsPointer();\n        for (GenericValue* v = e; v != e + data_.a.size; ++v)\n            v->~GenericValue();\n        data_.a.size = 0;\n    }\n\n    //! Get an element from array by index.\n    /*! \\pre IsArray() == true\n        \\param index Zero-based index of element.\n        \\see operator[](T*)\n    */\n    GenericValue& operator[](SizeType index) {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(index < data_.a.size);\n        return GetElementsPointer()[index];\n    }\n    const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }\n\n    //! Element iterator\n    /*! \\pre IsArray() == true */\n    ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }\n    //! \\em Past-the-end element iterator\n    /*! \\pre IsArray() == true */\n    ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }\n    //! Constant element iterator\n    /*! \\pre IsArray() == true */\n    ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }\n    //! Constant \\em past-the-end element iterator\n    /*! \\pre IsArray() == true */\n    ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }\n\n    //! Request the array to have enough capacity to store elements.\n    /*! \\param newCapacity  The capacity that the array at least need to have.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\note Linear time complexity.\n    */\n    GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {\n        RAPIDJSON_ASSERT(IsArray());\n        if (newCapacity > data_.a.capacity) {\n            SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));\n            data_.a.capacity = newCapacity;\n        }\n        return *this;\n    }\n\n    //! Append a GenericValue at the end of the array.\n    /*! \\param value        Value to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\post value.IsNull() == true\n        \\return The value itself for fluent API.\n        \\note The ownership of \\c value will be transferred to this array on success.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n        \\note Amortized constant time complexity.\n    */\n    GenericValue& PushBack(GenericValue& value, Allocator& allocator) {\n        RAPIDJSON_ASSERT(IsArray());\n        if (data_.a.size >= data_.a.capacity)\n            Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);\n        GetElementsPointer()[data_.a.size++].RawAssign(value);\n        return *this;\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {\n        return PushBack(value, allocator);\n    }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n    //! Append a constant string reference at the end of the array.\n    /*! \\param value        Constant string reference to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\return The value itself for fluent API.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n        \\note Amortized constant time complexity.\n        \\see GenericStringRef\n    */\n    GenericValue& PushBack(StringRefType value, Allocator& allocator) {\n        return (*this).template PushBack<StringRefType>(value, allocator);\n    }\n\n    //! Append a primitive value at the end of the array.\n    /*! \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t\n        \\param value Value of primitive type T to be appended.\n        \\param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().\n        \\pre IsArray() == true\n        \\return The value itself for fluent API.\n        \\note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.\n\n        \\note The source type \\c T explicitly disallows all pointer types,\n            especially (\\c const) \\ref Ch*.  This helps avoiding implicitly\n            referencing character strings with insufficient lifetime, use\n            \\ref PushBack(GenericValue&, Allocator&) or \\ref\n            PushBack(StringRefType, Allocator&).\n            All other pointer types would implicitly convert to \\c bool,\n            use an explicit cast instead, if needed.\n        \\note Amortized constant time complexity.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))\n    PushBack(T value, Allocator& allocator) {\n        GenericValue v(value);\n        return PushBack(v, allocator);\n    }\n\n    //! Remove the last element in the array.\n    /*!\n        \\note Constant time complexity.\n    */\n    GenericValue& PopBack() {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(!Empty());\n        GetElementsPointer()[--data_.a.size].~GenericValue();\n        return *this;\n    }\n\n    //! Remove an element of array by iterator.\n    /*!\n        \\param pos iterator to the element to remove\n        \\pre IsArray() == true && \\ref Begin() <= \\c pos < \\ref End()\n        \\return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.\n        \\note Linear time complexity.\n    */\n    ValueIterator Erase(ConstValueIterator pos) {\n        return Erase(pos, pos + 1);\n    }\n\n    //! Remove elements in the range [first, last) of the array.\n    /*!\n        \\param first iterator to the first element to remove\n        \\param last  iterator following the last element to remove\n        \\pre IsArray() == true && \\ref Begin() <= \\c first <= \\c last <= \\ref End()\n        \\return Iterator following the last removed element.\n        \\note Linear time complexity.\n    */\n    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {\n        RAPIDJSON_ASSERT(IsArray());\n        RAPIDJSON_ASSERT(data_.a.size > 0);\n        RAPIDJSON_ASSERT(GetElementsPointer() != 0);\n        RAPIDJSON_ASSERT(first >= Begin());\n        RAPIDJSON_ASSERT(first <= last);\n        RAPIDJSON_ASSERT(last <= End());\n        ValueIterator pos = Begin() + (first - Begin());\n        for (ValueIterator itr = pos; itr != last; ++itr)\n            itr->~GenericValue();       \n        std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));\n        data_.a.size -= static_cast<SizeType>(last - first);\n        return pos;\n    }\n\n    Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }\n    ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }\n\n    //@}\n\n    //!@name Number\n    //@{\n\n    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }\n    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }\n    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }\n    uint64_t GetUint64() const  { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }\n\n    //! Get the value as double type.\n    /*! \\note If the value is 64-bit integer type, it may lose precision. Use \\c IsLosslessDouble() to check whether the converison is lossless.\n    */\n    double GetDouble() const {\n        RAPIDJSON_ASSERT(IsNumber());\n        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.\n        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double\n        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double\n        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)\n        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)\n    }\n\n    //! Get the value as float type.\n    /*! \\note If the value is 64-bit integer type, it may lose precision. Use \\c IsLosslessFloat() to check whether the converison is lossless.\n    */\n    float GetFloat() const {\n        return static_cast<float>(GetDouble());\n    }\n\n    GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }\n    GenericValue& SetUint(unsigned u)       { this->~GenericValue(); new (this) GenericValue(u);    return *this; }\n    GenericValue& SetInt64(int64_t i64)     { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }\n    GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }\n    GenericValue& SetDouble(double d)       { this->~GenericValue(); new (this) GenericValue(d);    return *this; }\n    GenericValue& SetFloat(float f)         { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }\n\n    //@}\n\n    //!@name String\n    //@{\n\n    const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }\n\n    //! Get the length of string.\n    /*! Since rapidjson permits \"\\\\u0000\" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().\n    */\n    SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }\n\n    //! Set this value as a string without copying source string.\n    /*! This version has better performance with supplied length, and also support string containing null character.\n        \\param s source string pointer. \n        \\param length The length of source string, excluding the trailing null terminator.\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() == s && GetStringLength() == length\n        \\see SetString(StringRefType)\n    */\n    GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }\n\n    //! Set this value as a string without copying source string.\n    /*! \\param s source string reference\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() == s && GetStringLength() == s.length\n    */\n    GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }\n\n    //! Set this value as a string by copying from source string.\n    /*! This version has better performance with supplied length, and also support string containing null character.\n        \\param s source string. \n        \\param length The length of source string, excluding the trailing null terminator.\n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length\n    */\n    GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }\n\n    //! Set this value as a string by copying from source string.\n    /*! \\param s source string. \n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length\n    */\n    GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Set this value as a string by copying from source string.\n    /*! \\param s source string.\n        \\param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().\n        \\return The value itself for fluent API.\n        \\post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()\n        \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n    */\n    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }\n#endif\n\n    //@}\n\n    //!@name Array\n    //@{\n\n    //! Templated version for checking whether this value is type T.\n    /*!\n        \\tparam T Either \\c bool, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c double, \\c float, \\c const \\c char*, \\c std::basic_string<Ch>\n    */\n    template <typename T>\n    bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }\n\n    template <typename T>\n    T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }\n\n    template <typename T>\n    T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }\n\n    template<typename T>\n    ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }\n\n    template<typename T>\n    ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }\n\n    //@}\n\n    //! Generate events of this value to a Handler.\n    /*! This function adopts the GoF visitor pattern.\n        Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.\n        It can also be used to deep clone this value via GenericDocument, which is also a Handler.\n        \\tparam Handler type of handler.\n        \\param handler An object implementing concept Handler.\n    */\n    template <typename Handler>\n    bool Accept(Handler& handler) const {\n        switch(GetType()) {\n        case kNullType:     return handler.Null();\n        case kFalseType:    return handler.Bool(false);\n        case kTrueType:     return handler.Bool(true);\n\n        case kObjectType:\n            if (RAPIDJSON_UNLIKELY(!handler.StartObject()))\n                return false;\n            for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {\n                RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.\n                if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))\n                    return false;\n                if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))\n                    return false;\n            }\n            return handler.EndObject(data_.o.size);\n\n        case kArrayType:\n            if (RAPIDJSON_UNLIKELY(!handler.StartArray()))\n                return false;\n            for (const GenericValue* v = Begin(); v != End(); ++v)\n                if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))\n                    return false;\n            return handler.EndArray(data_.a.size);\n    \n        case kStringType:\n            return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);\n    \n        default:\n            RAPIDJSON_ASSERT(GetType() == kNumberType);\n            if (IsDouble())         return handler.Double(data_.n.d);\n            else if (IsInt())       return handler.Int(data_.n.i.i);\n            else if (IsUint())      return handler.Uint(data_.n.u.u);\n            else if (IsInt64())     return handler.Int64(data_.n.i64);\n            else                    return handler.Uint64(data_.n.u64);\n        }\n    }\n\nprivate:\n    template <typename, typename> friend class GenericValue;\n    template <typename, typename, typename> friend class GenericDocument;\n\n    enum {\n        kBoolFlag       = 0x0008,\n        kNumberFlag     = 0x0010,\n        kIntFlag        = 0x0020,\n        kUintFlag       = 0x0040,\n        kInt64Flag      = 0x0080,\n        kUint64Flag     = 0x0100,\n        kDoubleFlag     = 0x0200,\n        kStringFlag     = 0x0400,\n        kCopyFlag       = 0x0800,\n        kInlineStrFlag  = 0x1000,\n\n        // Initial flags of different types.\n        kNullFlag = kNullType,\n        kTrueFlag = kTrueType | kBoolFlag,\n        kFalseFlag = kFalseType | kBoolFlag,\n        kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,\n        kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,\n        kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,\n        kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,\n        kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,\n        kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,\n        kConstStringFlag = kStringType | kStringFlag,\n        kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,\n        kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,\n        kObjectFlag = kObjectType,\n        kArrayFlag = kArrayType,\n\n        kTypeMask = 0x07\n    };\n\n    static const SizeType kDefaultArrayCapacity = 16;\n    static const SizeType kDefaultObjectCapacity = 16;\n\n    struct Flag {\n#if RAPIDJSON_48BITPOINTER_OPTIMIZATION\n        char payload[sizeof(SizeType) * 2 + 6];     // 2 x SizeType + lower 48-bit pointer\n#elif RAPIDJSON_64BIT\n        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes\n#else\n        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes\n#endif\n        uint16_t flags;\n    };\n\n    struct String {\n        SizeType length;\n        SizeType hashcode;  //!< reserved\n        const Ch* str;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars\n    // (excluding the terminating zero) and store a value to determine the length of the contained\n    // string in the last character str[LenPos] by storing \"MaxSize - length\" there. If the string\n    // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as\n    // the string terminator as well. For getting the string length back from that value just use\n    // \"MaxSize - str[LenPos]\".\n    // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,\n    // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).\n    struct ShortString {\n        enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };\n        Ch str[MaxChars];\n\n        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }\n        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }\n        inline SizeType GetLength() const       { return  static_cast<SizeType>(MaxSize -  str[LenPos]); }\n    };  // at most as many bytes as \"String\" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    // By using proper binary layout, retrieval of different integer types do not need conversions.\n    union Number {\n#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN\n        struct I {\n            int i;\n            char padding[4];\n        }i;\n        struct U {\n            unsigned u;\n            char padding2[4];\n        }u;\n#else\n        struct I {\n            char padding[4];\n            int i;\n        }i;\n        struct U {\n            char padding2[4];\n            unsigned u;\n        }u;\n#endif\n        int64_t i64;\n        uint64_t u64;\n        double d;\n    };  // 8 bytes\n\n    struct ObjectData {\n        SizeType size;\n        SizeType capacity;\n        Member* members;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    struct ArrayData {\n        SizeType size;\n        SizeType capacity;\n        GenericValue* elements;\n    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode\n\n    union Data {\n        String s;\n        ShortString ss;\n        Number n;\n        ObjectData o;\n        ArrayData a;\n        Flag f;\n    };  // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n    RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }\n    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }\n    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }\n    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }\n    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }\n    RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }\n\n    // Initialize this value as array with initial data, without calling destructor.\n    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {\n        data_.f.flags = kArrayFlag;\n        if (count) {\n            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));\n            SetElementsPointer(e);\n            std::memcpy(e, values, count * sizeof(GenericValue));\n        }\n        else\n            SetElementsPointer(0);\n        data_.a.size = data_.a.capacity = count;\n    }\n\n    //! Initialize this value as object with initial data, without calling destructor.\n    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {\n        data_.f.flags = kObjectFlag;\n        if (count) {\n            Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));\n            SetMembersPointer(m);\n            std::memcpy(m, members, count * sizeof(Member));\n        }\n        else\n            SetMembersPointer(0);\n        data_.o.size = data_.o.capacity = count;\n    }\n\n    //! Initialize this value as constant string, without calling destructor.\n    void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {\n        data_.f.flags = kConstStringFlag;\n        SetStringPointer(s);\n        data_.s.length = s.length;\n    }\n\n    //! Initialize this value as copy string with initial data, without calling destructor.\n    void SetStringRaw(StringRefType s, Allocator& allocator) {\n        Ch* str = 0;\n        if (ShortString::Usable(s.length)) {\n            data_.f.flags = kShortStringFlag;\n            data_.ss.SetLength(s.length);\n            str = data_.ss.str;\n        } else {\n            data_.f.flags = kCopyStringFlag;\n            data_.s.length = s.length;\n            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));\n            SetStringPointer(str);\n        }\n        std::memcpy(str, s, s.length * sizeof(Ch));\n        str[s.length] = '\\0';\n    }\n\n    //! Assignment without calling destructor\n    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {\n        data_ = rhs.data_;\n        // data_.f.flags = rhs.data_.f.flags;\n        rhs.data_.f.flags = kNullFlag;\n    }\n\n    template <typename SourceAllocator>\n    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {\n        RAPIDJSON_ASSERT(IsString());\n        RAPIDJSON_ASSERT(rhs.IsString());\n\n        const SizeType len1 = GetStringLength();\n        const SizeType len2 = rhs.GetStringLength();\n        if(len1 != len2) { return false; }\n\n        const Ch* const str1 = GetString();\n        const Ch* const str2 = rhs.GetString();\n        if(str1 == str2) { return true; } // fast path for constant string\n\n        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);\n    }\n\n    Data data_;\n};\n\n//! GenericValue with UTF8 encoding\ntypedef GenericValue<UTF8<> > Value;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericDocument \n\n//! A document for parsing JSON text as DOM.\n/*!\n    \\note implements Handler concept\n    \\tparam Encoding Encoding for both parsing and string storage.\n    \\tparam Allocator Allocator for allocating memory for the DOM\n    \\tparam StackAllocator Allocator for allocating memory for stack during parsing.\n    \\warning Although GenericDocument inherits from GenericValue, the API does \\b not provide any virtual functions, especially no virtual destructor.  To avoid memory leaks, do not \\c delete a GenericDocument object via a pointer to a GenericValue.\n*/\ntemplate <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>\nclass GenericDocument : public GenericValue<Encoding, Allocator> {\npublic:\n    typedef typename Encoding::Ch Ch;                       //!< Character type derived from Encoding.\n    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.\n    typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.\n\n    //! Constructor\n    /*! Creates an empty document of specified type.\n        \\param type             Mandatory type of object to create.\n        \\param allocator        Optional allocator for allocating memory.\n        \\param stackCapacity    Optional initial capacity of stack in bytes.\n        \\param stackAllocator   Optional allocator for allocating memory for stack.\n    */\n    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :\n        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n    }\n\n    //! Constructor\n    /*! Creates an empty document which type is Null. \n        \\param allocator        Optional allocator for allocating memory.\n        \\param stackCapacity    Optional initial capacity of stack in bytes.\n        \\param stackAllocator   Optional allocator for allocating memory for stack.\n    */\n    GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : \n        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT\n        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document\n          allocator_(rhs.allocator_),\n          ownAllocator_(rhs.ownAllocator_),\n          stack_(std::move(rhs.stack_)),\n          parseResult_(rhs.parseResult_)\n    {\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.parseResult_ = ParseResult();\n    }\n#endif\n\n    ~GenericDocument() {\n        Destroy();\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move assignment in C++11\n    GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT\n    {\n        // The cast to ValueType is necessary here, because otherwise it would\n        // attempt to call GenericValue's templated assignment operator.\n        ValueType::operator=(std::forward<ValueType>(rhs));\n\n        // Calling the destructor here would prematurely call stack_'s destructor\n        Destroy();\n\n        allocator_ = rhs.allocator_;\n        ownAllocator_ = rhs.ownAllocator_;\n        stack_ = std::move(rhs.stack_);\n        parseResult_ = rhs.parseResult_;\n\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.parseResult_ = ParseResult();\n\n        return *this;\n    }\n#endif\n\n    //! Exchange the contents of this document with those of another.\n    /*!\n        \\param rhs Another document.\n        \\note Constant complexity.\n        \\see GenericValue::Swap\n    */\n    GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {\n        ValueType::Swap(rhs);\n        stack_.Swap(rhs.stack_);\n        internal::Swap(allocator_, rhs.allocator_);\n        internal::Swap(ownAllocator_, rhs.ownAllocator_);\n        internal::Swap(parseResult_, rhs.parseResult_);\n        return *this;\n    }\n\n    //! free-standing swap function helper\n    /*!\n        Helper function to enable support for common swap implementation pattern based on \\c std::swap:\n        \\code\n        void swap(MyClass& a, MyClass& b) {\n            using std::swap;\n            swap(a.doc, b.doc);\n            // ...\n        }\n        \\endcode\n        \\see Swap()\n     */\n    friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }\n\n    //! Populate this document by a generator which produces SAX events.\n    /*! \\tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.\n        \\param g Generator functor which sends SAX events to the parameter.\n        \\return The document itself for fluent API.\n    */\n    template <typename Generator>\n    GenericDocument& Populate(Generator& g) {\n        ClearStackOnExit scope(*this);\n        if (g(*this)) {\n            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object\n            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document\n        }\n        return *this;\n    }\n\n    //!@name Parse from stream\n    //!@{\n\n    //! Parse JSON text from an input stream (with Encoding conversion)\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam SourceEncoding Encoding of input stream\n        \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags, typename SourceEncoding, typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(\n            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);\n        ClearStackOnExit scope(*this);\n        parseResult_ = reader.template Parse<parseFlags>(is, *this);\n        if (parseResult_) {\n            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object\n            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document\n        }\n        return *this;\n    }\n\n    //! Parse JSON text from an input stream\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags, typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        return ParseStream<parseFlags, Encoding, InputStream>(is);\n    }\n\n    //! Parse JSON text from an input stream (with \\ref kParseDefaultFlags)\n    /*! \\tparam InputStream Type of input stream, implementing Stream concept\n        \\param is Input stream to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <typename InputStream>\n    GenericDocument& ParseStream(InputStream& is) {\n        return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);\n    }\n    //!@}\n\n    //!@name Parse in-place from mutable string\n    //!@{\n\n    //! Parse JSON text from a mutable string\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\param str Mutable zero-terminated string to be parsed.\n        \\return The document itself for fluent API.\n    */\n    template <unsigned parseFlags>\n    GenericDocument& ParseInsitu(Ch* str) {\n        GenericInsituStringStream<Encoding> s(str);\n        return ParseStream<parseFlags | kParseInsituFlag>(s);\n    }\n\n    //! Parse JSON text from a mutable string (with \\ref kParseDefaultFlags)\n    /*! \\param str Mutable zero-terminated string to be parsed.\n        \\return The document itself for fluent API.\n    */\n    GenericDocument& ParseInsitu(Ch* str) {\n        return ParseInsitu<kParseDefaultFlags>(str);\n    }\n    //!@}\n\n    //!@name Parse from read-only string\n    //!@{\n\n    //! Parse JSON text from a read-only string (with Encoding conversion)\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag (must not contain \\ref kParseInsituFlag).\n        \\tparam SourceEncoding Transcoding from input Encoding\n        \\param str Read-only zero-terminated string to be parsed.\n    */\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {\n        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));\n        GenericStringStream<SourceEncoding> s(str);\n        return ParseStream<parseFlags, SourceEncoding>(s);\n    }\n\n    //! Parse JSON text from a read-only string\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag (must not contain \\ref kParseInsituFlag).\n        \\param str Read-only zero-terminated string to be parsed.\n    */\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const Ch* str) {\n        return Parse<parseFlags, Encoding>(str);\n    }\n\n    //! Parse JSON text from a read-only string (with \\ref kParseDefaultFlags)\n    /*! \\param str Read-only zero-terminated string to be parsed.\n    */\n    GenericDocument& Parse(const Ch* str) {\n        return Parse<kParseDefaultFlags>(str);\n    }\n\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {\n        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));\n        MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));\n        EncodedInputStream<SourceEncoding, MemoryStream> is(ms);\n        ParseStream<parseFlags, SourceEncoding>(is);\n        return *this;\n    }\n\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const Ch* str, size_t length) {\n        return Parse<parseFlags, Encoding>(str, length);\n    }\n    \n    GenericDocument& Parse(const Ch* str, size_t length) {\n        return Parse<kParseDefaultFlags>(str, length);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    template <unsigned parseFlags, typename SourceEncoding>\n    GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {\n        // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)\n        return Parse<parseFlags, SourceEncoding>(str.c_str());\n    }\n\n    template <unsigned parseFlags>\n    GenericDocument& Parse(const std::basic_string<Ch>& str) {\n        return Parse<parseFlags, Encoding>(str.c_str());\n    }\n\n    GenericDocument& Parse(const std::basic_string<Ch>& str) {\n        return Parse<kParseDefaultFlags>(str);\n    }\n#endif // RAPIDJSON_HAS_STDSTRING    \n\n    //!@}\n\n    //!@name Handling parse errors\n    //!@{\n\n    //! Whether a parse error has occured in the last parsing.\n    bool HasParseError() const { return parseResult_.IsError(); }\n\n    //! Get the \\ref ParseErrorCode of last parsing.\n    ParseErrorCode GetParseError() const { return parseResult_.Code(); }\n\n    //! Get the position of last parsing error in input, 0 otherwise.\n    size_t GetErrorOffset() const { return parseResult_.Offset(); }\n\n    //! Implicit conversion to get the last parse result\n#ifndef __clang // -Wdocumentation\n    /*! \\return \\ref ParseResult of the last parse operation\n\n        \\code\n          Document doc;\n          ParseResult ok = doc.Parse(json);\n          if (!ok)\n            printf( \"JSON parse error: %s (%u)\\n\", GetParseError_En(ok.Code()), ok.Offset());\n        \\endcode\n     */\n#endif\n    operator ParseResult() const { return parseResult_; }\n    //!@}\n\n    //! Get the allocator of this document.\n    Allocator& GetAllocator() {\n        RAPIDJSON_ASSERT(allocator_);\n        return *allocator_;\n    }\n\n    //! Get the capacity of stack in bytes.\n    size_t GetStackCapacity() const { return stack_.GetCapacity(); }\n\nprivate:\n    // clear stack on any exit from ParseStream, e.g. due to exception\n    struct ClearStackOnExit {\n        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}\n        ~ClearStackOnExit() { d_.ClearStack(); }\n    private:\n        ClearStackOnExit(const ClearStackOnExit&);\n        ClearStackOnExit& operator=(const ClearStackOnExit&);\n        GenericDocument& d_;\n    };\n\n    // callers of the following private Handler functions\n    // template <typename,typename,typename> friend class GenericReader; // for parsing\n    template <typename, typename> friend class GenericValue; // for deep copying\n\npublic:\n    // Implementation of Handler\n    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }\n    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }\n    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }\n    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy) { \n        if (copy) \n            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());\n        else\n            new (stack_.template Push<ValueType>()) ValueType(str, length);\n        return true;\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy) { \n        if (copy) \n            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());\n        else\n            new (stack_.template Push<ValueType>()) ValueType(str, length);\n        return true;\n    }\n\n    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }\n    \n    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }\n\n    bool EndObject(SizeType memberCount) {\n        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);\n        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());\n        return true;\n    }\n\n    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }\n    \n    bool EndArray(SizeType elementCount) {\n        ValueType* elements = stack_.template Pop<ValueType>(elementCount);\n        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());\n        return true;\n    }\n\nprivate:\n    //! Prohibit copying\n    GenericDocument(const GenericDocument&);\n    //! Prohibit assignment\n    GenericDocument& operator=(const GenericDocument&);\n\n    void ClearStack() {\n        if (Allocator::kNeedFree)\n            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)\n                (stack_.template Pop<ValueType>(1))->~ValueType();\n        else\n            stack_.Clear();\n        stack_.ShrinkToFit();\n    }\n\n    void Destroy() {\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    static const size_t kDefaultStackCapacity = 1024;\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    internal::Stack<StackAllocator> stack_;\n    ParseResult parseResult_;\n};\n\n//! GenericDocument with UTF8 encoding\ntypedef GenericDocument<UTF8<> > Document;\n\n//! Helper class for accessing Value of array type.\n/*!\n    Instance of this helper class is obtained by \\c GenericValue::GetArray().\n    In addition to all APIs for array type, it provides range-based for loop if \\c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.\n*/\ntemplate <bool Const, typename ValueT>\nclass GenericArray {\npublic:\n    typedef GenericArray<true, ValueT> ConstArray;\n    typedef GenericArray<false, ValueT> Array;\n    typedef ValueT PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef ValueType* ValueIterator;  // This may be const or non-const iterator\n    typedef const ValueT* ConstValueIterator;\n    typedef typename ValueType::AllocatorType AllocatorType;\n    typedef typename ValueType::StringRefType StringRefType;\n\n    template <typename, typename>\n    friend class GenericValue;\n\n    GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}\n    GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }\n    ~GenericArray() {}\n\n    SizeType Size() const { return value_.Size(); }\n    SizeType Capacity() const { return value_.Capacity(); }\n    bool Empty() const { return value_.Empty(); }\n    void Clear() const { value_.Clear(); }\n    ValueType& operator[](SizeType index) const {  return value_[index]; }\n    ValueIterator Begin() const { return value_.Begin(); }\n    ValueIterator End() const { return value_.End(); }\n    GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }\n    GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }\n    GenericArray PopBack() const { value_.PopBack(); return *this; }\n    ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }\n    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }\n\n#if RAPIDJSON_HAS_CXX11_RANGE_FOR\n    ValueIterator begin() const { return value_.Begin(); }\n    ValueIterator end() const { return value_.End(); }\n#endif\n\nprivate:\n    GenericArray();\n    GenericArray(ValueType& value) : value_(value) {}\n    ValueType& value_;\n};\n\n//! Helper class for accessing Value of object type.\n/*!\n    Instance of this helper class is obtained by \\c GenericValue::GetObject().\n    In addition to all APIs for array type, it provides range-based for loop if \\c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.\n*/\ntemplate <bool Const, typename ValueT>\nclass GenericObject {\npublic:\n    typedef GenericObject<true, ValueT> ConstObject;\n    typedef GenericObject<false, ValueT> Object;\n    typedef ValueT PlainType;\n    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;\n    typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;  // This may be const or non-const iterator\n    typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;\n    typedef typename ValueType::AllocatorType AllocatorType;\n    typedef typename ValueType::StringRefType StringRefType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename ValueType::Ch Ch;\n\n    template <typename, typename>\n    friend class GenericValue;\n\n    GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}\n    GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }\n    ~GenericObject() {}\n\n    SizeType MemberCount() const { return value_.MemberCount(); }\n    bool ObjectEmpty() const { return value_.ObjectEmpty(); }\n    template <typename T> ValueType& operator[](T* name) const { return value_[name]; }\n    template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }\n#if RAPIDJSON_HAS_STDSTRING\n    ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }\n#endif\n    MemberIterator MemberBegin() const { return value_.MemberBegin(); }\n    MemberIterator MemberEnd() const { return value_.MemberEnd(); }\n    bool HasMember(const Ch* name) const { return value_.HasMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }\n#endif\n    template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }\n    MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }\n    template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }\n#endif\n    GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#if RAPIDJSON_HAS_STDSTRING\n    GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#endif\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }\n    void RemoveAllMembers() { value_.RemoveAllMembers(); }\n    bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }\n#endif\n    template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }\n    MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }\n    MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }\n    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }\n    bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }\n#if RAPIDJSON_HAS_STDSTRING\n    bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }\n#endif\n    template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }\n\n#if RAPIDJSON_HAS_CXX11_RANGE_FOR\n    MemberIterator begin() const { return value_.MemberBegin(); }\n    MemberIterator end() const { return value_.MemberEnd(); }\n#endif\n\nprivate:\n    GenericObject();\n    GenericObject(ValueType& value) : value_(value) {}\n    ValueType& value_;\n};\n\nRAPIDJSON_NAMESPACE_END\n#ifdef _MINWINDEF_       // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max\n#ifndef NOMINMAX\n#pragma pop_macro(\"min\")\n#pragma pop_macro(\"max\")\n#endif\n#endif\nRAPIDJSON_DIAG_POP\n\n#endif // RAPIDJSON_DOCUMENT_H_\n"
  },
  {
    "path": "third-party/rapidjson/encodedstream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ENCODEDSTREAM_H_\n#define RAPIDJSON_ENCODEDSTREAM_H_\n\n#include \"stream.h\"\n#include \"memorystream.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Input byte stream wrapper with a statically bound encoding.\n/*!\n    \\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.\n    \\tparam InputByteStream Type of input byte stream. For example, FileReadStream.\n*/\ntemplate <typename Encoding, typename InputByteStream>\nclass EncodedInputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    EncodedInputStream(InputByteStream& is) : is_(is) { \n        current_ = Encoding::TakeBOM(is_);\n    }\n\n    Ch Peek() const { return current_; }\n    Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }\n    size_t Tell() const { return is_.Tell(); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    EncodedInputStream(const EncodedInputStream&);\n    EncodedInputStream& operator=(const EncodedInputStream&);\n\n    InputByteStream& is_;\n    Ch current_;\n};\n\n//! Specialized for UTF8 MemoryStream.\ntemplate <>\nclass EncodedInputStream<UTF8<>, MemoryStream> {\npublic:\n    typedef UTF8<>::Ch Ch;\n\n    EncodedInputStream(MemoryStream& is) : is_(is) {\n        if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();\n        if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();\n        if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();\n    }\n    Ch Peek() const { return is_.Peek(); }\n    Ch Take() { return is_.Take(); }\n    size_t Tell() const { return is_.Tell(); }\n\n    // Not implemented\n    void Put(Ch) {}\n    void Flush() {} \n    Ch* PutBegin() { return 0; }\n    size_t PutEnd(Ch*) { return 0; }\n\n    MemoryStream& is_;\n\nprivate:\n    EncodedInputStream(const EncodedInputStream&);\n    EncodedInputStream& operator=(const EncodedInputStream&);\n};\n\n//! Output byte stream wrapper with statically bound encoding.\n/*!\n    \\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.\n    \\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.\n*/\ntemplate <typename Encoding, typename OutputByteStream>\nclass EncodedOutputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { \n        if (putBOM)\n            Encoding::PutBOM(os_);\n    }\n\n    void Put(Ch c) { Encoding::Put(os_, c);  }\n    void Flush() { os_.Flush(); }\n\n    // Not implemented\n    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}\n    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}\n    size_t Tell() const { RAPIDJSON_ASSERT(false);  return 0; }\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    EncodedOutputStream(const EncodedOutputStream&);\n    EncodedOutputStream& operator=(const EncodedOutputStream&);\n\n    OutputByteStream& os_;\n};\n\n#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x\n\n//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.\n/*!\n    \\tparam CharType Type of character for reading.\n    \\tparam InputByteStream type of input byte stream to be wrapped.\n*/\ntemplate <typename CharType, typename InputByteStream>\nclass AutoUTFInputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\npublic:\n    typedef CharType Ch;\n\n    //! Constructor.\n    /*!\n        \\param is input stream to be wrapped.\n        \\param type UTF encoding type if it is not detected from the stream.\n    */\n    AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {\n        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);        \n        DetectType();\n        static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };\n        takeFunc_ = f[type_];\n        current_ = takeFunc_(*is_);\n    }\n\n    UTFType GetType() const { return type_; }\n    bool HasBOM() const { return hasBOM_; }\n\n    Ch Peek() const { return current_; }\n    Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }\n    size_t Tell() const { return is_->Tell(); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    AutoUTFInputStream(const AutoUTFInputStream&);\n    AutoUTFInputStream& operator=(const AutoUTFInputStream&);\n\n    // Detect encoding type with BOM or RFC 4627\n    void DetectType() {\n        // BOM (Byte Order Mark):\n        // 00 00 FE FF  UTF-32BE\n        // FF FE 00 00  UTF-32LE\n        // FE FF        UTF-16BE\n        // FF FE        UTF-16LE\n        // EF BB BF     UTF-8\n\n        const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());\n        if (!c)\n            return;\n\n        unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));\n        hasBOM_ = false;\n        if (bom == 0xFFFE0000)                  { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }\n        else if (bom == 0x0000FEFF)             { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }\n        else if ((bom & 0xFFFF) == 0xFFFE)      { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take();                           }\n        else if ((bom & 0xFFFF) == 0xFEFF)      { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take();                           }\n        else if ((bom & 0xFFFFFF) == 0xBFBBEF)  { type_ = kUTF8;    hasBOM_ = true; is_->Take(); is_->Take(); is_->Take();              }\n\n        // RFC 4627: Section 3\n        // \"Since the first two characters of a JSON text will always be ASCII\n        // characters [RFC0020], it is possible to determine whether an octet\n        // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking\n        // at the pattern of nulls in the first four octets.\"\n        // 00 00 00 xx  UTF-32BE\n        // 00 xx 00 xx  UTF-16BE\n        // xx 00 00 00  UTF-32LE\n        // xx 00 xx 00  UTF-16LE\n        // xx xx xx xx  UTF-8\n\n        if (!hasBOM_) {\n            int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);\n            switch (pattern) {\n            case 0x08: type_ = kUTF32BE; break;\n            case 0x0A: type_ = kUTF16BE; break;\n            case 0x01: type_ = kUTF32LE; break;\n            case 0x05: type_ = kUTF16LE; break;\n            case 0x0F: type_ = kUTF8;    break;\n            default: break; // Use type defined by user.\n            }\n        }\n\n        // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.\n        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);\n        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);\n    }\n\n    typedef Ch (*TakeFunc)(InputByteStream& is);\n    InputByteStream* is_;\n    UTFType type_;\n    Ch current_;\n    TakeFunc takeFunc_;\n    bool hasBOM_;\n};\n\n//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.\n/*!\n    \\tparam CharType Type of character for writing.\n    \\tparam OutputByteStream type of output byte stream to be wrapped.\n*/\ntemplate <typename CharType, typename OutputByteStream>\nclass AutoUTFOutputStream {\n    RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\npublic:\n    typedef CharType Ch;\n\n    //! Constructor.\n    /*!\n        \\param os output stream to be wrapped.\n        \\param type UTF encoding type.\n        \\param putBOM Whether to write BOM at the beginning of the stream.\n    */\n    AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {\n        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);\n\n        // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.\n        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);\n        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);\n\n        static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };\n        putFunc_ = f[type_];\n\n        if (putBOM)\n            PutBOM();\n    }\n\n    UTFType GetType() const { return type_; }\n\n    void Put(Ch c) { putFunc_(*os_, c); }\n    void Flush() { os_->Flush(); } \n\n    // Not implemented\n    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}\n    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    AutoUTFOutputStream(const AutoUTFOutputStream&);\n    AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);\n\n    void PutBOM() { \n        typedef void (*PutBOMFunc)(OutputByteStream&);\n        static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };\n        f[type_](*os_);\n    }\n\n    typedef void (*PutFunc)(OutputByteStream&, Ch);\n\n    OutputByteStream* os_;\n    UTFType type_;\n    PutFunc putFunc_;\n};\n\n#undef RAPIDJSON_ENCODINGS_FUNC\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "third-party/rapidjson/encodings.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ENCODINGS_H_\n#define RAPIDJSON_ENCODINGS_H_\n\n#include \"rapidjson.h\"\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data\nRAPIDJSON_DIAG_OFF(4702)  // unreachable code\n#elif defined(__GNUC__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\nRAPIDJSON_DIAG_OFF(overflow)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Encoding\n\n/*! \\class rapidjson::Encoding\n    \\brief Concept for encoding of Unicode characters.\n\n\\code\nconcept Encoding {\n    typename Ch;    //! Type of character. A \"character\" is actually a code unit in unicode's definition.\n\n    enum { supportUnicode = 1 }; // or 0 if not supporting unicode\n\n    //! \\brief Encode a Unicode codepoint to an output stream.\n    //! \\param os Output stream.\n    //! \\param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint);\n\n    //! \\brief Decode a Unicode codepoint from an input stream.\n    //! \\param is Input stream.\n    //! \\param codepoint Output of the unicode codepoint.\n    //! \\return true if a valid codepoint can be decoded from the stream.\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint);\n\n    //! \\brief Validate one Unicode codepoint from an encoded stream.\n    //! \\param is Input stream to obtain codepoint.\n    //! \\param os Output for copying one codepoint.\n    //! \\return true if it is valid.\n    //! \\note This function just validating and copying the codepoint without actually decode it.\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os);\n\n    // The following functions are deal with byte streams.\n\n    //! Take a character from input byte stream, skip BOM if exist.\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is);\n\n    //! Take a character from input byte stream.\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is);\n\n    //! Put BOM to output byte stream.\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os);\n\n    //! Put a character to output byte stream.\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c);\n};\n\\endcode\n*/\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF8\n\n//! UTF-8 encoding.\n/*! http://en.wikipedia.org/wiki/UTF-8\n    http://tools.ietf.org/html/rfc3629\n    \\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.\n    \\note implements Encoding concept\n*/\ntemplate<typename CharType = char>\nstruct UTF8 {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        if (codepoint <= 0x7F) \n            os.Put(static_cast<Ch>(codepoint & 0xFF));\n        else if (codepoint <= 0x7FF) {\n            os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));\n        }\n        else if (codepoint <= 0xFFFF) {\n            os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        if (codepoint <= 0x7F) \n            PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));\n        else if (codepoint <= 0x7FF) {\n            PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));\n        }\n        else if (codepoint <= 0xFFFF) {\n            PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));\n            PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));\n        }\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)\n#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)\n#define TAIL() COPY(); TRANS(0x70)\n        typename InputStream::Ch c = is.Take();\n        if (!(c & 0x80)) {\n            *codepoint = static_cast<unsigned char>(c);\n            return true;\n        }\n\n        unsigned char type = GetRange(static_cast<unsigned char>(c));\n        if (type >= 32) {\n            *codepoint = 0;\n        } else {\n            *codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);\n        }\n        bool result = true;\n        switch (type) {\n        case 2: TAIL(); return result;\n        case 3: TAIL(); TAIL(); return result;\n        case 4: COPY(); TRANS(0x50); TAIL(); return result;\n        case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;\n        case 6: TAIL(); TAIL(); TAIL(); return result;\n        case 10: COPY(); TRANS(0x20); TAIL(); return result;\n        case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;\n        default: return false;\n        }\n#undef COPY\n#undef TRANS\n#undef TAIL\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n#define COPY() os.Put(c = is.Take())\n#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)\n#define TAIL() COPY(); TRANS(0x70)\n        Ch c;\n        COPY();\n        if (!(c & 0x80))\n            return true;\n\n        bool result = true;\n        switch (GetRange(static_cast<unsigned char>(c))) {\n        case 2: TAIL(); return result;\n        case 3: TAIL(); TAIL(); return result;\n        case 4: COPY(); TRANS(0x50); TAIL(); return result;\n        case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;\n        case 6: TAIL(); TAIL(); TAIL(); return result;\n        case 10: COPY(); TRANS(0x20); TAIL(); return result;\n        case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;\n        default: return false;\n        }\n#undef COPY\n#undef TRANS\n#undef TAIL\n    }\n\n    static unsigned char GetRange(unsigned char c) {\n        // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/\n        // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.\n        static const unsigned char type[] = {\n            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n            0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n            0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,\n            0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n            0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,\n            8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\n            10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,\n        };\n        return type[c];\n    }\n\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        typename InputByteStream::Ch c = Take(is);\n        if (static_cast<unsigned char>(c) != 0xEFu) return c;\n        c = is.Take();\n        if (static_cast<unsigned char>(c) != 0xBBu) return c;\n        c = is.Take();\n        if (static_cast<unsigned char>(c) != 0xBFu) return c;\n        c = is.Take();\n        return c;\n    }\n\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        return static_cast<Ch>(is.Take());\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF16\n\n//! UTF-16 encoding.\n/*! http://en.wikipedia.org/wiki/UTF-16\n    http://tools.ietf.org/html/rfc2781\n    \\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.\n    \\note implements Encoding concept\n\n    \\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.\n    For streaming, use UTF16LE and UTF16BE, which handle endianness.\n*/\ntemplate<typename CharType = wchar_t>\nstruct UTF16 {\n    typedef CharType Ch;\n    RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        if (codepoint <= 0xFFFF) {\n            RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair \n            os.Put(static_cast<typename OutputStream::Ch>(codepoint));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            unsigned v = codepoint - 0x10000;\n            os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));\n            os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));\n        }\n    }\n\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        if (codepoint <= 0xFFFF) {\n            RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair \n            PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));\n        }\n        else {\n            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n            unsigned v = codepoint - 0x10000;\n            PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));\n            PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));\n        }\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);\n        typename InputStream::Ch c = is.Take();\n        if (c < 0xD800 || c > 0xDFFF) {\n            *codepoint = static_cast<unsigned>(c);\n            return true;\n        }\n        else if (c <= 0xDBFF) {\n            *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;\n            c = is.Take();\n            *codepoint |= (static_cast<unsigned>(c) & 0x3FF);\n            *codepoint += 0x10000;\n            return c >= 0xDC00 && c <= 0xDFFF;\n        }\n        return false;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);\n        typename InputStream::Ch c;\n        os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));\n        if (c < 0xD800 || c > 0xDFFF)\n            return true;\n        else if (c <= 0xDBFF) {\n            os.Put(c = is.Take());\n            return c >= 0xDC00 && c <= 0xDFFF;\n        }\n        return false;\n    }\n};\n\n//! UTF-16 little endian encoding.\ntemplate<typename CharType = wchar_t>\nstruct UTF16LE : UTF16<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<uint8_t>(is.Take());\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));\n    }\n};\n\n//! UTF-16 big endian encoding.\ntemplate<typename CharType = wchar_t>\nstruct UTF16BE : UTF16<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<uint8_t>(is.Take());\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// UTF32\n\n//! UTF-32 encoding. \n/*! http://en.wikipedia.org/wiki/UTF-32\n    \\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.\n    \\note implements Encoding concept\n\n    \\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.\n    For streaming, use UTF32LE and UTF32BE, which handle endianness.\n*/\ntemplate<typename CharType = unsigned>\nstruct UTF32 {\n    typedef CharType Ch;\n    RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);\n\n    enum { supportUnicode = 1 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);\n        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n        os.Put(codepoint);\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);\n        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);\n        PutUnsafe(os, codepoint);\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);\n        Ch c = is.Take();\n        *codepoint = c;\n        return c <= 0x10FFFF;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);\n        Ch c;\n        os.Put(c = is.Take());\n        return c <= 0x10FFFF;\n    }\n};\n\n//! UTF-32 little endian enocoding.\ntemplate<typename CharType = unsigned>\nstruct UTF32LE : UTF32<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;\n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<uint8_t>(is.Take());\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));\n    }\n};\n\n//! UTF-32 big endian encoding.\ntemplate<typename CharType = unsigned>\nstruct UTF32BE : UTF32<CharType> {\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        CharType c = Take(is);\n        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; \n    }\n\n    template <typename InputByteStream>\n    static CharType Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;\n        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));\n        return static_cast<CharType>(c);\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, CharType c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));\n        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// ASCII\n\n//! ASCII encoding.\n/*! http://en.wikipedia.org/wiki/ASCII\n    \\tparam CharType Code unit for storing 7-bit ASCII data. Default is char.\n    \\note implements Encoding concept\n*/\ntemplate<typename CharType = char>\nstruct ASCII {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 0 };\n\n    template<typename OutputStream>\n    static void Encode(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_ASSERT(codepoint <= 0x7F);\n        os.Put(static_cast<Ch>(codepoint & 0xFF));\n    }\n\n    template<typename OutputStream>\n    static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        RAPIDJSON_ASSERT(codepoint <= 0x7F);\n        PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));\n    }\n\n    template <typename InputStream>\n    static bool Decode(InputStream& is, unsigned* codepoint) {\n        uint8_t c = static_cast<uint8_t>(is.Take());\n        *codepoint = c;\n        return c <= 0X7F;\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static bool Validate(InputStream& is, OutputStream& os) {\n        uint8_t c = static_cast<uint8_t>(is.Take());\n        os.Put(static_cast<typename OutputStream::Ch>(c));\n        return c <= 0x7F;\n    }\n\n    template <typename InputByteStream>\n    static CharType TakeBOM(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        uint8_t c = static_cast<uint8_t>(Take(is));\n        return static_cast<Ch>(c);\n    }\n\n    template <typename InputByteStream>\n    static Ch Take(InputByteStream& is) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);\n        return static_cast<Ch>(is.Take());\n    }\n\n    template <typename OutputByteStream>\n    static void PutBOM(OutputByteStream& os) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        (void)os;\n    }\n\n    template <typename OutputByteStream>\n    static void Put(OutputByteStream& os, Ch c) {\n        RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);\n        os.Put(static_cast<typename OutputByteStream::Ch>(c));\n    }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// AutoUTF\n\n//! Runtime-specified UTF encoding type of a stream.\nenum UTFType {\n    kUTF8 = 0,      //!< UTF-8.\n    kUTF16LE = 1,   //!< UTF-16 little endian.\n    kUTF16BE = 2,   //!< UTF-16 big endian.\n    kUTF32LE = 3,   //!< UTF-32 little endian.\n    kUTF32BE = 4    //!< UTF-32 big endian.\n};\n\n//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.\n/*! \\note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().\n*/\ntemplate<typename CharType>\nstruct AutoUTF {\n    typedef CharType Ch;\n\n    enum { supportUnicode = 1 };\n\n#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x\n\n    template<typename OutputStream>\n    static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {\n        typedef void (*EncodeFunc)(OutputStream&, unsigned);\n        static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };\n        (*f[os.GetType()])(os, codepoint);\n    }\n\n    template<typename OutputStream>\n    static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {\n        typedef void (*EncodeFunc)(OutputStream&, unsigned);\n        static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };\n        (*f[os.GetType()])(os, codepoint);\n    }\n\n    template <typename InputStream>\n    static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {\n        typedef bool (*DecodeFunc)(InputStream&, unsigned*);\n        static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };\n        return (*f[is.GetType()])(is, codepoint);\n    }\n\n    template <typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {\n        typedef bool (*ValidateFunc)(InputStream&, OutputStream&);\n        static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };\n        return (*f[is.GetType()])(is, os);\n    }\n\n#undef RAPIDJSON_ENCODINGS_FUNC\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Transcoder\n\n//! Encoding conversion.\ntemplate<typename SourceEncoding, typename TargetEncoding>\nstruct Transcoder {\n    //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {\n        unsigned codepoint;\n        if (!SourceEncoding::Decode(is, &codepoint))\n            return false;\n        TargetEncoding::Encode(os, codepoint);\n        return true;\n    }\n\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {\n        unsigned codepoint;\n        if (!SourceEncoding::Decode(is, &codepoint))\n            return false;\n        TargetEncoding::EncodeUnsafe(os, codepoint);\n        return true;\n    }\n\n    //! Validate one Unicode codepoint from an encoded stream.\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {\n        return Transcode(is, os);   // Since source/target encoding is different, must transcode.\n    }\n};\n\n// Forward declaration.\ntemplate<typename Stream>\ninline void PutUnsafe(Stream& stream, typename Stream::Ch c);\n\n//! Specialization of Transcoder with same source and target encoding.\ntemplate<typename Encoding>\nstruct Transcoder<Encoding, Encoding> {\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {\n        os.Put(is.Take());  // Just copy one code unit. This semantic is different from primary template class.\n        return true;\n    }\n    \n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {\n        PutUnsafe(os, is.Take());  // Just copy one code unit. This semantic is different from primary template class.\n        return true;\n    }\n    \n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {\n        return Encoding::Validate(is, os);  // source/target encoding are the same\n    }\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__GNUC__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ENCODINGS_H_\n"
  },
  {
    "path": "third-party/rapidjson/error/en.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ERROR_EN_H_\n#define RAPIDJSON_ERROR_EN_H_\n\n#include \"error.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(covered-switch-default)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Maps error code of parsing into error message.\n/*!\n    \\ingroup RAPIDJSON_ERRORS\n    \\param parseErrorCode Error code obtained in parsing.\n    \\return the error message.\n    \\note User can make a copy of this function for localization.\n        Using switch-case is safer for future modification of error codes.\n*/\ninline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {\n    switch (parseErrorCode) {\n        case kParseErrorNone:                           return RAPIDJSON_ERROR_STRING(\"No error.\");\n\n        case kParseErrorDocumentEmpty:                  return RAPIDJSON_ERROR_STRING(\"The document is empty.\");\n        case kParseErrorDocumentRootNotSingular:        return RAPIDJSON_ERROR_STRING(\"The document root must not be followed by other values.\");\n    \n        case kParseErrorValueInvalid:                   return RAPIDJSON_ERROR_STRING(\"Invalid value.\");\n    \n        case kParseErrorObjectMissName:                 return RAPIDJSON_ERROR_STRING(\"Missing a name for object member.\");\n        case kParseErrorObjectMissColon:                return RAPIDJSON_ERROR_STRING(\"Missing a colon after a name of object member.\");\n        case kParseErrorObjectMissCommaOrCurlyBracket:  return RAPIDJSON_ERROR_STRING(\"Missing a comma or '}' after an object member.\");\n    \n        case kParseErrorArrayMissCommaOrSquareBracket:  return RAPIDJSON_ERROR_STRING(\"Missing a comma or ']' after an array element.\");\n\n        case kParseErrorStringUnicodeEscapeInvalidHex:  return RAPIDJSON_ERROR_STRING(\"Incorrect hex digit after \\\\u escape in string.\");\n        case kParseErrorStringUnicodeSurrogateInvalid:  return RAPIDJSON_ERROR_STRING(\"The surrogate pair in string is invalid.\");\n        case kParseErrorStringEscapeInvalid:            return RAPIDJSON_ERROR_STRING(\"Invalid escape character in string.\");\n        case kParseErrorStringMissQuotationMark:        return RAPIDJSON_ERROR_STRING(\"Missing a closing quotation mark in string.\");\n        case kParseErrorStringInvalidEncoding:          return RAPIDJSON_ERROR_STRING(\"Invalid encoding in string.\");\n\n        case kParseErrorNumberTooBig:                   return RAPIDJSON_ERROR_STRING(\"Number too big to be stored in double.\");\n        case kParseErrorNumberMissFraction:             return RAPIDJSON_ERROR_STRING(\"Miss fraction part in number.\");\n        case kParseErrorNumberMissExponent:             return RAPIDJSON_ERROR_STRING(\"Miss exponent in number.\");\n\n        case kParseErrorTermination:                    return RAPIDJSON_ERROR_STRING(\"Terminate parsing due to Handler error.\");\n        case kParseErrorUnspecificSyntaxError:          return RAPIDJSON_ERROR_STRING(\"Unspecific syntax error.\");\n\n        default:                                        return RAPIDJSON_ERROR_STRING(\"Unknown error.\");\n    }\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ERROR_EN_H_\n"
  },
  {
    "path": "third-party/rapidjson/error/error.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ERROR_ERROR_H_\n#define RAPIDJSON_ERROR_ERROR_H_\n\n#include \"../rapidjson.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n/*! \\file error.h */\n\n/*! \\defgroup RAPIDJSON_ERRORS RapidJSON error handling */\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ERROR_CHARTYPE\n\n//! Character type of error messages.\n/*! \\ingroup RAPIDJSON_ERRORS\n    The default character type is \\c char.\n    On Windows, user can define this macro as \\c TCHAR for supporting both\n    unicode/non-unicode settings.\n*/\n#ifndef RAPIDJSON_ERROR_CHARTYPE\n#define RAPIDJSON_ERROR_CHARTYPE char\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ERROR_STRING\n\n//! Macro for converting string literial to \\ref RAPIDJSON_ERROR_CHARTYPE[].\n/*! \\ingroup RAPIDJSON_ERRORS\n    By default this conversion macro does nothing.\n    On Windows, user can define this macro as \\c _T(x) for supporting both\n    unicode/non-unicode settings.\n*/\n#ifndef RAPIDJSON_ERROR_STRING\n#define RAPIDJSON_ERROR_STRING(x) x\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// ParseErrorCode\n\n//! Error code of parsing.\n/*! \\ingroup RAPIDJSON_ERRORS\n    \\see GenericReader::Parse, GenericReader::GetParseErrorCode\n*/\nenum ParseErrorCode {\n    kParseErrorNone = 0,                        //!< No error.\n\n    kParseErrorDocumentEmpty,                   //!< The document is empty.\n    kParseErrorDocumentRootNotSingular,         //!< The document root must not follow by other values.\n\n    kParseErrorValueInvalid,                    //!< Invalid value.\n\n    kParseErrorObjectMissName,                  //!< Missing a name for object member.\n    kParseErrorObjectMissColon,                 //!< Missing a colon after a name of object member.\n    kParseErrorObjectMissCommaOrCurlyBracket,   //!< Missing a comma or '}' after an object member.\n\n    kParseErrorArrayMissCommaOrSquareBracket,   //!< Missing a comma or ']' after an array element.\n\n    kParseErrorStringUnicodeEscapeInvalidHex,   //!< Incorrect hex digit after \\\\u escape in string.\n    kParseErrorStringUnicodeSurrogateInvalid,   //!< The surrogate pair in string is invalid.\n    kParseErrorStringEscapeInvalid,             //!< Invalid escape character in string.\n    kParseErrorStringMissQuotationMark,         //!< Missing a closing quotation mark in string.\n    kParseErrorStringInvalidEncoding,           //!< Invalid encoding in string.\n\n    kParseErrorNumberTooBig,                    //!< Number too big to be stored in double.\n    kParseErrorNumberMissFraction,              //!< Miss fraction part in number.\n    kParseErrorNumberMissExponent,              //!< Miss exponent in number.\n\n    kParseErrorTermination,                     //!< Parsing was terminated.\n    kParseErrorUnspecificSyntaxError            //!< Unspecific syntax error.\n};\n\n//! Result of parsing (wraps ParseErrorCode)\n/*!\n    \\ingroup RAPIDJSON_ERRORS\n    \\code\n        Document doc;\n        ParseResult ok = doc.Parse(\"[42]\");\n        if (!ok) {\n            fprintf(stderr, \"JSON parse error: %s (%u)\",\n                    GetParseError_En(ok.Code()), ok.Offset());\n            exit(EXIT_FAILURE);\n        }\n    \\endcode\n    \\see GenericReader::Parse, GenericDocument::Parse\n*/\nstruct ParseResult {\npublic:\n    //! Default constructor, no error.\n    ParseResult() : code_(kParseErrorNone), offset_(0) {}\n    //! Constructor to set an error.\n    ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}\n\n    //! Get the error code.\n    ParseErrorCode Code() const { return code_; }\n    //! Get the error offset, if \\ref IsError(), 0 otherwise.\n    size_t Offset() const { return offset_; }\n\n    //! Conversion to \\c bool, returns \\c true, iff !\\ref IsError().\n    operator bool() const { return !IsError(); }\n    //! Whether the result is an error.\n    bool IsError() const { return code_ != kParseErrorNone; }\n\n    bool operator==(const ParseResult& that) const { return code_ == that.code_; }\n    bool operator==(ParseErrorCode code) const { return code_ == code; }\n    friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }\n\n    //! Reset error code.\n    void Clear() { Set(kParseErrorNone); }\n    //! Update error code and offset.\n    void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }\n\nprivate:\n    ParseErrorCode code_;\n    size_t offset_;\n};\n\n//! Function pointer type of GetParseError().\n/*! \\ingroup RAPIDJSON_ERRORS\n\n    This is the prototype for \\c GetParseError_X(), where \\c X is a locale.\n    User can dynamically change locale in runtime, e.g.:\n\\code\n    GetParseErrorFunc GetParseError = GetParseError_En; // or whatever\n    const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());\n\\endcode\n*/\ntypedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_ERROR_ERROR_H_\n"
  },
  {
    "path": "third-party/rapidjson/filereadstream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FILEREADSTREAM_H_\n#define RAPIDJSON_FILEREADSTREAM_H_\n\n#include \"stream.h\"\n#include <cstdio>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(missing-noreturn)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! File byte stream for input using fread().\n/*!\n    \\note implements Stream concept\n*/\nclass FileReadStream {\npublic:\n    typedef char Ch;    //!< Character type (byte).\n\n    //! Constructor.\n    /*!\n        \\param fp File pointer opened for read.\n        \\param buffer user-supplied buffer.\n        \\param bufferSize size of buffer in bytes. Must >=4 bytes.\n    */\n    FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { \n        RAPIDJSON_ASSERT(fp_ != 0);\n        RAPIDJSON_ASSERT(bufferSize >= 4);\n        Read();\n    }\n\n    Ch Peek() const { return *current_; }\n    Ch Take() { Ch c = *current_; Read(); return c; }\n    size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }\n\n    // Not implemented\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); } \n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        return (current_ + 4 <= bufferLast_) ? current_ : 0;\n    }\n\nprivate:\n    void Read() {\n        if (current_ < bufferLast_)\n            ++current_;\n        else if (!eof_) {\n            count_ += readCount_;\n            readCount_ = fread(buffer_, 1, bufferSize_, fp_);\n            bufferLast_ = buffer_ + readCount_ - 1;\n            current_ = buffer_;\n\n            if (readCount_ < bufferSize_) {\n                buffer_[readCount_] = '\\0';\n                ++bufferLast_;\n                eof_ = true;\n            }\n        }\n    }\n\n    std::FILE* fp_;\n    Ch *buffer_;\n    size_t bufferSize_;\n    Ch *bufferLast_;\n    Ch *current_;\n    size_t readCount_;\n    size_t count_;  //!< Number of characters read\n    bool eof_;\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "third-party/rapidjson/filewritestream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FILEWRITESTREAM_H_\n#define RAPIDJSON_FILEWRITESTREAM_H_\n\n#include \"stream.h\"\n#include <cstdio>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(unreachable-code)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of C file stream for input using fread().\n/*!\n    \\note implements Stream concept\n*/\nclass FileWriteStream {\npublic:\n    typedef char Ch;    //!< Character type. Only support char.\n\n    FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { \n        RAPIDJSON_ASSERT(fp_ != 0);\n    }\n\n    void Put(char c) { \n        if (current_ >= bufferEnd_)\n            Flush();\n\n        *current_++ = c;\n    }\n\n    void PutN(char c, size_t n) {\n        size_t avail = static_cast<size_t>(bufferEnd_ - current_);\n        while (n > avail) {\n            std::memset(current_, c, avail);\n            current_ += avail;\n            Flush();\n            n -= avail;\n            avail = static_cast<size_t>(bufferEnd_ - current_);\n        }\n\n        if (n > 0) {\n            std::memset(current_, c, n);\n            current_ += n;\n        }\n    }\n\n    void Flush() {\n        if (current_ != buffer_) {\n            size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);\n            if (result < static_cast<size_t>(current_ - buffer_)) {\n                // failure deliberately ignored at this time\n                // added to avoid warn_unused_result build errors\n            }\n            current_ = buffer_;\n        }\n    }\n\n    // Not implemented\n    char Peek() const { RAPIDJSON_ASSERT(false); return 0; }\n    char Take() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    FileWriteStream(const FileWriteStream&);\n    FileWriteStream& operator=(const FileWriteStream&);\n\n    std::FILE* fp_;\n    char *buffer_;\n    char *bufferEnd_;\n    char *current_;\n};\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(FileWriteStream& stream, char c, size_t n) {\n    stream.PutN(c, n);\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_FILESTREAM_H_\n"
  },
  {
    "path": "third-party/rapidjson/fwd.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_FWD_H_\n#define RAPIDJSON_FWD_H_\n\n#include \"rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n// encodings.h\n\ntemplate<typename CharType> struct UTF8;\ntemplate<typename CharType> struct UTF16;\ntemplate<typename CharType> struct UTF16BE;\ntemplate<typename CharType> struct UTF16LE;\ntemplate<typename CharType> struct UTF32;\ntemplate<typename CharType> struct UTF32BE;\ntemplate<typename CharType> struct UTF32LE;\ntemplate<typename CharType> struct ASCII;\ntemplate<typename CharType> struct AutoUTF;\n\ntemplate<typename SourceEncoding, typename TargetEncoding>\nstruct Transcoder;\n\n// allocators.h\n\nclass CrtAllocator;\n\ntemplate <typename BaseAllocator>\nclass MemoryPoolAllocator;\n\n// stream.h\n\ntemplate <typename Encoding>\nstruct GenericStringStream;\n\ntypedef GenericStringStream<UTF8<char> > StringStream;\n\ntemplate <typename Encoding>\nstruct GenericInsituStringStream;\n\ntypedef GenericInsituStringStream<UTF8<char> > InsituStringStream;\n\n// stringbuffer.h\n\ntemplate <typename Encoding, typename Allocator>\nclass GenericStringBuffer;\n\ntypedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;\n\n// filereadstream.h\n\nclass FileReadStream;\n\n// filewritestream.h\n\nclass FileWriteStream;\n\n// memorybuffer.h\n\ntemplate <typename Allocator>\nstruct GenericMemoryBuffer;\n\ntypedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;\n\n// memorystream.h\n\nstruct MemoryStream;\n\n// reader.h\n\ntemplate<typename Encoding, typename Derived>\nstruct BaseReaderHandler;\n\ntemplate <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>\nclass GenericReader;\n\ntypedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;\n\n// writer.h\n\ntemplate<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>\nclass Writer;\n\n// prettywriter.h\n\ntemplate<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>\nclass PrettyWriter;\n\n// document.h\n\ntemplate <typename Encoding, typename Allocator> \nstruct GenericMember;\n\ntemplate <bool Const, typename Encoding, typename Allocator>\nclass GenericMemberIterator;\n\ntemplate<typename CharType>\nstruct GenericStringRef;\n\ntemplate <typename Encoding, typename Allocator> \nclass GenericValue;\n\ntypedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;\n\ntemplate <typename Encoding, typename Allocator, typename StackAllocator>\nclass GenericDocument;\n\ntypedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;\n\n// pointer.h\n\ntemplate <typename ValueType, typename Allocator>\nclass GenericPointer;\n\ntypedef GenericPointer<Value, CrtAllocator> Pointer;\n\n// schema.h\n\ntemplate <typename SchemaDocumentType>\nclass IGenericRemoteSchemaDocumentProvider;\n\ntemplate <typename ValueT, typename Allocator>\nclass GenericSchemaDocument;\n\ntypedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;\ntypedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;\n\ntemplate <\n    typename SchemaDocumentType,\n    typename OutputHandler,\n    typename StateAllocator>\nclass GenericSchemaValidator;\n\ntypedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_RAPIDJSONFWD_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/biginteger.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_BIGINTEGER_H_\n#define RAPIDJSON_BIGINTEGER_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(_MSC_VER) && defined(_M_AMD64)\n#include <intrin.h> // for _umul128\n#pragma intrinsic(_umul128)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\nclass BigInteger {\npublic:\n    typedef uint64_t Type;\n\n    BigInteger(const BigInteger& rhs) : count_(rhs.count_) {\n        std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));\n    }\n\n    explicit BigInteger(uint64_t u) : count_(1) {\n        digits_[0] = u;\n    }\n\n    BigInteger(const char* decimals, size_t length) : count_(1) {\n        RAPIDJSON_ASSERT(length > 0);\n        digits_[0] = 0;\n        size_t i = 0;\n        const size_t kMaxDigitPerIteration = 19;  // 2^64 = 18446744073709551616 > 10^19\n        while (length >= kMaxDigitPerIteration) {\n            AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);\n            length -= kMaxDigitPerIteration;\n            i += kMaxDigitPerIteration;\n        }\n\n        if (length > 0)\n            AppendDecimal64(decimals + i, decimals + i + length);\n    }\n    \n    BigInteger& operator=(const BigInteger &rhs)\n    {\n        if (this != &rhs) {\n            count_ = rhs.count_;\n            std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));\n        }\n        return *this;\n    }\n    \n    BigInteger& operator=(uint64_t u) {\n        digits_[0] = u;            \n        count_ = 1;\n        return *this;\n    }\n\n    BigInteger& operator+=(uint64_t u) {\n        Type backup = digits_[0];\n        digits_[0] += u;\n        for (size_t i = 0; i < count_ - 1; i++) {\n            if (digits_[i] >= backup)\n                return *this; // no carry\n            backup = digits_[i + 1];\n            digits_[i + 1] += 1;\n        }\n\n        // Last carry\n        if (digits_[count_ - 1] < backup)\n            PushBack(1);\n\n        return *this;\n    }\n\n    BigInteger& operator*=(uint64_t u) {\n        if (u == 0) return *this = 0;\n        if (u == 1) return *this;\n        if (*this == 1) return *this = u;\n\n        uint64_t k = 0;\n        for (size_t i = 0; i < count_; i++) {\n            uint64_t hi;\n            digits_[i] = MulAdd64(digits_[i], u, k, &hi);\n            k = hi;\n        }\n        \n        if (k > 0)\n            PushBack(k);\n\n        return *this;\n    }\n\n    BigInteger& operator*=(uint32_t u) {\n        if (u == 0) return *this = 0;\n        if (u == 1) return *this;\n        if (*this == 1) return *this = u;\n\n        uint64_t k = 0;\n        for (size_t i = 0; i < count_; i++) {\n            const uint64_t c = digits_[i] >> 32;\n            const uint64_t d = digits_[i] & 0xFFFFFFFF;\n            const uint64_t uc = u * c;\n            const uint64_t ud = u * d;\n            const uint64_t p0 = ud + k;\n            const uint64_t p1 = uc + (p0 >> 32);\n            digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);\n            k = p1 >> 32;\n        }\n        \n        if (k > 0)\n            PushBack(k);\n\n        return *this;\n    }\n\n    BigInteger& operator<<=(size_t shift) {\n        if (IsZero() || shift == 0) return *this;\n\n        size_t offset = shift / kTypeBit;\n        size_t interShift = shift % kTypeBit;\n        RAPIDJSON_ASSERT(count_ + offset <= kCapacity);\n\n        if (interShift == 0) {\n            std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));\n            count_ += offset;\n        }\n        else {\n            digits_[count_] = 0;\n            for (size_t i = count_; i > 0; i--)\n                digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));\n            digits_[offset] = digits_[0] << interShift;\n            count_ += offset;\n            if (digits_[count_])\n                count_++;\n        }\n\n        std::memset(digits_, 0, offset * sizeof(Type));\n\n        return *this;\n    }\n\n    bool operator==(const BigInteger& rhs) const {\n        return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;\n    }\n\n    bool operator==(const Type rhs) const {\n        return count_ == 1 && digits_[0] == rhs;\n    }\n\n    BigInteger& MultiplyPow5(unsigned exp) {\n        static const uint32_t kPow5[12] = {\n            5,\n            5 * 5,\n            5 * 5 * 5,\n            5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,\n            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5\n        };\n        if (exp == 0) return *this;\n        for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27\n        for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13\n        if (exp > 0)                 *this *= kPow5[exp - 1];\n        return *this;\n    }\n\n    // Compute absolute difference of this and rhs.\n    // Assume this != rhs\n    bool Difference(const BigInteger& rhs, BigInteger* out) const {\n        int cmp = Compare(rhs);\n        RAPIDJSON_ASSERT(cmp != 0);\n        const BigInteger *a, *b;  // Makes a > b\n        bool ret;\n        if (cmp < 0) { a = &rhs; b = this; ret = true; }\n        else         { a = this; b = &rhs; ret = false; }\n\n        Type borrow = 0;\n        for (size_t i = 0; i < a->count_; i++) {\n            Type d = a->digits_[i] - borrow;\n            if (i < b->count_)\n                d -= b->digits_[i];\n            borrow = (d > a->digits_[i]) ? 1 : 0;\n            out->digits_[i] = d;\n            if (d != 0)\n                out->count_ = i + 1;\n        }\n\n        return ret;\n    }\n\n    int Compare(const BigInteger& rhs) const {\n        if (count_ != rhs.count_)\n            return count_ < rhs.count_ ? -1 : 1;\n\n        for (size_t i = count_; i-- > 0;)\n            if (digits_[i] != rhs.digits_[i])\n                return digits_[i] < rhs.digits_[i] ? -1 : 1;\n\n        return 0;\n    }\n\n    size_t GetCount() const { return count_; }\n    Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }\n    bool IsZero() const { return count_ == 1 && digits_[0] == 0; }\n\nprivate:\n    void AppendDecimal64(const char* begin, const char* end) {\n        uint64_t u = ParseUint64(begin, end);\n        if (IsZero())\n            *this = u;\n        else {\n            unsigned exp = static_cast<unsigned>(end - begin);\n            (MultiplyPow5(exp) <<= exp) += u;   // *this = *this * 10^exp + u\n        }\n    }\n\n    void PushBack(Type digit) {\n        RAPIDJSON_ASSERT(count_ < kCapacity);\n        digits_[count_++] = digit;\n    }\n\n    static uint64_t ParseUint64(const char* begin, const char* end) {\n        uint64_t r = 0;\n        for (const char* p = begin; p != end; ++p) {\n            RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');\n            r = r * 10u + static_cast<unsigned>(*p - '0');\n        }\n        return r;\n    }\n\n    // Assume a * b + k < 2^128\n    static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        uint64_t low = _umul128(a, b, outHigh) + k;\n        if (low < k)\n            (*outHigh)++;\n        return low;\n#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)\n        __extension__ typedef unsigned __int128 uint128;\n        uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);\n        p += k;\n        *outHigh = static_cast<uint64_t>(p >> 64);\n        return static_cast<uint64_t>(p);\n#else\n        const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;\n        uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;\n        x1 += (x0 >> 32); // can't give carry\n        x1 += x2;\n        if (x1 < x2)\n            x3 += (static_cast<uint64_t>(1) << 32);\n        uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);\n        uint64_t hi = x3 + (x1 >> 32);\n\n        lo += k;\n        if (lo < k)\n            hi++;\n        *outHigh = hi;\n        return lo;\n#endif\n    }\n\n    static const size_t kBitCount = 3328;  // 64bit * 54 > 10^1000\n    static const size_t kCapacity = kBitCount / sizeof(Type);\n    static const size_t kTypeBit = sizeof(Type) * 8;\n\n    Type digits_[kCapacity];\n    size_t count_;\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_BIGINTEGER_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/diyfp.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n// This is a C++ header-only implementation of Grisu2 algorithm from the publication:\n// Loitsch, Florian. \"Printing floating-point numbers quickly and accurately with\n// integers.\" ACM Sigplan Notices 45.6 (2010): 233-243.\n\n#ifndef RAPIDJSON_DIYFP_H_\n#define RAPIDJSON_DIYFP_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)\n#include <intrin.h>\n#pragma intrinsic(_BitScanReverse64)\n#pragma intrinsic(_umul128)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nstruct DiyFp {\n    DiyFp() : f(), e() {}\n\n    DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}\n\n    explicit DiyFp(double d) {\n        union {\n            double d;\n            uint64_t u64;\n        } u = { d };\n\n        int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);\n        uint64_t significand = (u.u64 & kDpSignificandMask);\n        if (biased_e != 0) {\n            f = significand + kDpHiddenBit;\n            e = biased_e - kDpExponentBias;\n        } \n        else {\n            f = significand;\n            e = kDpMinExponent + 1;\n        }\n    }\n\n    DiyFp operator-(const DiyFp& rhs) const {\n        return DiyFp(f - rhs.f, e);\n    }\n\n    DiyFp operator*(const DiyFp& rhs) const {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        uint64_t h;\n        uint64_t l = _umul128(f, rhs.f, &h);\n        if (l & (uint64_t(1) << 63)) // rounding\n            h++;\n        return DiyFp(h, e + rhs.e + 64);\n#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)\n        __extension__ typedef unsigned __int128 uint128;\n        uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);\n        uint64_t h = static_cast<uint64_t>(p >> 64);\n        uint64_t l = static_cast<uint64_t>(p);\n        if (l & (uint64_t(1) << 63)) // rounding\n            h++;\n        return DiyFp(h, e + rhs.e + 64);\n#else\n        const uint64_t M32 = 0xFFFFFFFF;\n        const uint64_t a = f >> 32;\n        const uint64_t b = f & M32;\n        const uint64_t c = rhs.f >> 32;\n        const uint64_t d = rhs.f & M32;\n        const uint64_t ac = a * c;\n        const uint64_t bc = b * c;\n        const uint64_t ad = a * d;\n        const uint64_t bd = b * d;\n        uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);\n        tmp += 1U << 31;  /// mult_round\n        return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);\n#endif\n    }\n\n    DiyFp Normalize() const {\n#if defined(_MSC_VER) && defined(_M_AMD64)\n        unsigned long index;\n        _BitScanReverse64(&index, f);\n        return DiyFp(f << (63 - index), e - (63 - index));\n#elif defined(__GNUC__) && __GNUC__ >= 4\n        int s = __builtin_clzll(f);\n        return DiyFp(f << s, e - s);\n#else\n        DiyFp res = *this;\n        while (!(res.f & (static_cast<uint64_t>(1) << 63))) {\n            res.f <<= 1;\n            res.e--;\n        }\n        return res;\n#endif\n    }\n\n    DiyFp NormalizeBoundary() const {\n        DiyFp res = *this;\n        while (!(res.f & (kDpHiddenBit << 1))) {\n            res.f <<= 1;\n            res.e--;\n        }\n        res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);\n        res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);\n        return res;\n    }\n\n    void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {\n        DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();\n        DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);\n        mi.f <<= mi.e - pl.e;\n        mi.e = pl.e;\n        *plus = pl;\n        *minus = mi;\n    }\n\n    double ToDouble() const {\n        union {\n            double d;\n            uint64_t u64;\n        }u;\n        const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : \n            static_cast<uint64_t>(e + kDpExponentBias);\n        u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);\n        return u.d;\n    }\n\n    static const int kDiySignificandSize = 64;\n    static const int kDpSignificandSize = 52;\n    static const int kDpExponentBias = 0x3FF + kDpSignificandSize;\n    static const int kDpMaxExponent = 0x7FF - kDpExponentBias;\n    static const int kDpMinExponent = -kDpExponentBias;\n    static const int kDpDenormalExponent = -kDpExponentBias + 1;\n    static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);\n    static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);\n    static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);\n\n    uint64_t f;\n    int e;\n};\n\ninline DiyFp GetCachedPowerByIndex(size_t index) {\n    // 10^-348, 10^-340, ..., 10^340\n    static const uint64_t kCachedPowers_F[] = {\n        RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76),\n        RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea),\n        RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df),\n        RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f),\n        RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c),\n        RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5),\n        RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d),\n        RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637),\n        RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7),\n        RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5),\n        RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b),\n        RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996),\n        RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6),\n        RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8),\n        RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053),\n        RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd),\n        RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94),\n        RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b),\n        RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac),\n        RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3),\n        RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb),\n        RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c),\n        RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000),\n        RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984),\n        RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70),\n        RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245),\n        RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8),\n        RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a),\n        RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea),\n        RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85),\n        RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2),\n        RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3),\n        RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25),\n        RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece),\n        RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5),\n        RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a),\n        RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c),\n        RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a),\n        RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129),\n        RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429),\n        RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d),\n        RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841),\n        RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9),\n        RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b)\n    };\n    static const int16_t kCachedPowers_E[] = {\n        -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007,  -980,\n        -954,  -927,  -901,  -874,  -847,  -821,  -794,  -768,  -741,  -715,\n        -688,  -661,  -635,  -608,  -582,  -555,  -529,  -502,  -475,  -449,\n        -422,  -396,  -369,  -343,  -316,  -289,  -263,  -236,  -210,  -183,\n        -157,  -130,  -103,   -77,   -50,   -24,     3,    30,    56,    83,\n        109,   136,   162,   189,   216,   242,   269,   295,   322,   348,\n        375,   402,   428,   455,   481,   508,   534,   561,   588,   614,\n        641,   667,   694,   720,   747,   774,   800,   827,   853,   880,\n        907,   933,   960,   986,  1013,  1039,  1066\n    };\n    return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);\n}\n    \ninline DiyFp GetCachedPower(int e, int* K) {\n\n    //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;\n    double dk = (-61 - e) * 0.30102999566398114 + 347;  // dk must be positive, so can do ceiling in positive\n    int k = static_cast<int>(dk);\n    if (dk - k > 0.0)\n        k++;\n\n    unsigned index = static_cast<unsigned>((k >> 3) + 1);\n    *K = -(-348 + static_cast<int>(index << 3));    // decimal exponent no need lookup table\n\n    return GetCachedPowerByIndex(index);\n}\n\ninline DiyFp GetCachedPower10(int exp, int *outExp) {\n     unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;\n     *outExp = -348 + static_cast<int>(index) * 8;\n     return GetCachedPowerByIndex(index);\n }\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_DIYFP_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/dtoa.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n// This is a C++ header-only implementation of Grisu2 algorithm from the publication:\n// Loitsch, Florian. \"Printing floating-point numbers quickly and accurately with\n// integers.\" ACM Sigplan Notices 45.6 (2010): 233-243.\n\n#ifndef RAPIDJSON_DTOA_\n#define RAPIDJSON_DTOA_\n\n#include \"itoa.h\" // GetDigitsLut()\n#include \"diyfp.h\"\n#include \"ieee754.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\nRAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124\n#endif\n\ninline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {\n    while (rest < wp_w && delta - rest >= ten_kappa &&\n           (rest + ten_kappa < wp_w ||  /// closer\n            wp_w - rest > rest + ten_kappa - wp_w)) {\n        buffer[len - 1]--;\n        rest += ten_kappa;\n    }\n}\n\ninline int CountDecimalDigit32(uint32_t n) {\n    // Simple pure C++ implementation was faster than __builtin_clz version in this situation.\n    if (n < 10) return 1;\n    if (n < 100) return 2;\n    if (n < 1000) return 3;\n    if (n < 10000) return 4;\n    if (n < 100000) return 5;\n    if (n < 1000000) return 6;\n    if (n < 10000000) return 7;\n    if (n < 100000000) return 8;\n    // Will not reach 10 digits in DigitGen()\n    //if (n < 1000000000) return 9;\n    //return 10;\n    return 9;\n}\n\ninline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {\n    static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };\n    const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);\n    const DiyFp wp_w = Mp - W;\n    uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);\n    uint64_t p2 = Mp.f & (one.f - 1);\n    int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]\n    *len = 0;\n\n    while (kappa > 0) {\n        uint32_t d = 0;\n        switch (kappa) {\n            case  9: d = p1 /  100000000; p1 %=  100000000; break;\n            case  8: d = p1 /   10000000; p1 %=   10000000; break;\n            case  7: d = p1 /    1000000; p1 %=    1000000; break;\n            case  6: d = p1 /     100000; p1 %=     100000; break;\n            case  5: d = p1 /      10000; p1 %=      10000; break;\n            case  4: d = p1 /       1000; p1 %=       1000; break;\n            case  3: d = p1 /        100; p1 %=        100; break;\n            case  2: d = p1 /         10; p1 %=         10; break;\n            case  1: d = p1;              p1 =           0; break;\n            default:;\n        }\n        if (d || *len)\n            buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));\n        kappa--;\n        uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;\n        if (tmp <= delta) {\n            *K += kappa;\n            GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);\n            return;\n        }\n    }\n\n    // kappa = 0\n    for (;;) {\n        p2 *= 10;\n        delta *= 10;\n        char d = static_cast<char>(p2 >> -one.e);\n        if (d || *len)\n            buffer[(*len)++] = static_cast<char>('0' + d);\n        p2 &= one.f - 1;\n        kappa--;\n        if (p2 < delta) {\n            *K += kappa;\n            int index = -kappa;\n            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));\n            return;\n        }\n    }\n}\n\ninline void Grisu2(double value, char* buffer, int* length, int* K) {\n    const DiyFp v(value);\n    DiyFp w_m, w_p;\n    v.NormalizedBoundaries(&w_m, &w_p);\n\n    const DiyFp c_mk = GetCachedPower(w_p.e, K);\n    const DiyFp W = v.Normalize() * c_mk;\n    DiyFp Wp = w_p * c_mk;\n    DiyFp Wm = w_m * c_mk;\n    Wm.f++;\n    Wp.f--;\n    DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);\n}\n\ninline char* WriteExponent(int K, char* buffer) {\n    if (K < 0) {\n        *buffer++ = '-';\n        K = -K;\n    }\n\n    if (K >= 100) {\n        *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));\n        K %= 100;\n        const char* d = GetDigitsLut() + K * 2;\n        *buffer++ = d[0];\n        *buffer++ = d[1];\n    }\n    else if (K >= 10) {\n        const char* d = GetDigitsLut() + K * 2;\n        *buffer++ = d[0];\n        *buffer++ = d[1];\n    }\n    else\n        *buffer++ = static_cast<char>('0' + static_cast<char>(K));\n\n    return buffer;\n}\n\ninline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {\n    const int kk = length + k;  // 10^(kk-1) <= v < 10^kk\n\n    if (0 <= k && kk <= 21) {\n        // 1234e7 -> 12340000000\n        for (int i = length; i < kk; i++)\n            buffer[i] = '0';\n        buffer[kk] = '.';\n        buffer[kk + 1] = '0';\n        return &buffer[kk + 2];\n    }\n    else if (0 < kk && kk <= 21) {\n        // 1234e-2 -> 12.34\n        std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));\n        buffer[kk] = '.';\n        if (0 > k + maxDecimalPlaces) {\n            // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1\n            // Remove extra trailing zeros (at least one) after truncation.\n            for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)\n                if (buffer[i] != '0')\n                    return &buffer[i + 1];\n            return &buffer[kk + 2]; // Reserve one zero\n        }\n        else\n            return &buffer[length + 1];\n    }\n    else if (-6 < kk && kk <= 0) {\n        // 1234e-6 -> 0.001234\n        const int offset = 2 - kk;\n        std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));\n        buffer[0] = '0';\n        buffer[1] = '.';\n        for (int i = 2; i < offset; i++)\n            buffer[i] = '0';\n        if (length - kk > maxDecimalPlaces) {\n            // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1\n            // Remove extra trailing zeros (at least one) after truncation.\n            for (int i = maxDecimalPlaces + 1; i > 2; i--)\n                if (buffer[i] != '0')\n                    return &buffer[i + 1];\n            return &buffer[3]; // Reserve one zero\n        }\n        else\n            return &buffer[length + offset];\n    }\n    else if (kk < -maxDecimalPlaces) {\n        // Truncate to zero\n        buffer[0] = '0';\n        buffer[1] = '.';\n        buffer[2] = '0';\n        return &buffer[3];\n    }\n    else if (length == 1) {\n        // 1e30\n        buffer[1] = 'e';\n        return WriteExponent(kk - 1, &buffer[2]);\n    }\n    else {\n        // 1234e30 -> 1.234e33\n        std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));\n        buffer[1] = '.';\n        buffer[length + 1] = 'e';\n        return WriteExponent(kk - 1, &buffer[0 + length + 2]);\n    }\n}\n\ninline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {\n    RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);\n    Double d(value);\n    if (d.IsZero()) {\n        if (d.Sign())\n            *buffer++ = '-';     // -0.0, Issue #289\n        buffer[0] = '0';\n        buffer[1] = '.';\n        buffer[2] = '0';\n        return &buffer[3];\n    }\n    else {\n        if (value < 0) {\n            *buffer++ = '-';\n            value = -value;\n        }\n        int length, K;\n        Grisu2(value, buffer, &length, &K);\n        return Prettify(buffer, length, K, maxDecimalPlaces);\n    }\n}\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_DTOA_\n"
  },
  {
    "path": "third-party/rapidjson/internal/ieee754.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_IEEE754_\n#define RAPIDJSON_IEEE754_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\nclass Double {\npublic:\n    Double() {}\n    Double(double d) : d_(d) {}\n    Double(uint64_t u) : u_(u) {}\n\n    double Value() const { return d_; }\n    uint64_t Uint64Value() const { return u_; }\n\n    double NextPositiveDouble() const {\n        RAPIDJSON_ASSERT(!Sign());\n        return Double(u_ + 1).Value();\n    }\n\n    bool Sign() const { return (u_ & kSignMask) != 0; }\n    uint64_t Significand() const { return u_ & kSignificandMask; }\n    int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }\n\n    bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }\n    bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }\n    bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }\n    bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }\n    bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }\n\n    uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }\n    int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }\n    uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }\n\n    static int EffectiveSignificandSize(int order) {\n        if (order >= -1021)\n            return 53;\n        else if (order <= -1074)\n            return 0;\n        else\n            return order + 1074;\n    }\n\nprivate:\n    static const int kSignificandSize = 52;\n    static const int kExponentBias = 0x3FF;\n    static const int kDenormalExponent = 1 - kExponentBias;\n    static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);\n    static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);\n    static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);\n    static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);\n\n    union {\n        double d_;\n        uint64_t u_;\n    };\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_IEEE754_\n"
  },
  {
    "path": "third-party/rapidjson/internal/itoa.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ITOA_\n#define RAPIDJSON_ITOA_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\ninline const char* GetDigitsLut() {\n    static const char cDigitsLut[200] = {\n        '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',\n        '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',\n        '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',\n        '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',\n        '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',\n        '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',\n        '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',\n        '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',\n        '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',\n        '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'\n    };\n    return cDigitsLut;\n}\n\ninline char* u32toa(uint32_t value, char* buffer) {\n    const char* cDigitsLut = GetDigitsLut();\n\n    if (value < 10000) {\n        const uint32_t d1 = (value / 100) << 1;\n        const uint32_t d2 = (value % 100) << 1;\n        \n        if (value >= 1000)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= 100)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= 10)\n            *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n    }\n    else if (value < 100000000) {\n        // value = bbbbcccc\n        const uint32_t b = value / 10000;\n        const uint32_t c = value % 10000;\n        \n        const uint32_t d1 = (b / 100) << 1;\n        const uint32_t d2 = (b % 100) << 1;\n        \n        const uint32_t d3 = (c / 100) << 1;\n        const uint32_t d4 = (c % 100) << 1;\n        \n        if (value >= 10000000)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= 1000000)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= 100000)\n            *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        \n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n    }\n    else {\n        // value = aabbbbcccc in decimal\n        \n        const uint32_t a = value / 100000000; // 1 to 42\n        value %= 100000000;\n        \n        if (a >= 10) {\n            const unsigned i = a << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a));\n\n        const uint32_t b = value / 10000; // 0 to 9999\n        const uint32_t c = value % 10000; // 0 to 9999\n        \n        const uint32_t d1 = (b / 100) << 1;\n        const uint32_t d2 = (b % 100) << 1;\n        \n        const uint32_t d3 = (c / 100) << 1;\n        const uint32_t d4 = (c % 100) << 1;\n        \n        *buffer++ = cDigitsLut[d1];\n        *buffer++ = cDigitsLut[d1 + 1];\n        *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n    }\n    return buffer;\n}\n\ninline char* i32toa(int32_t value, char* buffer) {\n    uint32_t u = static_cast<uint32_t>(value);\n    if (value < 0) {\n        *buffer++ = '-';\n        u = ~u + 1;\n    }\n\n    return u32toa(u, buffer);\n}\n\ninline char* u64toa(uint64_t value, char* buffer) {\n    const char* cDigitsLut = GetDigitsLut();\n    const uint64_t  kTen8 = 100000000;\n    const uint64_t  kTen9 = kTen8 * 10;\n    const uint64_t kTen10 = kTen8 * 100;\n    const uint64_t kTen11 = kTen8 * 1000;\n    const uint64_t kTen12 = kTen8 * 10000;\n    const uint64_t kTen13 = kTen8 * 100000;\n    const uint64_t kTen14 = kTen8 * 1000000;\n    const uint64_t kTen15 = kTen8 * 10000000;\n    const uint64_t kTen16 = kTen8 * kTen8;\n    \n    if (value < kTen8) {\n        uint32_t v = static_cast<uint32_t>(value);\n        if (v < 10000) {\n            const uint32_t d1 = (v / 100) << 1;\n            const uint32_t d2 = (v % 100) << 1;\n            \n            if (v >= 1000)\n                *buffer++ = cDigitsLut[d1];\n            if (v >= 100)\n                *buffer++ = cDigitsLut[d1 + 1];\n            if (v >= 10)\n                *buffer++ = cDigitsLut[d2];\n            *buffer++ = cDigitsLut[d2 + 1];\n        }\n        else {\n            // value = bbbbcccc\n            const uint32_t b = v / 10000;\n            const uint32_t c = v % 10000;\n            \n            const uint32_t d1 = (b / 100) << 1;\n            const uint32_t d2 = (b % 100) << 1;\n            \n            const uint32_t d3 = (c / 100) << 1;\n            const uint32_t d4 = (c % 100) << 1;\n            \n            if (value >= 10000000)\n                *buffer++ = cDigitsLut[d1];\n            if (value >= 1000000)\n                *buffer++ = cDigitsLut[d1 + 1];\n            if (value >= 100000)\n                *buffer++ = cDigitsLut[d2];\n            *buffer++ = cDigitsLut[d2 + 1];\n            \n            *buffer++ = cDigitsLut[d3];\n            *buffer++ = cDigitsLut[d3 + 1];\n            *buffer++ = cDigitsLut[d4];\n            *buffer++ = cDigitsLut[d4 + 1];\n        }\n    }\n    else if (value < kTen16) {\n        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);\n        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);\n        \n        const uint32_t b0 = v0 / 10000;\n        const uint32_t c0 = v0 % 10000;\n        \n        const uint32_t d1 = (b0 / 100) << 1;\n        const uint32_t d2 = (b0 % 100) << 1;\n        \n        const uint32_t d3 = (c0 / 100) << 1;\n        const uint32_t d4 = (c0 % 100) << 1;\n\n        const uint32_t b1 = v1 / 10000;\n        const uint32_t c1 = v1 % 10000;\n        \n        const uint32_t d5 = (b1 / 100) << 1;\n        const uint32_t d6 = (b1 % 100) << 1;\n        \n        const uint32_t d7 = (c1 / 100) << 1;\n        const uint32_t d8 = (c1 % 100) << 1;\n\n        if (value >= kTen15)\n            *buffer++ = cDigitsLut[d1];\n        if (value >= kTen14)\n            *buffer++ = cDigitsLut[d1 + 1];\n        if (value >= kTen13)\n            *buffer++ = cDigitsLut[d2];\n        if (value >= kTen12)\n            *buffer++ = cDigitsLut[d2 + 1];\n        if (value >= kTen11)\n            *buffer++ = cDigitsLut[d3];\n        if (value >= kTen10)\n            *buffer++ = cDigitsLut[d3 + 1];\n        if (value >= kTen9)\n            *buffer++ = cDigitsLut[d4];\n        if (value >= kTen8)\n            *buffer++ = cDigitsLut[d4 + 1];\n        \n        *buffer++ = cDigitsLut[d5];\n        *buffer++ = cDigitsLut[d5 + 1];\n        *buffer++ = cDigitsLut[d6];\n        *buffer++ = cDigitsLut[d6 + 1];\n        *buffer++ = cDigitsLut[d7];\n        *buffer++ = cDigitsLut[d7 + 1];\n        *buffer++ = cDigitsLut[d8];\n        *buffer++ = cDigitsLut[d8 + 1];\n    }\n    else {\n        const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844\n        value %= kTen16;\n        \n        if (a < 10)\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a));\n        else if (a < 100) {\n            const uint32_t i = a << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else if (a < 1000) {\n            *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));\n            \n            const uint32_t i = (a % 100) << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n        }\n        else {\n            const uint32_t i = (a / 100) << 1;\n            const uint32_t j = (a % 100) << 1;\n            *buffer++ = cDigitsLut[i];\n            *buffer++ = cDigitsLut[i + 1];\n            *buffer++ = cDigitsLut[j];\n            *buffer++ = cDigitsLut[j + 1];\n        }\n        \n        const uint32_t v0 = static_cast<uint32_t>(value / kTen8);\n        const uint32_t v1 = static_cast<uint32_t>(value % kTen8);\n        \n        const uint32_t b0 = v0 / 10000;\n        const uint32_t c0 = v0 % 10000;\n        \n        const uint32_t d1 = (b0 / 100) << 1;\n        const uint32_t d2 = (b0 % 100) << 1;\n        \n        const uint32_t d3 = (c0 / 100) << 1;\n        const uint32_t d4 = (c0 % 100) << 1;\n        \n        const uint32_t b1 = v1 / 10000;\n        const uint32_t c1 = v1 % 10000;\n        \n        const uint32_t d5 = (b1 / 100) << 1;\n        const uint32_t d6 = (b1 % 100) << 1;\n        \n        const uint32_t d7 = (c1 / 100) << 1;\n        const uint32_t d8 = (c1 % 100) << 1;\n        \n        *buffer++ = cDigitsLut[d1];\n        *buffer++ = cDigitsLut[d1 + 1];\n        *buffer++ = cDigitsLut[d2];\n        *buffer++ = cDigitsLut[d2 + 1];\n        *buffer++ = cDigitsLut[d3];\n        *buffer++ = cDigitsLut[d3 + 1];\n        *buffer++ = cDigitsLut[d4];\n        *buffer++ = cDigitsLut[d4 + 1];\n        *buffer++ = cDigitsLut[d5];\n        *buffer++ = cDigitsLut[d5 + 1];\n        *buffer++ = cDigitsLut[d6];\n        *buffer++ = cDigitsLut[d6 + 1];\n        *buffer++ = cDigitsLut[d7];\n        *buffer++ = cDigitsLut[d7 + 1];\n        *buffer++ = cDigitsLut[d8];\n        *buffer++ = cDigitsLut[d8 + 1];\n    }\n    \n    return buffer;\n}\n\ninline char* i64toa(int64_t value, char* buffer) {\n    uint64_t u = static_cast<uint64_t>(value);\n    if (value < 0) {\n        *buffer++ = '-';\n        u = ~u + 1;\n    }\n\n    return u64toa(u, buffer);\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ITOA_\n"
  },
  {
    "path": "third-party/rapidjson/internal/meta.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_META_H_\n#define RAPIDJSON_INTERNAL_META_H_\n\n#include \"../rapidjson.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n#if defined(_MSC_VER)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(6334)\n#endif\n\n#if RAPIDJSON_HAS_CXX11_TYPETRAITS\n#include <type_traits>\n#endif\n\n//@cond RAPIDJSON_INTERNAL\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching\ntemplate <typename T> struct Void { typedef void Type; };\n\n///////////////////////////////////////////////////////////////////////////////\n// BoolType, TrueType, FalseType\n//\ntemplate <bool Cond> struct BoolType {\n    static const bool Value = Cond;\n    typedef BoolType Type;\n};\ntypedef BoolType<true> TrueType;\ntypedef BoolType<false> FalseType;\n\n\n///////////////////////////////////////////////////////////////////////////////\n// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr\n//\n\ntemplate <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };\ntemplate <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };\ntemplate <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};\ntemplate <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};\n\ntemplate <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};\ntemplate <> struct AndExprCond<true, true> : TrueType {};\ntemplate <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};\ntemplate <> struct OrExprCond<false, false> : FalseType {};\n\ntemplate <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};\ntemplate <typename C> struct NotExpr  : SelectIf<C,FalseType,TrueType>::Type {};\ntemplate <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};\ntemplate <typename C1, typename C2> struct OrExpr  : OrExprCond<C1::Value, C2::Value>::Type {};\n\n\n///////////////////////////////////////////////////////////////////////////////\n// AddConst, MaybeAddConst, RemoveConst\ntemplate <typename T> struct AddConst { typedef const T Type; };\ntemplate <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};\ntemplate <typename T> struct RemoveConst { typedef T Type; };\ntemplate <typename T> struct RemoveConst<const T> { typedef T Type; };\n\n\n///////////////////////////////////////////////////////////////////////////////\n// IsSame, IsConst, IsMoreConst, IsPointer\n//\ntemplate <typename T, typename U> struct IsSame : FalseType {};\ntemplate <typename T> struct IsSame<T, T> : TrueType {};\n\ntemplate <typename T> struct IsConst : FalseType {};\ntemplate <typename T> struct IsConst<const T> : TrueType {};\n\ntemplate <typename CT, typename T>\nstruct IsMoreConst\n    : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,\n              BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};\n\ntemplate <typename T> struct IsPointer : FalseType {};\ntemplate <typename T> struct IsPointer<T*> : TrueType {};\n\n///////////////////////////////////////////////////////////////////////////////\n// IsBaseOf\n//\n#if RAPIDJSON_HAS_CXX11_TYPETRAITS\n\ntemplate <typename B, typename D> struct IsBaseOf\n    : BoolType< ::std::is_base_of<B,D>::value> {};\n\n#else // simplified version adopted from Boost\n\ntemplate<typename B, typename D> struct IsBaseOfImpl {\n    RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);\n    RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);\n\n    typedef char (&Yes)[1];\n    typedef char (&No) [2];\n\n    template <typename T>\n    static Yes Check(const D*, T);\n    static No  Check(const B*, int);\n\n    struct Host {\n        operator const B*() const;\n        operator const D*();\n    };\n\n    enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };\n};\n\ntemplate <typename B, typename D> struct IsBaseOf\n    : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};\n\n#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS\n\n\n//////////////////////////////////////////////////////////////////////////\n// EnableIf / DisableIf\n//\ntemplate <bool Condition, typename T = void> struct EnableIfCond  { typedef T Type; };\ntemplate <typename T> struct EnableIfCond<false, T> { /* empty */ };\n\ntemplate <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };\ntemplate <typename T> struct DisableIfCond<true, T> { /* empty */ };\n\ntemplate <typename Condition, typename T = void>\nstruct EnableIf : EnableIfCond<Condition::Value, T> {};\n\ntemplate <typename Condition, typename T = void>\nstruct DisableIf : DisableIfCond<Condition::Value, T> {};\n\n// SFINAE helpers\nstruct SfinaeTag {};\ntemplate <typename T> struct RemoveSfinaeTag;\ntemplate <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };\n\n#define RAPIDJSON_REMOVEFPTR_(type) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \\\n        < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type\n\n#define RAPIDJSON_ENABLEIF(cond) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL\n\n#define RAPIDJSON_DISABLEIF(cond) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL\n\n#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond), \\\n         RAPIDJSON_REMOVEFPTR_(returntype)>::Type\n\n#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \\\n    typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \\\n        <RAPIDJSON_REMOVEFPTR_(cond), \\\n         RAPIDJSON_REMOVEFPTR_(returntype)>::Type\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n//@endcond\n\n#if defined(__GNUC__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_META_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/pow10.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_POW10_\n#define RAPIDJSON_POW10_\n\n#include \"../rapidjson.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Computes integer powers of 10 in double (10.0^n).\n/*! This function uses lookup table for fast and accurate results.\n    \\param n non-negative exponent. Must <= 308.\n    \\return 10.0^n\n*/\ninline double Pow10(int n) {\n    static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes\n        1e+0,  \n        1e+1,  1e+2,  1e+3,  1e+4,  1e+5,  1e+6,  1e+7,  1e+8,  1e+9,  1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, \n        1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,\n        1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,\n        1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,\n        1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,\n        1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,\n        1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,\n        1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,\n        1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,\n        1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,\n        1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,\n        1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,\n        1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,\n        1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,\n        1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,\n        1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308\n    };\n    RAPIDJSON_ASSERT(n >= 0 && n <= 308);\n    return e[n];\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_POW10_\n"
  },
  {
    "path": "third-party/rapidjson/internal/regex.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_REGEX_H_\n#define RAPIDJSON_INTERNAL_REGEX_H_\n\n#include \"../allocators.h\"\n#include \"../stream.h\"\n#include \"stack.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\nRAPIDJSON_DIAG_OFF(implicit-fallthrough)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#if __GNUC__ >= 7\nRAPIDJSON_DIAG_OFF(implicit-fallthrough)\n#endif\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\n#ifndef RAPIDJSON_REGEX_VERBOSE\n#define RAPIDJSON_REGEX_VERBOSE 0\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n///////////////////////////////////////////////////////////////////////////////\n// DecodedStream\n\ntemplate <typename SourceStream, typename Encoding>\nclass DecodedStream {\npublic:\n    DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); }\n    unsigned Peek() { return codepoint_; }\n    unsigned Take() {\n        unsigned c = codepoint_;\n        if (c) // No further decoding when '\\0'\n            Decode();\n        return c;\n    }\n\nprivate:\n    void Decode() {\n        if (!Encoding::Decode(ss_, &codepoint_))\n            codepoint_ = 0;\n    }\n\n    SourceStream& ss_;\n    unsigned codepoint_;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericRegex\n\nstatic const SizeType kRegexInvalidState = ~SizeType(0);  //!< Represents an invalid index in GenericRegex::State::out, out1\nstatic const SizeType kRegexInvalidRange = ~SizeType(0);\n\ntemplate <typename Encoding, typename Allocator>\nclass GenericRegexSearch;\n\n//! Regular expression engine with subset of ECMAscript grammar.\n/*!\n    Supported regular expression syntax:\n    - \\c ab     Concatenation\n    - \\c a|b    Alternation\n    - \\c a?     Zero or one\n    - \\c a*     Zero or more\n    - \\c a+     One or more\n    - \\c a{3}   Exactly 3 times\n    - \\c a{3,}  At least 3 times\n    - \\c a{3,5} 3 to 5 times\n    - \\c (ab)   Grouping\n    - \\c ^a     At the beginning\n    - \\c a$     At the end\n    - \\c .      Any character\n    - \\c [abc]  Character classes\n    - \\c [a-c]  Character class range\n    - \\c [a-z0-9_] Character class combination\n    - \\c [^abc] Negated character classes\n    - \\c [^a-c] Negated character class range\n    - \\c [\\b]   Backspace (U+0008)\n    - \\c \\\\| \\\\\\\\ ...  Escape characters\n    - \\c \\\\f Form feed (U+000C)\n    - \\c \\\\n Line feed (U+000A)\n    - \\c \\\\r Carriage return (U+000D)\n    - \\c \\\\t Tab (U+0009)\n    - \\c \\\\v Vertical tab (U+000B)\n\n    \\note This is a Thompson NFA engine, implemented with reference to \n        Cox, Russ. \"Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).\", \n        https://swtch.com/~rsc/regexp/regexp1.html \n*/\ntemplate <typename Encoding, typename Allocator = CrtAllocator>\nclass GenericRegex {\npublic:\n    typedef Encoding EncodingType;\n    typedef typename Encoding::Ch Ch;\n    template <typename, typename> friend class GenericRegexSearch;\n\n    GenericRegex(const Ch* source, Allocator* allocator = 0) : \n        states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), \n        anchorBegin_(), anchorEnd_()\n    {\n        GenericStringStream<Encoding> ss(source);\n        DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);\n        Parse(ds);\n    }\n\n    ~GenericRegex() {}\n\n    bool IsValid() const {\n        return root_ != kRegexInvalidState;\n    }\n\nprivate:\n    enum Operator {\n        kZeroOrOne,\n        kZeroOrMore,\n        kOneOrMore,\n        kConcatenation,\n        kAlternation,\n        kLeftParenthesis\n    };\n\n    static const unsigned kAnyCharacterClass = 0xFFFFFFFF;   //!< For '.'\n    static const unsigned kRangeCharacterClass = 0xFFFFFFFE;\n    static const unsigned kRangeNegationFlag = 0x80000000;\n\n    struct Range {\n        unsigned start; // \n        unsigned end;\n        SizeType next;\n    };\n\n    struct State {\n        SizeType out;     //!< Equals to kInvalid for matching state\n        SizeType out1;    //!< Equals to non-kInvalid for split\n        SizeType rangeStart;\n        unsigned codepoint;\n    };\n\n    struct Frag {\n        Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {}\n        SizeType start;\n        SizeType out; //!< link-list of all output states\n        SizeType minIndex;\n    };\n\n    State& GetState(SizeType index) {\n        RAPIDJSON_ASSERT(index < stateCount_);\n        return states_.template Bottom<State>()[index];\n    }\n\n    const State& GetState(SizeType index) const {\n        RAPIDJSON_ASSERT(index < stateCount_);\n        return states_.template Bottom<State>()[index];\n    }\n\n    Range& GetRange(SizeType index) {\n        RAPIDJSON_ASSERT(index < rangeCount_);\n        return ranges_.template Bottom<Range>()[index];\n    }\n\n    const Range& GetRange(SizeType index) const {\n        RAPIDJSON_ASSERT(index < rangeCount_);\n        return ranges_.template Bottom<Range>()[index];\n    }\n\n    template <typename InputStream>\n    void Parse(DecodedStream<InputStream, Encoding>& ds) {\n        Allocator allocator;\n        Stack<Allocator> operandStack(&allocator, 256);     // Frag\n        Stack<Allocator> operatorStack(&allocator, 256);    // Operator\n        Stack<Allocator> atomCountStack(&allocator, 256);   // unsigned (Atom per parenthesis)\n\n        *atomCountStack.template Push<unsigned>() = 0;\n\n        unsigned codepoint;\n        while (ds.Peek() != 0) {\n            switch (codepoint = ds.Take()) {\n                case '^':\n                    anchorBegin_ = true;\n                    break;\n\n                case '$':\n                    anchorEnd_ = true;\n                    break;\n\n                case '|':\n                    while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation)\n                        if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                            return;\n                    *operatorStack.template Push<Operator>() = kAlternation;\n                    *atomCountStack.template Top<unsigned>() = 0;\n                    break;\n\n                case '(':\n                    *operatorStack.template Push<Operator>() = kLeftParenthesis;\n                    *atomCountStack.template Push<unsigned>() = 0;\n                    break;\n\n                case ')':\n                    while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis)\n                        if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                            return;\n                    if (operatorStack.Empty())\n                        return;\n                    operatorStack.template Pop<Operator>(1);\n                    atomCountStack.template Pop<unsigned>(1);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '?':\n                    if (!Eval(operandStack, kZeroOrOne))\n                        return;\n                    break;\n\n                case '*':\n                    if (!Eval(operandStack, kZeroOrMore))\n                        return;\n                    break;\n\n                case '+':\n                    if (!Eval(operandStack, kOneOrMore))\n                        return;\n                    break;\n\n                case '{':\n                    {\n                        unsigned n, m;\n                        if (!ParseUnsigned(ds, &n))\n                            return;\n\n                        if (ds.Peek() == ',') {\n                            ds.Take();\n                            if (ds.Peek() == '}')\n                                m = kInfinityQuantifier;\n                            else if (!ParseUnsigned(ds, &m) || m < n)\n                                return;\n                        }\n                        else\n                            m = n;\n\n                        if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')\n                            return;\n                        ds.Take();\n                    }\n                    break;\n\n                case '.':\n                    PushOperand(operandStack, kAnyCharacterClass);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '[':\n                    {\n                        SizeType range;\n                        if (!ParseRange(ds, &range))\n                            return;\n                        SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass);\n                        GetState(s).rangeStart = range;\n                        *operandStack.template Push<Frag>() = Frag(s, s, s);\n                    }\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n                    break;\n\n                case '\\\\': // Escape character\n                    if (!CharacterEscape(ds, &codepoint))\n                        return; // Unsupported escape character\n                    // fall through to default\n\n                default: // Pattern character\n                    PushOperand(operandStack, codepoint);\n                    ImplicitConcatenation(atomCountStack, operatorStack);\n            }\n        }\n\n        while (!operatorStack.Empty())\n            if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))\n                return;\n\n        // Link the operand to matching state.\n        if (operandStack.GetSize() == sizeof(Frag)) {\n            Frag* e = operandStack.template Pop<Frag>(1);\n            Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0));\n            root_ = e->start;\n\n#if RAPIDJSON_REGEX_VERBOSE\n            printf(\"root: %d\\n\", root_);\n            for (SizeType i = 0; i < stateCount_ ; i++) {\n                State& s = GetState(i);\n                printf(\"[%2d] out: %2d out1: %2d c: '%c'\\n\", i, s.out, s.out1, (char)s.codepoint);\n            }\n            printf(\"\\n\");\n#endif\n        }\n    }\n\n    SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) {\n        State* s = states_.template Push<State>();\n        s->out = out;\n        s->out1 = out1;\n        s->codepoint = codepoint;\n        s->rangeStart = kRegexInvalidRange;\n        return stateCount_++;\n    }\n\n    void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) {\n        SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint);\n        *operandStack.template Push<Frag>() = Frag(s, s, s);\n    }\n\n    void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) {\n        if (*atomCountStack.template Top<unsigned>())\n            *operatorStack.template Push<Operator>() = kConcatenation;\n        (*atomCountStack.template Top<unsigned>())++;\n    }\n\n    SizeType Append(SizeType l1, SizeType l2) {\n        SizeType old = l1;\n        while (GetState(l1).out != kRegexInvalidState)\n            l1 = GetState(l1).out;\n        GetState(l1).out = l2;\n        return old;\n    }\n\n    void Patch(SizeType l, SizeType s) {\n        for (SizeType next; l != kRegexInvalidState; l = next) {\n            next = GetState(l).out;\n            GetState(l).out = s;\n        }\n    }\n\n    bool Eval(Stack<Allocator>& operandStack, Operator op) {\n        switch (op) {\n            case kConcatenation:\n                RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2);\n                {\n                    Frag e2 = *operandStack.template Pop<Frag>(1);\n                    Frag e1 = *operandStack.template Pop<Frag>(1);\n                    Patch(e1.out, e2.start);\n                    *operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex));\n                }\n                return true;\n\n            case kAlternation:\n                if (operandStack.GetSize() >= sizeof(Frag) * 2) {\n                    Frag e2 = *operandStack.template Pop<Frag>(1);\n                    Frag e1 = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(e1.start, e2.start, 0);\n                    *operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex));\n                    return true;\n                }\n                return false;\n\n            case kZeroOrOne:\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    *operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex);\n                    return true;\n                }\n                return false;\n\n            case kZeroOrMore:\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    Patch(e.out, s);\n                    *operandStack.template Push<Frag>() = Frag(s, s, e.minIndex);\n                    return true;\n                }\n                return false;\n\n            default: \n                RAPIDJSON_ASSERT(op == kOneOrMore);\n                if (operandStack.GetSize() >= sizeof(Frag)) {\n                    Frag e = *operandStack.template Pop<Frag>(1);\n                    SizeType s = NewState(kRegexInvalidState, e.start, 0);\n                    Patch(e.out, s);\n                    *operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex);\n                    return true;\n                }\n                return false;\n        }\n    }\n\n    bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) {\n        RAPIDJSON_ASSERT(n <= m);\n        RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag));\n\n        if (n == 0) {\n            if (m == 0)                             // a{0} not support\n                return false;\n            else if (m == kInfinityQuantifier)\n                Eval(operandStack, kZeroOrMore);    // a{0,} -> a*\n            else {\n                Eval(operandStack, kZeroOrOne);         // a{0,5} -> a?\n                for (unsigned i = 0; i < m - 1; i++)\n                    CloneTopOperand(operandStack);      // a{0,5} -> a? a? a? a? a?\n                for (unsigned i = 0; i < m - 1; i++)\n                    Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a?\n            }\n            return true;\n        }\n\n        for (unsigned i = 0; i < n - 1; i++)        // a{3} -> a a a\n            CloneTopOperand(operandStack);\n\n        if (m == kInfinityQuantifier)\n            Eval(operandStack, kOneOrMore);         // a{3,} -> a a a+\n        else if (m > n) {\n            CloneTopOperand(operandStack);          // a{3,5} -> a a a a\n            Eval(operandStack, kZeroOrOne);         // a{3,5} -> a a a a?\n            for (unsigned i = n; i < m - 1; i++)\n                CloneTopOperand(operandStack);      // a{3,5} -> a a a a? a?\n            for (unsigned i = n; i < m; i++)\n                Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a?\n        }\n\n        for (unsigned i = 0; i < n - 1; i++)\n            Eval(operandStack, kConcatenation);     // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a?\n\n        return true;\n    }\n\n    static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; }\n\n    void CloneTopOperand(Stack<Allocator>& operandStack) {\n        const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation\n        SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_)\n        State* s = states_.template Push<State>(count);\n        memcpy(s, &GetState(src.minIndex), count * sizeof(State));\n        for (SizeType j = 0; j < count; j++) {\n            if (s[j].out != kRegexInvalidState)\n                s[j].out += count;\n            if (s[j].out1 != kRegexInvalidState)\n                s[j].out1 += count;\n        }\n        *operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count);\n        stateCount_ += count;\n    }\n\n    template <typename InputStream>\n    bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) {\n        unsigned r = 0;\n        if (ds.Peek() < '0' || ds.Peek() > '9')\n            return false;\n        while (ds.Peek() >= '0' && ds.Peek() <= '9') {\n            if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295\n                return false; // overflow\n            r = r * 10 + (ds.Take() - '0');\n        }\n        *u = r;\n        return true;\n    }\n\n    template <typename InputStream>\n    bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) {\n        bool isBegin = true;\n        bool negate = false;\n        int step = 0;\n        SizeType start = kRegexInvalidRange;\n        SizeType current = kRegexInvalidRange;\n        unsigned codepoint;\n        while ((codepoint = ds.Take()) != 0) {\n            if (isBegin) {\n                isBegin = false;\n                if (codepoint == '^') {\n                    negate = true;\n                    continue;\n                }\n            }\n\n            switch (codepoint) {\n            case ']':\n                if (start == kRegexInvalidRange)\n                    return false;   // Error: nothing inside []\n                if (step == 2) { // Add trailing '-'\n                    SizeType r = NewRange('-');\n                    RAPIDJSON_ASSERT(current != kRegexInvalidRange);\n                    GetRange(current).next = r;\n                }\n                if (negate)\n                    GetRange(start).start |= kRangeNegationFlag;\n                *range = start;\n                return true;\n\n            case '\\\\':\n                if (ds.Peek() == 'b') {\n                    ds.Take();\n                    codepoint = 0x0008; // Escape backspace character\n                }\n                else if (!CharacterEscape(ds, &codepoint))\n                    return false;\n                // fall through to default\n\n            default:\n                switch (step) {\n                case 1:\n                    if (codepoint == '-') {\n                        step++;\n                        break;\n                    }\n                    // fall through to step 0 for other characters\n\n                case 0:\n                    {\n                        SizeType r = NewRange(codepoint);\n                        if (current != kRegexInvalidRange)\n                            GetRange(current).next = r;\n                        if (start == kRegexInvalidRange)\n                            start = r;\n                        current = r;\n                    }\n                    step = 1;\n                    break;\n\n                default:\n                    RAPIDJSON_ASSERT(step == 2);\n                    GetRange(current).end = codepoint;\n                    step = 0;\n                }\n            }\n        }\n        return false;\n    }\n    \n    SizeType NewRange(unsigned codepoint) {\n        Range* r = ranges_.template Push<Range>();\n        r->start = r->end = codepoint;\n        r->next = kRegexInvalidRange;\n        return rangeCount_++;\n    }\n\n    template <typename InputStream>\n    bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) {\n        unsigned codepoint;\n        switch (codepoint = ds.Take()) {\n            case '^':\n            case '$':\n            case '|':\n            case '(':\n            case ')':\n            case '?':\n            case '*':\n            case '+':\n            case '.':\n            case '[':\n            case ']':\n            case '{':\n            case '}':\n            case '\\\\':\n                *escapedCodepoint = codepoint; return true;\n            case 'f': *escapedCodepoint = 0x000C; return true;\n            case 'n': *escapedCodepoint = 0x000A; return true;\n            case 'r': *escapedCodepoint = 0x000D; return true;\n            case 't': *escapedCodepoint = 0x0009; return true;\n            case 'v': *escapedCodepoint = 0x000B; return true;\n            default:\n                return false; // Unsupported escape character\n        }\n    }\n\n    Stack<Allocator> states_;\n    Stack<Allocator> ranges_;\n    SizeType root_;\n    SizeType stateCount_;\n    SizeType rangeCount_;\n\n    static const unsigned kInfinityQuantifier = ~0u;\n\n    // For SearchWithAnchoring()\n    bool anchorBegin_;\n    bool anchorEnd_;\n};\n\ntemplate <typename RegexType, typename Allocator = CrtAllocator>\nclass GenericRegexSearch {\npublic:\n    typedef typename RegexType::EncodingType Encoding;\n    typedef typename Encoding::Ch Ch;\n\n    GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : \n        regex_(regex), allocator_(allocator), ownAllocator_(0),\n        state0_(allocator, 0), state1_(allocator, 0), stateSet_()\n    {\n        RAPIDJSON_ASSERT(regex_.IsValid());\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n        stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));\n        state0_.template Reserve<SizeType>(regex_.stateCount_);\n        state1_.template Reserve<SizeType>(regex_.stateCount_);\n    }\n\n    ~GenericRegexSearch() {\n        Allocator::Free(stateSet_);\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    template <typename InputStream>\n    bool Match(InputStream& is) {\n        return SearchWithAnchoring(is, true, true);\n    }\n\n    bool Match(const Ch* s) {\n        GenericStringStream<Encoding> is(s);\n        return Match(is);\n    }\n\n    template <typename InputStream>\n    bool Search(InputStream& is) {\n        return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_);\n    }\n\n    bool Search(const Ch* s) {\n        GenericStringStream<Encoding> is(s);\n        return Search(is);\n    }\n\nprivate:\n    typedef typename RegexType::State State;\n    typedef typename RegexType::Range Range;\n\n    template <typename InputStream>\n    bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) {\n        DecodedStream<InputStream, Encoding> ds(is);\n\n        state0_.Clear();\n        Stack<Allocator> *current = &state0_, *next = &state1_;\n        const size_t stateSetSize = GetStateSetSize();\n        std::memset(stateSet_, 0, stateSetSize);\n\n        bool matched = AddState(*current, regex_.root_);\n        unsigned codepoint;\n        while (!current->Empty() && (codepoint = ds.Take()) != 0) {\n            std::memset(stateSet_, 0, stateSetSize);\n            next->Clear();\n            matched = false;\n            for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) {\n                const State& sr = regex_.GetState(*s);\n                if (sr.codepoint == codepoint ||\n                    sr.codepoint == RegexType::kAnyCharacterClass || \n                    (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))\n                {\n                    matched = AddState(*next, sr.out) || matched;\n                    if (!anchorEnd && matched)\n                        return true;\n                }\n                if (!anchorBegin)\n                    AddState(*next, regex_.root_);\n            }\n            internal::Swap(current, next);\n        }\n\n        return matched;\n    }\n\n    size_t GetStateSetSize() const {\n        return (regex_.stateCount_ + 31) / 32 * 4;\n    }\n\n    // Return whether the added states is a match state\n    bool AddState(Stack<Allocator>& l, SizeType index) {\n        RAPIDJSON_ASSERT(index != kRegexInvalidState);\n\n        const State& s = regex_.GetState(index);\n        if (s.out1 != kRegexInvalidState) { // Split\n            bool matched = AddState(l, s.out);\n            return AddState(l, s.out1) || matched;\n        }\n        else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) {\n            stateSet_[index >> 5] |= (1u << (index & 31));\n            *l.template PushUnsafe<SizeType>() = index;\n        }\n        return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.\n    }\n\n    bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {\n        bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0;\n        while (rangeIndex != kRegexInvalidRange) {\n            const Range& r = regex_.GetRange(rangeIndex);\n            if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end)\n                return yes;\n            rangeIndex = r.next;\n        }\n        return !yes;\n    }\n\n    const RegexType& regex_;\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    Stack<Allocator> state0_;\n    Stack<Allocator> state1_;\n    uint32_t* stateSet_;\n};\n\ntypedef GenericRegex<UTF8<> > Regex;\ntypedef GenericRegexSearch<Regex> RegexSearch;\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_REGEX_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/stack.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_STACK_H_\n#define RAPIDJSON_INTERNAL_STACK_H_\n\n#include \"../allocators.h\"\n#include \"swap.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n///////////////////////////////////////////////////////////////////////////////\n// Stack\n\n//! A type-unsafe stack for storing different types of data.\n/*! \\tparam Allocator Allocator for allocating stack memory.\n*/\ntemplate <typename Allocator>\nclass Stack {\npublic:\n    // Optimization note: Do not allocate memory for stack_ in constructor.\n    // Do it lazily when first Push() -> Expand() -> Resize().\n    Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Stack(Stack&& rhs)\n        : allocator_(rhs.allocator_),\n          ownAllocator_(rhs.ownAllocator_),\n          stack_(rhs.stack_),\n          stackTop_(rhs.stackTop_),\n          stackEnd_(rhs.stackEnd_),\n          initialCapacity_(rhs.initialCapacity_)\n    {\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.stack_ = 0;\n        rhs.stackTop_ = 0;\n        rhs.stackEnd_ = 0;\n        rhs.initialCapacity_ = 0;\n    }\n#endif\n\n    ~Stack() {\n        Destroy();\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Stack& operator=(Stack&& rhs) {\n        if (&rhs != this)\n        {\n            Destroy();\n\n            allocator_ = rhs.allocator_;\n            ownAllocator_ = rhs.ownAllocator_;\n            stack_ = rhs.stack_;\n            stackTop_ = rhs.stackTop_;\n            stackEnd_ = rhs.stackEnd_;\n            initialCapacity_ = rhs.initialCapacity_;\n\n            rhs.allocator_ = 0;\n            rhs.ownAllocator_ = 0;\n            rhs.stack_ = 0;\n            rhs.stackTop_ = 0;\n            rhs.stackEnd_ = 0;\n            rhs.initialCapacity_ = 0;\n        }\n        return *this;\n    }\n#endif\n\n    void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {\n        internal::Swap(allocator_, rhs.allocator_);\n        internal::Swap(ownAllocator_, rhs.ownAllocator_);\n        internal::Swap(stack_, rhs.stack_);\n        internal::Swap(stackTop_, rhs.stackTop_);\n        internal::Swap(stackEnd_, rhs.stackEnd_);\n        internal::Swap(initialCapacity_, rhs.initialCapacity_);\n    }\n\n    void Clear() { stackTop_ = stack_; }\n\n    void ShrinkToFit() { \n        if (Empty()) {\n            // If the stack is empty, completely deallocate the memory.\n            Allocator::Free(stack_);\n            stack_ = 0;\n            stackTop_ = 0;\n            stackEnd_ = 0;\n        }\n        else\n            Resize(GetSize());\n    }\n\n    // Optimization note: try to minimize the size of this function for force inline.\n    // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.\n    template<typename T>\n    RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {\n         // Expand the stack if needed\n        if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))\n            Expand<T>(count);\n    }\n\n    template<typename T>\n    RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {\n        Reserve<T>(count);\n        return PushUnsafe<T>(count);\n    }\n\n    template<typename T>\n    RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {\n        RAPIDJSON_ASSERT(stackTop_);\n        RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);\n        T* ret = reinterpret_cast<T*>(stackTop_);\n        stackTop_ += sizeof(T) * count;\n        return ret;\n    }\n\n    template<typename T>\n    T* Pop(size_t count) {\n        RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));\n        stackTop_ -= count * sizeof(T);\n        return reinterpret_cast<T*>(stackTop_);\n    }\n\n    template<typename T>\n    T* Top() { \n        RAPIDJSON_ASSERT(GetSize() >= sizeof(T));\n        return reinterpret_cast<T*>(stackTop_ - sizeof(T));\n    }\n\n    template<typename T>\n    const T* Top() const {\n        RAPIDJSON_ASSERT(GetSize() >= sizeof(T));\n        return reinterpret_cast<T*>(stackTop_ - sizeof(T));\n    }\n\n    template<typename T>\n    T* End() { return reinterpret_cast<T*>(stackTop_); }\n\n    template<typename T>\n    const T* End() const { return reinterpret_cast<T*>(stackTop_); }\n\n    template<typename T>\n    T* Bottom() { return reinterpret_cast<T*>(stack_); }\n\n    template<typename T>\n    const T* Bottom() const { return reinterpret_cast<T*>(stack_); }\n\n    bool HasAllocator() const {\n        return allocator_ != 0;\n    }\n\n    Allocator& GetAllocator() {\n        RAPIDJSON_ASSERT(allocator_);\n        return *allocator_;\n    }\n\n    bool Empty() const { return stackTop_ == stack_; }\n    size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }\n    size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }\n\nprivate:\n    template<typename T>\n    void Expand(size_t count) {\n        // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.\n        size_t newCapacity;\n        if (stack_ == 0) {\n            if (!allocator_)\n                ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n            newCapacity = initialCapacity_;\n        } else {\n            newCapacity = GetCapacity();\n            newCapacity += (newCapacity + 1) / 2;\n        }\n        size_t newSize = GetSize() + sizeof(T) * count;\n        if (newCapacity < newSize)\n            newCapacity = newSize;\n\n        Resize(newCapacity);\n    }\n\n    void Resize(size_t newCapacity) {\n        const size_t size = GetSize();  // Backup the current size\n        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));\n        stackTop_ = stack_ + size;\n        stackEnd_ = stack_ + newCapacity;\n    }\n\n    void Destroy() {\n        Allocator::Free(stack_);\n        RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack\n    }\n\n    // Prohibit copy constructor & assignment operator.\n    Stack(const Stack&);\n    Stack& operator=(const Stack&);\n\n    Allocator* allocator_;\n    Allocator* ownAllocator_;\n    char *stack_;\n    char *stackTop_;\n    char *stackEnd_;\n    size_t initialCapacity_;\n};\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_STACK_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/strfunc.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_\n#define RAPIDJSON_INTERNAL_STRFUNC_H_\n\n#include \"../stream.h\"\n#include <cwchar>\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Custom strlen() which works on different character types.\n/*! \\tparam Ch Character type (e.g. char, wchar_t, short)\n    \\param s Null-terminated input string.\n    \\return Number of characters in the string. \n    \\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.\n*/\ntemplate <typename Ch>\ninline SizeType StrLen(const Ch* s) {\n    RAPIDJSON_ASSERT(s != 0);\n    const Ch* p = s;\n    while (*p) ++p;\n    return SizeType(p - s);\n}\n\ntemplate <>\ninline SizeType StrLen(const char* s) {\n    return SizeType(std::strlen(s));\n}\n\ntemplate <>\ninline SizeType StrLen(const wchar_t* s) {\n    return SizeType(std::wcslen(s));\n}\n\n//! Returns number of code points in a encoded string.\ntemplate<typename Encoding>\nbool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {\n    RAPIDJSON_ASSERT(s != 0);\n    RAPIDJSON_ASSERT(outCount != 0);\n    GenericStringStream<Encoding> is(s);\n    const typename Encoding::Ch* end = s + length;\n    SizeType count = 0;\n    while (is.src_ < end) {\n        unsigned codepoint;\n        if (!Encoding::Decode(is, &codepoint))\n            return false;\n        count++;\n    }\n    *outCount = count;\n    return true;\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_INTERNAL_STRFUNC_H_\n"
  },
  {
    "path": "third-party/rapidjson/internal/strtod.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_STRTOD_\n#define RAPIDJSON_STRTOD_\n\n#include \"ieee754.h\"\n#include \"biginteger.h\"\n#include \"diyfp.h\"\n#include \"pow10.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\ninline double FastPath(double significand, int exp) {\n    if (exp < -308)\n        return 0.0;\n    else if (exp >= 0)\n        return significand * internal::Pow10(exp);\n    else\n        return significand / internal::Pow10(-exp);\n}\n\ninline double StrtodNormalPrecision(double d, int p) {\n    if (p < -308) {\n        // Prevent expSum < -308, making Pow10(p) = 0\n        d = FastPath(d, -308);\n        d = FastPath(d, p + 308);\n    }\n    else\n        d = FastPath(d, p);\n    return d;\n}\n\ntemplate <typename T>\ninline T Min3(T a, T b, T c) {\n    T m = a;\n    if (m > b) m = b;\n    if (m > c) m = c;\n    return m;\n}\n\ninline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {\n    const Double db(b);\n    const uint64_t bInt = db.IntegerSignificand();\n    const int bExp = db.IntegerExponent();\n    const int hExp = bExp - 1;\n\n    int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;\n\n    // Adjust for decimal exponent\n    if (dExp >= 0) {\n        dS_Exp2 += dExp;\n        dS_Exp5 += dExp;\n    }\n    else {\n        bS_Exp2 -= dExp;\n        bS_Exp5 -= dExp;\n        hS_Exp2 -= dExp;\n        hS_Exp5 -= dExp;\n    }\n\n    // Adjust for binary exponent\n    if (bExp >= 0)\n        bS_Exp2 += bExp;\n    else {\n        dS_Exp2 -= bExp;\n        hS_Exp2 -= bExp;\n    }\n\n    // Adjust for half ulp exponent\n    if (hExp >= 0)\n        hS_Exp2 += hExp;\n    else {\n        dS_Exp2 -= hExp;\n        bS_Exp2 -= hExp;\n    }\n\n    // Remove common power of two factor from all three scaled values\n    int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);\n    dS_Exp2 -= common_Exp2;\n    bS_Exp2 -= common_Exp2;\n    hS_Exp2 -= common_Exp2;\n\n    BigInteger dS = d;\n    dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);\n\n    BigInteger bS(bInt);\n    bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);\n\n    BigInteger hS(1);\n    hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);\n\n    BigInteger delta(0);\n    dS.Difference(bS, &delta);\n\n    return delta.Compare(hS);\n}\n\ninline bool StrtodFast(double d, int p, double* result) {\n    // Use fast path for string-to-double conversion if possible\n    // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/\n    if (p > 22  && p < 22 + 16) {\n        // Fast Path Cases In Disguise\n        d *= internal::Pow10(p - 22);\n        p = 22;\n    }\n\n    if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1\n        *result = FastPath(d, p);\n        return true;\n    }\n    else\n        return false;\n}\n\n// Compute an approximation and see if it is within 1/2 ULP\ninline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {\n    uint64_t significand = 0;\n    size_t i = 0;   // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999    \n    for (; i < length; i++) {\n        if (significand  >  RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||\n            (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))\n            break;\n        significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');\n    }\n    \n    if (i < length && decimals[i] >= '5') // Rounding\n        significand++;\n\n    size_t remaining = length - i;\n    const int kUlpShift = 3;\n    const int kUlp = 1 << kUlpShift;\n    int64_t error = (remaining == 0) ? 0 : kUlp / 2;\n\n    DiyFp v(significand, 0);\n    v = v.Normalize();\n    error <<= -v.e;\n\n    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;\n\n    int actualExp;\n    DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);\n    if (actualExp != dExp) {\n        static const DiyFp kPow10[] = {\n            DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60),  // 10^1\n            DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57),  // 10^2\n            DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54),  // 10^3\n            DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50),  // 10^4\n            DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47),  // 10^5\n            DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44),  // 10^6\n            DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40)   // 10^7\n        };\n        int  adjustment = dExp - actualExp - 1;\n        RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);\n        v = v * kPow10[adjustment];\n        if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit\n            error += kUlp / 2;\n    }\n\n    v = v * cachedPower;\n\n    error += kUlp + (error == 0 ? 0 : 1);\n\n    const int oldExp = v.e;\n    v = v.Normalize();\n    error <<= oldExp - v.e;\n\n    const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);\n    int precisionSize = 64 - effectiveSignificandSize;\n    if (precisionSize + kUlpShift >= 64) {\n        int scaleExp = (precisionSize + kUlpShift) - 63;\n        v.f >>= scaleExp;\n        v.e += scaleExp; \n        error = (error >> scaleExp) + 1 + kUlp;\n        precisionSize -= scaleExp;\n    }\n\n    DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);\n    const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;\n    const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;\n    if (precisionBits >= halfWay + static_cast<unsigned>(error)) {\n        rounded.f++;\n        if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)\n            rounded.f >>= 1;\n            rounded.e++;\n        }\n    }\n\n    *result = rounded.ToDouble();\n\n    return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);\n}\n\ninline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {\n    const BigInteger dInt(decimals, length);\n    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;\n    Double a(approx);\n    int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);\n    if (cmp < 0)\n        return a.Value();  // within half ULP\n    else if (cmp == 0) {\n        // Round towards even\n        if (a.Significand() & 1)\n            return a.NextPositiveDouble();\n        else\n            return a.Value();\n    }\n    else // adjustment\n        return a.NextPositiveDouble();\n}\n\ninline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {\n    RAPIDJSON_ASSERT(d >= 0.0);\n    RAPIDJSON_ASSERT(length >= 1);\n\n    double result;\n    if (StrtodFast(d, p, &result))\n        return result;\n\n    // Trim leading zeros\n    while (*decimals == '0' && length > 1) {\n        length--;\n        decimals++;\n        decimalPosition--;\n    }\n\n    // Trim trailing zeros\n    while (decimals[length - 1] == '0' && length > 1) {\n        length--;\n        decimalPosition--;\n        exp++;\n    }\n\n    // Trim right-most digits\n    const int kMaxDecimalDigit = 780;\n    if (static_cast<int>(length) > kMaxDecimalDigit) {\n        int delta = (static_cast<int>(length) - kMaxDecimalDigit);\n        exp += delta;\n        decimalPosition -= static_cast<unsigned>(delta);\n        length = kMaxDecimalDigit;\n    }\n\n    // If too small, underflow to zero\n    if (int(length) + exp < -324)\n        return 0.0;\n\n    if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))\n        return result;\n\n    // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison\n    return StrtodBigInteger(result, decimals, length, decimalPosition, exp);\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_STRTOD_\n"
  },
  {
    "path": "third-party/rapidjson/internal/swap.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_INTERNAL_SWAP_H_\n#define RAPIDJSON_INTERNAL_SWAP_H_\n\n#include \"../rapidjson.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\nnamespace internal {\n\n//! Custom swap() to avoid dependency on C++ <algorithm> header\n/*! \\tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.\n    \\note This has the same semantics as std::swap().\n*/\ntemplate <typename T>\ninline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {\n    T tmp = a;\n        a = b;\n        b = tmp;\n}\n\n} // namespace internal\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_INTERNAL_SWAP_H_\n"
  },
  {
    "path": "third-party/rapidjson/istreamwrapper.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_ISTREAMWRAPPER_H_\n#define RAPIDJSON_ISTREAMWRAPPER_H_\n\n#include \"stream.h\"\n#include <iosfwd>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of \\c std::basic_istream into RapidJSON's Stream concept.\n/*!\n    The classes can be wrapped including but not limited to:\n\n    - \\c std::istringstream\n    - \\c std::stringstream\n    - \\c std::wistringstream\n    - \\c std::wstringstream\n    - \\c std::ifstream\n    - \\c std::fstream\n    - \\c std::wifstream\n    - \\c std::wfstream\n\n    \\tparam StreamType Class derived from \\c std::basic_istream.\n*/\n   \ntemplate <typename StreamType>\nclass BasicIStreamWrapper {\npublic:\n    typedef typename StreamType::char_type Ch;\n    BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}\n\n    Ch Peek() const { \n        typename StreamType::int_type c = stream_.peek();\n        return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\\0');\n    }\n\n    Ch Take() { \n        typename StreamType::int_type c = stream_.get();\n        if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {\n            count_++;\n            return static_cast<Ch>(c);\n        }\n        else\n            return '\\0';\n    }\n\n    // tellg() may return -1 when failed. So we count by ourself.\n    size_t Tell() const { return count_; }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.\n        int i;\n        bool hasError = false;\n        for (i = 0; i < 4; ++i) {\n            typename StreamType::int_type c = stream_.get();\n            if (c == StreamType::traits_type::eof()) {\n                hasError = true;\n                stream_.clear();\n                break;\n            }\n            peekBuffer_[i] = static_cast<Ch>(c);\n        }\n        for (--i; i >= 0; --i)\n            stream_.putback(peekBuffer_[i]);\n        return !hasError ? peekBuffer_ : 0;\n    }\n\nprivate:\n    BasicIStreamWrapper(const BasicIStreamWrapper&);\n    BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);\n\n    StreamType& stream_;\n    size_t count_;  //!< Number of characters read. Note:\n    mutable Ch peekBuffer_[4];\n};\n\ntypedef BasicIStreamWrapper<std::istream> IStreamWrapper;\ntypedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;\n\n#if defined(__clang__) || defined(_MSC_VER)\nRAPIDJSON_DIAG_POP\n#endif\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_ISTREAMWRAPPER_H_\n"
  },
  {
    "path": "third-party/rapidjson/memorybuffer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_MEMORYBUFFER_H_\n#define RAPIDJSON_MEMORYBUFFER_H_\n\n#include \"stream.h\"\n#include \"internal/stack.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory output byte stream.\n/*!\n    This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.\n\n    It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.\n\n    Differences between MemoryBuffer and StringBuffer:\n    1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. \n    2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.\n\n    \\tparam Allocator type for allocating memory buffer.\n    \\note implements Stream concept\n*/\ntemplate <typename Allocator = CrtAllocator>\nstruct GenericMemoryBuffer {\n    typedef char Ch; // byte\n\n    GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}\n\n    void Put(Ch c) { *stack_.template Push<Ch>() = c; }\n    void Flush() {}\n\n    void Clear() { stack_.Clear(); }\n    void ShrinkToFit() { stack_.ShrinkToFit(); }\n    Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }\n    void Pop(size_t count) { stack_.template Pop<Ch>(count); }\n\n    const Ch* GetBuffer() const {\n        return stack_.template Bottom<Ch>();\n    }\n\n    size_t GetSize() const { return stack_.GetSize(); }\n\n    static const size_t kDefaultCapacity = 256;\n    mutable internal::Stack<Allocator> stack_;\n};\n\ntypedef GenericMemoryBuffer<> MemoryBuffer;\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {\n    std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_MEMORYBUFFER_H_\n"
  },
  {
    "path": "third-party/rapidjson/memorystream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_MEMORYSTREAM_H_\n#define RAPIDJSON_MEMORYSTREAM_H_\n\n#include \"stream.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(missing-noreturn)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory input byte stream.\n/*!\n    This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.\n\n    It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.\n\n    Differences between MemoryStream and StringStream:\n    1. StringStream has encoding but MemoryStream is a byte stream.\n    2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.\n    3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().\n    \\note implements Stream concept\n*/\nstruct MemoryStream {\n    typedef char Ch; // byte\n\n    MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}\n\n    Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\\0' : *src_; }\n    Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\\0' : *src_++; }\n    size_t Tell() const { return static_cast<size_t>(src_ - begin_); }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    // For encoding detection only.\n    const Ch* Peek4() const {\n        return Tell() + 4 <= size_ ? src_ : 0;\n    }\n\n    const Ch* src_;     //!< Current read position.\n    const Ch* begin_;   //!< Original head of the string.\n    const Ch* end_;     //!< End of stream.\n    size_t size_;       //!< Size of the stream.\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_MEMORYBUFFER_H_\n"
  },
  {
    "path": "third-party/rapidjson/msinttypes/inttypes.h",
    "content": "// ISO C9x  compliant inttypes.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 \n// \n//  Copyright (c) 2006-2013 Alexander Chemeris\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n// \n//   1. Redistributions of source code must retain the above copyright notice,\n//      this list of conditions and the following disclaimer.\n// \n//   2. Redistributions in binary form must reproduce the above copyright\n//      notice, this list of conditions and the following disclaimer in the\n//      documentation and/or other materials provided with the distribution.\n// \n//   3. Neither the name of the product nor the names of its contributors may\n//      be used to endorse or promote products derived from this software\n//      without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n///////////////////////////////////////////////////////////////////////////////\n\n// The above software in this distribution may have been modified by \n// THL A29 Limited (\"Tencent Modifications\"). \n// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.\n\n#ifndef _MSC_VER // [\n#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif // _MSC_VER ]\n\n#ifndef _MSC_INTTYPES_H_ // [\n#define _MSC_INTTYPES_H_\n\n#if _MSC_VER > 1000\n#pragma once\n#endif\n\n#include \"stdint.h\"\n\n// miloyip: VC supports inttypes.h since VC2013\n#if _MSC_VER >= 1800\n#include <inttypes.h>\n#else\n\n// 7.8 Format conversion of integer types\n\ntypedef struct {\n   intmax_t quot;\n   intmax_t rem;\n} imaxdiv_t;\n\n// 7.8.1 Macros for format specifiers\n\n#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198\n\n// The fprintf macros for signed integers are:\n#define PRId8       \"d\"\n#define PRIi8       \"i\"\n#define PRIdLEAST8  \"d\"\n#define PRIiLEAST8  \"i\"\n#define PRIdFAST8   \"d\"\n#define PRIiFAST8   \"i\"\n\n#define PRId16       \"hd\"\n#define PRIi16       \"hi\"\n#define PRIdLEAST16  \"hd\"\n#define PRIiLEAST16  \"hi\"\n#define PRIdFAST16   \"hd\"\n#define PRIiFAST16   \"hi\"\n\n#define PRId32       \"I32d\"\n#define PRIi32       \"I32i\"\n#define PRIdLEAST32  \"I32d\"\n#define PRIiLEAST32  \"I32i\"\n#define PRIdFAST32   \"I32d\"\n#define PRIiFAST32   \"I32i\"\n\n#define PRId64       \"I64d\"\n#define PRIi64       \"I64i\"\n#define PRIdLEAST64  \"I64d\"\n#define PRIiLEAST64  \"I64i\"\n#define PRIdFAST64   \"I64d\"\n#define PRIiFAST64   \"I64i\"\n\n#define PRIdMAX     \"I64d\"\n#define PRIiMAX     \"I64i\"\n\n#define PRIdPTR     \"Id\"\n#define PRIiPTR     \"Ii\"\n\n// The fprintf macros for unsigned integers are:\n#define PRIo8       \"o\"\n#define PRIu8       \"u\"\n#define PRIx8       \"x\"\n#define PRIX8       \"X\"\n#define PRIoLEAST8  \"o\"\n#define PRIuLEAST8  \"u\"\n#define PRIxLEAST8  \"x\"\n#define PRIXLEAST8  \"X\"\n#define PRIoFAST8   \"o\"\n#define PRIuFAST8   \"u\"\n#define PRIxFAST8   \"x\"\n#define PRIXFAST8   \"X\"\n\n#define PRIo16       \"ho\"\n#define PRIu16       \"hu\"\n#define PRIx16       \"hx\"\n#define PRIX16       \"hX\"\n#define PRIoLEAST16  \"ho\"\n#define PRIuLEAST16  \"hu\"\n#define PRIxLEAST16  \"hx\"\n#define PRIXLEAST16  \"hX\"\n#define PRIoFAST16   \"ho\"\n#define PRIuFAST16   \"hu\"\n#define PRIxFAST16   \"hx\"\n#define PRIXFAST16   \"hX\"\n\n#define PRIo32       \"I32o\"\n#define PRIu32       \"I32u\"\n#define PRIx32       \"I32x\"\n#define PRIX32       \"I32X\"\n#define PRIoLEAST32  \"I32o\"\n#define PRIuLEAST32  \"I32u\"\n#define PRIxLEAST32  \"I32x\"\n#define PRIXLEAST32  \"I32X\"\n#define PRIoFAST32   \"I32o\"\n#define PRIuFAST32   \"I32u\"\n#define PRIxFAST32   \"I32x\"\n#define PRIXFAST32   \"I32X\"\n\n#define PRIo64       \"I64o\"\n#define PRIu64       \"I64u\"\n#define PRIx64       \"I64x\"\n#define PRIX64       \"I64X\"\n#define PRIoLEAST64  \"I64o\"\n#define PRIuLEAST64  \"I64u\"\n#define PRIxLEAST64  \"I64x\"\n#define PRIXLEAST64  \"I64X\"\n#define PRIoFAST64   \"I64o\"\n#define PRIuFAST64   \"I64u\"\n#define PRIxFAST64   \"I64x\"\n#define PRIXFAST64   \"I64X\"\n\n#define PRIoMAX     \"I64o\"\n#define PRIuMAX     \"I64u\"\n#define PRIxMAX     \"I64x\"\n#define PRIXMAX     \"I64X\"\n\n#define PRIoPTR     \"Io\"\n#define PRIuPTR     \"Iu\"\n#define PRIxPTR     \"Ix\"\n#define PRIXPTR     \"IX\"\n\n// The fscanf macros for signed integers are:\n#define SCNd8       \"d\"\n#define SCNi8       \"i\"\n#define SCNdLEAST8  \"d\"\n#define SCNiLEAST8  \"i\"\n#define SCNdFAST8   \"d\"\n#define SCNiFAST8   \"i\"\n\n#define SCNd16       \"hd\"\n#define SCNi16       \"hi\"\n#define SCNdLEAST16  \"hd\"\n#define SCNiLEAST16  \"hi\"\n#define SCNdFAST16   \"hd\"\n#define SCNiFAST16   \"hi\"\n\n#define SCNd32       \"ld\"\n#define SCNi32       \"li\"\n#define SCNdLEAST32  \"ld\"\n#define SCNiLEAST32  \"li\"\n#define SCNdFAST32   \"ld\"\n#define SCNiFAST32   \"li\"\n\n#define SCNd64       \"I64d\"\n#define SCNi64       \"I64i\"\n#define SCNdLEAST64  \"I64d\"\n#define SCNiLEAST64  \"I64i\"\n#define SCNdFAST64   \"I64d\"\n#define SCNiFAST64   \"I64i\"\n\n#define SCNdMAX     \"I64d\"\n#define SCNiMAX     \"I64i\"\n\n#ifdef _WIN64 // [\n#  define SCNdPTR     \"I64d\"\n#  define SCNiPTR     \"I64i\"\n#else  // _WIN64 ][\n#  define SCNdPTR     \"ld\"\n#  define SCNiPTR     \"li\"\n#endif  // _WIN64 ]\n\n// The fscanf macros for unsigned integers are:\n#define SCNo8       \"o\"\n#define SCNu8       \"u\"\n#define SCNx8       \"x\"\n#define SCNX8       \"X\"\n#define SCNoLEAST8  \"o\"\n#define SCNuLEAST8  \"u\"\n#define SCNxLEAST8  \"x\"\n#define SCNXLEAST8  \"X\"\n#define SCNoFAST8   \"o\"\n#define SCNuFAST8   \"u\"\n#define SCNxFAST8   \"x\"\n#define SCNXFAST8   \"X\"\n\n#define SCNo16       \"ho\"\n#define SCNu16       \"hu\"\n#define SCNx16       \"hx\"\n#define SCNX16       \"hX\"\n#define SCNoLEAST16  \"ho\"\n#define SCNuLEAST16  \"hu\"\n#define SCNxLEAST16  \"hx\"\n#define SCNXLEAST16  \"hX\"\n#define SCNoFAST16   \"ho\"\n#define SCNuFAST16   \"hu\"\n#define SCNxFAST16   \"hx\"\n#define SCNXFAST16   \"hX\"\n\n#define SCNo32       \"lo\"\n#define SCNu32       \"lu\"\n#define SCNx32       \"lx\"\n#define SCNX32       \"lX\"\n#define SCNoLEAST32  \"lo\"\n#define SCNuLEAST32  \"lu\"\n#define SCNxLEAST32  \"lx\"\n#define SCNXLEAST32  \"lX\"\n#define SCNoFAST32   \"lo\"\n#define SCNuFAST32   \"lu\"\n#define SCNxFAST32   \"lx\"\n#define SCNXFAST32   \"lX\"\n\n#define SCNo64       \"I64o\"\n#define SCNu64       \"I64u\"\n#define SCNx64       \"I64x\"\n#define SCNX64       \"I64X\"\n#define SCNoLEAST64  \"I64o\"\n#define SCNuLEAST64  \"I64u\"\n#define SCNxLEAST64  \"I64x\"\n#define SCNXLEAST64  \"I64X\"\n#define SCNoFAST64   \"I64o\"\n#define SCNuFAST64   \"I64u\"\n#define SCNxFAST64   \"I64x\"\n#define SCNXFAST64   \"I64X\"\n\n#define SCNoMAX     \"I64o\"\n#define SCNuMAX     \"I64u\"\n#define SCNxMAX     \"I64x\"\n#define SCNXMAX     \"I64X\"\n\n#ifdef _WIN64 // [\n#  define SCNoPTR     \"I64o\"\n#  define SCNuPTR     \"I64u\"\n#  define SCNxPTR     \"I64x\"\n#  define SCNXPTR     \"I64X\"\n#else  // _WIN64 ][\n#  define SCNoPTR     \"lo\"\n#  define SCNuPTR     \"lu\"\n#  define SCNxPTR     \"lx\"\n#  define SCNXPTR     \"lX\"\n#endif  // _WIN64 ]\n\n#endif // __STDC_FORMAT_MACROS ]\n\n// 7.8.2 Functions for greatest-width integer types\n\n// 7.8.2.1 The imaxabs function\n#define imaxabs _abs64\n\n// 7.8.2.2 The imaxdiv function\n\n// This is modified version of div() function from Microsoft's div.c found\n// in %MSVC.NET%\\crt\\src\\div.c\n#ifdef STATIC_IMAXDIV // [\nstatic\n#else // STATIC_IMAXDIV ][\n_inline\n#endif // STATIC_IMAXDIV ]\nimaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)\n{\n   imaxdiv_t result;\n\n   result.quot = numer / denom;\n   result.rem = numer % denom;\n\n   if (numer < 0 && result.rem > 0) {\n      // did division wrong; must fix up\n      ++result.quot;\n      result.rem -= denom;\n   }\n\n   return result;\n}\n\n// 7.8.2.3 The strtoimax and strtoumax functions\n#define strtoimax _strtoi64\n#define strtoumax _strtoui64\n\n// 7.8.2.4 The wcstoimax and wcstoumax functions\n#define wcstoimax _wcstoi64\n#define wcstoumax _wcstoui64\n\n#endif // _MSC_VER >= 1800\n\n#endif // _MSC_INTTYPES_H_ ]\n"
  },
  {
    "path": "third-party/rapidjson/msinttypes/stdint.h",
    "content": "// ISO C9x  compliant stdint.h for Microsoft Visual Studio\n// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 \n// \n//  Copyright (c) 2006-2013 Alexander Chemeris\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n// \n//   1. Redistributions of source code must retain the above copyright notice,\n//      this list of conditions and the following disclaimer.\n// \n//   2. Redistributions in binary form must reproduce the above copyright\n//      notice, this list of conditions and the following disclaimer in the\n//      documentation and/or other materials provided with the distribution.\n// \n//   3. Neither the name of the product nor the names of its contributors may\n//      be used to endorse or promote products derived from this software\n//      without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n///////////////////////////////////////////////////////////////////////////////\n\n// The above software in this distribution may have been modified by \n// THL A29 Limited (\"Tencent Modifications\"). \n// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.\n\n#ifndef _MSC_VER // [\n#error \"Use this header only with Microsoft Visual C++ compilers!\"\n#endif // _MSC_VER ]\n\n#ifndef _MSC_STDINT_H_ // [\n#define _MSC_STDINT_H_\n\n#if _MSC_VER > 1000\n#pragma once\n#endif\n\n// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.\n#if _MSC_VER >= 1600 // [\n#include <stdint.h>\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260\n\n#undef INT8_C\n#undef INT16_C\n#undef INT32_C\n#undef INT64_C\n#undef UINT8_C\n#undef UINT16_C\n#undef UINT32_C\n#undef UINT64_C\n\n// 7.18.4.1 Macros for minimum-width integer constants\n\n#define INT8_C(val)  val##i8\n#define INT16_C(val) val##i16\n#define INT32_C(val) val##i32\n#define INT64_C(val) val##i64\n\n#define UINT8_C(val)  val##ui8\n#define UINT16_C(val) val##ui16\n#define UINT32_C(val) val##ui32\n#define UINT64_C(val) val##ui64\n\n// 7.18.4.2 Macros for greatest-width integer constants\n// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.\n// Check out Issue 9 for the details.\n#ifndef INTMAX_C //   [\n#  define INTMAX_C   INT64_C\n#endif // INTMAX_C    ]\n#ifndef UINTMAX_C //  [\n#  define UINTMAX_C  UINT64_C\n#endif // UINTMAX_C   ]\n\n#endif // __STDC_CONSTANT_MACROS ]\n\n#else // ] _MSC_VER >= 1700 [\n\n#include <limits.h>\n\n// For Visual Studio 6 in C++ mode and for many Visual Studio versions when\n// compiling for ARM we have to wrap <wchar.h> include with 'extern \"C++\" {}'\n// or compiler would give many errors like this:\n//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed\n#if defined(__cplusplus) && !defined(_M_ARM)\nextern \"C\" {\n#endif\n#  include <wchar.h>\n#if defined(__cplusplus) && !defined(_M_ARM)\n}\n#endif\n\n// Define _W64 macros to mark types changing their size, like intptr_t.\n#ifndef _W64\n#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300\n#     define _W64 __w64\n#  else\n#     define _W64\n#  endif\n#endif\n\n\n// 7.18.1 Integer types\n\n// 7.18.1.1 Exact-width integer types\n\n// Visual Studio 6 and Embedded Visual C++ 4 doesn't\n// realize that, e.g. char has the same size as __int8\n// so we give up on __intX for them.\n#if (_MSC_VER < 1300)\n   typedef signed char       int8_t;\n   typedef signed short      int16_t;\n   typedef signed int        int32_t;\n   typedef unsigned char     uint8_t;\n   typedef unsigned short    uint16_t;\n   typedef unsigned int      uint32_t;\n#else\n   typedef signed __int8     int8_t;\n   typedef signed __int16    int16_t;\n   typedef signed __int32    int32_t;\n   typedef unsigned __int8   uint8_t;\n   typedef unsigned __int16  uint16_t;\n   typedef unsigned __int32  uint32_t;\n#endif\ntypedef signed __int64       int64_t;\ntypedef unsigned __int64     uint64_t;\n\n\n// 7.18.1.2 Minimum-width integer types\ntypedef int8_t    int_least8_t;\ntypedef int16_t   int_least16_t;\ntypedef int32_t   int_least32_t;\ntypedef int64_t   int_least64_t;\ntypedef uint8_t   uint_least8_t;\ntypedef uint16_t  uint_least16_t;\ntypedef uint32_t  uint_least32_t;\ntypedef uint64_t  uint_least64_t;\n\n// 7.18.1.3 Fastest minimum-width integer types\ntypedef int8_t    int_fast8_t;\ntypedef int16_t   int_fast16_t;\ntypedef int32_t   int_fast32_t;\ntypedef int64_t   int_fast64_t;\ntypedef uint8_t   uint_fast8_t;\ntypedef uint16_t  uint_fast16_t;\ntypedef uint32_t  uint_fast32_t;\ntypedef uint64_t  uint_fast64_t;\n\n// 7.18.1.4 Integer types capable of holding object pointers\n#ifdef _WIN64 // [\n   typedef signed __int64    intptr_t;\n   typedef unsigned __int64  uintptr_t;\n#else // _WIN64 ][\n   typedef _W64 signed int   intptr_t;\n   typedef _W64 unsigned int uintptr_t;\n#endif // _WIN64 ]\n\n// 7.18.1.5 Greatest-width integer types\ntypedef int64_t   intmax_t;\ntypedef uint64_t  uintmax_t;\n\n\n// 7.18.2 Limits of specified-width integer types\n\n#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259\n\n// 7.18.2.1 Limits of exact-width integer types\n#define INT8_MIN     ((int8_t)_I8_MIN)\n#define INT8_MAX     _I8_MAX\n#define INT16_MIN    ((int16_t)_I16_MIN)\n#define INT16_MAX    _I16_MAX\n#define INT32_MIN    ((int32_t)_I32_MIN)\n#define INT32_MAX    _I32_MAX\n#define INT64_MIN    ((int64_t)_I64_MIN)\n#define INT64_MAX    _I64_MAX\n#define UINT8_MAX    _UI8_MAX\n#define UINT16_MAX   _UI16_MAX\n#define UINT32_MAX   _UI32_MAX\n#define UINT64_MAX   _UI64_MAX\n\n// 7.18.2.2 Limits of minimum-width integer types\n#define INT_LEAST8_MIN    INT8_MIN\n#define INT_LEAST8_MAX    INT8_MAX\n#define INT_LEAST16_MIN   INT16_MIN\n#define INT_LEAST16_MAX   INT16_MAX\n#define INT_LEAST32_MIN   INT32_MIN\n#define INT_LEAST32_MAX   INT32_MAX\n#define INT_LEAST64_MIN   INT64_MIN\n#define INT_LEAST64_MAX   INT64_MAX\n#define UINT_LEAST8_MAX   UINT8_MAX\n#define UINT_LEAST16_MAX  UINT16_MAX\n#define UINT_LEAST32_MAX  UINT32_MAX\n#define UINT_LEAST64_MAX  UINT64_MAX\n\n// 7.18.2.3 Limits of fastest minimum-width integer types\n#define INT_FAST8_MIN    INT8_MIN\n#define INT_FAST8_MAX    INT8_MAX\n#define INT_FAST16_MIN   INT16_MIN\n#define INT_FAST16_MAX   INT16_MAX\n#define INT_FAST32_MIN   INT32_MIN\n#define INT_FAST32_MAX   INT32_MAX\n#define INT_FAST64_MIN   INT64_MIN\n#define INT_FAST64_MAX   INT64_MAX\n#define UINT_FAST8_MAX   UINT8_MAX\n#define UINT_FAST16_MAX  UINT16_MAX\n#define UINT_FAST32_MAX  UINT32_MAX\n#define UINT_FAST64_MAX  UINT64_MAX\n\n// 7.18.2.4 Limits of integer types capable of holding object pointers\n#ifdef _WIN64 // [\n#  define INTPTR_MIN   INT64_MIN\n#  define INTPTR_MAX   INT64_MAX\n#  define UINTPTR_MAX  UINT64_MAX\n#else // _WIN64 ][\n#  define INTPTR_MIN   INT32_MIN\n#  define INTPTR_MAX   INT32_MAX\n#  define UINTPTR_MAX  UINT32_MAX\n#endif // _WIN64 ]\n\n// 7.18.2.5 Limits of greatest-width integer types\n#define INTMAX_MIN   INT64_MIN\n#define INTMAX_MAX   INT64_MAX\n#define UINTMAX_MAX  UINT64_MAX\n\n// 7.18.3 Limits of other integer types\n\n#ifdef _WIN64 // [\n#  define PTRDIFF_MIN  _I64_MIN\n#  define PTRDIFF_MAX  _I64_MAX\n#else  // _WIN64 ][\n#  define PTRDIFF_MIN  _I32_MIN\n#  define PTRDIFF_MAX  _I32_MAX\n#endif  // _WIN64 ]\n\n#define SIG_ATOMIC_MIN  INT_MIN\n#define SIG_ATOMIC_MAX  INT_MAX\n\n#ifndef SIZE_MAX // [\n#  ifdef _WIN64 // [\n#     define SIZE_MAX  _UI64_MAX\n#  else // _WIN64 ][\n#     define SIZE_MAX  _UI32_MAX\n#  endif // _WIN64 ]\n#endif // SIZE_MAX ]\n\n// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>\n#ifndef WCHAR_MIN // [\n#  define WCHAR_MIN  0\n#endif  // WCHAR_MIN ]\n#ifndef WCHAR_MAX // [\n#  define WCHAR_MAX  _UI16_MAX\n#endif  // WCHAR_MAX ]\n\n#define WINT_MIN  0\n#define WINT_MAX  _UI16_MAX\n\n#endif // __STDC_LIMIT_MACROS ]\n\n\n// 7.18.4 Limits of other integer types\n\n#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260\n\n// 7.18.4.1 Macros for minimum-width integer constants\n\n#define INT8_C(val)  val##i8\n#define INT16_C(val) val##i16\n#define INT32_C(val) val##i32\n#define INT64_C(val) val##i64\n\n#define UINT8_C(val)  val##ui8\n#define UINT16_C(val) val##ui16\n#define UINT32_C(val) val##ui32\n#define UINT64_C(val) val##ui64\n\n// 7.18.4.2 Macros for greatest-width integer constants\n// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.\n// Check out Issue 9 for the details.\n#ifndef INTMAX_C //   [\n#  define INTMAX_C   INT64_C\n#endif // INTMAX_C    ]\n#ifndef UINTMAX_C //  [\n#  define UINTMAX_C  UINT64_C\n#endif // UINTMAX_C   ]\n\n#endif // __STDC_CONSTANT_MACROS ]\n\n#endif // _MSC_VER >= 1600 ]\n\n#endif // _MSC_STDINT_H_ ]\n"
  },
  {
    "path": "third-party/rapidjson/ostreamwrapper.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_OSTREAMWRAPPER_H_\n#define RAPIDJSON_OSTREAMWRAPPER_H_\n\n#include \"stream.h\"\n#include <iosfwd>\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Wrapper of \\c std::basic_ostream into RapidJSON's Stream concept.\n/*!\n    The classes can be wrapped including but not limited to:\n\n    - \\c std::ostringstream\n    - \\c std::stringstream\n    - \\c std::wpstringstream\n    - \\c std::wstringstream\n    - \\c std::ifstream\n    - \\c std::fstream\n    - \\c std::wofstream\n    - \\c std::wfstream\n\n    \\tparam StreamType Class derived from \\c std::basic_ostream.\n*/\n   \ntemplate <typename StreamType>\nclass BasicOStreamWrapper {\npublic:\n    typedef typename StreamType::char_type Ch;\n    BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}\n\n    void Put(Ch c) {\n        stream_.put(c);\n    }\n\n    void Flush() {\n        stream_.flush();\n    }\n\n    // Not implemented\n    char Peek() const { RAPIDJSON_ASSERT(false); return 0; }\n    char Take() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }\n    char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }\n\nprivate:\n    BasicOStreamWrapper(const BasicOStreamWrapper&);\n    BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);\n\n    StreamType& stream_;\n};\n\ntypedef BasicOStreamWrapper<std::ostream> OStreamWrapper;\ntypedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_OSTREAMWRAPPER_H_\n"
  },
  {
    "path": "third-party/rapidjson/pointer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_POINTER_H_\n#define RAPIDJSON_POINTER_H_\n\n#include \"document.h\"\n#include \"internal/itoa.h\"\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(switch-enum)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\nstatic const SizeType kPointerInvalidIndex = ~SizeType(0);  //!< Represents an invalid index in GenericPointer::Token\n\n//! Error code of parsing.\n/*! \\ingroup RAPIDJSON_ERRORS\n    \\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode\n*/\nenum PointerParseErrorCode {\n    kPointerParseErrorNone = 0,                     //!< The parse is successful\n\n    kPointerParseErrorTokenMustBeginWithSolidus,    //!< A token must begin with a '/'\n    kPointerParseErrorInvalidEscape,                //!< Invalid escape\n    kPointerParseErrorInvalidPercentEncoding,       //!< Invalid percent encoding in URI fragment\n    kPointerParseErrorCharacterMustPercentEncode    //!< A character must percent encoded in URI fragment\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericPointer\n\n//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.\n/*!\n    This class implements RFC 6901 \"JavaScript Object Notation (JSON) Pointer\" \n    (https://tools.ietf.org/html/rfc6901).\n\n    A JSON pointer is for identifying a specific value in a JSON document\n    (GenericDocument). It can simplify coding of DOM tree manipulation, because it\n    can access multiple-level depth of DOM tree with single API call.\n\n    After it parses a string representation (e.g. \"/foo/0\" or URI fragment \n    representation (e.g. \"#/foo/0\") into its internal representation (tokens),\n    it can be used to resolve a specific value in multiple documents, or sub-tree \n    of documents.\n\n    Contrary to GenericValue, Pointer can be copy constructed and copy assigned.\n    Apart from assignment, a Pointer cannot be modified after construction.\n\n    Although Pointer is very convenient, please aware that constructing Pointer\n    involves parsing and dynamic memory allocation. A special constructor with user-\n    supplied tokens eliminates these.\n\n    GenericPointer depends on GenericDocument and GenericValue.\n    \n    \\tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >\n    \\tparam Allocator The allocator type for allocating memory for internal representation.\n    \n    \\note GenericPointer uses same encoding of ValueType.\n    However, Allocator of GenericPointer is independent of Allocator of Value.\n*/\ntemplate <typename ValueType, typename Allocator = CrtAllocator>\nclass GenericPointer {\npublic:\n    typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value\n    typedef typename ValueType::Ch Ch;                      //!< Character type from Value\n\n    //! A token is the basic units of internal representation.\n    /*!\n        A JSON pointer string representation \"/foo/123\" is parsed to two tokens: \n        \"foo\" and 123. 123 will be represented in both numeric form and string form.\n        They are resolved according to the actual value type (object or array).\n\n        For token that are not numbers, or the numeric value is out of bound\n        (greater than limits of SizeType), they are only treated as string form\n        (i.e. the token's index will be equal to kPointerInvalidIndex).\n\n        This struct is public so that user can create a Pointer without parsing and \n        allocation, using a special constructor.\n    */\n    struct Token {\n        const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.\n        SizeType length;            //!< Length of the name.\n        SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.\n    };\n\n    //!@name Constructors and destructor.\n    //@{\n\n    //! Default constructor.\n    GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}\n\n    //! Constructor that parses a string or URI fragment representation.\n    /*!\n        \\param source A null-terminated, string or URI fragment representation of JSON pointer.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n    */\n    explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source, internal::StrLen(source));\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Constructor that parses a string or URI fragment representation.\n    /*!\n        \\param source A string or URI fragment representation of JSON pointer.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n        \\note Requires the definition of the preprocessor symbol \\ref RAPIDJSON_HAS_STDSTRING.\n    */\n    explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source.c_str(), source.size());\n    }\n#endif\n\n    //! Constructor that parses a string or URI fragment representation, with length of the source string.\n    /*!\n        \\param source A string or URI fragment representation of JSON pointer.\n        \\param length Length of source.\n        \\param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.\n        \\note Slightly faster than the overload without length.\n    */\n    GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        Parse(source, length);\n    }\n\n    //! Constructor with user-supplied tokens.\n    /*!\n        This constructor let user supplies const array of tokens.\n        This prevents the parsing process and eliminates allocation.\n        This is preferred for memory constrained environments.\n\n        \\param tokens An constant array of tokens representing the JSON pointer.\n        \\param tokenCount Number of tokens.\n\n        \\b Example\n        \\code\n        #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }\n        #define INDEX(i) { #i, sizeof(#i) - 1, i }\n\n        static const Pointer::Token kTokens[] = { NAME(\"foo\"), INDEX(123) };\n        static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));\n        // Equivalent to static const Pointer p(\"/foo/123\");\n\n        #undef NAME\n        #undef INDEX\n        \\endcode\n    */\n    GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}\n\n    //! Copy constructor.\n    GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {\n        *this = rhs;\n    }\n\n    //! Destructor.\n    ~GenericPointer() {\n        if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.\n            Allocator::Free(tokens_);\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    //! Assignment operator.\n    GenericPointer& operator=(const GenericPointer& rhs) {\n        if (this != &rhs) {\n            // Do not delete ownAllcator\n            if (nameBuffer_)\n                Allocator::Free(tokens_);\n\n            tokenCount_ = rhs.tokenCount_;\n            parseErrorOffset_ = rhs.parseErrorOffset_;\n            parseErrorCode_ = rhs.parseErrorCode_;\n\n            if (rhs.nameBuffer_)\n                CopyFromRaw(rhs); // Normally parsed tokens.\n            else {\n                tokens_ = rhs.tokens_; // User supplied const tokens.\n                nameBuffer_ = 0;\n            }\n        }\n        return *this;\n    }\n\n    //@}\n\n    //!@name Append token\n    //@{\n\n    //! Append a token and return a new Pointer\n    /*!\n        \\param token Token to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const Token& token, Allocator* allocator = 0) const {\n        GenericPointer r;\n        r.allocator_ = allocator;\n        Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);\n        std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));\n        r.tokens_[tokenCount_].name = p;\n        r.tokens_[tokenCount_].length = token.length;\n        r.tokens_[tokenCount_].index = token.index;\n        return r;\n    }\n\n    //! Append a name token with length, and return a new Pointer\n    /*!\n        \\param name Name to be appended.\n        \\param length Length of name.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {\n        Token token = { name, length, kPointerInvalidIndex };\n        return Append(token, allocator);\n    }\n\n    //! Append a name token without length, and return a new Pointer\n    /*!\n        \\param name Name (const Ch*) to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))\n    Append(T* name, Allocator* allocator = 0) const {\n        return Append(name, internal::StrLen(name), allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Append a name token, and return a new Pointer\n    /*!\n        \\param name Name to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {\n        return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);\n    }\n#endif\n\n    //! Append a index token, and return a new Pointer\n    /*!\n        \\param index Index to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(SizeType index, Allocator* allocator = 0) const {\n        char buffer[21];\n        char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);\n        SizeType length = static_cast<SizeType>(end - buffer);\n        buffer[length] = '\\0';\n\n        if (sizeof(Ch) == 1) {\n            Token token = { reinterpret_cast<Ch*>(buffer), length, index };\n            return Append(token, allocator);\n        }\n        else {\n            Ch name[21];\n            for (size_t i = 0; i <= length; i++)\n                name[i] = static_cast<Ch>(buffer[i]);\n            Token token = { name, length, index };\n            return Append(token, allocator);\n        }\n    }\n\n    //! Append a token by value, and return a new Pointer\n    /*!\n        \\param token token to be appended.\n        \\param allocator Allocator for the newly return Pointer.\n        \\return A new Pointer with appended token.\n    */\n    GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {\n        if (token.IsString())\n            return Append(token.GetString(), token.GetStringLength(), allocator);\n        else {\n            RAPIDJSON_ASSERT(token.IsUint64());\n            RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));\n            return Append(static_cast<SizeType>(token.GetUint64()), allocator);\n        }\n    }\n\n    //!@name Handling Parse Error\n    //@{\n\n    //! Check whether this is a valid pointer.\n    bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }\n\n    //! Get the parsing error offset in code unit.\n    size_t GetParseErrorOffset() const { return parseErrorOffset_; }\n\n    //! Get the parsing error code.\n    PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }\n\n    //@}\n\n    //! Get the allocator of this pointer.\n    Allocator& GetAllocator() { return *allocator_; }\n\n    //!@name Tokens\n    //@{\n\n    //! Get the token array (const version only).\n    const Token* GetTokens() const { return tokens_; }\n\n    //! Get the number of tokens.\n    size_t GetTokenCount() const { return tokenCount_; }\n\n    //@}\n\n    //!@name Equality/inequality operators\n    //@{\n\n    //! Equality operator.\n    /*!\n        \\note When any pointers are invalid, always returns false.\n    */\n    bool operator==(const GenericPointer& rhs) const {\n        if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)\n            return false;\n\n        for (size_t i = 0; i < tokenCount_; i++) {\n            if (tokens_[i].index != rhs.tokens_[i].index ||\n                tokens_[i].length != rhs.tokens_[i].length || \n                (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    //! Inequality operator.\n    /*!\n        \\note When any pointers are invalid, always returns true.\n    */\n    bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }\n\n    //@}\n\n    //!@name Stringify\n    //@{\n\n    //! Stringify the pointer into string representation.\n    /*!\n        \\tparam OutputStream Type of output stream.\n        \\param os The output stream.\n    */\n    template<typename OutputStream>\n    bool Stringify(OutputStream& os) const {\n        return Stringify<false, OutputStream>(os);\n    }\n\n    //! Stringify the pointer into URI fragment representation.\n    /*!\n        \\tparam OutputStream Type of output stream.\n        \\param os The output stream.\n    */\n    template<typename OutputStream>\n    bool StringifyUriFragment(OutputStream& os) const {\n        return Stringify<true, OutputStream>(os);\n    }\n\n    //@}\n\n    //!@name Create value\n    //@{\n\n    //! Create a value in a subtree.\n    /*!\n        If the value is not exist, it creates all parent values and a JSON Null value.\n        So it always succeed and return the newly created or existing value.\n\n        Remind that it may change types of parents according to tokens, so it \n        potentially removes previously stored values. For example, if a document \n        was an array, and \"/foo\" is used to create a value, then the document \n        will be changed to an object, and all existing array elements are lost.\n\n        \\param root Root value of a DOM subtree to be resolved. It can be any value other than document root.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\param alreadyExist If non-null, it stores whether the resolved value is already exist.\n        \\return The resolved newly created (a JSON Null value), or already exists value.\n    */\n    ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {\n        RAPIDJSON_ASSERT(IsValid());\n        ValueType* v = &root;\n        bool exist = true;\n        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            if (v->IsArray() && t->name[0] == '-' && t->length == 1) {\n                v->PushBack(ValueType().Move(), allocator);\n                v = &((*v)[v->Size() - 1]);\n                exist = false;\n            }\n            else {\n                if (t->index == kPointerInvalidIndex) { // must be object name\n                    if (!v->IsObject())\n                        v->SetObject(); // Change to Object\n                }\n                else { // object name or array index\n                    if (!v->IsArray() && !v->IsObject())\n                        v->SetArray(); // Change to Array\n                }\n\n                if (v->IsArray()) {\n                    if (t->index >= v->Size()) {\n                        v->Reserve(t->index + 1, allocator);\n                        while (t->index >= v->Size())\n                            v->PushBack(ValueType().Move(), allocator);\n                        exist = false;\n                    }\n                    v = &((*v)[t->index]);\n                }\n                else {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd()) {\n                        v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);\n                        v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end\n                        exist = false;\n                    }\n                    else\n                        v = &m->value;\n                }\n            }\n        }\n\n        if (alreadyExist)\n            *alreadyExist = exist;\n\n        return *v;\n    }\n\n    //! Creates a value in a document.\n    /*!\n        \\param document A document to be resolved.\n        \\param alreadyExist If non-null, it stores whether the resolved value is already exist.\n        \\return The resolved newly created, or already exists value.\n    */\n    template <typename stackAllocator>\n    ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {\n        return Create(document, document.GetAllocator(), alreadyExist);\n    }\n\n    //@}\n\n    //!@name Query value\n    //@{\n\n    //! Query a value in a subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.\n        \\return Pointer to the value if it can be resolved. Otherwise null.\n\n        \\note\n        There are only 3 situations when a value cannot be resolved:\n        1. A value in the path is not an array nor object.\n        2. An object value does not contain the token.\n        3. A token is out of range of an array value.\n\n        Use unresolvedTokenIndex to retrieve the token index.\n    */\n    ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {\n        RAPIDJSON_ASSERT(IsValid());\n        ValueType* v = &root;\n        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            switch (v->GetType()) {\n            case kObjectType:\n                {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd())\n                        break;\n                    v = &m->value;\n                }\n                continue;\n            case kArrayType:\n                if (t->index == kPointerInvalidIndex || t->index >= v->Size())\n                    break;\n                v = &((*v)[t->index]);\n                continue;\n            default:\n                break;\n            }\n\n            // Error: unresolved token\n            if (unresolvedTokenIndex)\n                *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);\n            return 0;\n        }\n        return v;\n    }\n\n    //! Query a const value in a const subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\return Pointer to the value if it can be resolved. Otherwise null.\n    */\n    const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { \n        return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);\n    }\n\n    //@}\n\n    //!@name Query a value with default\n    //@{\n\n    //! Query a value in a subtree with default value.\n    /*!\n        Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.\n        So that this function always succeed.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param defaultValue Default value to be cloned if the value was not exists.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);\n    }\n\n    //! Query a value in a subtree with default null-terminated string.\n    ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.SetString(defaultValue, allocator);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Query a value in a subtree with default std::basic_string.\n    ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {\n        bool alreadyExist;\n        Value& v = Create(root, allocator, &alreadyExist);\n        return alreadyExist ? v : v.SetString(defaultValue, allocator);\n    }\n#endif\n\n    //! Query a value in a subtree with default primitive value.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {\n        return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);\n    }\n\n    //! Query a value in a document with default value.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n\n    //! Query a value in a document with default null-terminated string.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n    \n#if RAPIDJSON_HAS_STDSTRING\n    //! Query a value in a document with default std::basic_string.\n    template <typename stackAllocator>\n    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n#endif\n\n    //! Query a value in a document with default primitive value.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T, typename stackAllocator>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {\n        return GetWithDefault(document, defaultValue, document.GetAllocator());\n    }\n\n    //@}\n\n    //!@name Set a value\n    //@{\n\n    //! Set a value in a subtree, with move semantics.\n    /*!\n        It creates all parents if they are not exist or types are different to the tokens.\n        So this function always succeeds but potentially remove existing values.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param value Value to be set.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = value;\n    }\n\n    //! Set a value in a subtree, with copy semantics.\n    ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator).CopyFrom(value, allocator);\n    }\n\n    //! Set a null-terminated string in a subtree.\n    ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value, allocator).Move();\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Set a std::basic_string in a subtree.\n    ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value, allocator).Move();\n    }\n#endif\n\n    //! Set a primitive value in a subtree.\n    /*!\n        \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n    Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator) = ValueType(value).Move();\n    }\n\n    //! Set a value in a document, with move semantics.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {\n        return Create(document) = value;\n    }\n\n    //! Set a value in a document, with copy semantics.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {\n        return Create(document).CopyFrom(value, document.GetAllocator());\n    }\n\n    //! Set a null-terminated string in a document.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {\n        return Create(document) = ValueType(value, document.GetAllocator()).Move();\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    //! Sets a std::basic_string in a document.\n    template <typename stackAllocator>\n    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {\n        return Create(document) = ValueType(value, document.GetAllocator()).Move();\n    }\n#endif\n\n    //! Set a primitive value in a document.\n    /*!\n    \\tparam T Either \\ref Type, \\c int, \\c unsigned, \\c int64_t, \\c uint64_t, \\c bool\n    */\n    template <typename T, typename stackAllocator>\n    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))\n        Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {\n            return Create(document) = value;\n    }\n\n    //@}\n\n    //!@name Swap a value\n    //@{\n\n    //! Swap a value with a value in a subtree.\n    /*!\n        It creates all parents if they are not exist or types are different to the tokens.\n        So this function always succeeds but potentially remove existing values.\n\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\param value Value to be swapped.\n        \\param allocator Allocator for creating the values if the specified value or its parents are not exist.\n        \\see Create()\n    */\n    ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {\n        return Create(root, allocator).Swap(value);\n    }\n\n    //! Swap a value with a value in a document.\n    template <typename stackAllocator>\n    ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {\n        return Create(document).Swap(value);\n    }\n\n    //@}\n\n    //! Erase a value in a subtree.\n    /*!\n        \\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.\n        \\return Whether the resolved value is found and erased.\n\n        \\note Erasing with an empty pointer \\c Pointer(\"\"), i.e. the root, always fail and return false.\n    */\n    bool Erase(ValueType& root) const {\n        RAPIDJSON_ASSERT(IsValid());\n        if (tokenCount_ == 0) // Cannot erase the root\n            return false;\n\n        ValueType* v = &root;\n        const Token* last = tokens_ + (tokenCount_ - 1);\n        for (const Token *t = tokens_; t != last; ++t) {\n            switch (v->GetType()) {\n            case kObjectType:\n                {\n                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));\n                    if (m == v->MemberEnd())\n                        return false;\n                    v = &m->value;\n                }\n                break;\n            case kArrayType:\n                if (t->index == kPointerInvalidIndex || t->index >= v->Size())\n                    return false;\n                v = &((*v)[t->index]);\n                break;\n            default:\n                return false;\n            }\n        }\n\n        switch (v->GetType()) {\n        case kObjectType:\n            return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));\n        case kArrayType:\n            if (last->index == kPointerInvalidIndex || last->index >= v->Size())\n                return false;\n            v->Erase(v->Begin() + last->index);\n            return true;\n        default:\n            return false;\n        }\n    }\n\nprivate:\n    //! Clone the content from rhs to this.\n    /*!\n        \\param rhs Source pointer.\n        \\param extraToken Extra tokens to be allocated.\n        \\param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.\n        \\return Start of non-occupied name buffer, for storing extra names.\n    */\n    Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {\n        if (!allocator_) // allocator is independently owned.\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n\n        size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens\n        for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)\n            nameBufferSize += t->length;\n\n        tokenCount_ = rhs.tokenCount_ + extraToken;\n        tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));\n        nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);\n        if (rhs.tokenCount_ > 0) {\n            std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));\n        }\n        if (nameBufferSize > 0) {\n            std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));\n        }\n\n        // Adjust pointers to name buffer\n        std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;\n        for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)\n            t->name += diff;\n\n        return nameBuffer_ + nameBufferSize;\n    }\n\n    //! Check whether a character should be percent-encoded.\n    /*!\n        According to RFC 3986 2.3 Unreserved Characters.\n        \\param c The character (code unit) to be tested.\n    */\n    bool NeedPercentEncode(Ch c) const {\n        return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');\n    }\n\n    //! Parse a JSON String or its URI fragment representation into tokens.\n#ifndef __clang__ // -Wdocumentation\n    /*!\n        \\param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.\n        \\param length Length of the source string.\n        \\note Source cannot be JSON String Representation of JSON Pointer, e.g. In \"/\\u0000\", \\u0000 will not be unescaped.\n    */\n#endif\n    void Parse(const Ch* source, size_t length) {\n        RAPIDJSON_ASSERT(source != NULL);\n        RAPIDJSON_ASSERT(nameBuffer_ == 0);\n        RAPIDJSON_ASSERT(tokens_ == 0);\n\n        // Create own allocator if user did not supply.\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n\n        // Count number of '/' as tokenCount\n        tokenCount_ = 0;\n        for (const Ch* s = source; s != source + length; s++) \n            if (*s == '/')\n                tokenCount_++;\n\n        Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));\n        Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);\n        size_t i = 0;\n\n        // Detect if it is a URI fragment\n        bool uriFragment = false;\n        if (source[i] == '#') {\n            uriFragment = true;\n            i++;\n        }\n\n        if (i != length && source[i] != '/') {\n            parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;\n            goto error;\n        }\n\n        while (i < length) {\n            RAPIDJSON_ASSERT(source[i] == '/');\n            i++; // consumes '/'\n\n            token->name = name;\n            bool isNumber = true;\n\n            while (i < length && source[i] != '/') {\n                Ch c = source[i];\n                if (uriFragment) {\n                    // Decoding percent-encoding for URI fragment\n                    if (c == '%') {\n                        PercentDecodeStream is(&source[i], source + length);\n                        GenericInsituStringStream<EncodingType> os(name);\n                        Ch* begin = os.PutBegin();\n                        if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {\n                            parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;\n                            goto error;\n                        }\n                        size_t len = os.PutEnd(begin);\n                        i += is.Tell() - 1;\n                        if (len == 1)\n                            c = *name;\n                        else {\n                            name += len;\n                            isNumber = false;\n                            i++;\n                            continue;\n                        }\n                    }\n                    else if (NeedPercentEncode(c)) {\n                        parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;\n                        goto error;\n                    }\n                }\n\n                i++;\n                \n                // Escaping \"~0\" -> '~', \"~1\" -> '/'\n                if (c == '~') {\n                    if (i < length) {\n                        c = source[i];\n                        if (c == '0')       c = '~';\n                        else if (c == '1')  c = '/';\n                        else {\n                            parseErrorCode_ = kPointerParseErrorInvalidEscape;\n                            goto error;\n                        }\n                        i++;\n                    }\n                    else {\n                        parseErrorCode_ = kPointerParseErrorInvalidEscape;\n                        goto error;\n                    }\n                }\n\n                // First check for index: all of characters are digit\n                if (c < '0' || c > '9')\n                    isNumber = false;\n\n                *name++ = c;\n            }\n            token->length = static_cast<SizeType>(name - token->name);\n            if (token->length == 0)\n                isNumber = false;\n            *name++ = '\\0'; // Null terminator\n\n            // Second check for index: more than one digit cannot have leading zero\n            if (isNumber && token->length > 1 && token->name[0] == '0')\n                isNumber = false;\n\n            // String to SizeType conversion\n            SizeType n = 0;\n            if (isNumber) {\n                for (size_t j = 0; j < token->length; j++) {\n                    SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');\n                    if (m < n) {   // overflow detection\n                        isNumber = false;\n                        break;\n                    }\n                    n = m;\n                }\n            }\n\n            token->index = isNumber ? n : kPointerInvalidIndex;\n            token++;\n        }\n\n        RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer\n        parseErrorCode_ = kPointerParseErrorNone;\n        return;\n\n    error:\n        Allocator::Free(tokens_);\n        nameBuffer_ = 0;\n        tokens_ = 0;\n        tokenCount_ = 0;\n        parseErrorOffset_ = i;\n        return;\n    }\n\n    //! Stringify to string or URI fragment representation.\n    /*!\n        \\tparam uriFragment True for stringifying to URI fragment representation. False for string representation.\n        \\tparam OutputStream type of output stream.\n        \\param os The output stream.\n    */\n    template<bool uriFragment, typename OutputStream>\n    bool Stringify(OutputStream& os) const {\n        RAPIDJSON_ASSERT(IsValid());\n\n        if (uriFragment)\n            os.Put('#');\n\n        for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {\n            os.Put('/');\n            for (size_t j = 0; j < t->length; j++) {\n                Ch c = t->name[j];\n                if (c == '~') {\n                    os.Put('~');\n                    os.Put('0');\n                }\n                else if (c == '/') {\n                    os.Put('~');\n                    os.Put('1');\n                }\n                else if (uriFragment && NeedPercentEncode(c)) { \n                    // Transcode to UTF8 sequence\n                    GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);\n                    PercentEncodeStream<OutputStream> target(os);\n                    if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))\n                        return false;\n                    j += source.Tell() - 1;\n                }\n                else\n                    os.Put(c);\n            }\n        }\n        return true;\n    }\n\n    //! A helper stream for decoding a percent-encoded sequence into code unit.\n    /*!\n        This stream decodes %XY triplet into code unit (0-255).\n        If it encounters invalid characters, it sets output code unit as 0 and \n        mark invalid, and to be checked by IsValid().\n    */\n    class PercentDecodeStream {\n    public:\n        typedef typename ValueType::Ch Ch;\n\n        //! Constructor\n        /*!\n            \\param source Start of the stream\n            \\param end Past-the-end of the stream.\n        */\n        PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}\n\n        Ch Take() {\n            if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet\n                valid_ = false;\n                return 0;\n            }\n            src_++;\n            Ch c = 0;\n            for (int j = 0; j < 2; j++) {\n                c = static_cast<Ch>(c << 4);\n                Ch h = *src_;\n                if      (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');\n                else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);\n                else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);\n                else {\n                    valid_ = false;\n                    return 0;\n                }\n                src_++;\n            }\n            return c;\n        }\n\n        size_t Tell() const { return static_cast<size_t>(src_ - head_); }\n        bool IsValid() const { return valid_; }\n\n    private:\n        const Ch* src_;     //!< Current read position.\n        const Ch* head_;    //!< Original head of the string.\n        const Ch* end_;     //!< Past-the-end position.\n        bool valid_;        //!< Whether the parsing is valid.\n    };\n\n    //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.\n    template <typename OutputStream>\n    class PercentEncodeStream {\n    public:\n        PercentEncodeStream(OutputStream& os) : os_(os) {}\n        void Put(char c) { // UTF-8 must be byte\n            unsigned char u = static_cast<unsigned char>(c);\n            static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\n            os_.Put('%');\n            os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));\n            os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));\n        }\n    private:\n        OutputStream& os_;\n    };\n\n    Allocator* allocator_;                  //!< The current allocator. It is either user-supplied or equal to ownAllocator_.\n    Allocator* ownAllocator_;               //!< Allocator owned by this Pointer.\n    Ch* nameBuffer_;                        //!< A buffer containing all names in tokens.\n    Token* tokens_;                         //!< A list of tokens.\n    size_t tokenCount_;                     //!< Number of tokens in tokens_.\n    size_t parseErrorOffset_;               //!< Offset in code unit when parsing fail.\n    PointerParseErrorCode parseErrorCode_;  //!< Parsing error code.\n};\n\n//! GenericPointer for Value (UTF-8, default allocator).\ntypedef GenericPointer<Value> Pointer;\n\n//!@name Helper functions for GenericPointer\n//@{\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {\n    return pointer.Create(root, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {\n    return pointer.Create(document);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {\n    return pointer.Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T>\nconst typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {\n    return pointer.Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);\n}\n\ntemplate <typename T, typename CharType, size_t N>\nconst typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n#endif\n\ntemplate <typename T, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nGetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {\n    return pointer.GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n#endif\n\ntemplate <typename T, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nGetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n#endif\n\ntemplate <typename DocumentType, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nGetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {\n    return pointer.GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n#endif\n\ntemplate <typename DocumentType, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nGetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T>\ntypename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n#endif\n\ntemplate <typename T, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nSetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {\n    return pointer.Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n#endif\n\ntemplate <typename T, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))\nSetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);\n}\n\n// No allocator parameter\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {\n    return pointer.Set(document, value);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {\n    return pointer.Set(document, value);\n}\n#endif\n\ntemplate <typename DocumentType, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nSetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {\n    return pointer.Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\n#if RAPIDJSON_HAS_STDSTRING\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n#endif\n\ntemplate <typename DocumentType, typename CharType, size_t N, typename T2>\nRAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))\nSetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\ntypename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {\n    return pointer.Swap(root, value, a);\n}\n\ntemplate <typename T, typename CharType, size_t N>\ntypename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);\n}\n\ntemplate <typename DocumentType>\ntypename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {\n    return pointer.Swap(document, value);\n}\n\ntemplate <typename DocumentType, typename CharType, size_t N>\ntypename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {\n    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);\n}\n\n//////////////////////////////////////////////////////////////////////////////\n\ntemplate <typename T>\nbool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {\n    return pointer.Erase(root);\n}\n\ntemplate <typename T, typename CharType, size_t N>\nbool EraseValueByPointer(T& root, const CharType(&source)[N]) {\n    return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);\n}\n\n//@}\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_POINTER_H_\n"
  },
  {
    "path": "third-party/rapidjson/prettywriter.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_PRETTYWRITER_H_\n#define RAPIDJSON_PRETTYWRITER_H_\n\n#include \"writer.h\"\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Combination of PrettyWriter format flags.\n/*! \\see PrettyWriter::SetFormatOptions\n */\nenum PrettyFormatOptions {\n    kFormatDefault = 0,         //!< Default pretty formatting.\n    kFormatSingleLineArray = 1  //!< Format arrays on a single line.\n};\n\n//! Writer with indentation and spacing.\n/*!\n    \\tparam OutputStream Type of ouptut os.\n    \\tparam SourceEncoding Encoding of source string.\n    \\tparam TargetEncoding Encoding of output stream.\n    \\tparam StackAllocator Type of allocator for allocating memory of stack.\n*/\ntemplate<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>\nclass PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {\npublic:\n    typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;\n    typedef typename Base::Ch Ch;\n\n    //! Constructor\n    /*! \\param os Output stream.\n        \\param allocator User supplied allocator. If it is null, it will create a private one.\n        \\param levelDepth Initial capacity of stack.\n    */\n    explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : \n        Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}\n\n\n    explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : \n        Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    PrettyWriter(PrettyWriter&& rhs) :\n        Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}\n#endif\n\n    //! Set custom indentation.\n    /*! \\param indentChar       Character for indentation. Must be whitespace character (' ', '\\\\t', '\\\\n', '\\\\r').\n        \\param indentCharCount  Number of indent characters for each indentation level.\n        \\note The default indentation is 4 spaces.\n    */\n    PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {\n        RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\\t' || indentChar == '\\n' || indentChar == '\\r');\n        indentChar_ = indentChar;\n        indentCharCount_ = indentCharCount;\n        return *this;\n    }\n\n    //! Set pretty writer formatting options.\n    /*! \\param options Formatting options.\n    */\n    PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {\n        formatOptions_ = options;\n        return *this;\n    }\n\n    /*! @name Implementation of Handler\n        \\see Handler\n    */\n    //@{\n\n    bool Null()                 { PrettyPrefix(kNullType);   return Base::WriteNull(); }\n    bool Bool(bool b)           { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }\n    bool Int(int i)             { PrettyPrefix(kNumberType); return Base::WriteInt(i); }\n    bool Uint(unsigned u)       { PrettyPrefix(kNumberType); return Base::WriteUint(u); }\n    bool Int64(int64_t i64)     { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }\n    bool Uint64(uint64_t u64)   { PrettyPrefix(kNumberType); return Base::WriteUint64(u64);  }\n    bool Double(double d)       { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        PrettyPrefix(kNumberType);\n        return Base::WriteString(str, length);\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        PrettyPrefix(kStringType);\n        return Base::WriteString(str, length);\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool String(const std::basic_string<Ch>& str) {\n        return String(str.data(), SizeType(str.size()));\n    }\n#endif\n\n    bool StartObject() {\n        PrettyPrefix(kObjectType);\n        new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);\n        return Base::WriteStartObject();\n    }\n\n    bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool Key(const std::basic_string<Ch>& str) {\n        return Key(str.data(), SizeType(str.size()));\n    }\n#endif\n\t\n    bool EndObject(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object\n        RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object\n        RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value\n       \n        bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\n\n        if (!empty) {\n            Base::os_->Put('\\n');\n            WriteIndent();\n        }\n        bool ret = Base::WriteEndObject();\n        (void)ret;\n        RAPIDJSON_ASSERT(ret == true);\n        if (Base::level_stack_.Empty()) // end of json text\n            Base::Flush();\n        return true;\n    }\n\n    bool StartArray() {\n        PrettyPrefix(kArrayType);\n        new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);\n        return Base::WriteStartArray();\n    }\n\n    bool EndArray(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));\n        RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);\n        bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;\n\n        if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {\n            Base::os_->Put('\\n');\n            WriteIndent();\n        }\n        bool ret = Base::WriteEndArray();\n        (void)ret;\n        RAPIDJSON_ASSERT(ret == true);\n        if (Base::level_stack_.Empty()) // end of json text\n            Base::Flush();\n        return true;\n    }\n\n    //@}\n\n    /*! @name Convenience extensions */\n    //@{\n\n    //! Simpler but slower overload.\n    bool String(const Ch* str) { return String(str, internal::StrLen(str)); }\n    bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }\n\n    //@}\n\n    //! Write a raw JSON value.\n    /*!\n        For user to write a stringified JSON as a value.\n\n        \\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.\n        \\param length Length of the json.\n        \\param type Type of the root of json.\n        \\note When using PrettyWriter::RawValue(), the result json may not be indented correctly.\n    */\n    bool RawValue(const Ch* json, size_t length, Type type) {\n        RAPIDJSON_ASSERT(json != 0);\n        PrettyPrefix(type);\n        return Base::WriteRawValue(json, length);\n    }\n\nprotected:\n    void PrettyPrefix(Type type) {\n        (void)type;\n        if (Base::level_stack_.GetSize() != 0) { // this value is not at root\n            typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();\n\n            if (level->inArray) {\n                if (level->valueCount > 0) {\n                    Base::os_->Put(','); // add comma if it is not the first element in array\n                    if (formatOptions_ & kFormatSingleLineArray)\n                        Base::os_->Put(' ');\n                }\n\n                if (!(formatOptions_ & kFormatSingleLineArray)) {\n                    Base::os_->Put('\\n');\n                    WriteIndent();\n                }\n            }\n            else {  // in object\n                if (level->valueCount > 0) {\n                    if (level->valueCount % 2 == 0) {\n                        Base::os_->Put(',');\n                        Base::os_->Put('\\n');\n                    }\n                    else {\n                        Base::os_->Put(':');\n                        Base::os_->Put(' ');\n                    }\n                }\n                else\n                    Base::os_->Put('\\n');\n\n                if (level->valueCount % 2 == 0)\n                    WriteIndent();\n            }\n            if (!level->inArray && level->valueCount % 2 == 0)\n                RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\n            level->valueCount++;\n        }\n        else {\n            RAPIDJSON_ASSERT(!Base::hasRoot_);  // Should only has one and only one root.\n            Base::hasRoot_ = true;\n        }\n    }\n\n    void WriteIndent()  {\n        size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;\n        PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);\n    }\n\n    Ch indentChar_;\n    unsigned indentCharCount_;\n    PrettyFormatOptions formatOptions_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    PrettyWriter(const PrettyWriter&);\n    PrettyWriter& operator=(const PrettyWriter&);\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "third-party/rapidjson/rapidjson.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_RAPIDJSON_H_\n#define RAPIDJSON_RAPIDJSON_H_\n\n/*!\\file rapidjson.h\n    \\brief common definitions and configuration\n    \n    \\see RAPIDJSON_CONFIG\n */\n\n/*! \\defgroup RAPIDJSON_CONFIG RapidJSON configuration\n    \\brief Configuration macros for library features\n\n    Some RapidJSON features are configurable to adapt the library to a wide\n    variety of platforms, environments and usage scenarios.  Most of the\n    features can be configured in terms of overriden or predefined\n    preprocessor macros at compile-time.\n\n    Some additional customization is available in the \\ref RAPIDJSON_ERRORS APIs.\n\n    \\note These macros should be given on the compiler command-line\n          (where applicable)  to avoid inconsistent values when compiling\n          different translation units of a single application.\n */\n\n#include <cstdlib>  // malloc(), realloc(), free(), size_t\n#include <cstring>  // memset(), memcpy(), memmove(), memcmp()\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_VERSION_STRING\n//\n// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt.\n//\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n// token stringification\n#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)\n#define RAPIDJSON_DO_STRINGIFY(x) #x\n\n// token concatenation\n#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)\n#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)\n#define RAPIDJSON_DO_JOIN2(X, Y) X##Y\n//!@endcond\n\n/*! \\def RAPIDJSON_MAJOR_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Major version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_MINOR_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Minor version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_PATCH_VERSION\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Patch version of RapidJSON in integer.\n*/\n/*! \\def RAPIDJSON_VERSION_STRING\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Version of RapidJSON in \"<major>.<minor>.<patch>\" string format.\n*/\n#define RAPIDJSON_MAJOR_VERSION 1\n#define RAPIDJSON_MINOR_VERSION 1\n#define RAPIDJSON_PATCH_VERSION 0\n#define RAPIDJSON_VERSION_STRING \\\n    RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION)\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NAMESPACE_(BEGIN|END)\n/*! \\def RAPIDJSON_NAMESPACE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace\n\n    In order to avoid symbol clashes and/or \"One Definition Rule\" errors\n    between multiple inclusions of (different versions of) RapidJSON in\n    a single binary, users can customize the name of the main RapidJSON\n    namespace.\n\n    In case of a single nesting level, defining \\c RAPIDJSON_NAMESPACE\n    to a custom name (e.g. \\c MyRapidJSON) is sufficient.  If multiple\n    levels are needed, both \\ref RAPIDJSON_NAMESPACE_BEGIN and \\ref\n    RAPIDJSON_NAMESPACE_END need to be defined as well:\n\n    \\code\n    // in some .cpp file\n    #define RAPIDJSON_NAMESPACE my::rapidjson\n    #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {\n    #define RAPIDJSON_NAMESPACE_END   } }\n    #include \"rapidjson/...\"\n    \\endcode\n\n    \\see rapidjson\n */\n/*! \\def RAPIDJSON_NAMESPACE_BEGIN\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace (opening expression)\n    \\see RAPIDJSON_NAMESPACE\n*/\n/*! \\def RAPIDJSON_NAMESPACE_END\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief   provide custom rapidjson namespace (closing expression)\n    \\see RAPIDJSON_NAMESPACE\n*/\n#ifndef RAPIDJSON_NAMESPACE\n#define RAPIDJSON_NAMESPACE rapidjson\n#endif\n#ifndef RAPIDJSON_NAMESPACE_BEGIN\n#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {\n#endif\n#ifndef RAPIDJSON_NAMESPACE_END\n#define RAPIDJSON_NAMESPACE_END }\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_HAS_STDSTRING\n\n#ifndef RAPIDJSON_HAS_STDSTRING\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation\n#else\n#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default\n#endif\n/*! \\def RAPIDJSON_HAS_STDSTRING\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Enable RapidJSON support for \\c std::string\n\n    By defining this preprocessor symbol to \\c 1, several convenience functions for using\n    \\ref rapidjson::GenericValue with \\c std::string are enabled, especially\n    for construction and comparison.\n\n    \\hideinitializer\n*/\n#endif // !defined(RAPIDJSON_HAS_STDSTRING)\n\n#if RAPIDJSON_HAS_STDSTRING\n#include <string>\n#endif // RAPIDJSON_HAS_STDSTRING\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NO_INT64DEFINE\n\n/*! \\def RAPIDJSON_NO_INT64DEFINE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Use external 64-bit integer types.\n\n    RapidJSON requires the 64-bit integer types \\c int64_t and  \\c uint64_t types\n    to be available at global scope.\n\n    If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to\n    prevent RapidJSON from defining its own types.\n*/\n#ifndef RAPIDJSON_NO_INT64DEFINE\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#if defined(_MSC_VER) && (_MSC_VER < 1800)\t// Visual Studio 2013\n#include \"msinttypes/stdint.h\"\n#include \"msinttypes/inttypes.h\"\n#else\n// Other compilers should have this.\n#include <stdint.h>\n#include <inttypes.h>\n#endif\n//!@endcond\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_NO_INT64DEFINE\n#endif\n#endif // RAPIDJSON_NO_INT64TYPEDEF\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_FORCEINLINE\n\n#ifndef RAPIDJSON_FORCEINLINE\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#if defined(_MSC_VER) && defined(NDEBUG)\n#define RAPIDJSON_FORCEINLINE __forceinline\n#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG)\n#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))\n#else\n#define RAPIDJSON_FORCEINLINE\n#endif\n//!@endcond\n#endif // RAPIDJSON_FORCEINLINE\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ENDIAN\n#define RAPIDJSON_LITTLEENDIAN  0   //!< Little endian machine\n#define RAPIDJSON_BIGENDIAN     1   //!< Big endian machine\n\n//! Endianness of the machine.\n/*!\n    \\def RAPIDJSON_ENDIAN\n    \\ingroup RAPIDJSON_CONFIG\n\n    GCC 4.6 provided macro for detecting endianness of the target machine. But other\n    compilers may not have this. User can define RAPIDJSON_ENDIAN to either\n    \\ref RAPIDJSON_LITTLEENDIAN or \\ref RAPIDJSON_BIGENDIAN.\n\n    Default detection implemented with reference to\n    \\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html\n    \\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp\n*/\n#ifndef RAPIDJSON_ENDIAN\n// Detect with GCC 4.6's macro\n#  ifdef __BYTE_ORDER__\n#    if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#    elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#    else\n#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.\n#    endif // __BYTE_ORDER__\n// Detect with GLIBC's endian.h\n#  elif defined(__GLIBC__)\n#    include <endian.h>\n#    if (__BYTE_ORDER == __LITTLE_ENDIAN)\n#      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#    elif (__BYTE_ORDER == __BIG_ENDIAN)\n#      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#    else\n#      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.\n#   endif // __GLIBC__\n// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro\n#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n// Detect with architecture macros\n#  elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN\n#  elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(_MSC_VER) && defined(_M_ARM)\n#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN\n#  elif defined(RAPIDJSON_DOXYGEN_RUNNING)\n#    define RAPIDJSON_ENDIAN\n#  else\n#    error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.   \n#  endif\n#endif // RAPIDJSON_ENDIAN\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_64BIT\n\n//! Whether using 64-bit architecture\n#ifndef RAPIDJSON_64BIT\n#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__)\n#define RAPIDJSON_64BIT 1\n#else\n#define RAPIDJSON_64BIT 0\n#endif\n#endif // RAPIDJSON_64BIT\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ALIGN\n\n//! Data alignment of the machine.\n/*! \\ingroup RAPIDJSON_CONFIG\n    \\param x pointer to align\n\n    Some machines require strict data alignment. Currently the default uses 4 bytes\n    alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.\n    User can customize by defining the RAPIDJSON_ALIGN function macro.\n*/\n#ifndef RAPIDJSON_ALIGN\n#if RAPIDJSON_64BIT == 1\n#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))\n#else\n#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)\n#endif\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_UINT64_C2\n\n//! Construct a 64-bit literal by a pair of 32-bit integer.\n/*!\n    64-bit literal with or without ULL suffix is prone to compiler warnings.\n    UINT64_C() is C macro which cause compilation problems.\n    Use this macro to define 64-bit constants by a pair of 32-bit integer.\n*/\n#ifndef RAPIDJSON_UINT64_C2\n#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n//! Use only lower 48-bit address for some pointers.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n\n    This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address.\n    The higher 16-bit can be used for storing other data.\n    \\c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture.\n*/\n#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION\n#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)\n#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1\n#else\n#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0\n#endif\n#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION\n\n#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1\n#if RAPIDJSON_64BIT != 1\n#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1\n#endif\n#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))\n#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))\n#else\n#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x))\n#define RAPIDJSON_GETPOINTER(type, p) (p)\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD\n\n/*! \\def RAPIDJSON_SIMD\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief Enable SSE2/SSE4.2/Neon optimization.\n\n    RapidJSON supports optimized implementations for some parsing operations\n    based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel\n    or ARM compatible processors.\n\n    To enable these optimizations, three different symbols can be defined;\n    \\code\n    // Enable SSE2 optimization.\n    #define RAPIDJSON_SSE2\n\n    // Enable SSE4.2 optimization.\n    #define RAPIDJSON_SSE42\n    \\endcode\n\n    // Enable ARM Neon optimization.\n    #define RAPIDJSON_NEON\n    \\endcode\n\n    \\c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined.\n\n    If any of these symbols is defined, RapidJSON defines the macro\n    \\c RAPIDJSON_SIMD to indicate the availability of the optimized code.\n*/\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \\\n    || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)\n#define RAPIDJSON_SIMD\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_NO_SIZETYPEDEFINE\n\n#ifndef RAPIDJSON_NO_SIZETYPEDEFINE\n/*! \\def RAPIDJSON_NO_SIZETYPEDEFINE\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-provided \\c SizeType definition.\n\n    In order to avoid using 32-bit size types for indexing strings and arrays,\n    define this preprocessor symbol and provide the type rapidjson::SizeType\n    before including RapidJSON:\n    \\code\n    #define RAPIDJSON_NO_SIZETYPEDEFINE\n    namespace rapidjson { typedef ::std::size_t SizeType; }\n    #include \"rapidjson/...\"\n    \\endcode\n\n    \\see rapidjson::SizeType\n*/\n#ifdef RAPIDJSON_DOXYGEN_RUNNING\n#define RAPIDJSON_NO_SIZETYPEDEFINE\n#endif\nRAPIDJSON_NAMESPACE_BEGIN\n//! Size type (for string lengths, array sizes, etc.)\n/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,\n    instead of using \\c size_t. Users may override the SizeType by defining\n    \\ref RAPIDJSON_NO_SIZETYPEDEFINE.\n*/\ntypedef unsigned SizeType;\nRAPIDJSON_NAMESPACE_END\n#endif\n\n// always import std::size_t to rapidjson namespace\nRAPIDJSON_NAMESPACE_BEGIN\nusing std::size_t;\nRAPIDJSON_NAMESPACE_END\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_ASSERT\n\n//! Assertion.\n/*! \\ingroup RAPIDJSON_CONFIG\n    By default, rapidjson uses C \\c assert() for internal assertions.\n    User can override it by defining RAPIDJSON_ASSERT(x) macro.\n\n    \\note Parsing errors are handled and can be customized by the\n          \\ref RAPIDJSON_ERRORS APIs.\n*/\n#ifndef RAPIDJSON_ASSERT\n#include <cassert>\n#define RAPIDJSON_ASSERT(x) assert(x)\n#endif // RAPIDJSON_ASSERT\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_STATIC_ASSERT\n\n// Prefer C++11 static_assert, if available\n#ifndef RAPIDJSON_STATIC_ASSERT\n#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )\n#define RAPIDJSON_STATIC_ASSERT(x) \\\n   static_assert(x, RAPIDJSON_STRINGIFY(x))\n#endif // C++11\n#endif // RAPIDJSON_STATIC_ASSERT\n\n// Adopt C++03 implementation from boost\n#ifndef RAPIDJSON_STATIC_ASSERT\n#ifndef __clang__\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#endif\nRAPIDJSON_NAMESPACE_BEGIN\ntemplate <bool x> struct STATIC_ASSERTION_FAILURE;\ntemplate <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };\ntemplate <size_t x> struct StaticAssertTest {};\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__GNUC__)\n#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))\n#else\n#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE \n#endif\n#ifndef __clang__\n//!@endcond\n#endif\n\n/*! \\def RAPIDJSON_STATIC_ASSERT\n    \\brief (Internal) macro to check for conditions at compile-time\n    \\param x compile-time condition\n    \\hideinitializer\n */\n#define RAPIDJSON_STATIC_ASSERT(x) \\\n    typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \\\n      sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \\\n    RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE\n#endif // RAPIDJSON_STATIC_ASSERT\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY\n\n//! Compiler branching hint for expression with high probability to be true.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n    \\param x Boolean expression likely to be true.\n*/\n#ifndef RAPIDJSON_LIKELY\n#if defined(__GNUC__) || defined(__clang__)\n#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)\n#else\n#define RAPIDJSON_LIKELY(x) (x)\n#endif\n#endif\n\n//! Compiler branching hint for expression with low probability to be true.\n/*!\n    \\ingroup RAPIDJSON_CONFIG\n    \\param x Boolean expression unlikely to be true.\n*/\n#ifndef RAPIDJSON_UNLIKELY\n#if defined(__GNUC__) || defined(__clang__)\n#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)\n#else\n#define RAPIDJSON_UNLIKELY(x) (x)\n#endif\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Helpers\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n\n#define RAPIDJSON_MULTILINEMACRO_BEGIN do {  \n#define RAPIDJSON_MULTILINEMACRO_END \\\n} while((void)0, 0)\n\n// adopted from Boost\n#define RAPIDJSON_VERSION_CODE(x,y,z) \\\n  (((x)*100000) + ((y)*100) + (z))\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF\n\n#if defined(__GNUC__)\n#define RAPIDJSON_GNUC \\\n    RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)\n#endif\n\n#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))\n\n#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))\n#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)\n#define RAPIDJSON_DIAG_OFF(x) \\\n    RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))\n\n// push/pop support in Clang and GCC>=4.6\n#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))\n#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)\n#define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)\n#else // GCC >= 4.2, < 4.6\n#define RAPIDJSON_DIAG_PUSH /* ignored */\n#define RAPIDJSON_DIAG_POP /* ignored */\n#endif\n\n#elif defined(_MSC_VER)\n\n// pragma (MSVC specific)\n#define RAPIDJSON_PRAGMA(x) __pragma(x)\n#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))\n\n#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)\n#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)\n#define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)\n\n#else\n\n#define RAPIDJSON_DIAG_OFF(x) /* ignored */\n#define RAPIDJSON_DIAG_PUSH   /* ignored */\n#define RAPIDJSON_DIAG_POP    /* ignored */\n\n#endif // RAPIDJSON_DIAG_*\n\n///////////////////////////////////////////////////////////////////////////////\n// C++11 features\n\n#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#if defined(__clang__)\n#if __has_feature(cxx_rvalue_references) && \\\n    (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1\n#else\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0\n#endif\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \\\n      (defined(_MSC_VER) && _MSC_VER >= 1600)\n\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1\n#else\n#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0\n#endif\n#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS\n\n#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT\n#if defined(__clang__)\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))\n//    (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1\n#else\n#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0\n#endif\n#endif\n#if RAPIDJSON_HAS_CXX11_NOEXCEPT\n#define RAPIDJSON_NOEXCEPT noexcept\n#else\n#define RAPIDJSON_NOEXCEPT /* noexcept */\n#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT\n\n// no automatic detection, yet\n#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS\n#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0\n#endif\n\n#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR\n#if defined(__clang__)\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)\n#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \\\n      (defined(_MSC_VER) && _MSC_VER >= 1700)\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1\n#else\n#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0\n#endif\n#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR\n\n//!@endcond\n\n///////////////////////////////////////////////////////////////////////////////\n// new/delete\n\n#ifndef RAPIDJSON_NEW\n///! customization point for global \\c new\n#define RAPIDJSON_NEW(TypeName) new TypeName\n#endif\n#ifndef RAPIDJSON_DELETE\n///! customization point for global \\c delete\n#define RAPIDJSON_DELETE(x) delete x\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n// Type\n\n/*! \\namespace rapidjson\n    \\brief main RapidJSON namespace\n    \\see RAPIDJSON_NAMESPACE\n*/\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Type of JSON value\nenum Type {\n    kNullType = 0,      //!< null\n    kFalseType = 1,     //!< false\n    kTrueType = 2,      //!< true\n    kObjectType = 3,    //!< object\n    kArrayType = 4,     //!< array \n    kStringType = 5,    //!< string\n    kNumberType = 6     //!< number\n};\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "third-party/rapidjson/reader.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n//\n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_READER_H_\n#define RAPIDJSON_READER_H_\n\n/*! \\file reader.h */\n\n#include \"allocators.h\"\n#include \"stream.h\"\n#include \"encodedstream.h\"\n#include \"internal/meta.h\"\n#include \"internal/stack.h\"\n#include \"internal/strtod.h\"\n#include <limits>\n\n#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)\n#include <intrin.h>\n#pragma intrinsic(_BitScanForward)\n#endif\n#ifdef RAPIDJSON_SSE42\n#include <nmmintrin.h>\n#elif defined(RAPIDJSON_SSE2)\n#include <emmintrin.h>\n#elif defined(RAPIDJSON_NEON)\n#include <arm_neon.h>\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant\nRAPIDJSON_DIAG_OFF(4702)  // unreachable code\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(old-style-cast)\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(switch-enum)\n#endif\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define RAPIDJSON_NOTHING /* deliberately empty */\n#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN\n#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \\\n    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)\n//!@endcond\n\n/*! \\def RAPIDJSON_PARSE_ERROR_NORETURN\n    \\ingroup RAPIDJSON_ERRORS\n    \\brief Macro to indicate a parse error.\n    \\param parseErrorCode \\ref rapidjson::ParseErrorCode of the error\n    \\param offset  position of the error in JSON input (\\c size_t)\n\n    This macros can be used as a customization point for the internal\n    error handling mechanism of RapidJSON.\n\n    A common usage model is to throw an exception instead of requiring the\n    caller to explicitly check the \\ref rapidjson::GenericReader::Parse's\n    return value:\n\n    \\code\n    #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \\\n       throw ParseException(parseErrorCode, #parseErrorCode, offset)\n\n    #include <stdexcept>               // std::runtime_error\n    #include \"rapidjson/error/error.h\" // rapidjson::ParseResult\n\n    struct ParseException : std::runtime_error, rapidjson::ParseResult {\n      ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)\n        : std::runtime_error(msg), ParseResult(code, offset) {}\n    };\n\n    #include \"rapidjson/reader.h\"\n    \\endcode\n\n    \\see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse\n */\n#ifndef RAPIDJSON_PARSE_ERROR_NORETURN\n#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \\\n    SetParseError(parseErrorCode, offset); \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n\n/*! \\def RAPIDJSON_PARSE_ERROR\n    \\ingroup RAPIDJSON_ERRORS\n    \\brief (Internal) macro to indicate and handle a parse error.\n    \\param parseErrorCode \\ref rapidjson::ParseErrorCode of the error\n    \\param offset  position of the error in JSON input (\\c size_t)\n\n    Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.\n\n    \\see RAPIDJSON_PARSE_ERROR_NORETURN\n    \\hideinitializer\n */\n#ifndef RAPIDJSON_PARSE_ERROR\n#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \\\n    RAPIDJSON_MULTILINEMACRO_BEGIN \\\n    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \\\n    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \\\n    RAPIDJSON_MULTILINEMACRO_END\n#endif\n\n#include \"error/error.h\" // ParseErrorCode, ParseResult\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// ParseFlag\n\n/*! \\def RAPIDJSON_PARSE_DEFAULT_FLAGS\n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-defined kParseDefaultFlags definition.\n\n    User can define this as any \\c ParseFlag combinations.\n*/\n#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS\n#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags\n#endif\n\n//! Combination of parseFlags\n/*! \\see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream\n */\nenum ParseFlag {\n    kParseNoFlags = 0,              //!< No flags are set.\n    kParseInsituFlag = 1,           //!< In-situ(destructive) parsing.\n    kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.\n    kParseIterativeFlag = 4,        //!< Iterative(constant complexity in terms of function call stack size) parsing.\n    kParseStopWhenDoneFlag = 8,     //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.\n    kParseFullPrecisionFlag = 16,   //!< Parse number in full precision (but slower).\n    kParseCommentsFlag = 32,        //!< Allow one-line (//) and multi-line (/**/) comments.\n    kParseNumbersAsStringsFlag = 64,    //!< Parse all numbers (ints/doubles) as strings.\n    kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.\n    kParseNanAndInfFlag = 256,      //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.\n    kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Handler\n\n/*! \\class rapidjson::Handler\n    \\brief Concept for receiving events from GenericReader upon parsing.\n    The functions return true if no error occurs. If they return false,\n    the event publisher should terminate the process.\n\\code\nconcept Handler {\n    typename Ch;\n\n    bool Null();\n    bool Bool(bool b);\n    bool Int(int i);\n    bool Uint(unsigned i);\n    bool Int64(int64_t i);\n    bool Uint64(uint64_t i);\n    bool Double(double d);\n    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)\n    bool RawNumber(const Ch* str, SizeType length, bool copy);\n    bool String(const Ch* str, SizeType length, bool copy);\n    bool StartObject();\n    bool Key(const Ch* str, SizeType length, bool copy);\n    bool EndObject(SizeType memberCount);\n    bool StartArray();\n    bool EndArray(SizeType elementCount);\n};\n\\endcode\n*/\n///////////////////////////////////////////////////////////////////////////////\n// BaseReaderHandler\n\n//! Default implementation of Handler.\n/*! This can be used as base class of any reader handler.\n    \\note implements Handler concept\n*/\ntemplate<typename Encoding = UTF8<>, typename Derived = void>\nstruct BaseReaderHandler {\n    typedef typename Encoding::Ch Ch;\n\n    typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;\n\n    bool Default() { return true; }\n    bool Null() { return static_cast<Override&>(*this).Default(); }\n    bool Bool(bool) { return static_cast<Override&>(*this).Default(); }\n    bool Int(int) { return static_cast<Override&>(*this).Default(); }\n    bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }\n    bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }\n    bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }\n    bool Double(double) { return static_cast<Override&>(*this).Default(); }\n    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)\n    bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }\n    bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }\n    bool StartObject() { return static_cast<Override&>(*this).Default(); }\n    bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }\n    bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }\n    bool StartArray() { return static_cast<Override&>(*this).Default(); }\n    bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// StreamLocalCopy\n\nnamespace internal {\n\ntemplate<typename Stream, int = StreamTraits<Stream>::copyOptimization>\nclass StreamLocalCopy;\n\n//! Do copy optimization.\ntemplate<typename Stream>\nclass StreamLocalCopy<Stream, 1> {\npublic:\n    StreamLocalCopy(Stream& original) : s(original), original_(original) {}\n    ~StreamLocalCopy() { original_ = s; }\n\n    Stream s;\n\nprivate:\n    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;\n\n    Stream& original_;\n};\n\n//! Keep reference.\ntemplate<typename Stream>\nclass StreamLocalCopy<Stream, 0> {\npublic:\n    StreamLocalCopy(Stream& original) : s(original) {}\n\n    Stream& s;\n\nprivate:\n    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;\n};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// SkipWhitespace\n\n//! Skip the JSON white spaces in a stream.\n/*! \\param is A input stream for skipping white spaces.\n    \\note This function has SSE2/SSE4.2 specialization.\n*/\ntemplate<typename InputStream>\nvoid SkipWhitespace(InputStream& is) {\n    internal::StreamLocalCopy<InputStream> copy(is);\n    InputStream& s(copy.s);\n\n    typename InputStream::Ch c;\n    while ((c = s.Peek()) == ' ' || c == '\\n' || c == '\\r' || c == '\\t')\n        s.Take();\n}\n\ninline const char* SkipWhitespace(const char* p, const char* end) {\n    while (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    return p;\n}\n\n#ifdef RAPIDJSON_SSE42\n//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.\ninline const char *SkipWhitespace_SIMD(const char* p) {\n    // Fast return for single non-whitespace\n    if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n        ++p;\n    else\n        return p;\n\n    // 16-byte align to the next boundary\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    while (p != nextAligned)\n        if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n            ++p;\n        else\n            return p;\n\n    // The rest of string using SIMD\n    static const char whitespace[16] = \" \\n\\r\\t\";\n    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));\n\n    for (;; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);\n        if (r != 16)    // some of characters is non-whitespace\n            return p + r;\n    }\n}\n\ninline const char *SkipWhitespace_SIMD(const char* p, const char* end) {\n    // Fast return for single non-whitespace\n    if (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    else\n        return p;\n\n    // The middle of string using SIMD\n    static const char whitespace[16] = \" \\n\\r\\t\";\n    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));\n\n    for (; p <= end - 16; p += 16) {\n        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));\n        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);\n        if (r != 16)    // some of characters is non-whitespace\n            return p + r;\n    }\n\n    return SkipWhitespace(p, end);\n}\n\n#elif defined(RAPIDJSON_SSE2)\n\n//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.\ninline const char *SkipWhitespace_SIMD(const char* p) {\n    // Fast return for single non-whitespace\n    if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n        ++p;\n    else\n        return p;\n\n    // 16-byte align to the next boundary\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    while (p != nextAligned)\n        if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n            ++p;\n        else\n            return p;\n\n    // The rest of string\n    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }\n    static const char whitespaces[4][16] = { C16(' '), C16('\\n'), C16('\\r'), C16('\\t') };\n    #undef C16\n\n    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));\n    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));\n    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));\n    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));\n\n    for (;; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        __m128i x = _mm_cmpeq_epi8(s, w0);\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));\n        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));\n        if (r != 0) {   // some of characters may be non-whitespace\n#ifdef _MSC_VER         // Find the index of first non-whitespace\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            return p + offset;\n#else\n            return p + __builtin_ffs(r) - 1;\n#endif\n        }\n    }\n}\n\ninline const char *SkipWhitespace_SIMD(const char* p, const char* end) {\n    // Fast return for single non-whitespace\n    if (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    else\n        return p;\n\n    // The rest of string\n    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }\n    static const char whitespaces[4][16] = { C16(' '), C16('\\n'), C16('\\r'), C16('\\t') };\n    #undef C16\n\n    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));\n    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));\n    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));\n    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));\n\n    for (; p <= end - 16; p += 16) {\n        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));\n        __m128i x = _mm_cmpeq_epi8(s, w0);\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));\n        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));\n        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));\n        if (r != 0) {   // some of characters may be non-whitespace\n#ifdef _MSC_VER         // Find the index of first non-whitespace\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            return p + offset;\n#else\n            return p + __builtin_ffs(r) - 1;\n#endif\n        }\n    }\n\n    return SkipWhitespace(p, end);\n}\n\n#elif defined(RAPIDJSON_NEON)\n\n//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once.\ninline const char *SkipWhitespace_SIMD(const char* p) {\n    // Fast return for single non-whitespace\n    if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n        ++p;\n    else\n        return p;\n\n    // 16-byte align to the next boundary\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    while (p != nextAligned)\n        if (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t')\n            ++p;\n        else\n            return p;\n\n    const uint8x16_t w0 = vmovq_n_u8(' ');\n    const uint8x16_t w1 = vmovq_n_u8('\\n');\n    const uint8x16_t w2 = vmovq_n_u8('\\r');\n    const uint8x16_t w3 = vmovq_n_u8('\\t');\n\n    for (;; p += 16) {\n        const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));\n        uint8x16_t x = vceqq_u8(s, w0);\n        x = vorrq_u8(x, vceqq_u8(s, w1));\n        x = vorrq_u8(x, vceqq_u8(s, w2));\n        x = vorrq_u8(x, vceqq_u8(s, w3));\n\n        x = vmvnq_u8(x);                       // Negate\n        x = vrev64q_u8(x);                     // Rev in 64\n        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n        if (low == 0) {\n            if (high != 0) {\n                int lz =__builtin_clzll(high);;\n                return p + 8 + (lz >> 3);\n            }\n        } else {\n            int lz = __builtin_clzll(low);;\n            return p + (lz >> 3);\n        }\n    }\n}\n\ninline const char *SkipWhitespace_SIMD(const char* p, const char* end) {\n    // Fast return for single non-whitespace\n    if (p != end && (*p == ' ' || *p == '\\n' || *p == '\\r' || *p == '\\t'))\n        ++p;\n    else\n        return p;\n\n    const uint8x16_t w0 = vmovq_n_u8(' ');\n    const uint8x16_t w1 = vmovq_n_u8('\\n');\n    const uint8x16_t w2 = vmovq_n_u8('\\r');\n    const uint8x16_t w3 = vmovq_n_u8('\\t');\n\n    for (; p <= end - 16; p += 16) {\n        const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));\n        uint8x16_t x = vceqq_u8(s, w0);\n        x = vorrq_u8(x, vceqq_u8(s, w1));\n        x = vorrq_u8(x, vceqq_u8(s, w2));\n        x = vorrq_u8(x, vceqq_u8(s, w3));\n\n        x = vmvnq_u8(x);                       // Negate\n        x = vrev64q_u8(x);                     // Rev in 64\n        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n        if (low == 0) {\n            if (high != 0) {\n                int lz = __builtin_clzll(high);\n                return p + 8 + (lz >> 3);\n            }\n        } else {\n            int lz = __builtin_clzll(low);\n            return p + (lz >> 3);\n        }\n    }\n\n    return SkipWhitespace(p, end);\n}\n\n#endif // RAPIDJSON_NEON\n\n#ifdef RAPIDJSON_SIMD\n//! Template function specialization for InsituStringStream\ntemplate<> inline void SkipWhitespace(InsituStringStream& is) {\n    is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));\n}\n\n//! Template function specialization for StringStream\ntemplate<> inline void SkipWhitespace(StringStream& is) {\n    is.src_ = SkipWhitespace_SIMD(is.src_);\n}\n\ntemplate<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {\n    is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);\n}\n#endif // RAPIDJSON_SIMD\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericReader\n\n//! SAX-style JSON parser. Use \\ref Reader for UTF8 encoding and default allocator.\n/*! GenericReader parses JSON text from a stream, and send events synchronously to an\n    object implementing Handler concept.\n\n    It needs to allocate a stack for storing a single decoded string during\n    non-destructive parsing.\n\n    For in-situ parsing, the decoded string is directly written to the source\n    text string, no temporary buffer is required.\n\n    A GenericReader object can be reused for parsing multiple JSON text.\n\n    \\tparam SourceEncoding Encoding of the input stream.\n    \\tparam TargetEncoding Encoding of the parse output.\n    \\tparam StackAllocator Allocator type for stack.\n*/\ntemplate <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>\nclass GenericReader {\npublic:\n    typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type\n\n    //! Constructor.\n    /*! \\param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)\n        \\param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)\n    */\n    GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}\n\n    //! Parse JSON text.\n    /*! \\tparam parseFlags Combination of \\ref ParseFlag.\n        \\tparam InputStream Type of input stream, implementing Stream concept.\n        \\tparam Handler Type of handler, implementing Handler concept.\n        \\param is Input stream to be parsed.\n        \\param handler The handler to receive events.\n        \\return Whether the parsing is successful.\n    */\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    ParseResult Parse(InputStream& is, Handler& handler) {\n        if (parseFlags & kParseIterativeFlag)\n            return IterativeParse<parseFlags>(is, handler);\n\n        parseResult_.Clear();\n\n        ClearStackOnExit scope(*this);\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n        if (RAPIDJSON_UNLIKELY(is.Peek() == '\\0')) {\n            RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        }\n        else {\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n            if (!(parseFlags & kParseStopWhenDoneFlag)) {\n                SkipWhitespaceAndComments<parseFlags>(is);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n\n                if (RAPIDJSON_UNLIKELY(is.Peek() != '\\0')) {\n                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n                }\n            }\n        }\n\n        return parseResult_;\n    }\n\n    //! Parse JSON text (with \\ref kParseDefaultFlags)\n    /*! \\tparam InputStream Type of input stream, implementing Stream concept\n        \\tparam Handler Type of handler, implementing Handler concept.\n        \\param is Input stream to be parsed.\n        \\param handler The handler to receive events.\n        \\return Whether the parsing is successful.\n    */\n    template <typename InputStream, typename Handler>\n    ParseResult Parse(InputStream& is, Handler& handler) {\n        return Parse<kParseDefaultFlags>(is, handler);\n    }\n\n    //! Initialize JSON text token-by-token parsing\n    /*!\n     */\n    void IterativeParseInit() {\n        parseResult_.Clear();\n        state_ = IterativeParsingStartState;\n    }\n    \n    //! Parse one token from JSON text\n    /*! \\tparam InputStream Type of input stream, implementing Stream concept\n        \\tparam Handler Type of handler, implementing Handler concept.\n        \\param is Input stream to be parsed.\n        \\param handler The handler to receive events.\n        \\return Whether the parsing is successful.\n     */\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    bool IterativeParseNext(InputStream& is, Handler& handler) {\n        while (RAPIDJSON_LIKELY(is.Peek() != '\\0')) {\n            SkipWhitespaceAndComments<parseFlags>(is);\n            \n            Token t = Tokenize(is.Peek());\n            IterativeParsingState n = Predict(state_, t);\n            IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);\n            \n            // If we've finished or hit an error...\n            if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {\n                // Report errors.\n                if (d == IterativeParsingErrorState) {\n                    HandleError(state_, is);\n                    return false;\n                }\n            \n                // Transition to the finish state.\n                RAPIDJSON_ASSERT(d == IterativeParsingFinishState);\n                state_ = d;\n                \n                // If StopWhenDone is not set...\n                if (!(parseFlags & kParseStopWhenDoneFlag)) {\n                    // ... and extra non-whitespace data is found...\n                    SkipWhitespaceAndComments<parseFlags>(is);\n                    if (is.Peek() != '\\0') {\n                        // ... this is considered an error.\n                        HandleError(state_, is);\n                        return false;\n                    }\n                }\n                \n                // Success! We are done!\n                return true;\n            }\n            \n            // Transition to the new state.\n            state_ = d;\n\n            // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.\n            if (!IsIterativeParsingDelimiterState(n))\n                return true;\n        }\n        \n        // We reached the end of file.\n        stack_.Clear();\n\n        if (state_ != IterativeParsingFinishState) {\n            HandleError(state_, is);\n            return false;\n        }\n        \n        return true;\n    }\n    \n    //! Check if token-by-token parsing JSON text is complete\n    /*! \\return Whether the JSON has been fully decoded.\n     */\n    RAPIDJSON_FORCEINLINE bool IterativeParseComplete() {\n        return IsIterativeParsingCompleteState(state_);\n    }\n\n    //! Whether a parse error has occured in the last parsing.\n    bool HasParseError() const { return parseResult_.IsError(); }\n\n    //! Get the \\ref ParseErrorCode of last parsing.\n    ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }\n\n    //! Get the position of last parsing error in input, 0 otherwise.\n    size_t GetErrorOffset() const { return parseResult_.Offset(); }\n\nprotected:\n    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    GenericReader(const GenericReader&);\n    GenericReader& operator=(const GenericReader&);\n\n    void ClearStack() { stack_.Clear(); }\n\n    // clear stack on any exit from ParseStream, e.g. due to exception\n    struct ClearStackOnExit {\n        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}\n        ~ClearStackOnExit() { r_.ClearStack(); }\n    private:\n        GenericReader& r_;\n        ClearStackOnExit(const ClearStackOnExit&);\n        ClearStackOnExit& operator=(const ClearStackOnExit&);\n    };\n\n    template<unsigned parseFlags, typename InputStream>\n    void SkipWhitespaceAndComments(InputStream& is) {\n        SkipWhitespace(is);\n\n        if (parseFlags & kParseCommentsFlag) {\n            while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {\n                if (Consume(is, '*')) {\n                    while (true) {\n                        if (RAPIDJSON_UNLIKELY(is.Peek() == '\\0'))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());\n                        else if (Consume(is, '*')) {\n                            if (Consume(is, '/'))\n                                break;\n                        }\n                        else\n                            is.Take();\n                    }\n                }\n                else if (RAPIDJSON_LIKELY(Consume(is, '/')))\n                    while (is.Peek() != '\\0' && is.Take() != '\\n') {}\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());\n\n                SkipWhitespace(is);\n            }\n        }\n    }\n\n    // Parse object: { string : value, ... }\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseObject(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == '{');\n        is.Take();  // Skip '{'\n\n        if (RAPIDJSON_UNLIKELY(!handler.StartObject()))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n        if (Consume(is, '}')) {\n            if (RAPIDJSON_UNLIKELY(!handler.EndObject(0)))  // empty object\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n            return;\n        }\n\n        for (SizeType memberCount = 0;;) {\n            if (RAPIDJSON_UNLIKELY(is.Peek() != '\"'))\n                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());\n\n            ParseString<parseFlags>(is, handler, true);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))\n                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ++memberCount;\n\n            switch (is.Peek()) {\n                case ',':\n                    is.Take();\n                    SkipWhitespaceAndComments<parseFlags>(is);\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                    break;\n                case '}':\n                    is.Take();\n                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    return;\n                default:\n                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy\n            }\n\n            if (parseFlags & kParseTrailingCommasFlag) {\n                if (is.Peek() == '}') {\n                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    is.Take();\n                    return;\n                }\n            }\n        }\n    }\n\n    // Parse array: [ value, ... ]\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseArray(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == '[');\n        is.Take();  // Skip '['\n\n        if (RAPIDJSON_UNLIKELY(!handler.StartArray()))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n\n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n        if (Consume(is, ']')) {\n            if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n            return;\n        }\n\n        for (SizeType elementCount = 0;;) {\n            ParseValue<parseFlags>(is, handler);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            ++elementCount;\n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n\n            if (Consume(is, ',')) {\n                SkipWhitespaceAndComments<parseFlags>(is);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            }\n            else if (Consume(is, ']')) {\n                if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))\n                    RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                return;\n            }\n            else\n                RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());\n\n            if (parseFlags & kParseTrailingCommasFlag) {\n                if (is.Peek() == ']') {\n                    if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))\n                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n                    is.Take();\n                    return;\n                }\n            }\n        }\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseNull(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 'n');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Null()))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseTrue(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 't');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseFalse(InputStream& is, Handler& handler) {\n        RAPIDJSON_ASSERT(is.Peek() == 'f');\n        is.Take();\n\n        if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {\n            if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))\n                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());\n    }\n\n    template<typename InputStream>\n    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {\n        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {\n            is.Take();\n            return true;\n        }\n        else\n            return false;\n    }\n\n    // Helper function to parse four hexidecimal digits in \\uXXXX in ParseString().\n    template<typename InputStream>\n    unsigned ParseHex4(InputStream& is, size_t escapeOffset) {\n        unsigned codepoint = 0;\n        for (int i = 0; i < 4; i++) {\n            Ch c = is.Peek();\n            codepoint <<= 4;\n            codepoint += static_cast<unsigned>(c);\n            if (c >= '0' && c <= '9')\n                codepoint -= '0';\n            else if (c >= 'A' && c <= 'F')\n                codepoint -= 'A' - 10;\n            else if (c >= 'a' && c <= 'f')\n                codepoint -= 'a' - 10;\n            else {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);\n                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);\n            }\n            is.Take();\n        }\n        return codepoint;\n    }\n\n    template <typename CharType>\n    class StackStream {\n    public:\n        typedef CharType Ch;\n\n        StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}\n        RAPIDJSON_FORCEINLINE void Put(Ch c) {\n            *stack_.template Push<Ch>() = c;\n            ++length_;\n        }\n\n        RAPIDJSON_FORCEINLINE void* Push(SizeType count) {\n            length_ += count;\n            return stack_.template Push<Ch>(count);\n        }\n\n        size_t Length() const { return length_; }\n\n        Ch* Pop() {\n            return stack_.template Pop<Ch>(length_);\n        }\n\n    private:\n        StackStream(const StackStream&);\n        StackStream& operator=(const StackStream&);\n\n        internal::Stack<StackAllocator>& stack_;\n        SizeType length_;\n    };\n\n    // Parse string and generate String event. Different code paths for kParseInsituFlag.\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {\n        internal::StreamLocalCopy<InputStream> copy(is);\n        InputStream& s(copy.s);\n\n        RAPIDJSON_ASSERT(s.Peek() == '\\\"');\n        s.Take();  // Skip '\\\"'\n\n        bool success = false;\n        if (parseFlags & kParseInsituFlag) {\n            typename InputStream::Ch *head = s.PutBegin();\n            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            size_t length = s.PutEnd(head) - 1;\n            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);\n            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);\n            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));\n        }\n        else {\n            StackStream<typename TargetEncoding::Ch> stackStream(stack_);\n            ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n            SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;\n            const typename TargetEncoding::Ch* const str = stackStream.Pop();\n            success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));\n        }\n        if (RAPIDJSON_UNLIKELY(!success))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());\n    }\n\n    // Parse string to an output is\n    // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.\n    template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>\n    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n        static const char escape[256] = {\n            Z16, Z16, 0, 0,'\\\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',\n            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\\\', 0, 0, 0,\n            0, 0,'\\b', 0, 0, 0,'\\f', 0, 0, 0, 0, 0, 0, 0,'\\n', 0,\n            0, 0,'\\r', 0,'\\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16\n        };\n#undef Z16\n//!@endcond\n\n        for (;;) {\n            // Scan and copy string before \"\\\\\\\"\" or < 0x20. This is an optional optimzation.\n            if (!(parseFlags & kParseValidateEncodingFlag))\n                ScanCopyUnescapedString(is, os);\n\n            Ch c = is.Peek();\n            if (RAPIDJSON_UNLIKELY(c == '\\\\')) {    // Escape\n                size_t escapeOffset = is.Tell();    // For invalid escaping, report the inital '\\\\' as error offset\n                is.Take();\n                Ch e = is.Peek();\n                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {\n                    is.Take();\n                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));\n                }\n                else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode\n                    is.Take();\n                    unsigned codepoint = ParseHex4(is, escapeOffset);\n                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {\n                        // Handle UTF-16 surrogate pair\n                        if (RAPIDJSON_UNLIKELY(!Consume(is, '\\\\') || !Consume(is, 'u')))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);\n                        unsigned codepoint2 = ParseHex4(is, escapeOffset);\n                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;\n                        if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);\n                        codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;\n                    }\n                    TEncoding::Encode(os, codepoint);\n                }\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);\n            }\n            else if (RAPIDJSON_UNLIKELY(c == '\"')) {    // Closing double quote\n                is.Take();\n                os.Put('\\0');   // null-terminate the string\n                return;\n            }\n            else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF\n                if (c == '\\0')\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());\n                else\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());\n            }\n            else {\n                size_t offset = is.Tell();\n                if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?\n                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :\n                    !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))\n                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);\n            }\n        }\n    }\n\n    template<typename InputStream, typename OutputStream>\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {\n            // Do nothing for generic version\n    }\n\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\n    // StringStream -> StackStream<char>\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {\n        const char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                return;\n            }\n            else\n                os.Put(*p++);\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16]  = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                SizeType length;\n    #ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n    #else\n                length = static_cast<SizeType>(__builtin_ffs(r) - 1);\n    #endif\n                if (length != 0) {\n                    char* q = reinterpret_cast<char*>(os.Push(length));\n                    for (size_t i = 0; i < length; i++)\n                        q[i] = p[i];\n\n                    p += length;\n                }\n                break;\n            }\n            _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);\n        }\n\n        is.src_ = p;\n    }\n\n    // InsituStringStream -> InsituStringStream\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {\n        RAPIDJSON_ASSERT(&is == &os);\n        (void)os;\n\n        if (is.src_ == is.dst_) {\n            SkipUnescapedString(is);\n            return;\n        }\n\n        char* p = is.src_;\n        char *q = is.dst_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                is.dst_ = q;\n                return;\n            }\n            else\n                *q++ = *p++;\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16, q += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                size_t length;\n#ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n#else\n                length = static_cast<size_t>(__builtin_ffs(r) - 1);\n#endif\n                for (const char* pend = p + length; p != pend; )\n                    *q++ = *p++;\n                break;\n            }\n            _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);\n        }\n\n        is.src_ = p;\n        is.dst_ = q;\n    }\n\n    // When read/write pointers are the same for insitu stream, just skip unescaped characters\n    static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {\n        RAPIDJSON_ASSERT(is.src_ == is.dst_);\n        char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        for (; p != nextAligned; p++)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = is.dst_ = p;\n                return;\n            }\n\n        // The rest of string using SIMD\n        static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n        static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n        static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };\n        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n        for (;; p += 16) {\n            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n            const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n            const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F\n            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n                size_t length;\n#ifdef _MSC_VER         // Find the index of first escaped\n                unsigned long offset;\n                _BitScanForward(&offset, r);\n                length = offset;\n#else\n                length = static_cast<size_t>(__builtin_ffs(r) - 1);\n#endif\n                p += length;\n                break;\n            }\n        }\n\n        is.src_ = is.dst_ = p;\n    }\n#elif defined(RAPIDJSON_NEON)\n    // StringStream -> StackStream<char>\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {\n        const char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                return;\n            }\n            else\n                os.Put(*p++);\n\n        // The rest of string using SIMD\n        const uint8x16_t s0 = vmovq_n_u8('\"');\n        const uint8x16_t s1 = vmovq_n_u8('\\\\');\n        const uint8x16_t s2 = vmovq_n_u8('\\b');\n        const uint8x16_t s3 = vmovq_n_u8(32);\n\n        for (;; p += 16) {\n            const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));\n            uint8x16_t x = vceqq_u8(s, s0);\n            x = vorrq_u8(x, vceqq_u8(s, s1));\n            x = vorrq_u8(x, vceqq_u8(s, s2));\n            x = vorrq_u8(x, vcltq_u8(s, s3));\n\n            x = vrev64q_u8(x);                     // Rev in 64\n            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n            SizeType length = 0;\n            bool escaped = false;\n            if (low == 0) {\n                if (high != 0) {\n                    unsigned lz = (unsigned)__builtin_clzll(high);;\n                    length = 8 + (lz >> 3);\n                    escaped = true;\n                }\n            } else {\n                unsigned lz = (unsigned)__builtin_clzll(low);;\n                length = lz >> 3;\n                escaped = true;\n            }\n            if (RAPIDJSON_UNLIKELY(escaped)) {   // some of characters is escaped\n                if (length != 0) {\n                    char* q = reinterpret_cast<char*>(os.Push(length));\n                    for (size_t i = 0; i < length; i++)\n                        q[i] = p[i];\n\n                    p += length;\n                }\n                break;\n            }\n            vst1q_u8(reinterpret_cast<uint8_t *>(os.Push(16)), s);\n        }\n\n        is.src_ = p;\n    }\n\n    // InsituStringStream -> InsituStringStream\n    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {\n        RAPIDJSON_ASSERT(&is == &os);\n        (void)os;\n\n        if (is.src_ == is.dst_) {\n            SkipUnescapedString(is);\n            return;\n        }\n\n        char* p = is.src_;\n        char *q = is.dst_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        while (p != nextAligned)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = p;\n                is.dst_ = q;\n                return;\n            }\n            else\n                *q++ = *p++;\n\n        // The rest of string using SIMD\n        const uint8x16_t s0 = vmovq_n_u8('\"');\n        const uint8x16_t s1 = vmovq_n_u8('\\\\');\n        const uint8x16_t s2 = vmovq_n_u8('\\b');\n        const uint8x16_t s3 = vmovq_n_u8(32);\n\n        for (;; p += 16, q += 16) {\n            const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));\n            uint8x16_t x = vceqq_u8(s, s0);\n            x = vorrq_u8(x, vceqq_u8(s, s1));\n            x = vorrq_u8(x, vceqq_u8(s, s2));\n            x = vorrq_u8(x, vcltq_u8(s, s3));\n\n            x = vrev64q_u8(x);                     // Rev in 64\n            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n            SizeType length = 0;\n            bool escaped = false;\n            if (low == 0) {\n                if (high != 0) {\n                    unsigned lz = (unsigned)__builtin_clzll(high);\n                    length = 8 + (lz >> 3);\n                    escaped = true;\n                }\n            } else {\n                unsigned lz = (unsigned)__builtin_clzll(low);\n                length = lz >> 3;\n                escaped = true;\n            }\n            if (RAPIDJSON_UNLIKELY(escaped)) {   // some of characters is escaped\n                for (const char* pend = p + length; p != pend; ) {\n                    *q++ = *p++;\n                }\n                break;\n            }\n            vst1q_u8(reinterpret_cast<uint8_t *>(q), s);\n        }\n\n        is.src_ = p;\n        is.dst_ = q;\n    }\n\n    // When read/write pointers are the same for insitu stream, just skip unescaped characters\n    static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {\n        RAPIDJSON_ASSERT(is.src_ == is.dst_);\n        char* p = is.src_;\n\n        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)\n        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n        for (; p != nextAligned; p++)\n            if (RAPIDJSON_UNLIKELY(*p == '\\\"') || RAPIDJSON_UNLIKELY(*p == '\\\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {\n                is.src_ = is.dst_ = p;\n                return;\n            }\n\n        // The rest of string using SIMD\n        const uint8x16_t s0 = vmovq_n_u8('\"');\n        const uint8x16_t s1 = vmovq_n_u8('\\\\');\n        const uint8x16_t s2 = vmovq_n_u8('\\b');\n        const uint8x16_t s3 = vmovq_n_u8(32);\n\n        for (;; p += 16) {\n            const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));\n            uint8x16_t x = vceqq_u8(s, s0);\n            x = vorrq_u8(x, vceqq_u8(s, s1));\n            x = vorrq_u8(x, vceqq_u8(s, s2));\n            x = vorrq_u8(x, vcltq_u8(s, s3));\n\n            x = vrev64q_u8(x);                     // Rev in 64\n            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n            if (low == 0) {\n                if (high != 0) {\n                    int lz = __builtin_clzll(high);\n                    p += 8 + (lz >> 3);\n                    break;\n                }\n            } else {\n                int lz = __builtin_clzll(low);\n                p += lz >> 3;\n                break;\n            }\n        }\n\n        is.src_ = is.dst_ = p;\n    }\n#endif // RAPIDJSON_NEON\n\n    template<typename InputStream, bool backup, bool pushOnTake>\n    class NumberStream;\n\n    template<typename InputStream>\n    class NumberStream<InputStream, false, false> {\n    public:\n        typedef typename InputStream::Ch Ch;\n\n        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }\n\n        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }\n        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }\n        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }\n\t\t  RAPIDJSON_FORCEINLINE void Push(char) {}\n\n        size_t Tell() { return is.Tell(); }\n        size_t Length() { return 0; }\n        const char* Pop() { return 0; }\n\n    protected:\n        NumberStream& operator=(const NumberStream&);\n\n        InputStream& is;\n    };\n\n    template<typename InputStream>\n    class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {\n        typedef NumberStream<InputStream, false, false> Base;\n    public:\n        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}\n\n        RAPIDJSON_FORCEINLINE Ch TakePush() {\n            stackStream.Put(static_cast<char>(Base::is.Peek()));\n            return Base::is.Take();\n        }\n\n        RAPIDJSON_FORCEINLINE void Push(char c) {\n            stackStream.Put(c);\n        }\n\n        size_t Length() { return stackStream.Length(); }\n\n        const char* Pop() {\n            stackStream.Put('\\0');\n            return stackStream.Pop();\n        }\n\n    private:\n        StackStream<char> stackStream;\n    };\n\n    template<typename InputStream>\n    class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {\n        typedef NumberStream<InputStream, true, false> Base;\n    public:\n        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}\n\n        RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }\n    };\n\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseNumber(InputStream& is, Handler& handler) {\n        internal::StreamLocalCopy<InputStream> copy(is);\n        NumberStream<InputStream,\n            ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?\n                ((parseFlags & kParseInsituFlag) == 0) :\n                ((parseFlags & kParseFullPrecisionFlag) != 0),\n            (parseFlags & kParseNumbersAsStringsFlag) != 0 &&\n                (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);\n\n        size_t startOffset = s.Tell();\n        double d = 0.0;\n        bool useNanOrInf = false;\n\n        // Parse minus\n        bool minus = Consume(s, '-');\n\n        // Parse int: zero / ( digit1-9 *DIGIT )\n        unsigned i = 0;\n        uint64_t i64 = 0;\n        bool use64bit = false;\n        int significandDigit = 0;\n        if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {\n            i = 0;\n            s.TakePush();\n        }\n        else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {\n            i = static_cast<unsigned>(s.TakePush() - '0');\n\n            if (minus)\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648\n                        if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {\n                            i64 = i;\n                            use64bit = true;\n                            break;\n                        }\n                    }\n                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n            else\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295\n                        if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {\n                            i64 = i;\n                            use64bit = true;\n                            break;\n                        }\n                    }\n                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n        }\n        // Parse NaN or Infinity here\n        else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {\n            if (Consume(s, 'N')) {\n                if (Consume(s, 'a') && Consume(s, 'N')) {\n                    d = std::numeric_limits<double>::quiet_NaN();\n                    useNanOrInf = true;\n                }\n            }\n            else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {\n                if (Consume(s, 'n') && Consume(s, 'f')) {\n                    d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());\n                    useNanOrInf = true;\n\n                    if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')\n                                                                && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {\n                        RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n                    }\n                }\n            }\n            \n            if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {\n                RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n            }\n        }\n        else\n            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());\n\n        // Parse 64bit int\n        bool useDouble = false;\n        if (use64bit) {\n            if (minus)\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                     if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808\n                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {\n                            d = static_cast<double>(i64);\n                            useDouble = true;\n                            break;\n                        }\n                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n            else\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615\n                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {\n                            d = static_cast<double>(i64);\n                            useDouble = true;\n                            break;\n                        }\n                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                    significandDigit++;\n                }\n        }\n\n        // Force double for big integer\n        if (useDouble) {\n            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0\n                    RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);\n                d = d * 10 + (s.TakePush() - '0');\n            }\n        }\n\n        // Parse frac = decimal-point 1*DIGIT\n        int expFrac = 0;\n        size_t decimalPosition;\n        if (Consume(s, '.')) {\n            decimalPosition = s.Length();\n\n            if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))\n                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());\n\n            if (!useDouble) {\n#if RAPIDJSON_64BIT\n                // Use i64 to store significand in 64-bit architecture\n                if (!use64bit)\n                    i64 = i;\n\n                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path\n                        break;\n                    else {\n                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');\n                        --expFrac;\n                        if (i64 != 0)\n                            significandDigit++;\n                    }\n                }\n\n                d = static_cast<double>(i64);\n#else\n                // Use double to store significand in 32-bit architecture\n                d = static_cast<double>(use64bit ? i64 : i);\n#endif\n                useDouble = true;\n            }\n\n            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                if (significandDigit < 17) {\n                    d = d * 10.0 + (s.TakePush() - '0');\n                    --expFrac;\n                    if (RAPIDJSON_LIKELY(d > 0.0))\n                        significandDigit++;\n                }\n                else\n                    s.TakePush();\n            }\n        }\n        else\n            decimalPosition = s.Length(); // decimal position at the end of integer.\n\n        // Parse exp = e [ minus / plus ] 1*DIGIT\n        int exp = 0;\n        if (Consume(s, 'e') || Consume(s, 'E')) {\n            if (!useDouble) {\n                d = static_cast<double>(use64bit ? i64 : i);\n                useDouble = true;\n            }\n\n            bool expMinus = false;\n            if (Consume(s, '+'))\n                ;\n            else if (Consume(s, '-'))\n                expMinus = true;\n\n            if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                exp = static_cast<int>(s.Take() - '0');\n                if (expMinus) {\n                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                        exp = exp * 10 + static_cast<int>(s.Take() - '0');\n                        if (exp >= 214748364) {                         // Issue #313: prevent overflow exponent\n                            while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent\n                                s.Take();\n                        }\n                    }\n                }\n                else {  // positive exp\n                    int maxExp = 308 - expFrac;\n                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {\n                        exp = exp * 10 + static_cast<int>(s.Take() - '0');\n                        if (RAPIDJSON_UNLIKELY(exp > maxExp))\n                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);\n                    }\n                }\n            }\n            else\n                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());\n\n            if (expMinus)\n                exp = -exp;\n        }\n\n        // Finish parsing, call event according to the type of number.\n        bool cont = true;\n\n        if (parseFlags & kParseNumbersAsStringsFlag) {\n            if (parseFlags & kParseInsituFlag) {\n                s.Pop();  // Pop stack no matter if it will be used or not.\n                typename InputStream::Ch* head = is.PutBegin();\n                const size_t length = s.Tell() - startOffset;\n                RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);\n                // unable to insert the \\0 character here, it will erase the comma after this number\n                const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);\n                cont = handler.RawNumber(str, SizeType(length), false);\n            }\n            else {\n                SizeType numCharsToCopy = static_cast<SizeType>(s.Length());\n                StringStream srcStream(s.Pop());\n                StackStream<typename TargetEncoding::Ch> dstStream(stack_);\n                while (numCharsToCopy--) {\n                    Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);\n                }\n                dstStream.Put('\\0');\n                const typename TargetEncoding::Ch* str = dstStream.Pop();\n                const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;\n                cont = handler.RawNumber(str, SizeType(length), true);\n            }\n        }\n        else {\n           size_t length = s.Length();\n           const char* decimal = s.Pop();  // Pop stack no matter if it will be used or not.\n\n           if (useDouble) {\n               int p = exp + expFrac;\n               if (parseFlags & kParseFullPrecisionFlag)\n                   d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);\n               else\n                   d = internal::StrtodNormalPrecision(d, p);\n\n               cont = handler.Double(minus ? -d : d);\n           }\n           else if (useNanOrInf) {\n               cont = handler.Double(d);\n           }\n           else {\n               if (use64bit) {\n                   if (minus)\n                       cont = handler.Int64(static_cast<int64_t>(~i64 + 1));\n                   else\n                       cont = handler.Uint64(i64);\n               }\n               else {\n                   if (minus)\n                       cont = handler.Int(static_cast<int32_t>(~i + 1));\n                   else\n                       cont = handler.Uint(i);\n               }\n           }\n        }\n        if (RAPIDJSON_UNLIKELY(!cont))\n            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);\n    }\n\n    // Parse any JSON value\n    template<unsigned parseFlags, typename InputStream, typename Handler>\n    void ParseValue(InputStream& is, Handler& handler) {\n        switch (is.Peek()) {\n            case 'n': ParseNull  <parseFlags>(is, handler); break;\n            case 't': ParseTrue  <parseFlags>(is, handler); break;\n            case 'f': ParseFalse <parseFlags>(is, handler); break;\n            case '\"': ParseString<parseFlags>(is, handler); break;\n            case '{': ParseObject<parseFlags>(is, handler); break;\n            case '[': ParseArray <parseFlags>(is, handler); break;\n            default :\n                      ParseNumber<parseFlags>(is, handler);\n                      break;\n\n        }\n    }\n\n    // Iterative Parsing\n\n    // States\n    enum IterativeParsingState {\n        IterativeParsingFinishState = 0, // sink states at top\n        IterativeParsingErrorState,      // sink states at top\n        IterativeParsingStartState,\n\n        // Object states\n        IterativeParsingObjectInitialState,\n        IterativeParsingMemberKeyState,\n        IterativeParsingMemberValueState,\n        IterativeParsingObjectFinishState,\n\n        // Array states\n        IterativeParsingArrayInitialState,\n        IterativeParsingElementState,\n        IterativeParsingArrayFinishState,\n\n        // Single value state\n        IterativeParsingValueState,\n        \n        // Delimiter states (at bottom)\n        IterativeParsingElementDelimiterState,\n        IterativeParsingMemberDelimiterState,\n        IterativeParsingKeyValueDelimiterState,\n        \n        cIterativeParsingStateCount\n    };\n\n    // Tokens\n    enum Token {\n        LeftBracketToken = 0,\n        RightBracketToken,\n\n        LeftCurlyBracketToken,\n        RightCurlyBracketToken,\n\n        CommaToken,\n        ColonToken,\n\n        StringToken,\n        FalseToken,\n        TrueToken,\n        NullToken,\n        NumberToken,\n\n        kTokenCount\n    };\n\n    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {\n\n//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN\n#define N NumberToken\n#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N\n        // Maps from ASCII to Token\n        static const unsigned char tokenMap[256] = {\n            N16, // 00~0F\n            N16, // 10~1F\n            N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F\n            N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F\n            N16, // 40~4F\n            N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F\n            N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F\n            N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F\n            N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF\n        };\n#undef N\n#undef N16\n//!@endcond\n\n        if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)\n            return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);\n        else\n            return NumberToken;\n    }\n\n    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {\n        // current state x one lookahead token -> new state\n        static const char G[cIterativeParsingStateCount][kTokenCount] = {\n            // Finish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // Error(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // Start\n            {\n                IterativeParsingArrayInitialState,  // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingObjectInitialState, // Left curly bracket\n                IterativeParsingErrorState,         // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingValueState,         // String\n                IterativeParsingValueState,         // False\n                IterativeParsingValueState,         // True\n                IterativeParsingValueState,         // Null\n                IterativeParsingValueState          // Number\n            },\n            // ObjectInitial\n            {\n                IterativeParsingErrorState,         // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingErrorState,         // Left curly bracket\n                IterativeParsingObjectFinishState,  // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingMemberKeyState,     // String\n                IterativeParsingErrorState,         // False\n                IterativeParsingErrorState,         // True\n                IterativeParsingErrorState,         // Null\n                IterativeParsingErrorState          // Number\n            },\n            // MemberKey\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingKeyValueDelimiterState, // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // MemberValue\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingObjectFinishState,      // Right curly bracket\n                IterativeParsingMemberDelimiterState,   // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // ObjectFinish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // ArrayInitial\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push Element state)\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingElementState,           // String\n                IterativeParsingElementState,           // False\n                IterativeParsingElementState,           // True\n                IterativeParsingElementState,           // Null\n                IterativeParsingElementState            // Number\n            },\n            // Element\n            {\n                IterativeParsingErrorState,             // Left bracket\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingErrorState,             // Left curly bracket\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingElementDelimiterState,  // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingErrorState,             // String\n                IterativeParsingErrorState,             // False\n                IterativeParsingErrorState,             // True\n                IterativeParsingErrorState,             // Null\n                IterativeParsingErrorState              // Number\n            },\n            // ArrayFinish(sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // Single Value (sink state)\n            {\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,\n                IterativeParsingErrorState\n            },\n            // ElementDelimiter\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push Element state)\n                IterativeParsingArrayFinishState,       // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingElementState,           // String\n                IterativeParsingElementState,           // False\n                IterativeParsingElementState,           // True\n                IterativeParsingElementState,           // Null\n                IterativeParsingElementState            // Number\n            },\n            // MemberDelimiter\n            {\n                IterativeParsingErrorState,         // Left bracket\n                IterativeParsingErrorState,         // Right bracket\n                IterativeParsingErrorState,         // Left curly bracket\n                IterativeParsingObjectFinishState,  // Right curly bracket\n                IterativeParsingErrorState,         // Comma\n                IterativeParsingErrorState,         // Colon\n                IterativeParsingMemberKeyState,     // String\n                IterativeParsingErrorState,         // False\n                IterativeParsingErrorState,         // True\n                IterativeParsingErrorState,         // Null\n                IterativeParsingErrorState          // Number\n            },\n            // KeyValueDelimiter\n            {\n                IterativeParsingArrayInitialState,      // Left bracket(push MemberValue state)\n                IterativeParsingErrorState,             // Right bracket\n                IterativeParsingObjectInitialState,     // Left curly bracket(push MemberValue state)\n                IterativeParsingErrorState,             // Right curly bracket\n                IterativeParsingErrorState,             // Comma\n                IterativeParsingErrorState,             // Colon\n                IterativeParsingMemberValueState,       // String\n                IterativeParsingMemberValueState,       // False\n                IterativeParsingMemberValueState,       // True\n                IterativeParsingMemberValueState,       // Null\n                IterativeParsingMemberValueState        // Number\n            },\n        }; // End of G\n\n        return static_cast<IterativeParsingState>(G[state][token]);\n    }\n\n    // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().\n    // May return a new state on state pop.\n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {\n        (void)token;\n\n        switch (dst) {\n        case IterativeParsingErrorState:\n            return dst;\n\n        case IterativeParsingObjectInitialState:\n        case IterativeParsingArrayInitialState:\n        {\n            // Push the state(Element or MemeberValue) if we are nested in another array or value of member.\n            // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.\n            IterativeParsingState n = src;\n            if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)\n                n = IterativeParsingElementState;\n            else if (src == IterativeParsingKeyValueDelimiterState)\n                n = IterativeParsingMemberValueState;\n            // Push current state.\n            *stack_.template Push<SizeType>(1) = n;\n            // Initialize and push the member/element count.\n            *stack_.template Push<SizeType>(1) = 0;\n            // Call handler\n            bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return dst;\n            }\n        }\n\n        case IterativeParsingMemberKeyState:\n            ParseString<parseFlags>(is, handler, true);\n            if (HasParseError())\n                return IterativeParsingErrorState;\n            else\n                return dst;\n\n        case IterativeParsingKeyValueDelimiterState:\n            RAPIDJSON_ASSERT(token == ColonToken);\n            is.Take();\n            return dst;\n\n        case IterativeParsingMemberValueState:\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return dst;\n\n        case IterativeParsingElementState:\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return dst;\n\n        case IterativeParsingMemberDelimiterState:\n        case IterativeParsingElementDelimiterState:\n            is.Take();\n            // Update member/element count.\n            *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;\n            return dst;\n\n        case IterativeParsingObjectFinishState:\n        {\n            // Transit from delimiter is only allowed when trailing commas are enabled\n            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            // Get member count.\n            SizeType c = *stack_.template Pop<SizeType>(1);\n            // If the object is not empty, count the last member.\n            if (src == IterativeParsingMemberValueState)\n                ++c;\n            // Restore the state.\n            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));\n            // Transit to Finish state if this is the topmost scope.\n            if (n == IterativeParsingStartState)\n                n = IterativeParsingFinishState;\n            // Call handler\n            bool hr = handler.EndObject(c);\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return n;\n            }\n        }\n\n        case IterativeParsingArrayFinishState:\n        {\n            // Transit from delimiter is only allowed when trailing commas are enabled\n            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            // Get element count.\n            SizeType c = *stack_.template Pop<SizeType>(1);\n            // If the array is not empty, count the last element.\n            if (src == IterativeParsingElementState)\n                ++c;\n            // Restore the state.\n            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));\n            // Transit to Finish state if this is the topmost scope.\n            if (n == IterativeParsingStartState)\n                n = IterativeParsingFinishState;\n            // Call handler\n            bool hr = handler.EndArray(c);\n            // On handler short circuits the parsing.\n            if (!hr) {\n                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());\n                return IterativeParsingErrorState;\n            }\n            else {\n                is.Take();\n                return n;\n            }\n        }\n\n        default:\n            // This branch is for IterativeParsingValueState actually.\n            // Use `default:` rather than\n            // `case IterativeParsingValueState:` is for code coverage.\n\n            // The IterativeParsingStartState is not enumerated in this switch-case.\n            // It is impossible for that case. And it can be caught by following assertion.\n\n            // The IterativeParsingFinishState is not enumerated in this switch-case either.\n            // It is a \"derivative\" state which cannot triggered from Predict() directly.\n            // Therefore it cannot happen here. And it can be caught by following assertion.\n            RAPIDJSON_ASSERT(dst == IterativeParsingValueState);\n\n            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.\n            ParseValue<parseFlags>(is, handler);\n            if (HasParseError()) {\n                return IterativeParsingErrorState;\n            }\n            return IterativeParsingFinishState;\n        }\n    }\n\n    template <typename InputStream>\n    void HandleError(IterativeParsingState src, InputStream& is) {\n        if (HasParseError()) {\n            // Error flag has been set.\n            return;\n        }\n\n        switch (src) {\n        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;\n        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;\n        case IterativeParsingObjectInitialState:\n        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;\n        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;\n        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;\n        case IterativeParsingKeyValueDelimiterState:\n        case IterativeParsingArrayInitialState:\n        case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;\n        default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;\n        }\n    }\n\n    RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) {\n        return s >= IterativeParsingElementDelimiterState;\n    }\n    \n    RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) {\n        return s <= IterativeParsingErrorState;\n    }\n    \n    template <unsigned parseFlags, typename InputStream, typename Handler>\n    ParseResult IterativeParse(InputStream& is, Handler& handler) {\n        parseResult_.Clear();\n        ClearStackOnExit scope(*this);\n        IterativeParsingState state = IterativeParsingStartState;\n        \n        SkipWhitespaceAndComments<parseFlags>(is);\n        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        while (is.Peek() != '\\0') {\n            Token t = Tokenize(is.Peek());\n            IterativeParsingState n = Predict(state, t);\n            IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);\n            \n            if (d == IterativeParsingErrorState) {\n                HandleError(state, is);\n                break;\n            }\n            \n            state = d;\n            \n            // Do not further consume streams if a root JSON has been parsed.\n            if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)\n                break;\n            \n            SkipWhitespaceAndComments<parseFlags>(is);\n            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);\n        }\n        \n        // Handle the end of file.\n        if (state != IterativeParsingFinishState)\n            HandleError(state, is);\n        \n        return parseResult_;\n    }\n\n    static const size_t kDefaultStackCapacity = 256;    //!< Default stack capacity in bytes for storing a single decoded string.\n    internal::Stack<StackAllocator> stack_;  //!< A stack for storing decoded string temporarily during non-destructive parsing.\n    ParseResult parseResult_;\n    IterativeParsingState state_;\n}; // class GenericReader\n\n//! Reader with UTF8 encoding and default allocator.\ntypedef GenericReader<UTF8<>, UTF8<> > Reader;\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n\n#ifdef __GNUC__\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_READER_H_\n"
  },
  {
    "path": "third-party/rapidjson/schema.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available->\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved->\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License-> You may obtain a copy of the License at\n//\n// http://opensource->org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied-> See the License for the \n// specific language governing permissions and limitations under the License->\n\n#ifndef RAPIDJSON_SCHEMA_H_\n#define RAPIDJSON_SCHEMA_H_\n\n#include \"document.h\"\n#include \"pointer.h\"\n#include <cmath> // abs, floor\n\n#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)\n#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1\n#else\n#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0\n#endif\n\n#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))\n#define RAPIDJSON_SCHEMA_USE_STDREGEX 1\n#else\n#define RAPIDJSON_SCHEMA_USE_STDREGEX 0\n#endif\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n#include \"internal/regex.h\"\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n#include <regex>\n#endif\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX\n#define RAPIDJSON_SCHEMA_HAS_REGEX 1\n#else\n#define RAPIDJSON_SCHEMA_HAS_REGEX 0\n#endif\n\n#ifndef RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_SCHEMA_VERBOSE 0\n#endif\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#include \"stringbuffer.h\"\n#endif\n\nRAPIDJSON_DIAG_PUSH\n\n#if defined(__GNUC__)\nRAPIDJSON_DIAG_OFF(effc++)\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_OFF(weak-vtables)\nRAPIDJSON_DIAG_OFF(exit-time-destructors)\nRAPIDJSON_DIAG_OFF(c++98-compat-pedantic)\nRAPIDJSON_DIAG_OFF(variadic-macros)\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// Verbose Utilities\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n\nnamespace internal {\n\ninline void PrintInvalidKeyword(const char* keyword) {\n    printf(\"Fail keyword: %s\\n\", keyword);\n}\n\ninline void PrintInvalidKeyword(const wchar_t* keyword) {\n    wprintf(L\"Fail keyword: %ls\\n\", keyword);\n}\n\ninline void PrintInvalidDocument(const char* document) {\n    printf(\"Fail document: %s\\n\\n\", document);\n}\n\ninline void PrintInvalidDocument(const wchar_t* document) {\n    wprintf(L\"Fail document: %ls\\n\\n\", document);\n}\n\ninline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) {\n    printf(\"S: %*s%s\\nD: %*s%s\\n\\n\", depth * 4, \" \", s, depth * 4, \" \", d);\n}\n\ninline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) {\n    wprintf(L\"S: %*ls%ls\\nD: %*ls%ls\\n\\n\", depth * 4, L\" \", s, depth * 4, L\" \", d);\n}\n\n} // namespace internal\n\n#endif // RAPIDJSON_SCHEMA_VERBOSE\n\n///////////////////////////////////////////////////////////////////////////////\n// RAPIDJSON_INVALID_KEYWORD_RETURN\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword)\n#else\n#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)\n#endif\n\n#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\\\nRAPIDJSON_MULTILINEMACRO_BEGIN\\\n    context.invalidKeyword = keyword.GetString();\\\n    RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\\\n    return false;\\\nRAPIDJSON_MULTILINEMACRO_END\n\n///////////////////////////////////////////////////////////////////////////////\n// Forward declarations\n\ntemplate <typename ValueType, typename Allocator>\nclass GenericSchemaDocument;\n\nnamespace internal {\n\ntemplate <typename SchemaDocumentType>\nclass Schema;\n\n///////////////////////////////////////////////////////////////////////////////\n// ISchemaValidator\n\nclass ISchemaValidator {\npublic:\n    virtual ~ISchemaValidator() {}\n    virtual bool IsValid() const = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// ISchemaStateFactory\n\ntemplate <typename SchemaType>\nclass ISchemaStateFactory {\npublic:\n    virtual ~ISchemaStateFactory() {}\n    virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;\n    virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;\n    virtual void* CreateHasher() = 0;\n    virtual uint64_t GetHashCode(void* hasher) = 0;\n    virtual void DestroryHasher(void* hasher) = 0;\n    virtual void* MallocState(size_t size) = 0;\n    virtual void FreeState(void* p) = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Hasher\n\n// For comparison of compound value\ntemplate<typename Encoding, typename Allocator>\nclass Hasher {\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}\n\n    bool Null() { return WriteType(kNullType); }\n    bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }\n    bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }\n    bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }\n    bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }\n    bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }\n    bool Double(double d) { \n        Number n; \n        if (d < 0) n.u.i = static_cast<int64_t>(d);\n        else       n.u.u = static_cast<uint64_t>(d); \n        n.d = d;\n        return WriteNumber(n);\n    }\n\n    bool RawNumber(const Ch* str, SizeType len, bool) {\n        WriteBuffer(kNumberType, str, len * sizeof(Ch));\n        return true;\n    }\n\n    bool String(const Ch* str, SizeType len, bool) {\n        WriteBuffer(kStringType, str, len * sizeof(Ch));\n        return true;\n    }\n\n    bool StartObject() { return true; }\n    bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }\n    bool EndObject(SizeType memberCount) { \n        uint64_t h = Hash(0, kObjectType);\n        uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);\n        for (SizeType i = 0; i < memberCount; i++)\n            h ^= Hash(kv[i * 2], kv[i * 2 + 1]);  // Use xor to achieve member order insensitive\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n    \n    bool StartArray() { return true; }\n    bool EndArray(SizeType elementCount) { \n        uint64_t h = Hash(0, kArrayType);\n        uint64_t* e = stack_.template Pop<uint64_t>(elementCount);\n        for (SizeType i = 0; i < elementCount; i++)\n            h = Hash(h, e[i]); // Use hash to achieve element order sensitive\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n\n    bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); }\n\n    uint64_t GetHashCode() const {\n        RAPIDJSON_ASSERT(IsValid());\n        return *stack_.template Top<uint64_t>();\n    }\n\nprivate:\n    static const size_t kDefaultSize = 256;\n    struct Number {\n        union U {\n            uint64_t u;\n            int64_t i;\n        }u;\n        double d;\n    };\n\n    bool WriteType(Type type) { return WriteBuffer(type, 0, 0); }\n    \n    bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); }\n    \n    bool WriteBuffer(Type type, const void* data, size_t len) {\n        // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/\n        uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type);\n        const unsigned char* d = static_cast<const unsigned char*>(data);\n        for (size_t i = 0; i < len; i++)\n            h = Hash(h, d[i]);\n        *stack_.template Push<uint64_t>() = h;\n        return true;\n    }\n\n    static uint64_t Hash(uint64_t h, uint64_t d) {\n        static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3);\n        h ^= d;\n        h *= kPrime;\n        return h;\n    }\n\n    Stack<Allocator> stack_;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// SchemaValidationContext\n\ntemplate <typename SchemaDocumentType>\nstruct SchemaValidationContext {\n    typedef Schema<SchemaDocumentType> SchemaType;\n    typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType;\n    typedef typename SchemaType::ValueType ValueType;\n    typedef typename ValueType::Ch Ch;\n\n    enum PatternValidatorType {\n        kPatternValidatorOnly,\n        kPatternValidatorWithProperty,\n        kPatternValidatorWithAdditionalProperty\n    };\n\n    SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) :\n        factory(f),\n        schema(s),\n        valueSchema(),\n        invalidKeyword(),\n        hasher(),\n        arrayElementHashCodes(),\n        validators(),\n        validatorCount(),\n        patternPropertiesValidators(),\n        patternPropertiesValidatorCount(),\n        patternPropertiesSchemas(),\n        patternPropertiesSchemaCount(),\n        valuePatternValidatorType(kPatternValidatorOnly),\n        propertyExist(),\n        inArray(false),\n        valueUniqueness(false),\n        arrayUniqueness(false)\n    {\n    }\n\n    ~SchemaValidationContext() {\n        if (hasher)\n            factory.DestroryHasher(hasher);\n        if (validators) {\n            for (SizeType i = 0; i < validatorCount; i++)\n                factory.DestroySchemaValidator(validators[i]);\n            factory.FreeState(validators);\n        }\n        if (patternPropertiesValidators) {\n            for (SizeType i = 0; i < patternPropertiesValidatorCount; i++)\n                factory.DestroySchemaValidator(patternPropertiesValidators[i]);\n            factory.FreeState(patternPropertiesValidators);\n        }\n        if (patternPropertiesSchemas)\n            factory.FreeState(patternPropertiesSchemas);\n        if (propertyExist)\n            factory.FreeState(propertyExist);\n    }\n\n    SchemaValidatorFactoryType& factory;\n    const SchemaType* schema;\n    const SchemaType* valueSchema;\n    const Ch* invalidKeyword;\n    void* hasher; // Only validator access\n    void* arrayElementHashCodes; // Only validator access this\n    ISchemaValidator** validators;\n    SizeType validatorCount;\n    ISchemaValidator** patternPropertiesValidators;\n    SizeType patternPropertiesValidatorCount;\n    const SchemaType** patternPropertiesSchemas;\n    SizeType patternPropertiesSchemaCount;\n    PatternValidatorType valuePatternValidatorType;\n    PatternValidatorType objectPatternValidatorType;\n    SizeType arrayElementIndex;\n    bool* propertyExist;\n    bool inArray;\n    bool valueUniqueness;\n    bool arrayUniqueness;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// Schema\n\ntemplate <typename SchemaDocumentType>\nclass Schema {\npublic:\n    typedef typename SchemaDocumentType::ValueType ValueType;\n    typedef typename SchemaDocumentType::AllocatorType AllocatorType;\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n    typedef SchemaValidationContext<SchemaDocumentType> Context;\n    typedef Schema<SchemaDocumentType> SchemaType;\n    typedef GenericValue<EncodingType, AllocatorType> SValue;\n    friend class GenericSchemaDocument<ValueType, AllocatorType>;\n\n    Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :\n        allocator_(allocator),\n        typeless_(schemaDocument->GetTypeless()),\n        enum_(),\n        enumCount_(),\n        not_(),\n        type_((1 << kTotalSchemaType) - 1), // typeless\n        validatorCount_(),\n        properties_(),\n        additionalPropertiesSchema_(),\n        patternProperties_(),\n        patternPropertyCount_(),\n        propertyCount_(),\n        minProperties_(),\n        maxProperties_(SizeType(~0)),\n        additionalProperties_(true),\n        hasDependencies_(),\n        hasRequired_(),\n        hasSchemaDependencies_(),\n        additionalItemsSchema_(),\n        itemsList_(),\n        itemsTuple_(),\n        itemsTupleCount_(),\n        minItems_(),\n        maxItems_(SizeType(~0)),\n        additionalItems_(true),\n        uniqueItems_(false),\n        pattern_(),\n        minLength_(0),\n        maxLength_(~SizeType(0)),\n        exclusiveMinimum_(false),\n        exclusiveMaximum_(false)\n    {\n        typedef typename SchemaDocumentType::ValueType ValueType;\n        typedef typename ValueType::ConstValueIterator ConstValueIterator;\n        typedef typename ValueType::ConstMemberIterator ConstMemberIterator;\n\n        if (!value.IsObject())\n            return;\n\n        if (const ValueType* v = GetMember(value, GetTypeString())) {\n            type_ = 0;\n            if (v->IsString())\n                AddType(*v);\n            else if (v->IsArray())\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)\n                    AddType(*itr);\n        }\n\n        if (const ValueType* v = GetMember(value, GetEnumString()))\n            if (v->IsArray() && v->Size() > 0) {\n                enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {\n                    typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;\n                    char buffer[256 + 24];\n                    MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));\n                    EnumHasherType h(&hasherAllocator, 256);\n                    itr->Accept(h);\n                    enum_[enumCount_++] = h.GetHashCode();\n                }\n            }\n\n        if (schemaDocument) {\n            AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);\n            AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);\n            AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);\n        }\n\n        if (const ValueType* v = GetMember(value, GetNotString())) {\n            schemaDocument->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v, document);\n            notValidatorIndex_ = validatorCount_;\n            validatorCount_++;\n        }\n\n        // Object\n\n        const ValueType* properties = GetMember(value, GetPropertiesString());\n        const ValueType* required = GetMember(value, GetRequiredString());\n        const ValueType* dependencies = GetMember(value, GetDependenciesString());\n        {\n            // Gather properties from properties/required/dependencies\n            SValue allProperties(kArrayType);\n\n            if (properties && properties->IsObject())\n                for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)\n                    AddUniqueElement(allProperties, itr->name);\n            \n            if (required && required->IsArray())\n                for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)\n                    if (itr->IsString())\n                        AddUniqueElement(allProperties, *itr);\n\n            if (dependencies && dependencies->IsObject())\n                for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {\n                    AddUniqueElement(allProperties, itr->name);\n                    if (itr->value.IsArray())\n                        for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)\n                            if (i->IsString())\n                                AddUniqueElement(allProperties, *i);\n                }\n\n            if (allProperties.Size() > 0) {\n                propertyCount_ = allProperties.Size();\n                properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_));\n                for (SizeType i = 0; i < propertyCount_; i++) {\n                    new (&properties_[i]) Property();\n                    properties_[i].name = allProperties[i];\n                    properties_[i].schema = typeless_;\n                }\n            }\n        }\n\n        if (properties && properties->IsObject()) {\n            PointerType q = p.Append(GetPropertiesString(), allocator_);\n            for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {\n                SizeType index;\n                if (FindPropertyIndex(itr->name, &index))\n                    schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document);\n            }\n        }\n\n        if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {\n            PointerType q = p.Append(GetPatternPropertiesString(), allocator_);\n            patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount()));\n            patternPropertyCount_ = 0;\n\n            for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {\n                new (&patternProperties_[patternPropertyCount_]) PatternProperty();\n                patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);\n                schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document);\n                patternPropertyCount_++;\n            }\n        }\n\n        if (required && required->IsArray())\n            for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)\n                if (itr->IsString()) {\n                    SizeType index;\n                    if (FindPropertyIndex(*itr, &index)) {\n                        properties_[index].required = true;\n                        hasRequired_ = true;\n                    }\n                }\n\n        if (dependencies && dependencies->IsObject()) {\n            PointerType q = p.Append(GetDependenciesString(), allocator_);\n            hasDependencies_ = true;\n            for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {\n                SizeType sourceIndex;\n                if (FindPropertyIndex(itr->name, &sourceIndex)) {\n                    if (itr->value.IsArray()) {\n                        properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_));\n                        std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);\n                        for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {\n                            SizeType targetIndex;\n                            if (FindPropertyIndex(*targetItr, &targetIndex))\n                                properties_[sourceIndex].dependencies[targetIndex] = true;\n                        }\n                    }\n                    else if (itr->value.IsObject()) {\n                        hasSchemaDependencies_ = true;\n                        schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document);\n                        properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;\n                        validatorCount_++;\n                    }\n                }\n            }\n        }\n\n        if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {\n            if (v->IsBool())\n                additionalProperties_ = v->GetBool();\n            else if (v->IsObject())\n                schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document);\n        }\n\n        AssignIfExist(minProperties_, value, GetMinPropertiesString());\n        AssignIfExist(maxProperties_, value, GetMaxPropertiesString());\n\n        // Array\n        if (const ValueType* v = GetMember(value, GetItemsString())) {\n            PointerType q = p.Append(GetItemsString(), allocator_);\n            if (v->IsObject()) // List validation\n                schemaDocument->CreateSchema(&itemsList_, q, *v, document);\n            else if (v->IsArray()) { // Tuple validation\n                itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));\n                SizeType index = 0;\n                for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)\n                    schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document);\n            }\n        }\n\n        AssignIfExist(minItems_, value, GetMinItemsString());\n        AssignIfExist(maxItems_, value, GetMaxItemsString());\n\n        if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) {\n            if (v->IsBool())\n                additionalItems_ = v->GetBool();\n            else if (v->IsObject())\n                schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document);\n        }\n\n        AssignIfExist(uniqueItems_, value, GetUniqueItemsString());\n\n        // String\n        AssignIfExist(minLength_, value, GetMinLengthString());\n        AssignIfExist(maxLength_, value, GetMaxLengthString());\n\n        if (const ValueType* v = GetMember(value, GetPatternString()))\n            pattern_ = CreatePattern(*v);\n\n        // Number\n        if (const ValueType* v = GetMember(value, GetMinimumString()))\n            if (v->IsNumber())\n                minimum_.CopyFrom(*v, *allocator_);\n\n        if (const ValueType* v = GetMember(value, GetMaximumString()))\n            if (v->IsNumber())\n                maximum_.CopyFrom(*v, *allocator_);\n\n        AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());\n        AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());\n\n        if (const ValueType* v = GetMember(value, GetMultipleOfString()))\n            if (v->IsNumber() && v->GetDouble() > 0.0)\n                multipleOf_.CopyFrom(*v, *allocator_);\n    }\n\n    ~Schema() {\n        AllocatorType::Free(enum_);\n        if (properties_) {\n            for (SizeType i = 0; i < propertyCount_; i++)\n                properties_[i].~Property();\n            AllocatorType::Free(properties_);\n        }\n        if (patternProperties_) {\n            for (SizeType i = 0; i < patternPropertyCount_; i++)\n                patternProperties_[i].~PatternProperty();\n            AllocatorType::Free(patternProperties_);\n        }\n        AllocatorType::Free(itemsTuple_);\n#if RAPIDJSON_SCHEMA_HAS_REGEX\n        if (pattern_) {\n            pattern_->~RegexType();\n            AllocatorType::Free(pattern_);\n        }\n#endif\n    }\n\n    bool BeginValue(Context& context) const {\n        if (context.inArray) {\n            if (uniqueItems_)\n                context.valueUniqueness = true;\n\n            if (itemsList_)\n                context.valueSchema = itemsList_;\n            else if (itemsTuple_) {\n                if (context.arrayElementIndex < itemsTupleCount_)\n                    context.valueSchema = itemsTuple_[context.arrayElementIndex];\n                else if (additionalItemsSchema_)\n                    context.valueSchema = additionalItemsSchema_;\n                else if (additionalItems_)\n                    context.valueSchema = typeless_;\n                else\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());\n            }\n            else\n                context.valueSchema = typeless_;\n\n            context.arrayElementIndex++;\n        }\n        return true;\n    }\n\n    RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {\n        if (context.patternPropertiesValidatorCount > 0) {\n            bool otherValid = false;\n            SizeType count = context.patternPropertiesValidatorCount;\n            if (context.objectPatternValidatorType != Context::kPatternValidatorOnly)\n                otherValid = context.patternPropertiesValidators[--count]->IsValid();\n\n            bool patternValid = true;\n            for (SizeType i = 0; i < count; i++)\n                if (!context.patternPropertiesValidators[i]->IsValid()) {\n                    patternValid = false;\n                    break;\n                }\n\n            if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {\n                if (!patternValid)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n            }\n            else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {\n                if (!patternValid || !otherValid)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n            }\n            else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty)\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());\n        }\n\n        if (enum_) {\n            const uint64_t h = context.factory.GetHashCode(context.hasher);\n            for (SizeType i = 0; i < enumCount_; i++)\n                if (enum_[i] == h)\n                    goto foundEnum;\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());\n            foundEnum:;\n        }\n\n        if (allOf_.schemas)\n            for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)\n                if (!context.validators[i]->IsValid())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());\n        \n        if (anyOf_.schemas) {\n            for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)\n                if (context.validators[i]->IsValid())\n                    goto foundAny;\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());\n            foundAny:;\n        }\n\n        if (oneOf_.schemas) {\n            bool oneValid = false;\n            for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)\n                if (context.validators[i]->IsValid()) {\n                    if (oneValid)\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());\n                    else\n                        oneValid = true;\n                }\n            if (!oneValid)\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());\n        }\n\n        if (not_ && context.validators[notValidatorIndex_]->IsValid())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());\n\n        return true;\n    }\n\n    bool Null(Context& context) const { \n        if (!(type_ & (1 << kNullSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n        return CreateParallelValidator(context);\n    }\n    \n    bool Bool(Context& context, bool) const { \n        if (!(type_ & (1 << kBooleanSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n        return CreateParallelValidator(context);\n    }\n\n    bool Int(Context& context, int i) const {\n        if (!CheckInt(context, i))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Uint(Context& context, unsigned u) const {\n        if (!CheckUint(context, u))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Int64(Context& context, int64_t i) const {\n        if (!CheckInt(context, i))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Uint64(Context& context, uint64_t u) const {\n        if (!CheckUint(context, u))\n            return false;\n        return CreateParallelValidator(context);\n    }\n\n    bool Double(Context& context, double d) const {\n        if (!(type_ & (1 << kNumberSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))\n            return false;\n\n        if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))\n            return false;\n        \n        if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))\n            return false;\n        \n        return CreateParallelValidator(context);\n    }\n    \n    bool String(Context& context, const Ch* str, SizeType length, bool) const {\n        if (!(type_ & (1 << kStringSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (minLength_ != 0 || maxLength_ != SizeType(~0)) {\n            SizeType count;\n            if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {\n                if (count < minLength_)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());\n                if (count > maxLength_)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());\n            }\n        }\n\n        if (pattern_ && !IsPatternMatch(pattern_, str, length))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());\n\n        return CreateParallelValidator(context);\n    }\n\n    bool StartObject(Context& context) const { \n        if (!(type_ & (1 << kObjectSchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (hasDependencies_ || hasRequired_) {\n            context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_));\n            std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_);\n        }\n\n        if (patternProperties_) { // pre-allocate schema array\n            SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType\n            context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count));\n            context.patternPropertiesSchemaCount = 0;\n            std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);\n        }\n\n        return CreateParallelValidator(context);\n    }\n    \n    bool Key(Context& context, const Ch* str, SizeType len, bool) const {\n        if (patternProperties_) {\n            context.patternPropertiesSchemaCount = 0;\n            for (SizeType i = 0; i < patternPropertyCount_; i++)\n                if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) {\n                    context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema;\n                    context.valueSchema = typeless_;\n                }\n        }\n\n        SizeType index;\n        if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {\n            if (context.patternPropertiesSchemaCount > 0) {\n                context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;\n                context.valueSchema = typeless_;\n                context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;\n            }\n            else\n                context.valueSchema = properties_[index].schema;\n\n            if (context.propertyExist)\n                context.propertyExist[index] = true;\n\n            return true;\n        }\n\n        if (additionalPropertiesSchema_) {\n            if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {\n                context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;\n                context.valueSchema = typeless_;\n                context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;\n            }\n            else\n                context.valueSchema = additionalPropertiesSchema_;\n            return true;\n        }\n        else if (additionalProperties_) {\n            context.valueSchema = typeless_;\n            return true;\n        }\n\n        if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());\n\n        return true;\n    }\n\n    bool EndObject(Context& context, SizeType memberCount) const {\n        if (hasRequired_)\n            for (SizeType index = 0; index < propertyCount_; index++)\n                if (properties_[index].required)\n                    if (!context.propertyExist[index])\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());\n\n        if (memberCount < minProperties_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());\n\n        if (memberCount > maxProperties_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());\n\n        if (hasDependencies_) {\n            for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)\n                if (context.propertyExist[sourceIndex]) {\n                    if (properties_[sourceIndex].dependencies) {\n                        for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)\n                            if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex])\n                                RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());\n                    }\n                    else if (properties_[sourceIndex].dependenciesSchema)\n                        if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid())\n                            RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());\n                }\n        }\n\n        return true;\n    }\n\n    bool StartArray(Context& context) const { \n        if (!(type_ & (1 << kArraySchemaType)))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        context.arrayElementIndex = 0;\n        context.inArray = true;\n\n        return CreateParallelValidator(context);\n    }\n\n    bool EndArray(Context& context, SizeType elementCount) const { \n        context.inArray = false;\n        \n        if (elementCount < minItems_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());\n        \n        if (elementCount > maxItems_)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());\n\n        return true;\n    }\n\n    // Generate functions for string literal according to Ch\n#define RAPIDJSON_STRING_(name, ...) \\\n    static const ValueType& Get##name##String() {\\\n        static const Ch s[] = { __VA_ARGS__, '\\0' };\\\n        static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1));\\\n        return v;\\\n    }\n\n    RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')\n    RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')\n    RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')\n    RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')\n    RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')\n    RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')\n    RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')\n    RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')\n    RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')\n    RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')\n    RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')\n    RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')\n    RAPIDJSON_STRING_(Not, 'n', 'o', 't')\n    RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')\n    RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')\n    RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')\n    RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')\n    RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')\n    RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')\n    RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')\n    RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')\n    RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')\n\n#undef RAPIDJSON_STRING_\n\nprivate:\n    enum SchemaValueType {\n        kNullSchemaType,\n        kBooleanSchemaType,\n        kObjectSchemaType,\n        kArraySchemaType,\n        kStringSchemaType,\n        kNumberSchemaType,\n        kIntegerSchemaType,\n        kTotalSchemaType\n    };\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n        typedef internal::GenericRegex<EncodingType> RegexType;\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n        typedef std::basic_regex<Ch> RegexType;\n#else\n        typedef char RegexType;\n#endif\n\n    struct SchemaArray {\n        SchemaArray() : schemas(), count() {}\n        ~SchemaArray() { AllocatorType::Free(schemas); }\n        const SchemaType** schemas;\n        SizeType begin; // begin index of context.validators\n        SizeType count;\n    };\n\n    template <typename V1, typename V2>\n    void AddUniqueElement(V1& a, const V2& v) {\n        for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)\n            if (*itr == v)\n                return;\n        V1 c(v, *allocator_);\n        a.PushBack(c, *allocator_);\n    }\n\n    static const ValueType* GetMember(const ValueType& value, const ValueType& name) {\n        typename ValueType::ConstMemberIterator itr = value.FindMember(name);\n        return itr != value.MemberEnd() ? &(itr->value) : 0;\n    }\n\n    static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) {\n        if (const ValueType* v = GetMember(value, name))\n            if (v->IsBool())\n                out = v->GetBool();\n    }\n\n    static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) {\n        if (const ValueType* v = GetMember(value, name))\n            if (v->IsUint64() && v->GetUint64() <= SizeType(~0))\n                out = static_cast<SizeType>(v->GetUint64());\n    }\n\n    void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) {\n        if (const ValueType* v = GetMember(value, name)) {\n            if (v->IsArray() && v->Size() > 0) {\n                PointerType q = p.Append(name, allocator_);\n                out.count = v->Size();\n                out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));\n                memset(out.schemas, 0, sizeof(Schema*)* out.count);\n                for (SizeType i = 0; i < out.count; i++)\n                    schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document);\n                out.begin = validatorCount_;\n                validatorCount_ += out.count;\n            }\n        }\n    }\n\n#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType& value) {\n        if (value.IsString()) {\n            RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString());\n            if (!r->IsValid()) {\n                r->~RegexType();\n                AllocatorType::Free(r);\n                r = 0;\n            }\n            return r;\n        }\n        return 0;\n    }\n\n    static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) {\n        GenericRegexSearch<RegexType> rs(*pattern);\n        return rs.Search(str);\n    }\n#elif RAPIDJSON_SCHEMA_USE_STDREGEX\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType& value) {\n        if (value.IsString())\n            try {\n                return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);\n            }\n            catch (const std::regex_error&) {\n            }\n        return 0;\n    }\n\n    static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) {\n        std::match_results<const Ch*> r;\n        return std::regex_search(str, str + length, r, *pattern);\n    }\n#else\n    template <typename ValueType>\n    RegexType* CreatePattern(const ValueType&) { return 0; }\n\n    static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; }\n#endif // RAPIDJSON_SCHEMA_USE_STDREGEX\n\n    void AddType(const ValueType& type) {\n        if      (type == GetNullString()   ) type_ |= 1 << kNullSchemaType;\n        else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;\n        else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;\n        else if (type == GetArrayString()  ) type_ |= 1 << kArraySchemaType;\n        else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;\n        else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;\n        else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);\n    }\n\n    bool CreateParallelValidator(Context& context) const {\n        if (enum_ || context.arrayUniqueness)\n            context.hasher = context.factory.CreateHasher();\n\n        if (validatorCount_) {\n            RAPIDJSON_ASSERT(context.validators == 0);\n            context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));\n            context.validatorCount = validatorCount_;\n\n            if (allOf_.schemas)\n                CreateSchemaValidators(context, allOf_);\n\n            if (anyOf_.schemas)\n                CreateSchemaValidators(context, anyOf_);\n            \n            if (oneOf_.schemas)\n                CreateSchemaValidators(context, oneOf_);\n            \n            if (not_)\n                context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_);\n            \n            if (hasSchemaDependencies_) {\n                for (SizeType i = 0; i < propertyCount_; i++)\n                    if (properties_[i].dependenciesSchema)\n                        context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);\n            }\n        }\n\n        return true;\n    }\n\n    void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {\n        for (SizeType i = 0; i < schemas.count; i++)\n            context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);\n    }\n\n    // O(n)\n    bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {\n        SizeType len = name.GetStringLength();\n        const Ch* str = name.GetString();\n        for (SizeType index = 0; index < propertyCount_; index++)\n            if (properties_[index].name.GetStringLength() == len && \n                (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))\n            {\n                *outIndex = index;\n                return true;\n            }\n        return false;\n    }\n\n    bool CheckInt(Context& context, int64_t i) const {\n        if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull()) {\n            if (minimum_.IsInt64()) {\n                if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n            }\n            else if (minimum_.IsUint64()) {\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()\n            }\n            else if (!CheckDoubleMinimum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!maximum_.IsNull()) {\n            if (maximum_.IsInt64()) {\n                if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n            }\n            else if (maximum_.IsUint64()) { }\n                /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()\n            else if (!CheckDoubleMaximum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!multipleOf_.IsNull()) {\n            if (multipleOf_.IsUint64()) {\n                if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n            }\n            else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))\n                return false;\n        }\n\n        return true;\n    }\n\n    bool CheckUint(Context& context, uint64_t i) const {\n        if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());\n\n        if (!minimum_.IsNull()) {\n            if (minimum_.IsUint64()) {\n                if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n            }\n            else if (minimum_.IsInt64())\n                /* do nothing */; // i >= 0 > minimum.Getint64()\n            else if (!CheckDoubleMinimum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!maximum_.IsNull()) {\n            if (maximum_.IsUint64()) {\n                if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n            }\n            else if (maximum_.IsInt64())\n                RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_\n            else if (!CheckDoubleMaximum(context, static_cast<double>(i)))\n                return false;\n        }\n\n        if (!multipleOf_.IsNull()) {\n            if (multipleOf_.IsUint64()) {\n                if (i % multipleOf_.GetUint64() != 0)\n                    RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n            }\n            else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))\n                return false;\n        }\n\n        return true;\n    }\n\n    bool CheckDoubleMinimum(Context& context, double d) const {\n        if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());\n        return true;\n    }\n\n    bool CheckDoubleMaximum(Context& context, double d) const {\n        if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());\n        return true;\n    }\n\n    bool CheckDoubleMultipleOf(Context& context, double d) const {\n        double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());\n        double q = std::floor(a / b);\n        double r = a - q * b;\n        if (r > 0.0)\n            RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());\n        return true;\n    }\n\n    struct Property {\n        Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}\n        ~Property() { AllocatorType::Free(dependencies); }\n        SValue name;\n        const SchemaType* schema;\n        const SchemaType* dependenciesSchema;\n        SizeType dependenciesValidatorIndex;\n        bool* dependencies;\n        bool required;\n    };\n\n    struct PatternProperty {\n        PatternProperty() : schema(), pattern() {}\n        ~PatternProperty() { \n            if (pattern) {\n                pattern->~RegexType();\n                AllocatorType::Free(pattern);\n            }\n        }\n        const SchemaType* schema;\n        RegexType* pattern;\n    };\n\n    AllocatorType* allocator_;\n    const SchemaType* typeless_;\n    uint64_t* enum_;\n    SizeType enumCount_;\n    SchemaArray allOf_;\n    SchemaArray anyOf_;\n    SchemaArray oneOf_;\n    const SchemaType* not_;\n    unsigned type_; // bitmask of kSchemaType\n    SizeType validatorCount_;\n    SizeType notValidatorIndex_;\n\n    Property* properties_;\n    const SchemaType* additionalPropertiesSchema_;\n    PatternProperty* patternProperties_;\n    SizeType patternPropertyCount_;\n    SizeType propertyCount_;\n    SizeType minProperties_;\n    SizeType maxProperties_;\n    bool additionalProperties_;\n    bool hasDependencies_;\n    bool hasRequired_;\n    bool hasSchemaDependencies_;\n\n    const SchemaType* additionalItemsSchema_;\n    const SchemaType* itemsList_;\n    const SchemaType** itemsTuple_;\n    SizeType itemsTupleCount_;\n    SizeType minItems_;\n    SizeType maxItems_;\n    bool additionalItems_;\n    bool uniqueItems_;\n\n    RegexType* pattern_;\n    SizeType minLength_;\n    SizeType maxLength_;\n\n    SValue minimum_;\n    SValue maximum_;\n    SValue multipleOf_;\n    bool exclusiveMinimum_;\n    bool exclusiveMaximum_;\n};\n\ntemplate<typename Stack, typename Ch>\nstruct TokenHelper {\n    RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {\n        *documentStack.template Push<Ch>() = '/';\n        char buffer[21];\n        size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);\n        for (size_t i = 0; i < length; i++)\n            *documentStack.template Push<Ch>() = static_cast<Ch>(buffer[i]);\n    }\n};\n\n// Partial specialized version for char to prevent buffer copying.\ntemplate <typename Stack>\nstruct TokenHelper<Stack, char> {\n    RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {\n        if (sizeof(SizeType) == 4) {\n            char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint\n            *buffer++ = '/';\n            const char* end = internal::u32toa(index, buffer);\n             documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer)));\n        }\n        else {\n            char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64\n            *buffer++ = '/';\n            const char* end = internal::u64toa(index, buffer);\n            documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer)));\n        }\n    }\n};\n\n} // namespace internal\n\n///////////////////////////////////////////////////////////////////////////////\n// IGenericRemoteSchemaDocumentProvider\n\ntemplate <typename SchemaDocumentType>\nclass IGenericRemoteSchemaDocumentProvider {\npublic:\n    typedef typename SchemaDocumentType::Ch Ch;\n\n    virtual ~IGenericRemoteSchemaDocumentProvider() {}\n    virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;\n};\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericSchemaDocument\n\n//! JSON schema document.\n/*!\n    A JSON schema document is a compiled version of a JSON schema.\n    It is basically a tree of internal::Schema.\n\n    \\note This is an immutable class (i.e. its instance cannot be modified after construction).\n    \\tparam ValueT Type of JSON value (e.g. \\c Value ), which also determine the encoding.\n    \\tparam Allocator Allocator type for allocating memory of this document.\n*/\ntemplate <typename ValueT, typename Allocator = CrtAllocator>\nclass GenericSchemaDocument {\npublic:\n    typedef ValueT ValueType;\n    typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRemoteSchemaDocumentProviderType;\n    typedef Allocator AllocatorType;\n    typedef typename ValueType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n    typedef internal::Schema<GenericSchemaDocument> SchemaType;\n    typedef GenericPointer<ValueType, Allocator> PointerType;\n    friend class internal::Schema<GenericSchemaDocument>;\n    template <typename, typename, typename>\n    friend class GenericSchemaValidator;\n\n    //! Constructor.\n    /*!\n        Compile a JSON document into schema document.\n\n        \\param document A JSON document as source.\n        \\param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null.\n        \\param allocator An optional allocator instance for allocating memory. Can be null.\n    */\n    explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :\n        remoteProvider_(remoteProvider),\n        allocator_(allocator),\n        ownAllocator_(),\n        root_(),\n        typeless_(),\n        schemaMap_(allocator, kInitialSchemaMapSize),\n        schemaRef_(allocator, kInitialSchemaRefSize)\n    {\n        if (!allocator_)\n            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();\n\n        typeless_ = static_cast<SchemaType*>(allocator_->Malloc(sizeof(SchemaType)));\n        new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);\n\n        // Generate root schema, it will call CreateSchema() to create sub-schemas,\n        // And call AddRefSchema() if there are $ref.\n        CreateSchemaRecursive(&root_, PointerType(), document, document);\n\n        // Resolve $ref\n        while (!schemaRef_.Empty()) {\n            SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);\n            if (const SchemaType* s = GetSchema(refEntry->target)) {\n                if (refEntry->schema)\n                    *refEntry->schema = s;\n\n                // Create entry in map if not exist\n                if (!GetSchema(refEntry->source)) {\n                    new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);\n                }\n            }\n            else if (refEntry->schema)\n                *refEntry->schema = typeless_;\n\n            refEntry->~SchemaRefEntry();\n        }\n\n        RAPIDJSON_ASSERT(root_ != 0);\n\n        schemaRef_.ShrinkToFit(); // Deallocate all memory for ref\n    }\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    //! Move constructor in C++11\n    GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :\n        remoteProvider_(rhs.remoteProvider_),\n        allocator_(rhs.allocator_),\n        ownAllocator_(rhs.ownAllocator_),\n        root_(rhs.root_),\n        typeless_(rhs.typeless_),\n        schemaMap_(std::move(rhs.schemaMap_)),\n        schemaRef_(std::move(rhs.schemaRef_))\n    {\n        rhs.remoteProvider_ = 0;\n        rhs.allocator_ = 0;\n        rhs.ownAllocator_ = 0;\n        rhs.typeless_ = 0;\n    }\n#endif\n\n    //! Destructor\n    ~GenericSchemaDocument() {\n        while (!schemaMap_.Empty())\n            schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();\n\n        if (typeless_) {\n            typeless_->~SchemaType();\n            Allocator::Free(typeless_);\n        }\n\n        RAPIDJSON_DELETE(ownAllocator_);\n    }\n\n    //! Get the root schema.\n    const SchemaType& GetRoot() const { return *root_; }\n\nprivate:\n    //! Prohibit copying\n    GenericSchemaDocument(const GenericSchemaDocument&);\n    //! Prohibit assignment\n    GenericSchemaDocument& operator=(const GenericSchemaDocument&);\n\n    struct SchemaRefEntry {\n        SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}\n        PointerType source;\n        PointerType target;\n        const SchemaType** schema;\n    };\n\n    struct SchemaEntry {\n        SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}\n        ~SchemaEntry() {\n            if (owned) {\n                schema->~SchemaType();\n                Allocator::Free(schema);\n            }\n        }\n        PointerType pointer;\n        SchemaType* schema;\n        bool owned;\n    };\n\n    void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {\n        if (schema)\n            *schema = typeless_;\n\n        if (v.GetType() == kObjectType) {\n            const SchemaType* s = GetSchema(pointer);\n            if (!s)\n                CreateSchema(schema, pointer, v, document);\n\n            for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)\n                CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document);\n        }\n        else if (v.GetType() == kArrayType)\n            for (SizeType i = 0; i < v.Size(); i++)\n                CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document);\n    }\n\n    void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {\n        RAPIDJSON_ASSERT(pointer.IsValid());\n        if (v.IsObject()) {\n            if (!HandleRefSchema(pointer, schema, v, document)) {\n                SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_);\n                new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);\n                if (schema)\n                    *schema = s;\n            }\n        }\n    }\n\n    bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) {\n        static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\\0' };\n        static const ValueType kRefValue(kRefString, 4);\n\n        typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);\n        if (itr == v.MemberEnd())\n            return false;\n\n        if (itr->value.IsString()) {\n            SizeType len = itr->value.GetStringLength();\n            if (len > 0) {\n                const Ch* s = itr->value.GetString();\n                SizeType i = 0;\n                while (i < len && s[i] != '#') // Find the first #\n                    i++;\n\n                if (i > 0) { // Remote reference, resolve immediately\n                    if (remoteProvider_) {\n                        if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) {\n                            PointerType pointer(&s[i], len - i, allocator_);\n                            if (pointer.IsValid()) {\n                                if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {\n                                    if (schema)\n                                        *schema = sc;\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n                else if (s[i] == '#') { // Local reference, defer resolution\n                    PointerType pointer(&s[i], len - i, allocator_);\n                    if (pointer.IsValid()) {\n                        if (const ValueType* nv = pointer.Get(document))\n                            if (HandleRefSchema(source, schema, *nv, document))\n                                return true;\n\n                        new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n    const SchemaType* GetSchema(const PointerType& pointer) const {\n        for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)\n            if (pointer == target->pointer)\n                return target->schema;\n        return 0;\n    }\n\n    PointerType GetPointer(const SchemaType* schema) const {\n        for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)\n            if (schema == target->schema)\n                return target->pointer;\n        return PointerType();\n    }\n\n    const SchemaType* GetTypeless() const { return typeless_; }\n\n    static const size_t kInitialSchemaMapSize = 64;\n    static const size_t kInitialSchemaRefSize = 64;\n\n    IRemoteSchemaDocumentProviderType* remoteProvider_;\n    Allocator *allocator_;\n    Allocator *ownAllocator_;\n    const SchemaType* root_;                //!< Root schema.\n    SchemaType* typeless_;\n    internal::Stack<Allocator> schemaMap_;  // Stores created Pointer -> Schemas\n    internal::Stack<Allocator> schemaRef_;  // Stores Pointer from $ref and schema which holds the $ref\n};\n\n//! GenericSchemaDocument using Value type.\ntypedef GenericSchemaDocument<Value> SchemaDocument;\n//! IGenericRemoteSchemaDocumentProvider using SchemaDocument.\ntypedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;\n\n///////////////////////////////////////////////////////////////////////////////\n// GenericSchemaValidator\n\n//! JSON Schema Validator.\n/*!\n    A SAX style JSON schema validator.\n    It uses a \\c GenericSchemaDocument to validate SAX events.\n    It delegates the incoming SAX events to an output handler.\n    The default output handler does nothing.\n    It can be reused multiple times by calling \\c Reset().\n\n    \\tparam SchemaDocumentType Type of schema document.\n    \\tparam OutputHandler Type of output handler. Default handler does nothing.\n    \\tparam StateAllocator Allocator for storing the internal validation states.\n*/\ntemplate <\n    typename SchemaDocumentType,\n    typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>,\n    typename StateAllocator = CrtAllocator>\nclass GenericSchemaValidator :\n    public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>, \n    public internal::ISchemaValidator\n{\npublic:\n    typedef typename SchemaDocumentType::SchemaType SchemaType;\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename SchemaType::EncodingType EncodingType;\n    typedef typename EncodingType::Ch Ch;\n\n    //! Constructor without output handler.\n    /*!\n        \\param schemaDocument The schema document to conform to.\n        \\param allocator Optional allocator for storing internal validation states.\n        \\param schemaStackCapacity Optional initial capacity of schema path stack.\n        \\param documentStackCapacity Optional initial capacity of document path stack.\n    */\n    GenericSchemaValidator(\n        const SchemaDocumentType& schemaDocument,\n        StateAllocator* allocator = 0, \n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(schemaDocument.GetRoot()),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(CreateNullHandler()),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(0)\n#endif\n    {\n    }\n\n    //! Constructor with output handler.\n    /*!\n        \\param schemaDocument The schema document to conform to.\n        \\param allocator Optional allocator for storing internal validation states.\n        \\param schemaStackCapacity Optional initial capacity of schema path stack.\n        \\param documentStackCapacity Optional initial capacity of document path stack.\n    */\n    GenericSchemaValidator(\n        const SchemaDocumentType& schemaDocument,\n        OutputHandler& outputHandler,\n        StateAllocator* allocator = 0, \n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(schemaDocument.GetRoot()),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(outputHandler),\n        nullHandler_(0),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(0)\n#endif\n    {\n    }\n\n    //! Destructor.\n    ~GenericSchemaValidator() {\n        Reset();\n        if (nullHandler_) {\n            nullHandler_->~OutputHandler();\n            StateAllocator::Free(nullHandler_);\n        }\n        RAPIDJSON_DELETE(ownStateAllocator_);\n    }\n\n    //! Reset the internal states.\n    void Reset() {\n        while (!schemaStack_.Empty())\n            PopSchema();\n        documentStack_.Clear();\n        valid_ = true;\n    }\n\n    //! Checks whether the current state is valid.\n    // Implementation of ISchemaValidator\n    virtual bool IsValid() const { return valid_; }\n\n    //! Gets the JSON pointer pointed to the invalid schema.\n    PointerType GetInvalidSchemaPointer() const {\n        return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema());\n    }\n\n    //! Gets the keyword of invalid schema.\n    const Ch* GetInvalidSchemaKeyword() const {\n        return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;\n    }\n\n    //! Gets the JSON pointer pointed to the invalid value.\n    PointerType GetInvalidDocumentPointer() const {\n        return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch));\n    }\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \\\nRAPIDJSON_MULTILINEMACRO_BEGIN\\\n    *documentStack_.template Push<Ch>() = '\\0';\\\n    documentStack_.template Pop<Ch>(1);\\\n    internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\\\nRAPIDJSON_MULTILINEMACRO_END\n#else\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_()\n#endif\n\n#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\\\n    if (!valid_) return false; \\\n    if (!BeginValue() || !CurrentSchema().method arg1) {\\\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\\\n        return valid_ = false;\\\n    }\n\n#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\\\n    for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\\\n        if (context->hasher)\\\n            static_cast<HasherType*>(context->hasher)->method arg2;\\\n        if (context->validators)\\\n            for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\\\n                static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\\\n        if (context->patternPropertiesValidators)\\\n            for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\\\n                static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\\\n    }\n\n#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\\\n    return valid_ = EndValue() && outputHandler_.method arg2\n\n#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \\\n    RAPIDJSON_SCHEMA_HANDLE_BEGIN_   (method, arg1);\\\n    RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\\\n    RAPIDJSON_SCHEMA_HANDLE_END_     (method, arg2)\n\n    bool Null()             { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null,   (CurrentContext()   ), ( )); }\n    bool Bool(bool b)       { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool,   (CurrentContext(), b), (b)); }\n    bool Int(int i)         { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int,    (CurrentContext(), i), (i)); }\n    bool Uint(unsigned u)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint,   (CurrentContext(), u), (u)); }\n    bool Int64(int64_t i)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64,  (CurrentContext(), i), (i)); }\n    bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }\n    bool Double(double d)   { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }\n    bool RawNumber(const Ch* str, SizeType length, bool copy)\n                                    { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }\n    bool String(const Ch* str, SizeType length, bool copy)\n                                    { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }\n\n    bool StartObject() {\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());\n        return valid_ = outputHandler_.StartObject();\n    }\n    \n    bool Key(const Ch* str, SizeType len, bool copy) {\n        if (!valid_) return false;\n        AppendToken(str, len);\n        if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));\n        return valid_ = outputHandler_.Key(str, len, copy);\n    }\n    \n    bool EndObject(SizeType memberCount) { \n        if (!valid_) return false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));\n        if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));\n    }\n\n    bool StartArray() {\n        RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());\n        return valid_ = outputHandler_.StartArray();\n    }\n    \n    bool EndArray(SizeType elementCount) {\n        if (!valid_) return false;\n        RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));\n        if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;\n        RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));\n    }\n\n#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_\n#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_\n#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_\n#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_\n\n    // Implementation of ISchemaStateFactory<SchemaType>\n    virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {\n        return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root,\n#if RAPIDJSON_SCHEMA_VERBOSE\n        depth_ + 1,\n#endif\n        &GetStateAllocator());\n    }\n\n    virtual void DestroySchemaValidator(ISchemaValidator* validator) {\n        GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator);\n        v->~GenericSchemaValidator();\n        StateAllocator::Free(v);\n    }\n\n    virtual void* CreateHasher() {\n        return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());\n    }\n\n    virtual uint64_t GetHashCode(void* hasher) {\n        return static_cast<HasherType*>(hasher)->GetHashCode();\n    }\n\n    virtual void DestroryHasher(void* hasher) {\n        HasherType* h = static_cast<HasherType*>(hasher);\n        h->~HasherType();\n        StateAllocator::Free(h);\n    }\n\n    virtual void* MallocState(size_t size) {\n        return GetStateAllocator().Malloc(size);\n    }\n\n    virtual void FreeState(void* p) {\n        StateAllocator::Free(p);\n    }\n\nprivate:\n    typedef typename SchemaType::Context Context;\n    typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;\n    typedef internal::Hasher<EncodingType, StateAllocator> HasherType;\n\n    GenericSchemaValidator( \n        const SchemaDocumentType& schemaDocument,\n        const SchemaType& root,\n#if RAPIDJSON_SCHEMA_VERBOSE\n        unsigned depth,\n#endif\n        StateAllocator* allocator = 0,\n        size_t schemaStackCapacity = kDefaultSchemaStackCapacity,\n        size_t documentStackCapacity = kDefaultDocumentStackCapacity)\n        :\n        schemaDocument_(&schemaDocument),\n        root_(root),\n        stateAllocator_(allocator),\n        ownStateAllocator_(0),\n        schemaStack_(allocator, schemaStackCapacity),\n        documentStack_(allocator, documentStackCapacity),\n        outputHandler_(CreateNullHandler()),\n        valid_(true)\n#if RAPIDJSON_SCHEMA_VERBOSE\n        , depth_(depth)\n#endif\n    {\n    }\n\n    StateAllocator& GetStateAllocator() {\n        if (!stateAllocator_)\n            stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)();\n        return *stateAllocator_;\n    }\n\n    bool BeginValue() {\n        if (schemaStack_.Empty())\n            PushSchema(root_);\n        else {\n            if (CurrentContext().inArray)\n                internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);\n\n            if (!CurrentSchema().BeginValue(CurrentContext()))\n                return false;\n\n            SizeType count = CurrentContext().patternPropertiesSchemaCount;\n            const SchemaType** sa = CurrentContext().patternPropertiesSchemas;\n            typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;\n            bool valueUniqueness = CurrentContext().valueUniqueness;\n            RAPIDJSON_ASSERT(CurrentContext().valueSchema);\n            PushSchema(*CurrentContext().valueSchema);\n\n            if (count > 0) {\n                CurrentContext().objectPatternValidatorType = patternValidatorType;\n                ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;\n                SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;\n                va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));\n                for (SizeType i = 0; i < count; i++)\n                    va[validatorCount++] = CreateSchemaValidator(*sa[i]);\n            }\n\n            CurrentContext().arrayUniqueness = valueUniqueness;\n        }\n        return true;\n    }\n\n    bool EndValue() {\n        if (!CurrentSchema().EndValue(CurrentContext()))\n            return false;\n\n#if RAPIDJSON_SCHEMA_VERBOSE\n        GenericStringBuffer<EncodingType> sb;\n        schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);\n\n        *documentStack_.template Push<Ch>() = '\\0';\n        documentStack_.template Pop<Ch>(1);\n        internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());\n#endif\n\n        uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0;\n        \n        PopSchema();\n\n        if (!schemaStack_.Empty()) {\n            Context& context = CurrentContext();\n            if (context.valueUniqueness) {\n                HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);\n                if (!a)\n                    CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);\n                for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)\n                    if (itr->GetUint64() == h)\n                        RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString());\n                a->PushBack(h, GetStateAllocator());\n            }\n        }\n\n        // Remove the last token of document pointer\n        while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')\n            ;\n\n        return true;\n    }\n\n    void AppendToken(const Ch* str, SizeType len) {\n        documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters\n        *documentStack_.template PushUnsafe<Ch>() = '/';\n        for (SizeType i = 0; i < len; i++) {\n            if (str[i] == '~') {\n                *documentStack_.template PushUnsafe<Ch>() = '~';\n                *documentStack_.template PushUnsafe<Ch>() = '0';\n            }\n            else if (str[i] == '/') {\n                *documentStack_.template PushUnsafe<Ch>() = '~';\n                *documentStack_.template PushUnsafe<Ch>() = '1';\n            }\n            else\n                *documentStack_.template PushUnsafe<Ch>() = str[i];\n        }\n    }\n\n    RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); }\n    \n    RAPIDJSON_FORCEINLINE void PopSchema() {\n        Context* c = schemaStack_.template Pop<Context>(1);\n        if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {\n            a->~HashCodeArray();\n            StateAllocator::Free(a);\n        }\n        c->~Context();\n    }\n\n    const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }\n    Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }\n    const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }\n\n    OutputHandler& CreateNullHandler() {\n        return *(nullHandler_ = new (GetStateAllocator().Malloc(sizeof(OutputHandler))) OutputHandler);\n    }\n\n    static const size_t kDefaultSchemaStackCapacity = 1024;\n    static const size_t kDefaultDocumentStackCapacity = 256;\n    const SchemaDocumentType* schemaDocument_;\n    const SchemaType& root_;\n    StateAllocator* stateAllocator_;\n    StateAllocator* ownStateAllocator_;\n    internal::Stack<StateAllocator> schemaStack_;    //!< stack to store the current path of schema (BaseSchemaType *)\n    internal::Stack<StateAllocator> documentStack_;  //!< stack to store the current path of validating document (Ch)\n    OutputHandler& outputHandler_;\n    OutputHandler* nullHandler_;\n    bool valid_;\n#if RAPIDJSON_SCHEMA_VERBOSE\n    unsigned depth_;\n#endif\n};\n\ntypedef GenericSchemaValidator<SchemaDocument> SchemaValidator;\n\n///////////////////////////////////////////////////////////////////////////////\n// SchemaValidatingReader\n\n//! A helper class for parsing with validation.\n/*!\n    This helper class is a functor, designed as a parameter of \\ref GenericDocument::Populate().\n\n    \\tparam parseFlags Combination of \\ref ParseFlag.\n    \\tparam InputStream Type of input stream, implementing Stream concept.\n    \\tparam SourceEncoding Encoding of the input stream.\n    \\tparam SchemaDocumentType Type of schema document.\n    \\tparam StackAllocator Allocator type for stack.\n*/\ntemplate <\n    unsigned parseFlags,\n    typename InputStream,\n    typename SourceEncoding,\n    typename SchemaDocumentType = SchemaDocument,\n    typename StackAllocator = CrtAllocator>\nclass SchemaValidatingReader {\npublic:\n    typedef typename SchemaDocumentType::PointerType PointerType;\n    typedef typename InputStream::Ch Ch;\n\n    //! Constructor\n    /*!\n        \\param is Input stream.\n        \\param sd Schema document.\n    */\n    SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {}\n\n    template <typename Handler>\n    bool operator()(Handler& handler) {\n        GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader;\n        GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler);\n        parseResult_ = reader.template Parse<parseFlags>(is_, validator);\n\n        isValid_ = validator.IsValid();\n        if (isValid_) {\n            invalidSchemaPointer_ = PointerType();\n            invalidSchemaKeyword_ = 0;\n            invalidDocumentPointer_ = PointerType();\n        }\n        else {\n            invalidSchemaPointer_ = validator.GetInvalidSchemaPointer();\n            invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword();\n            invalidDocumentPointer_ = validator.GetInvalidDocumentPointer();\n        }\n\n        return parseResult_;\n    }\n\n    const ParseResult& GetParseResult() const { return parseResult_; }\n    bool IsValid() const { return isValid_; }\n    const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; }\n    const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }\n    const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; }\n\nprivate:\n    InputStream& is_;\n    const SchemaDocumentType& sd_;\n\n    ParseResult parseResult_;\n    PointerType invalidSchemaPointer_;\n    const Ch* invalidSchemaKeyword_;\n    PointerType invalidDocumentPointer_;\n    bool isValid_;\n};\n\nRAPIDJSON_NAMESPACE_END\nRAPIDJSON_DIAG_POP\n\n#endif // RAPIDJSON_SCHEMA_H_\n"
  },
  {
    "path": "third-party/rapidjson/stream.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#include \"rapidjson.h\"\n\n#ifndef RAPIDJSON_STREAM_H_\n#define RAPIDJSON_STREAM_H_\n\n#include \"encodings.h\"\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n//  Stream\n\n/*! \\class rapidjson::Stream\n    \\brief Concept for reading and writing characters.\n\n    For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().\n\n    For write-only stream, only need to implement Put() and Flush().\n\n\\code\nconcept Stream {\n    typename Ch;    //!< Character type of the stream.\n\n    //! Read the current character from stream without moving the read cursor.\n    Ch Peek() const;\n\n    //! Read the current character from stream and moving the read cursor to next character.\n    Ch Take();\n\n    //! Get the current read cursor.\n    //! \\return Number of characters read from start.\n    size_t Tell();\n\n    //! Begin writing operation at the current read pointer.\n    //! \\return The begin writer pointer.\n    Ch* PutBegin();\n\n    //! Write a character.\n    void Put(Ch c);\n\n    //! Flush the buffer.\n    void Flush();\n\n    //! End the writing operation.\n    //! \\param begin The begin write pointer returned by PutBegin().\n    //! \\return Number of characters written.\n    size_t PutEnd(Ch* begin);\n}\n\\endcode\n*/\n\n//! Provides additional information for stream.\n/*!\n    By using traits pattern, this type provides a default configuration for stream.\n    For custom stream, this type can be specialized for other configuration.\n    See TEST(Reader, CustomStringStream) in readertest.cpp for example.\n*/\ntemplate<typename Stream>\nstruct StreamTraits {\n    //! Whether to make local copy of stream for optimization during parsing.\n    /*!\n        By default, for safety, streams do not use local copy optimization.\n        Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.\n    */\n    enum { copyOptimization = 0 };\n};\n\n//! Reserve n characters for writing to a stream.\ntemplate<typename Stream>\ninline void PutReserve(Stream& stream, size_t count) {\n    (void)stream;\n    (void)count;\n}\n\n//! Write character to a stream, presuming buffer is reserved.\ntemplate<typename Stream>\ninline void PutUnsafe(Stream& stream, typename Stream::Ch c) {\n    stream.Put(c);\n}\n\n//! Put N copies of a character to a stream.\ntemplate<typename Stream, typename Ch>\ninline void PutN(Stream& stream, Ch c, size_t n) {\n    PutReserve(stream, n);\n    for (size_t i = 0; i < n; i++)\n        PutUnsafe(stream, c);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// StringStream\n\n//! Read-only string stream.\n/*! \\note implements Stream concept\n*/\ntemplate <typename Encoding>\nstruct GenericStringStream {\n    typedef typename Encoding::Ch Ch;\n\n    GenericStringStream(const Ch *src) : src_(src), head_(src) {}\n\n    Ch Peek() const { return *src_; }\n    Ch Take() { return *src_++; }\n    size_t Tell() const { return static_cast<size_t>(src_ - head_); }\n\n    Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }\n    void Put(Ch) { RAPIDJSON_ASSERT(false); }\n    void Flush() { RAPIDJSON_ASSERT(false); }\n    size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }\n\n    const Ch* src_;     //!< Current read position.\n    const Ch* head_;    //!< Original head of the string.\n};\n\ntemplate <typename Encoding>\nstruct StreamTraits<GenericStringStream<Encoding> > {\n    enum { copyOptimization = 1 };\n};\n\n//! String stream with UTF8 encoding.\ntypedef GenericStringStream<UTF8<> > StringStream;\n\n///////////////////////////////////////////////////////////////////////////////\n// InsituStringStream\n\n//! A read-write string stream.\n/*! This string stream is particularly designed for in-situ parsing.\n    \\note implements Stream concept\n*/\ntemplate <typename Encoding>\nstruct GenericInsituStringStream {\n    typedef typename Encoding::Ch Ch;\n\n    GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}\n\n    // Read\n    Ch Peek() { return *src_; }\n    Ch Take() { return *src_++; }\n    size_t Tell() { return static_cast<size_t>(src_ - head_); }\n\n    // Write\n    void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }\n\n    Ch* PutBegin() { return dst_ = src_; }\n    size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }\n    void Flush() {}\n\n    Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }\n    void Pop(size_t count) { dst_ -= count; }\n\n    Ch* src_;\n    Ch* dst_;\n    Ch* head_;\n};\n\ntemplate <typename Encoding>\nstruct StreamTraits<GenericInsituStringStream<Encoding> > {\n    enum { copyOptimization = 1 };\n};\n\n//! Insitu string stream with UTF8 encoding.\ntypedef GenericInsituStringStream<UTF8<> > InsituStringStream;\n\nRAPIDJSON_NAMESPACE_END\n\n#endif // RAPIDJSON_STREAM_H_\n"
  },
  {
    "path": "third-party/rapidjson/stringbuffer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_STRINGBUFFER_H_\n#define RAPIDJSON_STRINGBUFFER_H_\n\n#include \"stream.h\"\n#include \"internal/stack.h\"\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n#include <utility> // std::move\n#endif\n\n#include \"internal/stack.h\"\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n//! Represents an in-memory output stream.\n/*!\n    \\tparam Encoding Encoding of the stream.\n    \\tparam Allocator type for allocating memory buffer.\n    \\note implements Stream concept\n*/\ntemplate <typename Encoding, typename Allocator = CrtAllocator>\nclass GenericStringBuffer {\npublic:\n    typedef typename Encoding::Ch Ch;\n\n    GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}\n    GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {\n        if (&rhs != this)\n            stack_ = std::move(rhs.stack_);\n        return *this;\n    }\n#endif\n\n    void Put(Ch c) { *stack_.template Push<Ch>() = c; }\n    void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }\n    void Flush() {}\n\n    void Clear() { stack_.Clear(); }\n    void ShrinkToFit() {\n        // Push and pop a null terminator. This is safe.\n        *stack_.template Push<Ch>() = '\\0';\n        stack_.ShrinkToFit();\n        stack_.template Pop<Ch>(1);\n    }\n\n    void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }\n    Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }\n    Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }\n    void Pop(size_t count) { stack_.template Pop<Ch>(count); }\n\n    const Ch* GetString() const {\n        // Push and pop a null terminator. This is safe.\n        *stack_.template Push<Ch>() = '\\0';\n        stack_.template Pop<Ch>(1);\n\n        return stack_.template Bottom<Ch>();\n    }\n\n    //! Get the size of string in bytes in the string buffer.\n    size_t GetSize() const { return stack_.GetSize(); }\n\n    //! Get the length of string in Ch in the string buffer.\n    size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }\n\n    static const size_t kDefaultCapacity = 256;\n    mutable internal::Stack<Allocator> stack_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    GenericStringBuffer(const GenericStringBuffer&);\n    GenericStringBuffer& operator=(const GenericStringBuffer&);\n};\n\n//! String buffer with UTF8 encoding\ntypedef GenericStringBuffer<UTF8<> > StringBuffer;\n\ntemplate<typename Encoding, typename Allocator>\ninline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {\n    stream.Reserve(count);\n}\n\ntemplate<typename Encoding, typename Allocator>\ninline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {\n    stream.PutUnsafe(c);\n}\n\n//! Implement specialized version of PutN() with memset() for better performance.\ntemplate<>\ninline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {\n    std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));\n}\n\nRAPIDJSON_NAMESPACE_END\n\n#if defined(__clang__)\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_STRINGBUFFER_H_\n"
  },
  {
    "path": "third-party/rapidjson/writer.h",
    "content": "// Tencent is pleased to support the open source community by making RapidJSON available.\n// \n// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\n//\n// Licensed under the MIT License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// http://opensource.org/licenses/MIT\n//\n// Unless required by applicable law or agreed to in writing, software distributed \n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR \n// CONDITIONS OF ANY KIND, either express or implied. See the License for the \n// specific language governing permissions and limitations under the License.\n\n#ifndef RAPIDJSON_WRITER_H_\n#define RAPIDJSON_WRITER_H_\n\n#include \"stream.h\"\n#include \"internal/meta.h\"\n#include \"internal/stack.h\"\n#include \"internal/strfunc.h\"\n#include \"internal/dtoa.h\"\n#include \"internal/itoa.h\"\n#include \"stringbuffer.h\"\n#include <new>      // placement new\n\n#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)\n#include <intrin.h>\n#pragma intrinsic(_BitScanForward)\n#endif\n#ifdef RAPIDJSON_SSE42\n#include <nmmintrin.h>\n#elif defined(RAPIDJSON_SSE2)\n#include <emmintrin.h>\n#elif defined(RAPIDJSON_NEON)\n#include <arm_neon.h>\n#endif\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(4127) // conditional expression is constant\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_PUSH\nRAPIDJSON_DIAG_OFF(padded)\nRAPIDJSON_DIAG_OFF(unreachable-code)\nRAPIDJSON_DIAG_OFF(c++98-compat)\n#endif\n\nRAPIDJSON_NAMESPACE_BEGIN\n\n///////////////////////////////////////////////////////////////////////////////\n// WriteFlag\n\n/*! \\def RAPIDJSON_WRITE_DEFAULT_FLAGS \n    \\ingroup RAPIDJSON_CONFIG\n    \\brief User-defined kWriteDefaultFlags definition.\n\n    User can define this as any \\c WriteFlag combinations.\n*/\n#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS\n#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags\n#endif\n\n//! Combination of writeFlags\nenum WriteFlag {\n    kWriteNoFlags = 0,              //!< No flags are set.\n    kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.\n    kWriteNanAndInfFlag = 2,        //!< Allow writing of Infinity, -Infinity and NaN.\n    kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS  //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS\n};\n\n//! JSON writer\n/*! Writer implements the concept Handler.\n    It generates JSON text by events to an output os.\n\n    User may programmatically calls the functions of a writer to generate JSON text.\n\n    On the other side, a writer can also be passed to objects that generates events, \n\n    for example Reader::Parse() and Document::Accept().\n\n    \\tparam OutputStream Type of output stream.\n    \\tparam SourceEncoding Encoding of source string.\n    \\tparam TargetEncoding Encoding of output stream.\n    \\tparam StackAllocator Type of allocator for allocating memory of stack.\n    \\note implements Handler concept\n*/\ntemplate<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>\nclass Writer {\npublic:\n    typedef typename SourceEncoding::Ch Ch;\n\n    static const int kDefaultMaxDecimalPlaces = 324;\n\n    //! Constructor\n    /*! \\param os Output stream.\n        \\param stackAllocator User supplied allocator. If it is null, it will create a private one.\n        \\param levelDepth Initial capacity of stack.\n    */\n    explicit\n    Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : \n        os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}\n\n    explicit\n    Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :\n        os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}\n\n#if RAPIDJSON_HAS_CXX11_RVALUE_REFS\n    Writer(Writer&& rhs) :\n        os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {\n        rhs.os_ = 0;\n    }\n#endif\n\n    //! Reset the writer with a new stream.\n    /*!\n        This function reset the writer with a new stream and default settings,\n        in order to make a Writer object reusable for output multiple JSONs.\n\n        \\param os New output stream.\n        \\code\n        Writer<OutputStream> writer(os1);\n        writer.StartObject();\n        // ...\n        writer.EndObject();\n\n        writer.Reset(os2);\n        writer.StartObject();\n        // ...\n        writer.EndObject();\n        \\endcode\n    */\n    void Reset(OutputStream& os) {\n        os_ = &os;\n        hasRoot_ = false;\n        level_stack_.Clear();\n    }\n\n    //! Checks whether the output is a complete JSON.\n    /*!\n        A complete JSON has a complete root object or array.\n    */\n    bool IsComplete() const {\n        return hasRoot_ && level_stack_.Empty();\n    }\n\n    int GetMaxDecimalPlaces() const {\n        return maxDecimalPlaces_;\n    }\n\n    //! Sets the maximum number of decimal places for double output.\n    /*!\n        This setting truncates the output with specified number of decimal places.\n\n        For example, \n\n        \\code\n        writer.SetMaxDecimalPlaces(3);\n        writer.StartArray();\n        writer.Double(0.12345);                 // \"0.123\"\n        writer.Double(0.0001);                  // \"0.0\"\n        writer.Double(1.234567890123456e30);    // \"1.234567890123456e30\" (do not truncate significand for positive exponent)\n        writer.Double(1.23e-4);                 // \"0.0\"                  (do truncate significand for negative exponent)\n        writer.EndArray();\n        \\endcode\n\n        The default setting does not truncate any decimal places. You can restore to this setting by calling\n        \\code\n        writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);\n        \\endcode\n    */\n    void SetMaxDecimalPlaces(int maxDecimalPlaces) {\n        maxDecimalPlaces_ = maxDecimalPlaces;\n    }\n\n    /*!@name Implementation of Handler\n        \\see Handler\n    */\n    //@{\n\n    bool Null()                 { Prefix(kNullType);   return EndValue(WriteNull()); }\n    bool Bool(bool b)           { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }\n    bool Int(int i)             { Prefix(kNumberType); return EndValue(WriteInt(i)); }\n    bool Uint(unsigned u)       { Prefix(kNumberType); return EndValue(WriteUint(u)); }\n    bool Int64(int64_t i64)     { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }\n    bool Uint64(uint64_t u64)   { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }\n\n    //! Writes the given \\c double value to the stream\n    /*!\n        \\param d The value to be written.\n        \\return Whether it is succeed.\n    */\n    bool Double(double d)       { Prefix(kNumberType); return EndValue(WriteDouble(d)); }\n\n    bool RawNumber(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        Prefix(kNumberType);\n        return EndValue(WriteString(str, length));\n    }\n\n    bool String(const Ch* str, SizeType length, bool copy = false) {\n        RAPIDJSON_ASSERT(str != 0);\n        (void)copy;\n        Prefix(kStringType);\n        return EndValue(WriteString(str, length));\n    }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool String(const std::basic_string<Ch>& str) {\n        return String(str.data(), SizeType(str.size()));\n    }\n#endif\n\n    bool StartObject() {\n        Prefix(kObjectType);\n        new (level_stack_.template Push<Level>()) Level(false);\n        return WriteStartObject();\n    }\n\n    bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }\n\n#if RAPIDJSON_HAS_STDSTRING\n    bool Key(const std::basic_string<Ch>& str)\n    {\n      return Key(str.data(), SizeType(str.size()));\n    }\n#endif\n\t\n    bool EndObject(SizeType memberCount = 0) {\n        (void)memberCount;\n        RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object\n        RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object\n        RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value\n        level_stack_.template Pop<Level>(1);\n        return EndValue(WriteEndObject());\n    }\n\n    bool StartArray() {\n        Prefix(kArrayType);\n        new (level_stack_.template Push<Level>()) Level(true);\n        return WriteStartArray();\n    }\n\n    bool EndArray(SizeType elementCount = 0) {\n        (void)elementCount;\n        RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));\n        RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);\n        level_stack_.template Pop<Level>(1);\n        return EndValue(WriteEndArray());\n    }\n    //@}\n\n    /*! @name Convenience extensions */\n    //@{\n\n    //! Simpler but slower overload.\n    bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); }\n    bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); }\n    \n    //@}\n\n    //! Write a raw JSON value.\n    /*!\n        For user to write a stringified JSON as a value.\n\n        \\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.\n        \\param length Length of the json.\n        \\param type Type of the root of json.\n    */\n    bool RawValue(const Ch* json, size_t length, Type type) {\n        RAPIDJSON_ASSERT(json != 0);\n        Prefix(type);\n        return EndValue(WriteRawValue(json, length));\n    }\n\n    //! Flush the output stream.\n    /*!\n        Allows the user to flush the output stream immediately.\n     */\n    void Flush() {\n        os_->Flush();\n    }\n\nprotected:\n    //! Information for each nested level\n    struct Level {\n        Level(bool inArray_) : valueCount(0), inArray(inArray_) {}\n        size_t valueCount;  //!< number of values in this level\n        bool inArray;       //!< true if in array, otherwise in object\n    };\n\n    static const size_t kDefaultLevelDepth = 32;\n\n    bool WriteNull()  {\n        PutReserve(*os_, 4);\n        PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;\n    }\n\n    bool WriteBool(bool b)  {\n        if (b) {\n            PutReserve(*os_, 4);\n            PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');\n        }\n        else {\n            PutReserve(*os_, 5);\n            PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');\n        }\n        return true;\n    }\n\n    bool WriteInt(int i) {\n        char buffer[11];\n        const char* end = internal::i32toa(i, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));\n        return true;\n    }\n\n    bool WriteUint(unsigned u) {\n        char buffer[10];\n        const char* end = internal::u32toa(u, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));\n        return true;\n    }\n\n    bool WriteInt64(int64_t i64) {\n        char buffer[21];\n        const char* end = internal::i64toa(i64, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (const char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));\n        return true;\n    }\n\n    bool WriteUint64(uint64_t u64) {\n        char buffer[20];\n        char* end = internal::u64toa(u64, buffer);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));\n        return true;\n    }\n\n    bool WriteDouble(double d) {\n        if (internal::Double(d).IsNanOrInf()) {\n            if (!(writeFlags & kWriteNanAndInfFlag))\n                return false;\n            if (internal::Double(d).IsNan()) {\n                PutReserve(*os_, 3);\n                PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');\n                return true;\n            }\n            if (internal::Double(d).Sign()) {\n                PutReserve(*os_, 9);\n                PutUnsafe(*os_, '-');\n            }\n            else\n                PutReserve(*os_, 8);\n            PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');\n            PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');\n            return true;\n        }\n\n        char buffer[25];\n        char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);\n        PutReserve(*os_, static_cast<size_t>(end - buffer));\n        for (char* p = buffer; p != end; ++p)\n            PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));\n        return true;\n    }\n\n    bool WriteString(const Ch* str, SizeType length)  {\n        static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };\n        static const char escape[256] = {\n#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n            //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F\n            'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00\n            'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10\n              0,   0, '\"',   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 20\n            Z16, Z16,                                                                       // 30~4F\n              0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,'\\\\',   0,   0,   0, // 50\n            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16                                // 60~FF\n#undef Z16\n        };\n\n        if (TargetEncoding::supportUnicode)\n            PutReserve(*os_, 2 + length * 6); // \"\\uxxxx...\"\n        else\n            PutReserve(*os_, 2 + length * 12);  // \"\\uxxxx\\uyyyy...\"\n\n        PutUnsafe(*os_, '\\\"');\n        GenericStringStream<SourceEncoding> is(str);\n        while (ScanWriteUnescapedString(is, length)) {\n            const Ch c = is.Peek();\n            if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {\n                // Unicode escaping\n                unsigned codepoint;\n                if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))\n                    return false;\n                PutUnsafe(*os_, '\\\\');\n                PutUnsafe(*os_, 'u');\n                if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {\n                    PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(codepoint      ) & 15]);\n                }\n                else {\n                    RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);\n                    // Surrogate pair\n                    unsigned s = codepoint - 0x010000;\n                    unsigned lead = (s >> 10) + 0xD800;\n                    unsigned trail = (s & 0x3FF) + 0xDC00;\n                    PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(lead      ) & 15]);\n                    PutUnsafe(*os_, '\\\\');\n                    PutUnsafe(*os_, 'u');\n                    PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail >>  8) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail >>  4) & 15]);\n                    PutUnsafe(*os_, hexDigits[(trail      ) & 15]);                    \n                }\n            }\n            else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)]))  {\n                is.Take();\n                PutUnsafe(*os_, '\\\\');\n                PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(escape[static_cast<unsigned char>(c)]));\n                if (escape[static_cast<unsigned char>(c)] == 'u') {\n                    PutUnsafe(*os_, '0');\n                    PutUnsafe(*os_, '0');\n                    PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);\n                    PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);\n                }\n            }\n            else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? \n                Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :\n                Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))\n                return false;\n        }\n        PutUnsafe(*os_, '\\\"');\n        return true;\n    }\n\n    bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {\n        return RAPIDJSON_LIKELY(is.Tell() < length);\n    }\n\n    bool WriteStartObject() { os_->Put('{'); return true; }\n    bool WriteEndObject()   { os_->Put('}'); return true; }\n    bool WriteStartArray()  { os_->Put('['); return true; }\n    bool WriteEndArray()    { os_->Put(']'); return true; }\n\n    bool WriteRawValue(const Ch* json, size_t length) {\n        PutReserve(*os_, length);\n        for (size_t i = 0; i < length; i++) {\n            RAPIDJSON_ASSERT(json[i] != '\\0');\n            PutUnsafe(*os_, json[i]);\n        }\n        return true;\n    }\n\n    void Prefix(Type type) {\n        (void)type;\n        if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root\n            Level* level = level_stack_.template Top<Level>();\n            if (level->valueCount > 0) {\n                if (level->inArray) \n                    os_->Put(','); // add comma if it is not the first element in array\n                else  // in object\n                    os_->Put((level->valueCount % 2 == 0) ? ',' : ':');\n            }\n            if (!level->inArray && level->valueCount % 2 == 0)\n                RAPIDJSON_ASSERT(type == kStringType);  // if it's in object, then even number should be a name\n            level->valueCount++;\n        }\n        else {\n            RAPIDJSON_ASSERT(!hasRoot_);    // Should only has one and only one root.\n            hasRoot_ = true;\n        }\n    }\n\n    // Flush the value if it is the top level one.\n    bool EndValue(bool ret) {\n        if (RAPIDJSON_UNLIKELY(level_stack_.Empty()))   // end of json text\n            Flush();\n        return ret;\n    }\n\n    OutputStream* os_;\n    internal::Stack<StackAllocator> level_stack_;\n    int maxDecimalPlaces_;\n    bool hasRoot_;\n\nprivate:\n    // Prohibit copy constructor & assignment operator.\n    Writer(const Writer&);\n    Writer& operator=(const Writer&);\n};\n\n// Full specialization for StringStream to prevent memory copying\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteInt(int i) {\n    char *buffer = os_->Push(11);\n    const char* end = internal::i32toa(i, buffer);\n    os_->Pop(static_cast<size_t>(11 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteUint(unsigned u) {\n    char *buffer = os_->Push(10);\n    const char* end = internal::u32toa(u, buffer);\n    os_->Pop(static_cast<size_t>(10 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {\n    char *buffer = os_->Push(21);\n    const char* end = internal::i64toa(i64, buffer);\n    os_->Pop(static_cast<size_t>(21 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {\n    char *buffer = os_->Push(20);\n    const char* end = internal::u64toa(u, buffer);\n    os_->Pop(static_cast<size_t>(20 - (end - buffer)));\n    return true;\n}\n\ntemplate<>\ninline bool Writer<StringBuffer>::WriteDouble(double d) {\n    if (internal::Double(d).IsNanOrInf()) {\n        // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).\n        if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))\n            return false;\n        if (internal::Double(d).IsNan()) {\n            PutReserve(*os_, 3);\n            PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');\n            return true;\n        }\n        if (internal::Double(d).Sign()) {\n            PutReserve(*os_, 9);\n            PutUnsafe(*os_, '-');\n        }\n        else\n            PutReserve(*os_, 8);\n        PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');\n        PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');\n        return true;\n    }\n    \n    char *buffer = os_->Push(25);\n    char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);\n    os_->Pop(static_cast<size_t>(25 - (end - buffer)));\n    return true;\n}\n\n#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)\ntemplate<>\ninline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {\n    if (length < 16)\n        return RAPIDJSON_LIKELY(is.Tell() < length);\n\n    if (!RAPIDJSON_LIKELY(is.Tell() < length))\n        return false;\n\n    const char* p = is.src_;\n    const char* end = is.head_ + length;\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));\n    if (nextAligned > end)\n        return true;\n\n    while (p != nextAligned)\n        if (*p < 0x20 || *p == '\\\"' || *p == '\\\\') {\n            is.src_ = p;\n            return RAPIDJSON_LIKELY(is.Tell() < length);\n        }\n        else\n            os_->PutUnsafe(*p++);\n\n    // The rest of string using SIMD\n    static const char dquote[16] = { '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"', '\\\"' };\n    static const char bslash[16] = { '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\', '\\\\' };\n    static const char space[16]  = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };\n    const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));\n    const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));\n    const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));\n\n    for (; p != endAligned; p += 16) {\n        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));\n        const __m128i t1 = _mm_cmpeq_epi8(s, dq);\n        const __m128i t2 = _mm_cmpeq_epi8(s, bs);\n        const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F\n        const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);\n        unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));\n        if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped\n            SizeType len;\n#ifdef _MSC_VER         // Find the index of first escaped\n            unsigned long offset;\n            _BitScanForward(&offset, r);\n            len = offset;\n#else\n            len = static_cast<SizeType>(__builtin_ffs(r) - 1);\n#endif\n            char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));\n            for (size_t i = 0; i < len; i++)\n                q[i] = p[i];\n\n            p += len;\n            break;\n        }\n        _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);\n    }\n\n    is.src_ = p;\n    return RAPIDJSON_LIKELY(is.Tell() < length);\n}\n#elif defined(RAPIDJSON_NEON)\ntemplate<>\ninline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {\n    if (length < 16)\n        return RAPIDJSON_LIKELY(is.Tell() < length);\n\n    if (!RAPIDJSON_LIKELY(is.Tell() < length))\n        return false;\n\n    const char* p = is.src_;\n    const char* end = is.head_ + length;\n    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));\n    const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));\n    if (nextAligned > end)\n        return true;\n\n    while (p != nextAligned)\n        if (*p < 0x20 || *p == '\\\"' || *p == '\\\\') {\n            is.src_ = p;\n            return RAPIDJSON_LIKELY(is.Tell() < length);\n        }\n        else\n            os_->PutUnsafe(*p++);\n\n    // The rest of string using SIMD\n    const uint8x16_t s0 = vmovq_n_u8('\"');\n    const uint8x16_t s1 = vmovq_n_u8('\\\\');\n    const uint8x16_t s2 = vmovq_n_u8('\\b');\n    const uint8x16_t s3 = vmovq_n_u8(32);\n\n    for (; p != endAligned; p += 16) {\n        const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));\n        uint8x16_t x = vceqq_u8(s, s0);\n        x = vorrq_u8(x, vceqq_u8(s, s1));\n        x = vorrq_u8(x, vceqq_u8(s, s2));\n        x = vorrq_u8(x, vcltq_u8(s, s3));\n\n        x = vrev64q_u8(x);                     // Rev in 64\n        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract\n        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract\n\n        SizeType len = 0;\n        bool escaped = false;\n        if (low == 0) {\n            if (high != 0) {\n                unsigned lz = (unsigned)__builtin_clzll(high);\n                len = 8 + (lz >> 3);\n                escaped = true;\n            }\n        } else {\n            unsigned lz = (unsigned)__builtin_clzll(low);\n            len = lz >> 3;\n            escaped = true;\n        }\n        if (RAPIDJSON_UNLIKELY(escaped)) {   // some of characters is escaped\n            char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));\n            for (size_t i = 0; i < len; i++)\n                q[i] = p[i];\n\n            p += len;\n            break;\n        }\n        vst1q_u8(reinterpret_cast<uint8_t *>(os_->PushUnsafe(16)), s);\n    }\n\n    is.src_ = p;\n    return RAPIDJSON_LIKELY(is.Tell() < length);\n}\n#endif // RAPIDJSON_NEON\n\nRAPIDJSON_NAMESPACE_END\n\n#ifdef _MSC_VER\nRAPIDJSON_DIAG_POP\n#endif\n\n#ifdef __clang__\nRAPIDJSON_DIAG_POP\n#endif\n\n#endif // RAPIDJSON_RAPIDJSON_H_\n"
  },
  {
    "path": "unittest/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2 FATAL_ERROR)\n\nproject(\"napa-unittest\")\n\nset(NAPA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..)\n\n# Require Cxx14 features\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Test Files\nfile(GLOB_RECURSE TEST_FILES\n    main.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/module/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/platform/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/settings/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/utils/*.cpp\n    ${CMAKE_CURRENT_SOURCE_DIR}/zone/*.cpp)\n\n# Source files under test\nfile(GLOB_RECURSE SOURCE_FILES\n    ${NAPA_ROOT}/src/module/core-modules/node/file-system-helpers.cpp\n    ${NAPA_ROOT}/src/module/loader/module-resolver-cache.cpp\n    ${NAPA_ROOT}/src/module/loader/module-resolver.cpp\n    ${NAPA_ROOT}/src/platform/filesystem.cpp\n    ${NAPA_ROOT}/src/platform/os.cpp\n    ${NAPA_ROOT}/src/platform/process.cpp\n    ${NAPA_ROOT}/src/settings/settings-parser.cpp\n    ${NAPA_ROOT}/src/zone/simple-thread-pool.cpp\n    ${NAPA_ROOT}/src/zone/timer.cpp)\n\n# The target name\nset(TARGET_NAME ${PROJECT_NAME})\n\n# The generated test executable\nadd_executable(${TARGET_NAME} ${TEST_FILES} ${SOURCE_FILES} ${PLATFORM_SOURCE_FILES})\n\n# Compiler definitions\ntarget_compile_definitions(${TARGET_NAME} PRIVATE NAPA_LOG_DISABLED)\n\n# Include directories\ntarget_include_directories(${TARGET_NAME}\n    PRIVATE\n    ${NAPA_ROOT}/inc\n    ${NAPA_ROOT}/src\n    ${NAPA_ROOT}/third-party)\n\n# Set output directory for dll/libs\nset_target_properties(${TARGET_NAME} PROPERTIES\n    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/build/test\n    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/build/test\n)\n\n# GCC/Clang: enable std::thread via -pthread option.\nif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Clang\" OR\n    \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\")\n    set(THREADS_PREFER_PTHREAD_FLAG ON)\n    find_package(Threads REQUIRED)\n    target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)\nendif()\n\n# Copy module tests artifacts\nadd_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND\n    ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/module/test-files ${CMAKE_CURRENT_SOURCE_DIR}/build/test)\n"
  },
  {
    "path": "unittest/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#define CATCH_CONFIG_MAIN\n#include <catch/catch.hpp>\n"
  },
  {
    "path": "unittest/module/file-system-helpers-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n\n#include <platform/os.h>\n#include <module/core-modules/node/file-system-helpers.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nTEST_CASE(\"File system helpers reads/writes a file correctly.\", \"[file-system-helpers]\") {\n    const std::string dirname(\"file-system-helpers-test\");\n    const std::string filename(dirname + platform::DIR_SEPARATOR + \"file-system-helpers-test.dat\");\n\n    file_system_helpers::MkdirSync(dirname);\n    file_system_helpers::WriteFileSync(filename, dirname.data(), dirname.length());\n\n    REQUIRE(file_system_helpers::ExistsSync(filename));\n\n    auto content = file_system_helpers::ReadFileSync(filename);\n    REQUIRE(content.compare(dirname) == 0);\n\n    file_system_helpers::MkdirSync(dirname + platform::DIR_SEPARATOR + \"1\");\n    file_system_helpers::MkdirSync(dirname + platform::DIR_SEPARATOR + \"2\");\n\n    auto names = file_system_helpers::ReadDirectorySync(dirname);\n    REQUIRE(names.size() == 3);\n}"
  },
  {
    "path": "unittest/module/module-resolver-cache-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n\n#include <module/loader/module-resolver-cache.h>\n\nusing namespace napa;\nusing namespace napa::module;\n\nnamespace {\n    ModuleResolverCache& GetModuleResolverCache() {\n        static ModuleResolverCache cache;\n        return cache;\n    }\n}\n\nTEST_CASE(\"module resolver cache works correctly.\", \"[module-resolver-cache]\") {\n\n    SECTION(\"cache not hit\") {\n        ModuleResolverCache cache;\n        auto result = cache.Lookup(\"a\", \"/home/napajs/test/\");\n        REQUIRE(result.type == ModuleType::NONE);\n    }\n\n    SECTION(\"cache hit\") {\n        ModuleResolverCache cache;\n        cache.Insert(\"a\", \"/home/napajs/test/\", ModuleInfo{ModuleType::JAVASCRIPT, \"/home/napajs/test/a.js\", std::string()});\n        \n        auto result = cache.Lookup(\"a\", \"/home/napajs/test/\");\n        REQUIRE(result.type == ModuleType::JAVASCRIPT);\n        REQUIRE(result.fullPath == \"/home/napajs/test/a.js\");\n    }\n}\n"
  },
  {
    "path": "unittest/module/module-resolver-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n\n#include <module/loader/module-resolver.h>\n#include <platform/filesystem.h>\n#include <platform/os.h>\n#include <platform/process.h>\n\n#include <sstream>\n\nusing namespace napa;\nusing namespace napa::module;\n\n\nnamespace {\n\n    ModuleResolver& GetModuleResolver() {\n        // Set environment variables before module resolver is initialized.\n        static bool setNodePath = []() {\n            std::ostringstream oss;\n            oss << (filesystem::CurrentDirectory() / \"resolve-env\").String()\n                << platform::ENV_DELIMITER\n                << (filesystem::CurrentDirectory() / \"child\" / \"node_modules\" / \"child\").String();\n            return platform::SetEnv(\"NODE_PATH\", oss.str().c_str());\n        }();\n        REQUIRE(setNodePath);\n\n        static ModuleResolver resolver;\n        return resolver;\n    }\n\n    void ResolveIt(const char* module,\n                   const char* expected,\n                   ModuleType type) {\n        auto detail = GetModuleResolver().Resolve(module);\n\n        REQUIRE(detail.fullPath == expected);\n        REQUIRE(detail.type == type);\n    }\n\n    void ResolveIt(const char* module,\n                   const filesystem::Path& expected,\n                   ModuleType type) {\n        auto detail = GetModuleResolver().Resolve(module);\n\n        REQUIRE(detail.fullPath == expected);\n        REQUIRE(detail.type == type);\n    }\n\n    void ResolveIt(const char* module,\n                   const filesystem::Path& expected,\n                   ModuleType type,\n                   const filesystem::Path& package) {\n        auto detail = GetModuleResolver().Resolve(module);\n\n        REQUIRE(detail.fullPath == expected);\n        REQUIRE(detail.type == type);\n        REQUIRE(detail.packageJsonPath == package.String());\n    }\n\n}   // Namespace of anonymous namespace.\n\nTEST_CASE(\"resolve node modules correctly.\", \"[module-resolver]\") {\n    auto currentPath = filesystem::CurrentDirectory();\n\n    SECTION(\"resolve built-in or core modules\") {\n        // Set build-in and core modules.\n        GetModuleResolver().SetAsCoreModule(\"console\");\n        GetModuleResolver().SetAsCoreModule(\"fs\");\n\n        // 'console' built-in module.\n        ResolveIt(\"console\", \"console\", ModuleType::CORE);\n\n        // 'fs' core module.\n        ResolveIt(\"fs\", \"fs\", ModuleType::CORE);\n\n        // No 'built-in' module.\n        ResolveIt(\"built-in\", \"\", ModuleType::NONE);\n    }\n\n    SECTION(\"resolve as a file\") {\n        // Starts with \"./\" and a file exists.\n        ResolveIt(\"./resolve-file\", currentPath / \"resolve-file\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a javascript file exists.\n        ResolveIt(\"./resolve-file-js\", currentPath / \"resolve-file-js.js\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a json file exists.\n        ResolveIt(\"./resolve-file-json\", currentPath / \"resolve-file-json.json\", ModuleType::JSON);\n\n        // Starts with \"./\" and a binary file exists.\n        ResolveIt(\"./resolve-file-napa\", currentPath / \"resolve-file-napa.napa\", ModuleType::NAPA);\n\n        // Starts with \"./\" and a javascript file exists.\n        ResolveIt(\"./resolve-file-js.js\", currentPath / \"resolve-file-js.js\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a json file exists.\n        ResolveIt(\"./resolve-file-js.json\", currentPath / \"resolve-file-js.json\", ModuleType::JSON);\n\n        // Starts with \"./\" and a binary file exists.\n        ResolveIt(\"./resolve-file-js.napa\", currentPath / \"resolve-file-js.napa\", ModuleType::NAPA);\n\n        // Starts with \"./\", but a file doesn't exist.\n        ResolveIt(\"./resolve-file-non-existent\", \"\", ModuleType::NONE);\n\n        // Start with \"./\", but a file doesn't exist and it doesn't resolve to \".js\" file.\n        ResolveIt(\"./resolve-file-no.json\", \"\", ModuleType::NONE);\n\n        // Start with \"./\", but a file doesn't exist and it doesn't resolve to \".js\" file.\n        ResolveIt(\"./resolve-file-no.napa\", \"\", ModuleType::NONE);\n\n        // Starts with \"../\" and a file exists.\n        std::ostringstream oss;\n        oss << \"../\" << currentPath.Filename().String() << \"/resolve-file\";\n        ResolveIt(oss.str().c_str(), currentPath / \"resolve-file\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"/\", but a file doesn't exist.\n        ResolveIt(\"/resolve-file\", \"\", ModuleType::NONE);\n\n        // Use absolute path and a file exists.\n        ResolveIt((currentPath / \"resolve-file\").c_str(),\n                  currentPath / \"resolve-file\",\n                  ModuleType::JAVASCRIPT);\n    }\n\n    SECTION(\"resolve as a directory\") {\n        // Starts with \"./\" and a directory with package.json exists.\n        ResolveIt(\"./resolve-directory/resolver\",\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"package.json\");\n\n        // Starts with \"./\" and a directory with index.js exists.\n        ResolveIt(\"./resolve-directory/resolver-js\",\n                  currentPath / \"resolve-directory\" / \"resolver-js\" / \"index.js\",\n                  ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a directory with index.json exists.\n        ResolveIt(\"./resolve-directory/resolver-json\",\n                  currentPath / \"resolve-directory\" / \"resolver-json\" / \"index.json\",\n                  ModuleType::JSON);\n\n        // Starts with \"./\" and a directory with index.napa exists.\n        ResolveIt(\"./resolve-directory/resolver-napa\",\n                  currentPath / \"resolve-directory\" / \"resolver-napa\" / \"index.napa\",\n                  ModuleType::NAPA);\n\n        // Non existent directory.\n        ResolveIt(\"./resolve-directory/resolver-non-existent\", \"\", ModuleType::NONE);\n\n        // Starts with \"../\" and a directory exists.\n        std::ostringstream oss;\n        oss << \"../\" << currentPath.Filename().String() << \"/resolve-directory/resolver\";\n        ResolveIt(oss.str().c_str(),\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"package.json\");\n\n        // Starts with \"/\", but a file doesn't exist.\n        ResolveIt(\"/resolve-directory/resolver\", \"\", ModuleType::NONE);\n\n        // Use absolute path and a file exists.\n        ResolveIt((currentPath / \"resolve-directory\" / \"resolver\").c_str(),\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"resolve-directory\" / \"resolver\" / \"package.json\");\n    }\n\n    SECTION(\"resolve from node_modules\") {\n        // A file exists.\n        ResolveIt(\"resolve-nm-file\", currentPath / \"node_modules\" / \"resolve-nm-file\", ModuleType::JAVASCRIPT);\n\n        // A javascript file exists.\n        ResolveIt(\"resolve-nm-file-js\", currentPath / \"node_modules\" / \"resolve-nm-file-js.js\", ModuleType::JAVASCRIPT);\n\n        // A json file exists.\n        ResolveIt(\"resolve-nm-file-json\", currentPath / \"node_modules\" / \"resolve-nm-file-json.json\", ModuleType::JSON);\n\n        // A binary file exists.\n        ResolveIt(\"resolve-nm-file-napa\", currentPath / \"node_modules\" / \"resolve-nm-file-napa.napa\", ModuleType::NAPA);\n\n        // A directory with package.json exists.\n        ResolveIt(\"resolver-nm\",\n                  currentPath / \"node_modules\" / \"resolver-nm\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"node_modules\" / \"resolver-nm\" / \"package.json\");\n\n        // A directory with index.js exists.\n        ResolveIt(\"resolver-nm-js\", currentPath / \"node_modules\" / \"resolver-nm-js\" / \"index.js\", ModuleType::JAVASCRIPT);\n\n        // A directory with index.json exists.\n        ResolveIt(\"resolver-nm-json\", currentPath / \"node_modules\" / \"resolver-nm-json\" / \"index.json\", ModuleType::JSON);\n\n        // A directory with index.napa exists.\n        ResolveIt(\"resolver-nm-napa\", currentPath / \"node_modules\" / \"resolver-nm-napa\" / \"index.napa\", ModuleType::NAPA);\n    }\n\n    SECTION(\"resolve from NODE_PATH\") {\n        // Starts with \"./\" and a file exists.\n        ResolveIt(\"./resolve-env-file\", currentPath / \"resolve-env\" / \"resolve-env-file\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a javascript file exists.\n        ResolveIt(\"./resolve-env-file-js\", currentPath / \"resolve-env\" / \"resolve-env-file-js.js\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a json file exists.\n        ResolveIt(\"./resolve-env-file-json\", currentPath / \"resolve-env\" / \"resolve-env-file-json.json\", ModuleType::JSON);\n\n        // Starts with \"./\" and a binary file exists.\n        ResolveIt(\"./resolve-env-file-napa\", currentPath / \"resolve-env\" / \"resolve-env-file-napa.napa\", ModuleType::NAPA);\n\n        // Starts with \"../\" and a file exists.\n        ResolveIt(\"../resolve-env/resolve-env-file\", currentPath / \"resolve-env\" / \"resolve-env-file\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a directory with package.json exists.\n        ResolveIt(\"./resolver-env\",\n                  currentPath / \"resolve-env\" / \"resolver-env\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"resolve-env\" / \"resolver-env\" / \"package.json\");\n\n        // Starts with \"./\" and a directory with index.js exists.\n        ResolveIt(\"./resolver-env-js\", currentPath /\"resolve-env\" / \"resolver-env-js\" / \"index.js\", ModuleType::JAVASCRIPT);\n\n        // Starts with \"./\" and a directory with index.json exists.\n        ResolveIt(\"./resolver-env-json\", currentPath / \"resolve-env\" / \"resolver-env-json\" / \"index.json\", ModuleType::JSON);\n\n        // Starts with \"./\" and a directory with index.napa exists.\n        ResolveIt(\"./resolver-env-napa\", currentPath / \"resolve-env\" / \"resolver-env-napa\" / \"index.napa\", ModuleType::NAPA);\n\n        // Starts with \"../\" and a directory exists.\n        ResolveIt(\"../resolve-env/resolver-env\",\n                  currentPath / \"resolve-env\" / \"resolver-env\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"resolve-env\" / \"resolver-env\" / \"package.json\");\n    }\n\n    SECTION(\"resolve from parent node_modules\") {\n        // A file exists.\n        ResolveIt(\"resolve-cc-file\", currentPath / \"child\" / \"node_modules\" / \"resolve-cc-file\", ModuleType::JAVASCRIPT);\n\n        // A javascript file exists.\n        ResolveIt(\"resolve-cc-file-js\", currentPath / \"child\" / \"node_modules\" / \"resolve-cc-file-js.js\", ModuleType::JAVASCRIPT);\n\n        // A json file exists.\n        ResolveIt(\"resolve-cc-file-json\", currentPath / \"child\" / \"node_modules\" / \"resolve-cc-file-json.json\", ModuleType::JSON);\n\n        // A binary file exists.\n        ResolveIt(\"resolve-cc-file-napa\", currentPath / \"child\" / \"node_modules\" / \"resolve-cc-file-napa.napa\", ModuleType::NAPA);\n\n        // A directory with package.json exists.\n        ResolveIt(\"resolver-cc\",\n                  currentPath / \"child\" / \"node_modules\" / \"resolver-cc\" / \"resolve-file\",\n                  ModuleType::JAVASCRIPT,\n                  currentPath / \"child\" / \"node_modules\" / \"resolver-cc\" / \"package.json\");\n\n        // A directory with index.js exists.\n        ResolveIt(\"resolver-cc-js\", currentPath / \"child\" / \"node_modules\" / \"resolver-cc-js\" / \"index.js\", ModuleType::JAVASCRIPT);\n\n        // A directory with index.json exists.\n        ResolveIt(\"resolver-cc-json\", currentPath / \"child\" / \"node_modules\" / \"resolver-cc-json\" / \"index.json\", ModuleType::JSON);\n\n        // A directory with index.napa exists.\n        ResolveIt(\"resolver-cc-napa\", currentPath / \"child\" / \"node_modules\" / \"resolver-cc-napa\" / \"index.napa\", ModuleType::NAPA);\n    }\n}\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-js.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-js.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-js.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-json.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-json.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file-napa.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolve-nm-file.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm/package.json",
    "content": "{\n    \"name\": \"@napajs/resolve-directory\",\n    \"version\": \"0.0.1\",\n    \"author\": \"napajs\",\n    \"main\": \"resolve-file\"\n}\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm/resolve-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-js/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-js/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-js/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-json/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-json/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/node_modules/resolver-nm-napa/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver/package.json",
    "content": "{\n    \"name\": \"@napajs/resolve-directory\",\n    \"version\": \"0.0.1\",\n    \"author\": \"napajs\",\n    \"main\": \"resolve-file\"\n}\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver/resolve-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-js/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-js/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-js/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-json/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-json/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-directory/resolver-napa/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-js.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-js.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-js.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-json.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-json.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file-napa.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolve-env-file.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env/package.json",
    "content": "{\n    \"name\": \"@napajs/resolve-directory\",\n    \"version\": \"0.0.1\",\n    \"author\": \"napajs\",\n    \"main\": \"resolve-file\"\n}\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env/resolve-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-js/index.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-js/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-js/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-json/index.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-json/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-env/resolver-env-napa/index.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-js.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-js.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-js.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-json.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-json.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-napa.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file-no.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file.js",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file.json",
    "content": "true\n"
  },
  {
    "path": "unittest/module/test-files/resolve-file.napa",
    "content": "true\n"
  },
  {
    "path": "unittest/platform/filesystem-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n#include <platform/filesystem.h>\n\nusing namespace napa;\n\nTEST_CASE(\"filesystem::Path\", \"[Path]\") {\n\n    SECTION(\"Empty path\") {\n        filesystem::Path path;\n        REQUIRE(path.IsEmpty());\n        REQUIRE(!path.IsAbsolute());\n        REQUIRE(path.IsRelative());\n\n        REQUIRE(!path.IsFilenameDot());\n        REQUIRE(!path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \".\");\n        REQUIRE(!path.HasFilename());\n        REQUIRE(path.Basename().IsEmpty());\n        REQUIRE(!path.HasExtension());\n\n        REQUIRE(path.ReplaceExtension(\".exe\").IsEmpty());\n\n        REQUIRE(path.Normalize().IsEmpty());\n        REQUIRE(path.Absolute().IsEmpty());\n        REQUIRE(path.Relative(\"a/b\").IsEmpty());\n        REQUIRE(path.Parent().IsEmpty());\n        REQUIRE(path.String() == \"\");\n        REQUIRE(path.DriveSpec().IsEmpty());\n        REQUIRE(!path.HasUncPrefix());\n    }\n\n    SECTION(\"Explicit relative path\") {\n        // ../a/c\n        filesystem::Path path(\"../a\\\\b/../c\");\n        REQUIRE(!path.IsEmpty());\n        REQUIRE(!path.IsAbsolute());\n        REQUIRE(path.IsRelative());\n\n        REQUIRE(!path.IsFilenameDot());\n        REQUIRE(!path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \"../a\\\\b/..\");\n        REQUIRE(path.Filename() == \"c\");\n        REQUIRE(path.Basename() == \"c\");\n        REQUIRE(path.Extension().IsEmpty());\n\n        REQUIRE(path.ReplaceExtension(\".exe\").Extension().IsEmpty());\n\n#ifdef _WIN32\n        REQUIRE(path.Normalize() == \"..\\\\a\\\\c\");\n        REQUIRE(path.Parent().Normalize() == \"..\\\\a\");\n        REQUIRE(path.Parent().Parent().Normalize() == \"..\");\n        REQUIRE(path.Parent().Parent().Parent().Normalize() == \"..\\\\..\");\n        REQUIRE(path.String() == \"..\\\\a\\\\c\");\n#else\n        REQUIRE(path.Normalize() == \"../a/c\");\n        REQUIRE(path.Parent().Normalize() == \"../a\");\n        REQUIRE(path.Parent().Parent().Normalize() == \"..\");\n        REQUIRE(path.Parent().Parent().Parent().Normalize() == \"../..\");\n\n        REQUIRE(path.String() == \"../a/c\");\n#endif\n        \n        REQUIRE(path.GenericForm() == \"../a/c\");\n        REQUIRE(path.DriveSpec().IsEmpty());\n        REQUIRE(!path.HasUncPrefix());\n    }\n\n    SECTION(\"Implicit relative path\") {\n        filesystem::Path path(\"a/b\\\\c\\\\../d\\\\.\\\\e.txt\");\n        REQUIRE(!path.IsEmpty());\n        REQUIRE(!path.IsAbsolute());\n        REQUIRE(path.IsRelative());\n\n        REQUIRE(!path.IsFilenameDot());\n        REQUIRE(!path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \"a/b\\\\c\\\\../d\\\\.\");\n        REQUIRE(path.Filename() == \"e.txt\");\n        REQUIRE(path.Basename() == \"e\");\n        REQUIRE(path.Extension() == \".txt\");\n\n        REQUIRE(path.ReplaceExtension(\".exe\").Extension() == \".exe\");\n\n#ifdef _WIN32   \n        REQUIRE(path.Normalize() == \"a\\\\b\\\\d\\\\e.exe\");\n        REQUIRE(path.Parent().Normalize() == \"a\\\\b\\\\d\");\n        \n        REQUIRE(path.Relative(\"a/b/./e\") == \"..\\\\d\\\\e.exe\");\n        REQUIRE(path.Relative(\"b/c/../e\") == \"..\\\\..\\\\a\\\\b\\\\d\\\\e.exe\");\n        REQUIRE(path.Relative(filesystem::CurrentDirectory() / \"e\" / \"f\") == \"..\\\\..\\\\a\\\\b\\\\d\\\\e.exe\");\n        REQUIRE(path.Relative(\"F:\\\\a\\\\b\") == path.Absolute().Normalize());\n        REQUIRE(path.String() == \"a\\\\b\\\\d\\\\e.exe\");\n#else   \n        REQUIRE(path.Normalize() == \"a/b/d/e.exe\");\n        REQUIRE(path.Parent().Normalize() == \"a/b/d\");\n\n        REQUIRE(path.Relative(\"a/b/./e\") == \"../d/e.exe\");\n        REQUIRE(path.Relative(\"b/c/../e\") == \"../../a/b/d/e.exe\");\n        REQUIRE(path.Relative(filesystem::CurrentDirectory() / \"e\" / \"f\") == \"../../a/b/d/e.exe\");\n\n        REQUIRE(path.String() == \"a/b/d/e.exe\");\n#endif\n        \n        REQUIRE(path.Parent().Parent().Parent().Normalize() == \"a\");\n        REQUIRE(path.Parent().Parent().Parent().Parent().Normalize() == \".\");\n        REQUIRE(path.Parent().Parent().Parent().Parent().Parent().Normalize() == \"..\");\n\n        REQUIRE(path.GenericForm() == \"a/b/d/e.exe\");\n        REQUIRE(path.DriveSpec().IsEmpty());\n        REQUIRE(!path.HasUncPrefix());\n    }\n\n\n    SECTION(\"Absolute path (posix)\") {\n        // /a\n        filesystem::Path path(\"/a/./b/../c/..\");\n        REQUIRE(!path.IsEmpty());\n        REQUIRE(path.IsAbsolute());\n        REQUIRE(!path.IsRelative());\n\n        REQUIRE(!path.IsFilenameDot());\n        REQUIRE(path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \"/a/./b/../c\");\n        REQUIRE(path.Filename() == \"..\");\n        REQUIRE(path.Basename() == \"\");\n        REQUIRE(path.Extension() == \"\");\n\n        REQUIRE(path.ReplaceExtension(\".exe\").Extension().IsEmpty());\n\n#ifdef _WIN32   \n        REQUIRE(path.Normalize() == \"\\\\a\");\n        REQUIRE(path.Parent().Normalize().String() == \"\\\\\");\n        REQUIRE(path.String() == \"\\\\a\");\n#else     \n        REQUIRE(path.Normalize() == \"/a\");\n        REQUIRE(path.Parent().Normalize().String() == \"/\");\n        REQUIRE(path.String() == \"/a\");\n#endif\n        \n        REQUIRE(path.Parent().Parent().Normalize().IsEmpty());\n\n        REQUIRE(path.Relative(\"/\") == \"a\");\n        REQUIRE(path.Relative(\"/a/c\") == \"..\");\n        REQUIRE(path.GenericForm() == \"/a\");\n        REQUIRE(path.DriveSpec() == \"\");\n        REQUIRE(!path.HasUncPrefix());\n    }\n\n#ifdef _WIN32\n    SECTION(\"Absolute path (Windows)\") {\n        // C:/a/c/.\n        filesystem::Path path(\"C:\\\\a\\\\./b\\\\..\\\\c/.\");\n        REQUIRE(!path.IsEmpty());\n        REQUIRE(path.IsAbsolute());\n        REQUIRE(!path.IsRelative());\n\n        REQUIRE(path.IsFilenameDot());\n        REQUIRE(!path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \"C:\\\\a\\\\./b\\\\..\\\\c\");\n        REQUIRE(path.Filename() == \".\");\n        REQUIRE(path.Basename() == \"\");\n        REQUIRE(path.Extension() == \"\");\n\n        REQUIRE(path.ReplaceExtension(\".exe\").Extension().IsEmpty());\n        REQUIRE(path.Normalize() == \"C:\\\\a\\\\c\");\n\n        REQUIRE(path.Parent().Normalize() == \"C:\\\\a\");\n        REQUIRE(path.Parent().Parent().Normalize() == \"C:\\\\\");\n        REQUIRE(path.Parent().Parent().Parent().Normalize().IsEmpty());\n\n        REQUIRE(path.Relative(\"C:/\") == \"a\\\\c\");\n        REQUIRE(path.Relative(\"C:/a/c\") == \"\");\n        REQUIRE(path.Relative(\"C:/b/c\") == \"..\\\\..\\\\a\\\\c\");\n        REQUIRE(path.Relative(\"F:\\\\a\\\\b\") == path.Absolute().Normalize());\n        REQUIRE(path.String() == \"C:\\\\a\\\\c\");\n        REQUIRE(path.GenericForm() == \"C:/a/c\");\n        REQUIRE(path.DriveSpec() == \"C:\");\n        REQUIRE(!path.HasUncPrefix());\n    }\n\n    SECTION(\"UNC path (windows)\") {\n        filesystem::Path path(\"\\\\\\\\?\\\\c:\\\\a\\\\b\\\\..\\\\c\");\n        REQUIRE(!path.IsEmpty());\n        REQUIRE(path.IsAbsolute());\n        REQUIRE(!path.IsRelative());\n\n        REQUIRE(!path.IsFilenameDot());\n        REQUIRE(!path.IsFilenameDotDot());\n\n        REQUIRE(path.Dirname() == \"\\\\\\\\?\\\\c:\\\\a\\\\b\\\\..\");\n        REQUIRE(path.Filename() == \"c\");\n        REQUIRE(path.Basename() == \"c\");\n        REQUIRE(path.Extension() == \"\");\n\n        REQUIRE(path.ReplaceExtension(\".exe\").Extension().IsEmpty());\n        REQUIRE(path.Normalize() == \"\\\\\\\\?\\\\c:\\\\a\\\\c\");\n\n        REQUIRE(path.Parent().Normalize() == \"\\\\\\\\?\\\\c:\\\\a\");\n        REQUIRE(path.Parent().Parent().Normalize() == \"\\\\\\\\?\\\\c:\\\\\");\n        REQUIRE(path.Parent().Parent().Parent().Normalize().IsEmpty());\n\n        REQUIRE(path.Relative(\"C:/\") == \"a\\\\c\");\n        REQUIRE(path.Relative(\"C:/a/c\") == \"\");\n        REQUIRE(path.Relative(\"C:/b/c\") == \"..\\\\..\\\\a\\\\c\");\n        REQUIRE(path.Relative(\"F:\\\\a\\\\b\") == path.Absolute().Normalize());\n        REQUIRE(path.String() == \"\\\\\\\\?\\\\c:\\\\a\\\\c\");\n        REQUIRE(path.GenericForm() == \"\\\\\\\\?\\\\c:\\\\a\\\\c\");\n        REQUIRE(path.DriveSpec() == \"c:\");\n        REQUIRE(path.HasUncPrefix());\n    }\n#endif    \n}\n\nTEST_CASE(\"filesystem::PathIterator\", \"[PathIterator]\") {\n\n    SECTION(\"Path not exist\") {\n        filesystem::PathIterator it(\"/a/b/c\");\n        REQUIRE(!it.Next());\n        REQUIRE(*it == \"\");\n        REQUIRE(it->IsEmpty());\n    }\n\n    SECTION(\"Path exists\") {\n        auto exePath = filesystem::ProgramPath();\n        auto exeDir = exePath.Parent().Normalize();\n        filesystem::PathIterator it(exeDir);\n        REQUIRE(it.Next());\n\n        bool hasDot = false;\n        bool hasDotDot = false;\n        bool hasExe = false;\n\n        do {\n            REQUIRE(!it->IsEmpty());\n            REQUIRE(it->Dirname().Absolute().Normalize() == exeDir);\n             \n            if (it->IsFilenameDot()) {\n                hasDot = true;\n            }\n            if (it->IsFilenameDotDot()) {\n                hasDotDot = true;\n            }\n            if (*it == exePath) {\n                hasExe = true;\n            }\n        } while (it.Next());\n\n        REQUIRE(!hasDot);\n        REQUIRE(!hasDotDot);\n        REQUIRE(hasExe);\n    }\n}\n\nTEST_CASE(\"filesystem\", \"[Operations]\") {\n\n    SECTION(\"Exists\") {\n        REQUIRE(filesystem::Exists(\".\"));\n        REQUIRE(filesystem::Exists(filesystem::ProgramPath()));\n    }\n\n    SECTION(\"IsDirectory\") {\n        REQUIRE(filesystem::IsDirectory(\".\"));\n    }\n\n    SECTION(\"IsRegularFile\") {\n        REQUIRE(filesystem::IsRegularFile(filesystem::ProgramPath()));\n    }\n\n    SECTION(\"MakeDirectory\") {\n        REQUIRE(filesystem::MakeDirectory(\"./abc\"));\n        REQUIRE(filesystem::IsDirectory(\"./abc\"));\n    }\n\n    SECTION(\"MakeDirectories\") {\n        REQUIRE(filesystem::MakeDirectories(\"./a/b/c\"));\n        REQUIRE(filesystem::IsDirectory(\"./a/b/c\"));\n    }\n}"
  },
  {
    "path": "unittest/run.js",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\nvar path = require('path');\nvar childProcess = require('child_process');\n\ntry {\n    childProcess.execFileSync(\n        path.join(__dirname, 'build/test/', process.platform === 'win32'? 'napa-unittest.exe': 'napa-unittest'),\n        [],\n        {\n            cwd: path.join(__dirname, 'build/test'),\n            stdio: 'inherit'\n        }\n    );\n}\ncatch(err) {\n    process.exit(1); // Error\n}\n"
  },
  {
    "path": "unittest/settings/parser-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n\n#include <settings/settings-parser.h>\n\n#include <string>\n\nusing namespace napa;\n\nTEST_CASE(\"Parsing nothing doesn't fail\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n\n    REQUIRE(settings::ParseFromString(\"\", settings));\n\n    std::vector<const char*> args = { \"dummy.exe\" };\n    REQUIRE(settings::ParseFromConsole(static_cast<int>(args.size()), args.data(), settings));\n}\n\nTEST_CASE(\"Parsing from string\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n    settings.loggingProvider = \"\";\n\n    REQUIRE(settings::ParseFromString(\"--loggingProvider myProvider\", settings));\n    REQUIRE(settings.loggingProvider == \"myProvider\");\n}\n\nTEST_CASE(\"Parsing from console\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n    settings.loggingProvider = \"\";\n\n    std::vector<const char*> args = { \"dummy.exe\", \"--loggingProvider\", \"myProvider\" };\n\n    REQUIRE(settings::ParseFromConsole(static_cast<int>(args.size()), args.data(), settings));\n    REQUIRE(settings.loggingProvider == \"myProvider\");\n}\n\nTEST_CASE(\"Parsing non existing setting fails\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n\n    REQUIRE(settings::ParseFromString(\"--thisSettingDoesNotExist noValue\", settings) == false);\n}\n\nTEST_CASE(\"Parsing does not change defaults if setting is not provided\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n    settings.metricProvider = \"myMetricProvider\";\n\n    REQUIRE(settings::ParseFromString(\"--loggingProvider myProvider\", settings));\n    REQUIRE(settings.metricProvider == \"myMetricProvider\");\n}\n\nTEST_CASE(\"Parsing with extra white spaces succeeds\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n    settings.loggingProvider = \"\";\n\n    REQUIRE(settings::ParseFromString(\"  --loggingProvider \\t   myProvider \\t\\t \", settings));\n    REQUIRE(settings.loggingProvider == \"myProvider\");\n}\n\nTEST_CASE(\"Parsing with empty string succeeds\", \"[settings-parser]\") {\n    settings::PlatformSettings settings;\n\n    REQUIRE(settings::ParseFromString(\"\", settings) == true);\n}\n\nTEST_CASE(\"Parsing with different value type fails\", \"[settings-parser]\") {\n    settings::ZoneSettings settings;\n\n    REQUIRE(settings::ParseFromString(\"--workers five\", settings) == false);\n}\n"
  },
  {
    "path": "unittest/utils/string-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n#include <utils/string.h>\n\nusing namespace napa;\n\nTEST_CASE(\"utils\", \"[string]\") {\n\n    SECTION(\"ReplaceAll - No match\") {\n        std::string str = \"no match at all\";\n        utils::string::ReplaceAll(str, \"some\", \"other\");\n        REQUIRE(str == \"no match at all\");\n    }\n\n    SECTION(\"ReplaceAll - Matched\") {\n        std::string str = \"this is a test\";\n        utils::string::ReplaceAll(str, \"is\", \"at\");\n        REQUIRE(str == \"that at a test\");\n    }\n\n    SECTION(\"ReplaceAllCopy\") {\n        auto str = utils::string::ReplaceAllCopy(\"this is a test\", \"is\", \"at\");\n        REQUIRE(str == \"that at a test\");\n    }\n\n    SECTION(\"Split: no compress\") {\n        std::vector<std::string> items;\n        utils::string::Split(\" this is a  \\ttest \", items, \" \\t\", false);\n\n        std::vector<std::string> expected = { \"\", \"this\", \"is\", \"a\", \"\", \"\", \"test\", \"\" };\n        REQUIRE(items == expected);\n    }\n\n    SECTION(\"Split: compress\") {\n        std::vector<std::string> items;\n        utils::string::Split(\" this is a  \\ttest \", items, \" \\t\", true);\n\n        std::vector<std::string> expected = { \"this\", \"is\", \"a\", \"test\" };\n        REQUIRE(items == expected);\n    }\n\n    SECTION(\"Split: iterator with compress\") {\n        std::string str = \" this is a  \\ttest \";\n        std::vector<std::string> items;\n        utils::string::Split(str.begin() + 5, str.end(), items, \" \\t\", true);\n\n        std::vector<std::string> expected = { \"is\", \"a\", \"test\" };\n        REQUIRE(items == expected);\n    }\n\n    SECTION(\"ToLower\") {\n        std::string str = \"This Is A Test\";\n        utils::string::ToLower(str);\n        REQUIRE(str == \"this is a test\");\n    }\n\n    SECTION(\"ToLowerCopy\") {\n        REQUIRE(utils::string::ToLowerCopy(\"THIs Is A TesT\") == \"this is a test\");\n    }\n\n    SECTION(\"ToUpper\") {\n        std::string str = \"This Is A Test\";\n        utils::string::ToUpper(str);\n        REQUIRE(str == \"THIS IS A TEST\");\n    }\n\n    SECTION(\"ToUpperCopy\") {\n        REQUIRE(utils::string::ToUpperCopy(\"THIs Is A TesT\") == \"THIS IS A TEST\");\n    }\n\n    SECTION(\"CaseInsensitiveCompare\") {\n        REQUIRE(utils::string::CaseInsensitiveCompare(\"abc\", \"abd\") < 0);\n        REQUIRE(utils::string::CaseInsensitiveCompare(\"abc\", \"ABc\") == 0);\n        REQUIRE(utils::string::CaseInsensitiveCompare(\"abc\", \"AB\") > 0);\n    }\n\n    SECTION(\"CaseInsensitiveEquals\") {\n        REQUIRE(!utils::string::CaseInsensitiveEquals(\"abc\", \"abd\"));\n        REQUIRE(utils::string::CaseInsensitiveEquals(\"abc\", \"ABc\"));\n        REQUIRE(!utils::string::CaseInsensitiveEquals(\"abc\", \"AB\"));\n    }\n}"
  },
  {
    "path": "unittest/zone/scheduler-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n#include <zone/scheduler.h>\n\n#include <cstddef>\n#include <atomic>\n#include <future>\n\nusing namespace napa;\nusing namespace napa::zone;\nusing namespace napa::settings;\n\nclass TestTask : public Task {\npublic:\n    TestTask(std::function<void()> callback = []() {}) : \n        numberOfExecutions(0),\n        lastExecutedWorkerId(99),\n        _callback(std::move(callback)) {}\n\n    void SetCurrentWorkerId(WorkerId id) {\n        lastExecutedWorkerId = id;\n    }\n\n    virtual void Execute() override\n    {\n        numberOfExecutions++;\n        _callback();\n    }\n\n    std::atomic<uint32_t> numberOfExecutions;\n    std::atomic<WorkerId> lastExecutedWorkerId;\n\nprivate:\n    std::function<void()> _callback;\n};\n\n\ntemplate <uint32_t I>\nclass TestWorker {\npublic:\n\n    TestWorker(WorkerId id,\n               const ZoneSettings &settings,\n               std::function<void(WorkerId)> setupCompleteCallback,\n               std::function<void(WorkerId)> idleCallback) : _id(id) {\n        \n        numberOfWorkers++;\n        _idleNotificationCallback = idleCallback;\n        setupCompleteCallback(id);\n    }\n\n    ~TestWorker() {\n        for (auto& fut : _futures) {\n            fut.get();\n        }\n    }\n\n    void Start() {\n        _idleNotificationCallback(_id);\n    }\n\n    void Schedule(std::shared_ptr<Task> task, SchedulePhase phase=SchedulePhase::DefaultPhase) {\n        auto testTask = std::dynamic_pointer_cast<TestTask>(task);\n        testTask->SetCurrentWorkerId(_id);\n\n        _futures.emplace_back(std::async(std::launch::async, [this, task]() {\n            task->Execute();\n            _idleNotificationCallback(_id);\n        }));\n    }\n\n    static uint32_t numberOfWorkers;\n\nprivate:\n    WorkerId _id;\n    std::vector<std::shared_future<void>> _futures;\n    std::function<void(WorkerId)> _idleNotificationCallback;\n};\n\ntemplate <uint32_t I>\nuint32_t TestWorker<I>::numberOfWorkers = 0;\n\n\nTEST_CASE(\"scheduler creates correct number of worker\", \"[scheduler]\") {\n    ZoneSettings settings;\n    settings.workers = 3;\n\n    auto scheduler = std::make_unique<SchedulerImpl<TestWorker<1>>>(settings, [](WorkerId) {});\n\n    REQUIRE(TestWorker<1>::numberOfWorkers == settings.workers);\n}\n\nTEST_CASE(\"scheduler dispatches worker setup complete callback correctly\", \"[scheduler]\") {\n    ZoneSettings settings;\n    settings.workers = 3;\n    WorkerId idSum = 0;\n    auto scheduler = std::make_unique<SchedulerImpl<TestWorker<1>>>(settings, [&idSum](WorkerId id) {\n        idSum += id;\n    });\n\n    REQUIRE(idSum == settings.workers * (settings.workers - 1) / 2);\n}\n\nTEST_CASE(\"scheduler assigns tasks correctly\", \"[scheduler]\") {\n    ZoneSettings settings;\n    settings.workers = 3;\n\n    auto scheduler = std::make_unique<SchedulerImpl<TestWorker<2>>>(settings, [](WorkerId) {});\n    auto task = std::make_shared<TestTask>();\n\n    SECTION(\"schedules on exactly one worker\") {\n        scheduler->Schedule(task);\n        scheduler = nullptr; // force draining all scheduled tasks\n\n        REQUIRE(task->numberOfExecutions == 1);\n    }\n\n    SECTION(\"schedule on a specific worker\") {\n        scheduler->ScheduleOnWorker(2, task);\n        scheduler = nullptr; // force draining all scheduled tasks\n\n        REQUIRE(task->numberOfExecutions == 1);\n        REQUIRE(task->lastExecutedWorkerId == 2);\n    }\n\n    SECTION(\"schedule on all workers\") {\n        scheduler->ScheduleOnAllWorkers(task);\n        scheduler = nullptr; // force draining all scheduled tasks\n\n        REQUIRE(task->numberOfExecutions == settings.workers);\n    }\n}\n\nTEST_CASE(\"scheduler distributes and schedules all tasks\", \"[scheduler]\") {\n    ZoneSettings settings;\n    settings.workers = 4;\n\n    auto scheduler = std::make_unique<SchedulerImpl<TestWorker<3>>>(settings, [](WorkerId) {});\n\n    std::vector<std::shared_ptr<TestTask>> tasks;\n    for (size_t i = 0; i < 1000; i++) {\n        auto task = std::make_shared<TestTask>();\n        tasks.push_back(task);\n        scheduler->Schedule(task);\n    }\n\n    scheduler = nullptr; // force draining all scheduled tasks\n\n    std::vector<bool> scheduledWorkersFlags = { false, false, false, false };\n    size_t notRun = 0;\n    for (size_t i = 0; i < 1000; i++) {\n        // Make sure that each task was executed once\n        if (tasks[i]->numberOfExecutions == 0) {\n            ++notRun;\n        }\n        //REQUIRE(tasks[i]->numberOfExecutions == 1);\n        scheduledWorkersFlags[tasks[i]->lastExecutedWorkerId] = true;\n    }\n    REQUIRE(notRun == 0);\n\n    // Make sure that all workers were participating\n    for (auto flag: scheduledWorkersFlags) {\n        REQUIRE(flag);\n    }\n}\n"
  },
  {
    "path": "unittest/zone/timer-tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT license.\n\n#include <catch/catch.hpp>\n\n#include \"zone/timer.h\"\n\n#include <atomic>\n#include <future>\n\n#include <iostream>\n\nusing namespace napa::zone;\nusing namespace std::chrono;\nusing namespace std::chrono_literals;\n\n\nTEST_CASE(\"timer is triggered after provided timeout\", \"[timer][!mayfail]\") {\n    std::promise<high_resolution_clock::time_point> promise;\n    auto future = promise.get_future();\n\n    Timer timer([&promise]() {\n        promise.set_value(high_resolution_clock::now());\n    }, 50ms);\n\n    auto startTime = high_resolution_clock::now();\n    timer.Start();\n\n    auto status = future.wait_for(100ms);\n    REQUIRE(status != std::future_status::timeout);\n\n    REQUIRE(future.get() - startTime >= 50ms);\n}\n\nTEST_CASE(\"timer is not called if stopped\", \"[timer]\") {\n    std::promise<void> promise;\n    auto future = promise.get_future();\n\n    Timer timer([&promise]() {\n        promise.set_value();\n    }, 200ms);\n\n    timer.Start();\n    std::this_thread::sleep_for(100ms);\n    timer.Stop();\n\n    auto status = future.wait_for(200ms);\n    REQUIRE(status == std::future_status::timeout);\n}\n\nTEST_CASE(\"timers are called by order\", \"[timer]\") {\n    std::atomic<int> callOrder(0);\n\n    std::promise<int> promise1;\n    auto future1 = promise1.get_future();\n    Timer timer1([&promise1, &callOrder]() {\n        promise1.set_value(++callOrder);\n    }, 300ms);\n\n    std::promise<int> promise2;\n    auto future2 = promise2.get_future();\n    Timer timer2([&promise2, &callOrder]() {\n        promise2.set_value(++callOrder);\n    }, 200ms);\n\n    std::promise<int> promise3;\n    auto future3 = promise3.get_future();\n    Timer timer3([&promise3, &callOrder]() {\n        promise3.set_value(++callOrder);\n    }, 100ms);\n\n    timer1.Start();\n    timer2.Start();\n    timer3.Start();\n\n    // The order of which the timer callbacks are expected.\n    REQUIRE(future1.get() == 3);\n    REQUIRE(future2.get() == 2);\n    REQUIRE(future3.get() == 1);\n}"
  }
]