[
  {
    "path": ".gitattributes",
    "content": "* text=auto\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\n\non: [push, pull_request]\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        image: [\"gcc:13\", \"clang:16\"]\n        config: [Debug, Release]\n\n    runs-on: ubuntu-latest\n    container:\n      image: ghcr.io/think-cell/${{matrix.image}}\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Setup Boost\n      shell: bash\n      run: |\n        curl -L https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.zip --output boost_1_83_0.zip\n        unzip -q boost_1_83_0.zip\n        mv boost_1_83_0/ boost/\n\n    - name: CMake configure\n      run: cmake -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DBoost_INCLUDE_DIR=$GITHUB_WORKSPACE/boost/ -DBoost_LIBRARY_DIR=$GITHUB_WORKSPACE/boost/\n\n    - name: Compile\n      run: cmake --build build\n    - name: Run\n      run: cmake --build build --target test\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.21)\n\nproject(\n  tc_library_test\n  VERSION 1.0\n  LANGUAGES C CXX\n)\n\nset(CMAKE_CXX_STANDARD 20)\n\n# cmake -S . -B build -DBoost_INCLUDE_DIR=C:\\Libraries\\boost_1_79_0/ -DBoost_LIBRARY_DIR=C:\\Libraries\\boost_1_79_0/\nfind_package(Boost 1.75 REQUIRED)\n\n# Generate one cpp file per header\nfile(\n  GLOB_RECURSE liststrLibrary\n  LIST_DIRECTORIES false \n  CONFIGURE_DEPENDS\n  RELATIVE ${CMAKE_SOURCE_DIR}/tc\n  ${CMAKE_SOURCE_DIR}/tc/*.h\n)\n\nset(liststrLibraryCpp \"\")\n\nforeach(strLibrary ${liststrLibrary})\n  set(strLibraryCpp ${CMAKE_BINARY_DIR}/test/${strLibrary}.cpp)\n  list(APPEND liststrLibraryCpp ${strLibraryCpp})\n\n  file(WRITE ${strLibraryCpp} \n    \"#include \" \\\"${strLibrary}\\\"\n  )\nendforeach()\n\nfile(WRITE ${CMAKE_BINARY_DIR}/test/main.cpp\n  \"int main() { return 0; }\"\n)\n\n# Test if each header compiles individually\nadd_executable(compile_test ${liststrLibraryCpp} ${CMAKE_BINARY_DIR}/test/main.cpp)\ntarget_include_directories(compile_test PRIVATE ${CMAKE_SOURCE_DIR}/tc)\ntarget_link_libraries(compile_test Boost::boost Boost::disable_autolinking)\n\n# Run unit tests\ninclude(CTest)\nlist(APPEND CMAKE_CTEST_ARGUMENTS \"--verbose\")\n\nfile(\n  GLOB_RECURSE liststrUnitTestFiles\n  LIST_DIRECTORIES false \n  CONFIGURE_DEPENDS\n  ${CMAKE_SOURCE_DIR}/tc/*.t.cpp\n)\n\nadd_executable(unit_test ${liststrUnitTestFiles} ${CMAKE_BINARY_DIR}/test/main.cpp)\ntarget_include_directories(unit_test PRIVATE ${CMAKE_SOURCE_DIR}/tc)\ntarget_link_libraries(unit_test Boost::boost Boost::disable_autolinking)\nadd_test(NAME unit_test COMMAND unit_test)\n\nadd_executable(example_test range.example.cpp)\ntarget_link_libraries(example_test Boost::boost Boost::disable_autolinking)\nadd_test(NAME example_test COMMAND example_test)\n"
  },
  {
    "path": "LICENSE_1_0.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.\n"
  },
  {
    "path": "README.md",
    "content": "[![CI](https://github.com/think-cell/range/actions/workflows/main.yml/badge.svg)](https://github.com/think-cell/range/actions/workflows/main.yml)\n\n\nthink-cell public library\n=========================\n\nThis library consists of several core C++ utilities that we at *think-cell Software* have developed and consider to be useful.\nIt mostly covers ranges, but you will see that it also contains other handy features.\n\nWe continuously improve our library as part of our daily work, and whenever we gain new insights, we add them as we go.\nTo get in touch with other programmers, we regularly [give talks about our ideas](https://www.think-cell.com/career/talks/overview.shtml), using this library as a reference.\n\nWe consider the library to be production-quality code, but it is important to know that we do not strive for stable interfaces. Being free of such constraints is an important requirement for further enhancements.\n\nClean and expressive code makes reasoning about it - and thus further progress - easier. Therefore, we adopt the latest language features quickly if it helps the case.\n\nThis library has been made publicly available as an example of modern C++ coding techniques and as a source of inspiration for other library writers. And of course because we are proud of it!\n\nThe documentation is currently lacking and we are working on that. We will publish usage examples on our new [developer blog](https://www.think-cell.com/devblog) and will merge them into the library as comments. \n\n-------------\nContributions\n-------------\nIf you propose a change that improves correctness or standard-conformance, we encourage you to make a pull request.\nBut please understand that, for the above-mentioned reasons, we are not keen on workarounds to accommodate outdated compilers. \n \nDoes hacking our library give you a kick, and do you think you can contribute more? We are a friendly and driven bunch of C++ enthusiasts with a knack for elegant algorithms, and we are always looking for [new colleagues](https://www.think-cell.com/career).\n\n------------------\nUsage instructions\n------------------\nYou need to have boost installed (we tested with [1.75.0](https://www.boost.org/users/history/version_1_75_0.html)) and the following compiler settings:\n\n##### Visual C++ 19.28 (Visual Studio 2019 16.9)\n* `/std:c++latest`\n\n##### clang (*13.0.0* and *Apple LLVM 14.0.0*)\n* `-std=c++2a`\n\n##### gcc 12\n* `-std=c++2a`\n\n`range.example.cpp` provides a good entry point to get started quickly. If you want to see more examples, there are some unit tests in `tc/*.t.cpp`.\n"
  },
  {
    "path": "range.example.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) 2016-2018 think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"tc/range/meta.h\"\n#include \"tc/range/filter_adaptor.h\"\n#include \"tc/string/format.h\"\n#include \"tc/string/make_c_str.h\"\n\n#include <boost/range/adaptors.hpp>\n\n#include <vector>\n#include <cstdio>\n\nnamespace {\n\ntemplate <typename... Args>\nvoid print(Args&&... args) noexcept {\n\tstd::printf(\"%s\", tc::implicit_cast<char const*>(tc::make_c_str<char>(std::forward<Args>(args)...)));\n}\n\n//---- Basic ------------------------------------------------------------------------------------------------------------------\nvoid basic () {\n\tstd::vector<int> v = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};\n\n\ttc::for_each(\n\t\ttc::filter(v, [](const int& n){ return (n%2==0);}),\n\t\t[&](auto const& n) {\n\t\t\tprint(tc::as_dec(n), \", \");\n\t\t}\n\t);\n\tprint(\"\\n\");\n}\n\n//---- Generator Range --------------------------------------------------------------------------------------------------------\nnamespace {\n\tstruct generator_range {\n\t\ttemplate< typename Func >\n\t\tvoid operator()( Func func ) const& {\n\t\t\tfor(int i=0;i<50;++i) {\n\t\t\t\tfunc(i);\n\t\t\t}\n\t\t}\n\t};\n}\n\nvoid ex_generator_range () {\n\ttc::for_each( tc::filter( generator_range(), [](int i){ return i%2==0; } ), [](int i) {\n\t\tprint(tc::as_dec(i), \", \");\n\t});\n\tprint(\"\\n\");\n}\n\n//---- Generator Range (with break) -------------------------------------------------------------------------------------------\nnamespace {\n\tstruct generator_range_break {\n\t\ttemplate< typename Func >\n\t\ttc::break_or_continue operator()( Func func ) const& {\n\t\t\tusing namespace tc;\n\t\t\tfor(int i=0;i<5000;++i) {\n\t\t\t\tif (func(i)==break_) { return break_; }\n\t\t\t}\n\t\t\treturn continue_;\n\t\t}\n\t};\n}\n\nvoid ex_generator_range_break () {\n\ttc::for_each( tc::filter( generator_range_break(), [](int i){ return i%2==0; } ), [](int i) -> tc::break_or_continue {\n\t\tprint(tc::as_dec(i), \", \");\n\t\treturn (i>=50)? tc::break_ : tc::continue_;\n\t});\n\tprint(\"\\n\");\n}\n\n//---- Stacked filters --------------------------------------------------------------------------------------------------------\nvoid stacked_filters() {\n\ttc::for_each( tc::filter( tc::filter( tc::filter(\n\t\t\t\t\t\t\t\tgenerator_range_break(),\n\t\t\t\t\t\t\t\t[](int i){ return i%2!=0; } ),\n\t\t\t\t\t\t\t\t[](int i){ return i%3!=0; } ),\n\t\t\t\t\t\t\t\t[](int i){ return i%5!=0; } )\n\t\t\t, [](int i) -> tc::break_or_continue\n\t{\n\t\tprint(tc::as_dec(i), \", \");\n\t\treturn (i>25)? tc::break_ : tc::continue_;\n\t});\n\tprint(\"\\n\");\n}\n\n}\n\nint main() {\n\tprint(\"-- Running Examples ----------\\n\");\n\n\tbasic();\n\tex_generator_range();\n\tex_generator_range_break();\n\tstacked_filters();\n\n\tusing namespace tc;\n\n\tint av[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};\n\tauto v = std::vector<int> (av, av+sizeof(av)/sizeof(int)); \n  \n\t//---- filter example with iterators  -------------------------------------------\n\n\tauto r =  tc::filter( tc::filter( tc::filter(\n\t\t\t\t\t\t\t\tv,\n\t\t\t\t\t\t\t\t[](int i){ return i%2!=0; } ),\n\t\t\t\t\t\t\t\t[](int i){ return i%3!=0; } ),\n\t\t\t\t\t\t\t\t[](int i){ return i%5!=0; } );\n\n\tfor (auto it = std::begin(r),\n\t\t\t\tend = std::end(r);\n\t\tit != end;\n\t\t++it)\n\t{\n\t\tprint(tc::as_dec(*it), \", \");\n\t}\n\tprint(\"\\n\");\n\n\t//---- boost for comparison -----------------------------------------------------\n\n\tauto br = v | boost::adaptors::filtered([](int i){ return i%2!=0; })\n\t\t\t\t| boost::adaptors::filtered([](int i){ return i%3!=0; })\n\t\t\t\t| boost::adaptors::filtered([](int i){ return i%5!=0; });\n\n\n\tfor (auto it = std::begin(br),\n\t\tend = std::end(br);\n\t\tit != end;\n\t\t++it)\n\t{\n\t\tprint(tc::as_dec(*it), \", \");\n\t}\n\tprint(\"\\n\");\n\t\n\tprint(\"-- Done ----------\\n\");\n\tstd::fflush(stdout);\n\n\treturn EXIT_SUCCESS;\n}\n\n\n\n"
  },
  {
    "path": "tc/algorithm/accumulate.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"for_each.h\"\n#include \"../base/modified.h\"\n#include \"../optional.h\"\n\nnamespace tc {\n\t/////////////////////////////////////////////////////\n\t// accumulate\n\n\tnamespace no_adl {\n\t\ttemplate< typename T, typename AccuOp >\n\t\tstruct accumulate_fn /*final*/ {\n\t\t\tT * m_pt;\n\t\t\tAccuOp * m_paccuop;\n\t\t\tconstexpr accumulate_fn( T & t, AccuOp & accuop ) noexcept\n\t\t\t:  m_pt(std::addressof(t)), m_paccuop(std::addressof(accuop))\n\t\t\t{}\n\n\t\t\ttemplate<typename S>\n\t\t\tconstexpr auto operator()(S&& s) const& MAYTHROW {\n\t\t\t\treturn tc::continue_if_not_break(*m_paccuop, *m_pt, tc_move_if_owned(s));\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate< typename Rng, typename T, typename AccuOp >\n\t[[nodiscard]] constexpr T accumulate(Rng&& rng, T t, AccuOp accuop) MAYTHROW {\n\t\ttc::for_each(tc_move_if_owned(rng), no_adl::accumulate_fn<T,AccuOp>(t,accuop));\n\t\treturn t;\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate< typename T, typename AccuOp >\n\t\tstruct [[nodiscard]] accumulator_with_front /*final*/ {\n\t\t\tstd::optional<T> & m_t;\n\t\t\tAccuOp m_accuop;\n\n\t\t\ttemplate< typename S >\n\t\t\tconstexpr auto operator()( S&& s ) const& MAYTHROW {\n\t\t\t\treturn tc_conditional_prvalue_as_val(\n\t\t\t\t\tm_t,\n\t\t\t\t\ttc::continue_if_not_break( m_accuop, *m_t, tc_move_if_owned(s) ),\n\t\t\t\t\tTC_FWD(tc::optional_emplace(m_t, tc_move_if_owned(s)), tc::constant<tc::continue_>())\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Value, typename AccuOp>\n\tconstexpr no_adl::accumulator_with_front<Value, AccuOp> make_accumulator_with_front(std::optional<Value>& value, AccuOp&& accumulate) noexcept {\n\t\treturn {value, tc_move_if_owned(accumulate)};\n\t}\n\n\ttemplate<typename T, typename Rng, typename AccuOp>\n\t[[nodiscard]] constexpr std::optional<T> accumulate_with_front(Rng&& rng, AccuOp&& accuop) MAYTHROW {\n\t\tstatic_assert(tc::decayed<T>);\n\t\tstd::optional<T> t;\n\t\ttc::for_each(tc_move_if_owned(rng), tc::make_accumulator_with_front(t, tc_move_if_owned(accuop)));\n\t\treturn t;\n\t}\n\n\ttemplate<typename Rng, typename AccuOp>\n\t[[nodiscard]] constexpr auto accumulate_with_front(Rng&& rng, AccuOp&& accuop) MAYTHROW {\n\t\treturn tc::accumulate_with_front<tc::range_value_t<Rng>>(tc_move_if_owned(rng), tc_move_if_owned(accuop));\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/algorithm.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/functors.h\"\n#include \"../base/tag_type.h\"\n#include \"../range/adjacent_adaptor.h\"\n#include \"../range/make_range.h\"\n#include \"../range/meta.h\"\n#include \"../range/join_framed_adaptor.h\"\n#include \"../range/subrange.h\"\n#include \"../range/unique_range_adaptor.h\"\n#include \"../range/iota_range.h\"\n#include \"../range/concat_adaptor.h\"\n#include \"../range/filter_adaptor.h\"\n\n#include \"../container/container_traits.h\"\n#include \"../container/container.h\" // tc::vector\n#include \"../container/cont_assign.h\"\n#include \"../container/insert.h\"\n#include \"../container/cont_reserve.h\"\n\n#include \"../storage_for.h\"\n#include \"../string/spirit.h\"\n\n#include \"append.h\"\n#include \"size.h\"\n#include \"element.h\"\n#include \"equal.h\"\n#include \"quantifier.h\"\n#include \"empty.h\"\n#include \"minmax.h\"\n#include \"compare.h\"\n#include \"for_each_xxx.h\"\n#include \"accumulate.h\"\n#include \"size_bounded.h\"\n#include \"find.h\"\n#include \"filter_inplace.h\"\n#include \"best_element.h\"\n#include \"partition_iterator.h\"\n#include \"partition_range.h\"\n#include \"size_linear.h\"\n\n\n#include <boost/preprocessor/repetition/enum.hpp>\n#include <boost/utility.hpp>\n#include <boost/range/algorithm/copy.hpp>\n\n#include <boost/multi_index_container_fwd.hpp>\n#include <boost/multi_index/hashed_index_fwd.hpp>\n#include <boost/multi_index/ordered_index_fwd.hpp>\n#include <boost/intrusive/set.hpp>\n\n#include <type_traits>\n#include <set>\n#include <map>\n#include <utility>\n#include <algorithm>\n\nnamespace tc {\n\ttemplate< typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] constexpr bool is_strictly_sorted(Rng const& rng, Less less = Less()) noexcept {\n\t\treturn tc::all_of(tc::adjacent<2>(rng), [&](auto const& first, auto const& second) noexcept {\n\t\t\treturn less(first, second);\n\t\t});\n\t}\n\ttemplate< typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] constexpr bool is_sorted(Rng const& rng, Less less = Less()) MAYTHROW {\n\t\treturn !tc::any_of(tc::adjacent<2>(rng), [&](auto const& first, auto const& second) MAYTHROW {\n\t\t\treturn less(second, first); // MAYTHROW\n\t\t});\n\t}\n\n\t/////////////////////////////////\n\t// associative containers\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename TTarget, typename Rng>\n\t\t\trequires has_mem_fn_lower_bound<TTarget> || has_mem_fn_hash_function<TTarget>\n\t\tTTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, Rng&& rng) noexcept {\n\t\t\tTTarget cont;\n\t\t\t// force each element to be inserted\n\t\t\ttc::cont_must_insert_range(cont, tc_move_if_owned(rng));\n\t\t\treturn cont;\n\t\t}\n\t}\n\n\t/////////////////////////////////////////////////////\n\t// sort\n#ifdef __clang__\n\tnamespace constexpr_sort_inplace_detail {\n\n\t\t// This duplicates the functionality of tc::sort, which cannot be used in a constant expression,\n\t\t// because it uses std::sort which is not constexpr (until C++20).\n\t\ttemplate<typename Iterator, typename Pred>\n\t\tconstexpr void constexpr_sort_inplace(Iterator itBegin, Iterator itEnd, Pred pred) noexcept {\n#if defined(_CHECKS) && defined(TC_PRIVATE)\n\t\t\tint nIterationCount = 0;\n#endif\n\t\t\twhile (1 < itEnd - itBegin) {\n\t\t\t\t_ASSERTENOTIFY( ++nIterationCount <= 32 ); // Do we actually run into O(n^2) complexity?\n\t\t\t\tauto itPartitionBegin = itBegin;\n\t\t\t\tauto itPartitionEnd = tc_modified(itEnd, --_);\n\t\t\t\t// Any iterator in the interval [itBegin, itEnd - 2] works.\n\t\t\t\t// Middle is best for sorted and reverse sorted ranges.\n\t\t\t\tauto itPivotElement = tc::middle_point(itBegin, itPartitionEnd);\n\n\t\t\t\tfor (;;) {\n\t\t\t\t\twhile (pred(*itPartitionBegin, *itPivotElement)) {\n\t\t\t\t\t\t++itPartitionBegin;\n\t\t\t\t\t}\n\t\t\t\t\twhile (pred(*itPivotElement, *itPartitionEnd)) {\n\t\t\t\t\t\t--itPartitionEnd;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (itPartitionEnd <= itPartitionBegin) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (itPartitionBegin == itPivotElement) {\n\t\t\t\t\t\titPivotElement = itPartitionEnd;\n\t\t\t\t\t} else if (itPartitionEnd == itPivotElement) {\n\t\t\t\t\t\titPivotElement = itPartitionBegin;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttc::swap(*itPartitionBegin, *itPartitionEnd);\n\n\t\t\t\t\t++itPartitionBegin;\n\t\t\t\t\t--itPartitionEnd;\n\t\t\t\t}\n\n\t\t\t\tauto const itSplitPoint = itPartitionEnd + 1;\n\t#if defined(_CHECKS) && defined(_DEBUG)\n\t\t\t\t_ASSERTE(itBegin < itSplitPoint);\n\t\t\t\t_ASSERTE(itSplitPoint < itEnd);\n\n\t\t\t\tfor (auto j = itBegin; j < itSplitPoint; ++j) {\n\t\t\t\t\t_ASSERTE(!pred(*itPivotElement, *j));\n\t\t\t\t}\n\t\t\t\tfor (auto j = itSplitPoint; j < itEnd; ++j) {\n\t\t\t\t\t_ASSERTE(!pred(*j, *itPivotElement));\n\t\t\t\t}\n\t#endif\n\n\t\t\t\t// Recur into smaller subrange and sort larger subrange in next iteration to get O(log n) space complexity.\n\t\t\t\tif( itSplitPoint - itBegin < itEnd - itSplitPoint ) {\n\t\t\t\t\tconstexpr_sort_inplace_detail::constexpr_sort_inplace(itBegin, itSplitPoint, pred);\n\t\t\t\t\titBegin = itSplitPoint;\n\t\t\t\t} else {\n\t\t\t\t\tconstexpr_sort_inplace_detail::constexpr_sort_inplace(itSplitPoint, itEnd, pred);\n\t\t\t\t\titEnd = itSplitPoint;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n#endif\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\tconstexpr void sort_inplace(Rng&& rng, Less&& less = Less()) noexcept(noexcept(less(tc::front(rng), tc::front(rng)))) {\n\t\tif constexpr( has_mem_fn_sort< Rng >) {\n\t\t\tstatic_assert( std::is_lvalue_reference<Rng>::value );\n\t\t\trng.sort( tc_move_if_owned(less) );\n\t\t} else {\n#ifdef __clang__ // xcode12 does not support constexpr std::sort\n\t\t\tif(std::is_constant_evaluated()) {\n\t\t\t\tconstexpr_sort_inplace_detail::constexpr_sort_inplace(tc::begin(rng), tc::end(rng), less);\n\t\t\t\t_ASSERTE( tc::is_sorted(rng, less) );\n\t\t\t} else {\n#endif\n\t\t\t\tstd::sort( tc::begin(rng), tc::end(rng), tc_move_if_owned(less) );\n#ifdef __clang__\n\t\t\t}\n#endif\n\t\t}\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\tvoid stable_sort_inplace(Rng&& rng, Less&& less = Less()) noexcept(noexcept(less(tc::front(rng), tc::front(rng)))) {\n\t\tstd::stable_sort(tc::begin(rng), tc::end(rng), tc_move_if_owned(less));\n\t}\n\n\ttemplate< typename Less=tc::fn_less >\n\tconstexpr void strictly_sort_inplace(auto&& rng, Less less=Less()) noexcept(noexcept(less(tc::front(rng), tc::front(rng)))) {\n\t\ttc::sort_inplace(rng, less);\n\t\t_ASSERT( tc::is_strictly_sorted(rng, less) );\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng, bool bStable>\n\t\tstruct [[nodiscard]] sorted_index_adaptor final\n\t\t\t: tc::range_adaptor_base_range<Rng>\n\t\t\t, tc::index_range_adaptor<\n\t\t\t\tsorted_index_adaptor<Rng, bStable>,\n\t\t\t\ttc::vector<tc::index_t<std::remove_reference_t<Rng>>>,\n\t\t\t\tindex_range_adaptor_flags::inherit_begin_end | index_range_adaptor_flags::inherit_traversal\n\t\t\t>\n\t\t\t, private tc::nonmovable // disable copy ctor and default move ctor\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = sorted_index_adaptor;\n\t\t\tusing base_range_base = tc::range_adaptor_base_range<Rng>;\n\t\t\tusing index_base = typename this_type::index_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing base_range_base::base_range;\n\t\t\tusing typename index_base::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=false;\n\n\t\t\ttemplate<typename LessOrComp>\n\t\t\texplicit sorted_index_adaptor(Rng&& rng, LessOrComp lessorcomp) noexcept\n\t\t\t\t: base_range_base(tc::aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, index_base(tc::aggregate_tag, tc::explicit_cast<tc::vector<tc::index_t<std::remove_reference_t<Rng>>>>(\n\t\t\t\t\ttc::transform(tc::make_range_of_iterators(base_range()), tc_fn(tc::iterator2index<Rng>))\n\t\t\t\t))\n\t\t\t{\n\t\t\t\ttc::sort_inplace(\n\t\t\t\t\tthis->index_base::base_range(),\n\t\t\t\t\t[&](auto const& idxLhs, auto const& idxRhs ) noexcept -> bool {\n\t\t\t\t\t\ttc_auto_cref(lhs, tc::dereference_index(base_range(), idxLhs));\n\t\t\t\t\t\ttc_auto_cref(rhs, tc::dereference_index(base_range(), idxRhs));\n\t\t\t\t\t\tif constexpr (bStable) {\n\t\t\t\t\t\t\tstatic_assert(tc::random_access_range<Rng>);\n\t\t\t\t\t\t\ttc_auto_cref(order, lessorcomp(lhs, rhs));\n\t\t\t\t\t\t\tstatic_assert(tc::is_comparison_category<std::remove_cvref_t<decltype(order)>>);\n\t\t\t\t\t\t\tif(tc::is_eq(order)) {\n\t\t\t\t\t\t\t\treturn 0<tc::distance_to_index(base_range(), idxLhs, idxRhs);\n\t\t\t\t\t\t\t} else if(std::is_lt(order)) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t_ASSERTDEBUG(std::is_gt(order));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn lessorcomp(lhs, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsorted_index_adaptor(sorted_index_adaptor&& src) noexcept requires tc::stable_index_on_move<Rng> // tc::reference_or_value is movable for const Rng as well\n\t\t\t\t: base_range_base(tc::base_cast<base_range_base>(tc_move(src)))\n\t\t\t\t, index_base(tc::base_cast<index_base>(tc_move(src)))\n\t\t\t{}\n\t\tprivate:\n\t\t\tSTATIC_FINAL(dereference_index)(tc_index const& idx) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::dereference_index(base_range(), *idx)\n\t\t\t)\n\n\t\t\tSTATIC_FINAL(dereference_index)(tc_index const& idx) & return_decltype_MAYTHROW(\n\t\t\t\ttc::dereference_index(base_range(), *idx)\n\t\t\t)\n\n\t\tpublic:\n\t\t\tstatic decltype(auto) element_base_index(tc_index const& idx) noexcept {\n\t\t\t\treturn *idx;\n\t\t\t}\n\t\t\tstatic decltype(auto) element_base_index(tc_index&& idx) noexcept {\n\t\t\t\treturn *tc_move(idx);\n\t\t\t}\n\n\t\t\tconstexpr decltype(auto) dereference_untransform(tc_index const& idx) const& noexcept {\n\t\t\t\treturn base_range().dereference_untransform(*idx);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::sorted_index_adaptor;\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto sorted_iterator_range(Rng& rng, Less&& less = Less()) noexcept {\n\t\tauto vecitSorted=tc::make_vector( tc::make_range_of_iterators(rng) );\n\t\ttc::sort_inplace(vecitSorted, tc::projected( tc_move_if_owned(less), tc::fn_indirection() ) );\n\t\treturn vecitSorted;\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto sort(Rng&& rng, Less&& less = Less()) noexcept {\n\t\treturn tc::sorted_index_adaptor<Rng, false/*bStable*/>(tc_move_if_owned(rng), tc_move_if_owned(less));\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] constexpr auto constexpr_sort(Rng&& rng, Less&& less = Less()) noexcept {\n\t\tauto a = tc::make_array(tc_move_if_owned(rng));\n\t\ttc::sort_inplace(a, tc_move_if_owned(less));\n\t\treturn a;\n\t}\n\n\ttemplate<typename Rng, typename Comp = tc::fn_compare>\n\t[[nodiscard]] auto stable_sort(Rng&& rng, Comp&& comp = Comp()) noexcept {\n\t\treturn tc::sorted_index_adaptor<Rng, true/*bStable*/>(tc_move_if_owned(rng), tc_move_if_owned(comp));\n\t}\n\t\n\tnamespace no_adl {\n\t\ttemplate< typename Rng >\n\t\tstruct [[nodiscard]] untransform_adaptor\n\t\t\t:  tc::index_range_adaptor<\n\t\t\t\tuntransform_adaptor<Rng>,\n\t\t\t\tRng, tc::index_range_adaptor_flags::inherit_begin_end | tc::index_range_adaptor_flags::inherit_traversal\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = untransform_adaptor;\n\t\t\tusing base_ = typename untransform_adaptor::index_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\t\t\tusing base_::base_;\n\n\t\t\tSTATIC_FINAL_MOD(template<typename Index> constexpr, dereference_index)(Index&& idx) & return_decltype_MAYTHROW(\n\t\t\t\tthis->base_range().dereference_untransform(tc_move_if_owned(idx))\n\t\t\t)\n\n\t\t\tSTATIC_FINAL_MOD(template<typename Index> constexpr, dereference_index)(Index&& idx) const& return_decltype_MAYTHROW(\n\t\t\t\tthis->base_range().dereference_untransform(tc_move_if_owned(idx))\n\t\t\t)\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] auto untransform(Rng&& rng) noexcept {\n\t\treturn no_adl::untransform_adaptor<Rng>(tc::aggregate_tag, tc_move_if_owned(rng));\n\t}\n\n\t///////////////////////////////////////\n\t// partition ranges into subranges\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto ordered_unique_range(Rng&& rng, Less&& less = Less()) noexcept {\n\t\t_ASSERTDEBUG( tc::is_sorted( rng, less ) );\n\t\treturn tc::adjacent_unique_range( tc_move_if_owned(rng), std::not_fn( tc_move_if_owned(less) ) );\n\t}\n\n\ttemplate<typename Rng, typename FuncRngStart, typename FuncRngElement, typename Less = tc::fn_less>\n\tauto generator_ordered_unique_range(Rng&& rng, FuncRngStart funcStart, FuncRngElement funcElem, Less&& less = Less()) noexcept {\n\t\tstd::optional<tc::range_value_t<Rng>> oelem;\n\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&& element) noexcept {\n\t\t\tif (!oelem || less(*oelem, element)) {\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(funcStart))\n\t\t\t\ttc::optional_emplace(oelem, element);\n\t\t\t}\n\t\t\treturn tc::continue_if_not_break(funcElem,tc_move_if_owned(element));\n\t\t});\n\t}\n\n\ttemplate<typename Rng, typename Comp = tc::fn_compare>\n\t[[nodiscard]] auto stable_sort_unique_range(Rng&& rng, Comp const& comp = Comp()) noexcept {\n\t\treturn tc::ordered_unique_range( tc::stable_sort( tc_move_if_owned(rng), comp ), tc::lessfrom3way(comp) );\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto sort_unique_range(Rng&& rng, Less const& less = Less()) noexcept {\n\t\treturn tc::ordered_unique_range( tc::sort( tc_move_if_owned(rng), less ), less );\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto sort_inplace_unique_range(Rng&& rng, Less&& less = Less()) noexcept {\n\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\ttc::sort_inplace( rng, std::ref(less) );\n\t\treturn tc::ordered_unique_range( tc_move_if_owned(rng), tc_move_if_owned(less) );\n\t}\n\n\ttemplate< typename Rng, typename Less, typename Accu >\n\tvoid accumulate_each_unique_range(Rng&& cont, Less less, Accu accu) noexcept {\n\t\trange_filter< tc::decay_t<Rng> > rngfilter( cont );\n\t\ttc::for_each(\n\t\t\ttc::ordered_unique_range(\n\t\t\t\tcont,\n\t\t\t\ttc_move(less)\n\t\t\t),\n\t\t\t[&accu,&rngfilter]( auto const& rngEqualSubRange ) noexcept {\n\t\t\t\tfor(\n\t\t\t\t\tauto it=tc::begin_next<tc::return_border>(rngEqualSubRange);\n\t\t\t\t\tit!=tc::end(rngEqualSubRange);\n\t\t\t\t\t++it\n\t\t\t\t) {\n\t\t\t\t\ttc_invoke(accu,*tc::begin(rngEqualSubRange), *it);\n\t\t\t\t}\n\t\t\t\trngfilter.keep( tc::begin(rngEqualSubRange) );\n\t\t\t}\n\t\t);\n\t}\n\n\ttemplate< typename Rng, typename Less, typename Accu >\n\tvoid sort_accumulate_each_unique_range(Rng&& cont, Less less, Accu accu) noexcept {\n\t\ttc::sort_inplace( cont, less );\n\t\ttc::accumulate_each_unique_range(cont, tc_move(less), tc_move(accu));\n\t}\n\n\ttemplate< typename Cont, typename Equals = decltype(tc::equal_to)>\n\tvoid front_unique_inplace(Cont& cont, Equals&& pred={}) noexcept(noexcept(pred(tc::front(cont), tc::front(cont)))) {\n\t\ttc::range_filter< tc::decay_t<Cont> > rngfilter(cont);\n\t\ttc::for_each(\n\t\t\ttc::transform(\n\t\t\t\ttc::front_unique_range(cont, tc_move_if_owned(pred)),\n\t\t\t\ttc_fn(tc::begin)\n\t\t\t),\n\t\t\t[&](auto it) noexcept {\n\t\t\t\trngfilter.keep(tc_move(it));\n\t\t\t}\n\t\t);\n\t}\n\n\t/*\n\t\tIn contrast to std::unique, tc::adjacent_unique / tc::adjacent_unique_inplace always compares adjacent elements. This allows implementing\n\t\tbidirectional tc::adjacent_unique, with tc::adjacent_unique_inplace yielding the same result.\n\t*/\n\ttemplate< typename Cont, typename Equals=decltype(tc::equal_to)>\n\tconstexpr void adjacent_unique_inplace(Cont & cont, Equals&& pred={}) noexcept(noexcept(pred(tc::front(cont), tc::front(cont)))) {\n\t\ttc::range_filter< tc::decay_t<Cont> > rngfilter(cont);\n\t\t// When this function is evaluated at compile time, the range returned by tc::make_range_of_iterators cannot use an rvalue as a base range.\n\t\t// This is because it stores the base range in a mutable field inside tc::reference_or_value.\n\t\ttc::for_each(\n\t\t\ttc::may_remove_current(tc::make_range_of_iterators(tc::as_lvalue(tc::adjacent_unique(cont, tc_move_if_owned(pred/*MAYTHROW*/))))),\n\t\t\t[&](auto it) noexcept {\n\t\t\t\trngfilter.keep(it.element_base());\n\t\t\t}\n\t\t);\n\t}\n\n\ttemplate<typename Cont, typename Less=tc::fn_less>\n\tconstexpr void ordered_unique_inplace( Cont& cont, Less less=Less() ) noexcept(noexcept(less(tc::front(cont), tc::front(cont)))) {\n\t\t_ASSERTDEBUG( tc::is_sorted( cont, less ) );\n\t\ttc::adjacent_unique_inplace( cont, std::not_fn( tc_move(less) ) );\n\t}\n\n\ttemplate< typename Cont, typename Less=tc::fn_less >\n\tconstexpr void sort_unique_inplace(Cont& cont, Less less=Less()) noexcept(noexcept(less(tc::front(cont), tc::front(cont)))) {\n\t\ttc::sort_inplace( cont, less );\n\t\ttc::ordered_unique_inplace( cont, tc_move(less) );\n\t}\n\n\ttemplate< typename Cont, typename Less=tc::fn_less >\n\tvoid stable_sort_unique_inplace(Cont& cont, Less less=Less()) noexcept(noexcept(less(tc::front(cont), tc::front(cont)))) {\n\t\ttc::stable_sort_inplace( cont, less );\n\t\ttc::ordered_unique_inplace( cont, tc_move(less) );\n\t}\n\n\ttemplate<typename Rng, typename Less>\n\tauto ordered_unique_begin_and_count(Rng&& rng, Less&& less) noexcept {\n\t\treturn tc::transform(tc::ordered_unique_range( tc_move_if_owned(rng), tc_move_if_owned(less)), [&](auto const& rngSub) noexcept {\n\t\t\treturn std::make_pair(\n\t\t\t\ttc::begin(rngSub),\n\t\t\t\ttc::implicit_cast<typename boost::range_size< std::remove_reference_t<Rng> >::type >(tc::size_linear(rngSub))\n\t\t\t);\n\t\t});\n\t}\n\n\ttemplate<typename RangeReturn, typename Rng>\n\t[[nodiscard]] auto plurality_element(Rng&& rng) noexcept {\n\t\tauto vecitSorted = tc::sorted_iterator_range(rng, tc::fn_less()); // do not inline, oit->first points into vecitSorted\n\t\tif(auto oit = tc::max_element<tc::return_value_or_none>(\n\t\t\ttc::ordered_unique_begin_and_count(\n\t\t\t\tvecitSorted,\n\t\t\t\ttc::projected(tc::fn_less(), fn_indirection())\n\t\t\t),\n\t\t\ttc_member(.second)\n\t\t)) {\n\t\t\treturn RangeReturn::pack_element(tc_move_always(*oit->first), tc_move_if_owned(rng));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Pred >\n\t[[nodiscard]] decltype(auto) trim_left_if(Rng&& rng, Pred&& pred) MAYTHROW {\n\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\treturn tc_rewrap_temporary(Rng&&, RangeReturn::pack_border(\n\t\t\ttc::find_first_if<tc::return_border_before_or_end>( tc_unwrap_temporary(rng), std::not_fn(tc_move_if_owned(pred)) ),\n\t\t\ttc_unwrap_temporary(tc_move_if_owned(rng))\n\t\t));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Pred >\n\t[[nodiscard]] decltype(auto) trim_right_if(Rng&& rng, Pred&& pred) MAYTHROW {\n\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\treturn tc_rewrap_temporary(Rng&&, RangeReturn::pack_border(\n\t\t\ttc::find_last_if<tc::return_border_after_or_begin>( tc_unwrap_temporary(rng), std::not_fn(tc_move_if_owned(pred)) ),\n\t\t\ttc_unwrap_temporary(tc_move_if_owned(rng))\n\t\t));\n\t}\n\n\ttemplate< typename Rng, typename Pred >\n\t[[nodiscard]] decltype(auto) trim_if(Rng&& rng, Pred&& pred) MAYTHROW {\n\t\treturn tc_invoke(tc::chained(\n\t\t\t // clang crashes if we use return_decltype_allow_xvalue\n\t\t\t[&](auto&& rng)\t-> decltype(auto) { return tc::trim_left_if<tc::return_drop>(tc_move_if_owned(rng), tc_move_if_owned(pred)); },\n\t\t\t[&](auto&& rng)\t-> decltype(auto) { return tc::trim_right_if<tc::return_take>(tc_move_if_owned(rng), pred); }\n\t\t), tc_move_if_owned(rng));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename RngTrim >\n\t[[nodiscard]] decltype(auto) trim_left(Rng&& rng, RngTrim const& rngTrim) MAYTHROW {\n\t\treturn tc::trim_left_if<RangeReturn>( tc_move_if_owned(rng), [&](auto const& _) noexcept { return tc::find_first<tc::return_bool>(rngTrim, _); } );\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename RngTrim >\n\t[[nodiscard]] decltype(auto) trim_right(Rng&& rng, RngTrim const& rngTrim) MAYTHROW {\n\t\treturn tc::trim_right_if<RangeReturn>( tc_move_if_owned(rng), [&](auto const& _) noexcept { return tc::find_first<tc::return_bool>(rngTrim, _); } );\n\t}\n\n\ttemplate< typename Rng, typename RngTrim >\n\t[[nodiscard]] decltype(auto) trim(Rng&& rng, RngTrim const& rngTrim) MAYTHROW {\n\t\treturn tc::trim_if( tc_move_if_owned(rng), [&](auto const& _) noexcept { return tc::find_first<tc::return_bool>(rngTrim, _); } );\n\t}\n\n\ttemplate< typename Rng, typename T >\n\t[[nodiscard]] bool contains_single(Rng const& rng, T const& t) noexcept {\n\t\treturn 1==size_bounded(rng,2) && tc::front( rng )==t;\n\t}\n\n\tnamespace cont_find_detail {\n\t\ttemplate< typename RangeReturn, typename Cont>\n\t\tdecltype(auto) cont_find_impl(Cont& cont, tc::iterator_t< Cont > it) noexcept {\n\t\t\tif( it==tc::end(cont) ) {\n\t\t\t\treturn RangeReturn::pack_no_element(\n\t\t\t\t\tcont\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn RangeReturn::pack_element(\n\t\t\t\t\tit,\n\t\t\t\t\tcont\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename Cont, typename Arg >\n\t[[nodiscard]] decltype(auto) cont_find(Cont& cont, Arg&& arg) noexcept {\n\t\treturn cont_find_detail::cont_find_impl<RangeReturn>(cont, cont.find(tc_move_if_owned(arg)));\n\t}\n\n#ifdef _DEBUG\n\tusing static_vector_size_t = std::uint32_t; // fixed width integer for shared heap\n\tnamespace static_vector_adl {\n\t\ttemplate< typename T, tc::static_vector_size_t N> struct static_vector;\n\t}\n\tusing static_vector_adl::static_vector;\n#endif\n\n\ttemplate<typename Rng>\n\tvoid assert_no_null_terminator(Rng const& rng) noexcept {\n\t\tif constexpr( tc::char_type< tc::range_value_t<Rng const&> > ) {\n\t\t\t_ASSERT( !tc::find_first<tc::return_bool>(rng, tc::explicit_cast<tc::range_value_t<Rng const&>>('\\0') ));\n\t\t}\n\t}\n\n\ttemplate<typename Rng>\n\tvoid remove_null_terminator(Rng& rng) noexcept {\n\t\tstatic_assert( tc::char_type< tc::range_value_t<decltype((rng))> > );\n\t\t_ASSERTEQUAL( tc::back(rng), tc::explicit_cast< tc::range_value_t<decltype((rng))> >('\\0') );\n\t\ttc::drop_last_inplace(rng);\n\t\ttc::assert_no_null_terminator(rng);\n\t}\n\n\ttemplate<typename Char, std::size_t N>\n\t[[nodiscard]] constexpr Char const* take_null_terminated(Char const (&ach)[N]) noexcept {\n\t\tstatic_assert( tc::char_type<Char> );\n\t\t_ASSERTDEBUG( tc::find_first<tc::return_bool>(tc::as_array(ach), Char()) );\n\t\treturn ach;\n\t}\n\n\tnamespace get_buffer_detail {\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Cont>\n\t\t\tstruct container_with_sentinel final {\n\t\t\t\tusing type = Cont;\n\t\t\t};\n\n\t\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\t\tstruct container_with_sentinel<tc::static_vector<T, N>> final {\n\t\t\t\tusing type = tc::static_vector<T, N + 1>;\n\t\t\t};\n\t\t}\n#endif\n\n\t\t/* Calls func(pBuffer, nBufferSize) with buffers of increasing size; func may read into\n\t\t[pBuffer, pBuffer+nBufferSize) and return nSize, which is either the correct size of the\n\t\tbuffer (if nSize <= nBufferSize) or an estimate otherwise. */\n\t\ttemplate<typename Cont, typename Func>\n\t\tvoid append_buffer_allowing_nulls(Cont& cont, Func func) MAYTHROW {\n\t\t\tauto const nOffset = tc::size(cont);\n\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\t\ttc::cont_reserve(cont, tc::size(cont)+1);\n#endif\n\n\t\t\tfor (;;) {\n\t\t\t\ttc::cont_extend(cont, cont.capacity(), boost::container::default_init); // Allow func to use the whole allocated buffer\n\n\t\t\t\t// sentinel to detect buffer overrun\n\t\t\t\tIF_NO_MSVC_WORKAROUND(static) constexpr typename boost::range_size<Cont>::type nSentinel= // workaround MSVC compiler bug: https://developercommunity.visualstudio.com/t/code-generation-bug-on-static-variable-i/10541326\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\t\t\t\t1;\n\t\t\t\t_ASSERT(nOffset+nSentinel <= tc::size(cont));\n\t\t\t\ttc::for_each(tc::begin_next<tc::return_drop>(cont, nOffset), tc_fn(UNINITIALIZED));\n#else\n\t\t\t\t\t0;\n#endif\n\n\t\t\t\tauto const nNeededBufferSize = func(tc::ptr_begin(cont)+nOffset, tc::size(cont)-nOffset-nSentinel);\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\t\t\ttc::assert_uninitialized(tc::back(cont));\n#endif\n\n\t\t\t\tauto const nSize = nOffset + nNeededBufferSize;\n\t\t\t\tif (nSize+nSentinel <= tc::size(cont)) {\n\t\t\t\t\t_ASSERT(0 <= nSize);\n\t\t\t\t\ttc::take_first_inplace(cont, nSize);\n\t\t\t\t\tIF_TC_CHECKS(if (!tc::empty(cont)) _ASSERTINITIALIZED(tc::back(cont));)\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttc::take_first_inplace(cont, nOffset);\n\t\t\t\ttc::cont_reserve(cont, nSize+nSentinel); // The container must grow bigger, but let cont_reserve decide by how much\n\t\t\t}\n\t\t}\n\n\t\t/* Calls func(pBuffer, nBufferSize) with buffers of increasing size; func may read into\n\t\t[pBuffer, pBuffer+nBufferSize) and return nSize, which is either the correct size of the\n\t\tbuffer (if nSize <= nBufferSize) or an estimate otherwise. */\n\t\ttemplate<typename Cont, typename Func>\n\t\tCont get_buffer_allowing_nulls(Func&& func) MAYTHROW {\n\t\t\tstatic_assert(tc::decayed<Cont>);\n\n\t\t\t// sentinel to detect buffer overrun\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\t\ttypename no_adl::container_with_sentinel<Cont>::type\n#else\n\t\t\tCont\n#endif\n\t\t\t\tcont;\n\t\t\tif (0 == cont.capacity()) {\n\t\t\t\ttc::cont_reserve(cont, 8);\n\t\t\t}\n\n\t\t\tappend_buffer_allowing_nulls(cont, tc_move_if_owned(func));\n\t\t\tif constexpr (std::is_same<Cont, decltype(cont)>::value) {\n\t\t\t\treturn cont;\n\t\t\t} else {\n\t\t\t\ttc_return_cast( tc_move(cont) );\n\t\t\t}\n\t\t}\n\n\t\ttemplate<typename Cont, typename Func>\n\t\tCont get_truncating_buffer_allowing_nulls(Func func) noexcept {\n\t\t\treturn tc::get_buffer_detail::get_buffer_allowing_nulls<Cont>([&](auto pBuffer, auto const nBufferSize) noexcept {\n\t\t\t\tauto nSize = func(pBuffer, nBufferSize);\n\t\t\t\tif (nSize == nBufferSize) {\n\t\t\t\t\treturn nSize+1; // Any return value larger than nBufferSize causes a retry with a larger buffer\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERT(nSize < nBufferSize);\n\t\t\t\t\treturn nSize;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\t[[nodiscard]] Cont get_truncating_buffer(Func&& func) noexcept {\n\t\tauto cont=tc::get_buffer_detail::get_truncating_buffer_allowing_nulls<Cont>(tc_move_if_owned(func));\n\t\ttc::assert_no_null_terminator(cont);\n\t\treturn cont;\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\t[[nodiscard]] Cont get_truncating_null_terminated_buffer(Func&& func) noexcept {\n\t\tauto cont=tc::get_buffer_detail::get_truncating_buffer_allowing_nulls<Cont>(tc_move_if_owned(func));\n\t\ttc::remove_null_terminator(cont);\n\t\treturn cont;\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\t[[nodiscard]] Cont get_buffer(Func&& func) MAYTHROW {\n\t\tauto cont=tc::get_buffer_detail::get_buffer_allowing_nulls<Cont>(tc_move_if_owned(func)); // MAYTHROW\n\t\ttc::assert_no_null_terminator(cont);\n\t\treturn cont;\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\tvoid append_buffer(Cont& cont, Func&& func) MAYTHROW {\n\t\tIF_TC_CHECKS(auto const nOffset = tc::size(cont));\n\t\ttc::get_buffer_detail::append_buffer_allowing_nulls<Cont>(cont, tc_move_if_owned(func)); // MAYTHROW\n\t\tIF_TC_CHECKS(tc::assert_no_null_terminator(tc::begin_next<tc::return_drop>(cont, nOffset)));\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\t[[nodiscard]] Cont get_null_terminated_buffer(Func&& func) MAYTHROW {\n\t\tauto cont=tc::get_buffer_detail::get_buffer_allowing_nulls<Cont>(tc_move_if_owned(func)); // MAYTHROW\n\t\tstatic_assert( tc::char_type< tc::range_value_t<decltype((cont))> > );\n\t\ttc::remove_null_terminator(cont);\n\t\treturn cont;\n\t}\n\n\ttemplate<typename Cont, typename Func>\n\t[[nodiscard]] Cont get_buffer_may_be_null_terminated(Func&& func) MAYTHROW {\n\t\tauto cont = tc::get_buffer_detail::get_buffer_allowing_nulls<Cont>(tc_move_if_owned(func)); // MAYTHROW\n\t\tstatic_assert( tc::char_type< tc::range_value_t<decltype((cont))> > );\n\t\ttc::take_inplace(cont, tc::ends_with<tc::return_border_or_end>(cont, tc::single(tc::explicit_cast< tc::range_value_t<decltype((cont))> >('\\0'))));\n\t\ttc::assert_no_null_terminator(cont);\n\t\treturn cont;\n\t}\n\n\n\ttemplate<typename... MultiIndexArgs, typename K, typename... ValueTypeCtorArgs >\n\tstd::pair< tc::iterator_t<boost::multi_index::detail::hashed_index<MultiIndexArgs...>>, bool >\n\tmulti_index_try_emplace_with_key(boost::multi_index::detail::hashed_index<MultiIndexArgs...>& hashed_index, K const& key, ValueTypeCtorArgs&& ... valuetypectorargs) MAYTHROW\n\t{\n\t\tif(auto it = tc::cont_find<tc::return_element_or_null>(hashed_index, key)) {\n\t\t\treturn std::make_pair(tc_move(it), false);\n\t\t} else {\n\t\t\treturn hashed_index.emplace(tc_move_if_owned(valuetypectorargs)...); // MAYTHROW\n\t\t}\n\t}\n\n\ttemplate<typename... MultiIndexArgs, typename K, typename... ValueTypeCtorArgs >\n\tstd::pair< tc::iterator_t<boost::multi_index::detail::ordered_index<MultiIndexArgs...>>, bool >\n\tmulti_index_try_emplace_with_key(boost::multi_index::detail::ordered_index<MultiIndexArgs...>& ordered_index, K const& key, ValueTypeCtorArgs&& ... valuetypectorargs) MAYTHROW\n\t{\n\t\tauto it = ordered_index.lower_bound(key);\n\t\tif (tc::end(ordered_index)==it || ordered_index.key_comp()(key, ordered_index.key_extractor()(*it))) {\n\t\t\treturn std::make_pair(\n\t\t\t\ttc::cont_must_emplace_before(ordered_index, tc_move(it), tc_move_if_owned(valuetypectorargs)...), // MAYTHROW\n\t\t\t\ttrue\n\t\t\t);\n\t\t} else {\n\t\t\treturn std::make_pair(tc_move(it), false);\n\t\t}\n\t}\n\n\ttemplate<typename... MultiIndexArgs, typename K>\n\tstd::pair<tc::iterator_t<boost::multi_index::detail::hashed_index<MultiIndexArgs...>>, bool>\n\tmap_query_cache(boost::multi_index::detail::hashed_index<MultiIndexArgs...>& hashed_index, K&& key) MAYTHROW {\n\t\tif (auto it = tc::cont_find<tc::return_element_or_null>(hashed_index, tc::as_const(key))) {\n\t\t\treturn std::make_pair(tc_move(it), false);\n\t\t} else {\n\t\t\treturn hashed_index.emplace(tc_move_if_owned(key)); // MAYTHROW\n\t\t}\n\t}\n\n\ttemplate<typename Cont, typename Key>\n\tvoid cont_must_erase(Cont& cont, Key&& key) noexcept {\n\t\tVERIFYEQUAL( cont.erase(tc_move_if_owned(key)), 1u );\n\t}\n\n\ttemplate<typename Cont, typename Key>\n\tbool cont_try_erase(Cont& cont, Key&& key) noexcept {\n\t\tswitch_no_default(cont.erase(tc_move_if_owned(key))) {\n\t\t\tcase 0: return false;\n\t\t\tcase 1: return true;\n\t\t};\n\t}\n\n\ttemplate< typename Cont, typename SubRng >\n\tvoid cont_erase_range(Cont& cont, SubRng const& rng) noexcept {\n\t\tcont.erase(tc::begin(rng), tc::end(rng));\n\t}\n\n\t/////////////////////////////////////////////////////\n\t// remove_count_erase\n\n\ttemplate<typename Cont, typename Pred>\n\t[[nodiscard]] \n\ttypename tc::size_proxy< typename boost::range_size<Cont>::type > remove_count_erase_if(Cont& cont, Pred pred) noexcept {\n\t\ttypename boost::range_size<Cont>::type count=0;\n\t\ttc::filter_inplace( cont, [&]( auto&& t ) noexcept ->bool {\n\t\t\tbool const b=tc_invoke(pred, tc_move_if_owned(t));\n\t\t\tcount += (b ? 1 : 0);\n\t\t\treturn !b;\n\t\t} );\n\t\treturn tc::size_proxy< typename boost::range_size<Cont>::type >(count);\n\t}\n\n\ttemplate<typename Cont, typename T>\n\t[[nodiscard]] \n\ttypename tc::size_proxy< typename boost::range_size<Cont>::type > remove_count_erase(Cont& cont, T const& t) noexcept {\n\t\treturn remove_count_erase_if( cont, [&](auto const& _) noexcept { return tc::equal_to(_, t); } );\n\t}\n\n\t/////////////////////////////////////////////////////\n\t// reverse_inplace\n\t// inplace algorithms should accept only lvalue containers, but reverse_inplace is called with\n\t// subranges of containers, so it must accept rvalues.\n\n\ttemplate<typename Rng>\n\tconstexpr void reverse_inplace(Rng&& rng) noexcept {\n\t\tif constexpr( has_mem_fn_reverse<std::remove_reference_t<Rng>> ) {\n\t\t\trng.reverse();\n\t\t} else {\n\t\t\tstd::reverse(tc::begin(rng), tc::end(rng));\n\t\t}\n\t}\n\n\ttemplate<typename Rng, typename Less>\n\t[[nodiscard]] auto ordered_unique(Rng&& rng, Less less) noexcept code_return_decltype (\n\t\t_ASSERTDEBUG( tc::is_sorted( rng, less ) );,\n\t\ttc::adjacent_unique( tc_move_if_owned(rng), std::not_fn( tc_move(less) ) )\n\t)\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] auto ordered_unique(Rng&& rng) return_decltype_noexcept(\n\t\ttc::ordered_unique( tc_move_if_owned(rng), tc::fn_less() )\n\t)\n\n\ttemplate<typename Rng, typename Less = tc::fn_less>\n\t[[nodiscard]] auto sort_inplace_unique(Rng&& rng, Less less = Less()) noexcept code_return_decltype(\n\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\ttc::sort_inplace( rng, less );,\n\t\ttc::ordered_unique( tc_move_if_owned(rng), tc_move(less) )\n\t)\n\n\ttemplate<typename Rng, typename Less>\n\t[[nodiscard]] auto sort_unique(Rng&& rng, Less less) return_decltype_noexcept(\n\t\ttc::ordered_unique(tc::sort(tc_move_if_owned(rng), less), less)\n\t)\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] auto sort_unique(Rng&& rng) return_decltype_noexcept(\n\t\tsort_unique(tc_move_if_owned(rng), tc::fn_less())\n\t)\n\n\ttemplate<typename Rng, typename Less=tc::fn_less>\n\t[[nodiscard]] constexpr auto constexpr_sort_unique(Rng&& rng, Less&& less=Less()) noexcept {\n\t\treturn tc_modified(\n\t\t\ttc::make_static_vector<tc::constexpr_size<Rng>()>(tc_move_if_owned(rng)),\n\t\t\ttc::sort_unique_inplace(_, tc_move_if_owned(less))\n\t\t);\n\t}\n\n\tnamespace find_first_or_unique_adl {\n\t\ttemplate< typename RangeReturn, IF_TC_CHECKS(bool c_bCheckUnique,) typename T, T... t, typename U >\n\t\t[[nodiscard]] constexpr decltype(auto) find_first_or_unique_impl(adl_tag_t, IF_TC_CHECKS(tc::constant<c_bCheckUnique>,) std::integer_sequence<T, t...>, U const& u) noexcept {\n#ifdef _CHECKS\n\t\t\tif constexpr (c_bCheckUnique) {\n\t\t\t\t// This assert is stronger than the usual find_unique precondition, which allows duplicates as long as they are not searched for.\n\t\t\t\tstatic_assert( tc::is_strictly_sorted(tc::constexpr_sort(tc::make_array(tc::aggregate_tag, t...))) );\n\t\t\t}\n#endif\n\t\t\treturn ((tc::equal_to(t, u)) || ...);\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename SetType, typename T, typename Less >\n\tvoid binary_find_unique(tc::unordered_set<SetType> const& rng, T const& t, Less less) noexcept = delete;\n\n\tnamespace binary_find_first_or_unique_adl {\n\t\ttemplate< typename RangeReturn, bool c_bAssertUniqueness, typename Rng, typename T, typename Pred >\n\t\t[[nodiscard]] decltype(auto) binary_find_first_or_unique(Rng&& rng, T const& t, Pred predLessOr3way) noexcept {\n\t\t\t// The result of tc::binary_find_unique must be unambiguous. In general, this means that rng is strictly\n\t\t\t// ordered. In some cases, it is convenient to allow multiple occurrences of the same item in\n\t\t\t// rng, which is not a problem as long as these items are not searched for.\n\n\t\t\t// preserve order of arguments for 3way predicates\n\t\t\tauto const c_b3way = tc::is_comparison_category<decltype(predLessOr3way(tc::front(rng), t))>; // tc_static_auto_constexpr_capture causes ICE\n\t\t\tauto it=[&]() noexcept {\n\t\t\t\tif constexpr(c_b3way) {\n\t\t\t\t\t_ASSERTDEBUG( tc::is_sorted(rng, tc::lessfrom3way(std::ref(predLessOr3way))) );\n\t\t\t\t\treturn tc::lower_bound<tc::return_border>( rng, t, tc::lessfrom3way(std::ref(predLessOr3way)) );\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERTDEBUG( tc::is_sorted(rng, predLessOr3way) );\n\t\t\t\t\treturn tc::lower_bound<tc::return_border>( rng, t, std::ref(predLessOr3way) );\n\t\t\t\t}\n\t\t\t}();\n\t\t\tif( it==tc::end( rng ) ) {\n\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t\t} else {\n\t\t\t\tauto const Greater = [&](auto const& elem) noexcept {\n\t\t\t\t\tif constexpr(c_b3way) {\n\t\t\t\t\t\treturn std::is_gt(predLessOr3way(elem, t));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn predLessOr3way(t, elem);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tauto && ref=*it;\n\t\t\t\tif (Greater(tc::as_const(ref))) {\n\t\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t\t\t} else {\n#ifdef _CHECKS\n\t\t\t\t\tif constexpr(c_bAssertUniqueness) {\n\t\t\t\t\t\tauto itNext = tc_modified(it, ++_);\n\t\t\t\t\t\t_ASSERT( tc::end(rng)==itNext || Greater(tc::as_const(*itNext)));\n\t\t\t\t\t}\n#endif\n\t\t\t\t\treturn RangeReturn::pack_element(it,tc_move_if_owned(rng),tc_move_if_owned(ref));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\ttemplate< typename RangeReturn, typename Rng, typename T, typename Pred >\n\t[[nodiscard]] decltype(auto) binary_find_unique(Rng&& rng, T const& t, Pred predLessOr3way) noexcept {\n\t\treturn binary_find_first_or_unique_adl::binary_find_first_or_unique<RangeReturn, /*c_bAssertUniqueness*/ true>(tc_move_if_owned(rng), t, tc_move(predLessOr3way));\n\t}\n\t\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] decltype(auto) binary_find_unique(Rng&& rng, T const& t) noexcept {\n\t\treturn tc::binary_find_unique<RangeReturn>( tc_move_if_owned(rng), t, tc::fn_less() );\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T, typename Pred >\n\t[[nodiscard]] decltype(auto) binary_find_first(Rng&& rng, T const& t, Pred predLessOr3way) noexcept {\n\t\treturn binary_find_first_or_unique_adl::binary_find_first_or_unique<RangeReturn, /*c_bAssertUniqueness*/ false>(tc_move_if_owned(rng), t, tc_move(predLessOr3way));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] decltype(auto) binary_find_first(Rng&& rng, T const& t) noexcept {\n\t\treturn tc::binary_find_first<RangeReturn>( tc_move_if_owned(rng), t, tc::fn_less() );\n\t}\n\n\t// would be cleaner to search on the distance metric (starting with lower_bound(rng,0)),\n\t// but subtraction may cause unnecessary overflows\n\ttemplate< typename Rng, typename T >\n\t[[nodiscard]] auto binary_closest(Rng&& rng, T const& t) noexcept {\n\t\tauto it = tc::lower_bound<tc::return_border>(rng, t);\n\t\tif( tc::begin(rng)==it ) {\n\t\t\treturn it;\n\t\t} else if( tc::end(rng)==it ) {\n\t\t\treturn tc_modified(it, --_);\n\t\t} else {\n\t\t\tauto itPrior = tc_modified(it, --_);\n\t\t\treturn (t - *itPrior) < (*it - t) ? itPrior : it;\n\t\t}\n\t}\n\n\ttemplate< typename RngA, typename RngB, typename Comp, typename FuncElementA, typename FuncElementB, typename FuncElementBoth > \n\tauto interleave_may_remove_current_iterator(RngA&& rngA, RngB&& rngB, Comp comp, FuncElementA fnElementA, FuncElementB fnElementB, FuncElementBoth fnElementBoth) noexcept -> tc::common_type_t<\n\t\tdecltype(tc::continue_if_not_break(fnElementA, tc::begin(rngA), tc::begin(rngB))),\n\t\tdecltype(tc::continue_if_not_break(fnElementB, tc::begin(rngA), tc::begin(rngB))),\n\t\tdecltype(tc::continue_if_not_break(fnElementBoth, tc::begin(rngA), tc::begin(rngB)))\n\t> {\n\t\tauto itA=tc::begin(rngA);\n\t\tauto itEndA=tc::end(rngA);\n\t\tauto itB=tc::begin(rngB);\n\t\tauto itEndB=tc::end(rngB);\n\t\tif( itA==itEndA ) goto endA;\n\t\tif( itB==itEndB ) goto endB;\n\t\tfor(;;) {\n\t\t\tif(tc_auto_cref(order, comp( tc::as_const(*itA), tc::as_const(*itB) )); std::is_lt(order)) {\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(fnElementA, itA++, itB))\n\t\t\t\tif( itA==itEndA ) goto endA;\n\t\t\t} else if(tc::is_eq(order)) {\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(fnElementBoth, itA++, itB++))\n\t\t\t\tif( itA==itEndA ) goto endA;\n\t\t\t\tif( itB==itEndB ) goto endB;\n\t\t\t} else {\n\t\t\t\t_ASSERTDEBUG(std::is_gt(order));\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(fnElementB, itA, itB++))\n\t\t\t\tif( itB==itEndB ) goto endB;\n\t\t\t}\n\t\t}\n\tendB:\n\t\twhile (itA != itEndA) tc_return_if_break(tc::continue_if_not_break(fnElementA, itA++, itEndB))\n\t\ttc_return_cast(tc::continue_);\n\tendA:\n\t\twhile(itB != itEndB) tc_return_if_break(tc::continue_if_not_break(fnElementB, itEndA, itB++))\n\t\ttc_return_cast(tc::continue_);\n\t}\n\n\ttemplate< typename RngA, typename RngB, typename Comp, typename FuncElementA, typename FuncElementB, typename FuncElementBoth >\n\tauto interleave_may_remove_current(RngA&& rngA, RngB&& rngB, Comp comp, FuncElementA fnElementA, FuncElementB fnElementB, FuncElementBoth fnElementBoth) noexcept {\n\t\treturn interleave_may_remove_current_iterator(rngA, rngB, comp,\n\t\t\t[&](auto const& lhs, tc::unused /*rhs*/) noexcept { return tc_invoke(fnElementA, *lhs); },\n\t\t\t[&](tc::unused /*lhs*/, auto const& rhs) noexcept { return tc_invoke(fnElementB, *rhs); },\n\t\t\t[&](auto const& lhs, auto const& rhs) noexcept { return tc_invoke(fnElementBoth, *lhs, *rhs); }\n\t\t);\n\t}\n\n\tnamespace interleave_2_detail {\n\t\tDEFINE_TAG_TYPE(lhs_tag)\n\t\tDEFINE_TAG_TYPE(rhs_tag)\n\t\tDEFINE_TAG_TYPE(lhsrhs_tag)\n\n\t\tnamespace no_adl {\n\t\t\t// MSVC (from 15.8 to 17.0.2) sometimes crashes when this is inlined as a lambda in interleave_2.\n\t\t\ttemplate<typename RngRhs, typename Comp, typename Sink>\n\t\t\tstruct interleave_2_sink {\n\t\t\t\ttc::iterator_t<RngRhs>& m_itrhs;\n\t\t\t\ttc::sentinel_t<RngRhs> const& m_endrhs;\n\t\t\t\tComp const m_comp;\n\t\t\t\tSink const& m_sink;\n\n\t\t\t\ttemplate<typename Lhs>\n\t\t\t\tconstexpr auto operator()(Lhs&& lhs) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\t\tdecltype(tc::continue_if_not_break(m_sink, lhs_tag, std::declval<Lhs>())),\n\t\t\t\t\tdecltype(tc::continue_if_not_break(m_sink, rhs_tag, *m_itrhs)),\n\t\t\t\t\tdecltype(tc::continue_if_not_break(m_sink, lhsrhs_tag, std::declval<Lhs>(), *m_itrhs)),\n\t\t\t\t\ttc::constant<tc::continue_>\n\t\t\t\t> {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tif( m_itrhs == m_endrhs ) {\n\t\t\t\t\t\t\treturn tc::continue_if_not_break(m_sink, lhs_tag, tc_move_if_owned(lhs));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdecltype(auto) rhs = *m_itrhs;\n\t\t\t\t\t\t\tif(auto const order=tc_invoke(m_comp, tc::as_const(lhs), tc::as_const(rhs) ); std::is_lt(order)) {\n\t\t\t\t\t\t\t\treturn tc::continue_if_not_break(m_sink, lhs_tag, tc_move_if_owned(lhs));\n\t\t\t\t\t\t\t} else if (std::is_gt(order)) {\n\t\t\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(m_sink, rhs_tag, tc_move_if_owned(rhs)))\n\t\t\t\t\t\t\t\t++m_itrhs;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(m_sink, lhsrhs_tag, tc_move_if_owned(lhs), tc_move_if_owned(rhs)))\n\t\t\t\t\t\t\t\t++m_itrhs;\n\t\t\t\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate<typename SinkLhs, typename SinkRhs, typename SinkLhsRhs>\n\t\t\tstruct SDemultiplexByTagSink { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\t\tSinkLhs const m_sinklhs;\n\t\t\t\tSinkRhs const m_sinkrhs;\n\t\t\t\tSinkLhsRhs const m_sinklhsrhs;\n\t\t\t\ttemplate<typename... Args>\n\t\t\t\tconstexpr auto operator()(lhs_tag_t, Args&&... args) const& return_decltype_MAYTHROW( m_sinklhs(tc_move_if_owned(args)...) )\n\t\t\t\ttemplate<typename... Args>\n\t\t\t\tconstexpr auto operator()(rhs_tag_t, Args&&... args) const& return_decltype_MAYTHROW( m_sinkrhs(tc_move_if_owned(args)...) )\n\t\t\t\ttemplate<typename... Args>\n\t\t\t\tconstexpr auto operator()(lhsrhs_tag_t, Args&&... args) const& return_decltype_MAYTHROW( m_sinklhsrhs(tc_move_if_owned(args)...) )\n\t\t\t};\n\n\t\t\ttemplate<typename Sink>\n\t\t\tstruct SExchangedRangeSink { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\t\tSink const m_sink;\n\t\t\t\ttemplate<typename Rhs>\n\t\t\t\tconstexpr auto operator()(lhs_tag_t, Rhs&& rhs) const& return_decltype_MAYTHROW( tc_invoke(m_sink, rhs_tag, tc_move_if_owned(rhs)) )\n\t\t\t\ttemplate<typename Lhs>\n\t\t\t\tconstexpr auto operator()(rhs_tag_t, Lhs&& lhs) const& return_decltype_MAYTHROW( tc_invoke(m_sink, lhs_tag, tc_move_if_owned(lhs)) )\n\t\t\t\ttemplate<typename Rhs, typename Lhs>\n\t\t\t\tconstexpr auto operator()(lhsrhs_tag_t, Rhs&& rhs, Lhs&& lhs) const& return_decltype_MAYTHROW( tc_invoke(m_sink, lhsrhs_tag, tc_move_if_owned(lhs), tc_move_if_owned(rhs)) )\n\t\t\t};\n\n\t\t\ttemplate<typename Comp>\n\t\t\tstruct SExchangedRangeComp { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\t\tComp const m_comp;\n\t\t\t\tconstexpr auto operator()(auto const& rhs, auto const& lhs) const& MAYTHROW {\n\t\t\t\t\treturn tc::negate(tc_invoke(m_comp, lhs, rhs));\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\ttemplate< typename RngLhs, tc::range_with_iterators RngRhs, typename Comp, typename Sink>\n\t\t\trequires tc::prefers_for_each<RngLhs> || (!tc::prefers_for_each<RngRhs>)\n\t\tconstexpr auto internal_interleave_2(RngLhs&& rnglhs, RngRhs&& rngrhs, Comp&& comp, Sink const sink) MAYTHROW {\n\t\t\tauto itrhs=tc::begin(rngrhs);\n\t\t\tauto endrhs=tc::end(rngrhs);\n\n\t\t\ttc_return_if_break(tc::for_each(\n\t\t\t\trnglhs,\n\t\t\t\tno_adl::interleave_2_sink<RngRhs, decay_t<Comp>, Sink>{itrhs, endrhs, tc_move_if_owned(comp), sink}\n\t\t\t));\n\n\t\t\twhile (itrhs != endrhs) {\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, rhs_tag, *itrhs))\n\t\t\t\t++itrhs;\n\t\t\t}\n\t\t\treturn tc::implicit_cast<decltype(tc::for_each(rnglhs,\n\t\t\t\tstd::declval<no_adl::interleave_2_sink<RngRhs, tc::decay_t<Comp>, Sink>>()\n\t\t\t))>(tc::constant<tc::continue_>());\n\t\t}\n\n\t\ttemplate< tc::range_with_iterators RngLhs, tc::prefers_for_each RngRhs, typename Comp, typename Sink>\n\t\t\trequires (!tc::prefers_for_each<RngLhs>)\n\t\tconstexpr auto internal_interleave_2(RngLhs&& rnglhs, RngRhs&& rngrhs, Comp&& comp, Sink&& sink) MAYTHROW {\n\t\t\treturn interleave_2_detail::internal_interleave_2(\n\t\t\t\ttc_move_if_owned(rngrhs),\n\t\t\t\ttc_move_if_owned(rnglhs),\n\t\t\t\tno_adl::SExchangedRangeComp<tc::decay_t<Comp>>{tc_move_if_owned(comp)},\n\t\t\t\tno_adl::SExchangedRangeSink<tc::decay_t<Sink>>{tc_move_if_owned(sink)}\n\t\t\t);\n\t\t}\n\t}\n\n\ttemplate<typename SinkLhs, typename SinkRhs, typename SinkLhsRhs>\n\tconstexpr auto interleave_2(auto&& rnglhs, auto&& rngrhs, auto&& comp, SinkLhs&& sinklhs, SinkRhs&& sinkrhs, SinkLhsRhs&& sinklhsrhs) MAYTHROW  {\n\t\treturn interleave_2_detail::internal_interleave_2(\n\t\t\ttc_move_if_owned(rnglhs),\n\t\t\ttc_move_if_owned(rngrhs),\n\t\t\ttc_move_if_owned(comp),\n\t\t\tinterleave_2_detail::no_adl::SDemultiplexByTagSink<tc::decay_t<SinkLhs>, tc::decay_t<SinkRhs>, tc::decay_t<SinkLhsRhs>>{\n\t\t\t\ttc_move_if_owned(sinklhs),\n\t\t\t\ttc_move_if_owned(sinkrhs),\n\t\t\t\ttc_move_if_owned(sinklhsrhs)\n\t\t\t}\n\t\t);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Compare>\n\t\tstruct SInterleaveImpl {\n\t\t\ttc::decay_t<Compare> m_compare;\n\n\t\t\tbool HasBetterElement(bool* const, tc::unused) const& noexcept {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttemplate<\n\t\t\t\ttypename PairItItBest,\n\t\t\t\ttypename PairItIt0,\n\t\t\t\ttypename... Args\n\t\t\t>\n\t\t\tbool HasBetterElement(bool* const itb, PairItItBest const& argBest, PairItIt0 const& pairitit0, Args const&... args) const& noexcept {\n\t\t\t\tif (pairitit0.first != pairitit0.second) {\n\t\t\t\t\tif(tc_auto_cref(order, m_compare(tc::as_const(*argBest.first), tc::as_const(*pairitit0.first))); std::is_lt(order)) {\n\t\t\t\t\t\t*itb = false;\n\t\t\t\t\t\treturn HasBetterElement(tc_modified(itb, ++_), argBest, args...);\n\t\t\t\t\t} else if(tc::is_eq(order)) {\n\t\t\t\t\t\tbool b = HasBetterElement(tc_modified(itb, ++_), argBest, args...);\n\t\t\t\t\t\t*itb = !b;\n\t\t\t\t\t\treturn b;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERTDEBUG(std::is_gt(order));\n\t\t\t\t\t\t*itb = !HasBetterElement(tc_modified(itb, ++_), pairitit0, args...);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t*itb = false;\n\t\t\t\t\treturn HasBetterElement(tc_modified(itb, ++_), argBest, args...);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool FindBest(bool* const) const& {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttemplate<\n\t\t\t\ttypename PairItIt0,\n\t\t\t\ttypename... Args\n\t\t\t>\n\t\t\tbool FindBest(bool* const itb, PairItIt0 const& pairitit0, Args const&... args) const& {\n\t\t\t\tif (pairitit0.first != pairitit0.second) {\n\t\t\t\t\t*itb = !HasBetterElement(tc_modified(itb, ++_), pairitit0, args...);\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\t*itb = false;\n\t\t\t\t\treturn FindBest(tc_modified(itb, ++_), args...);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSInterleaveImpl(Compare&& compare) noexcept\n\t\t\t\t: m_compare(tc_move_if_owned(compare))\n\t\t\t{}\n\n\t\t\ttemplate<\n\t\t\t\ttypename Func,\n\t\t\t\tstd::size_t... I,\n\t\t\t\ttypename... PairItIt\n\t\t\t>\n\t\t\ttc::break_or_continue operator()(Func func, std::index_sequence<I...>, PairItIt... pairitit) const noexcept {\n\t\t\t\tbool ab[sizeof...(PairItIt)];\n\n\t\t\t\twhile (FindBest(tc::begin(ab), pairitit...)) {\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(func, std::make_pair(pairitit.first, tc::at(ab, I))...  ));\n\n\t\t\t\t\t([](auto& it, bool const b) noexcept {if (b) ++it;}(pairitit.first, tc::at(ab,I)), ...);\n\t\t\t\t}\n\t\t\t\treturn tc::continue_;\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<\n\t\ttypename Compare,\n\t\ttypename Func,\n\t\ttypename... Rng\n\t>\n\ttc::break_or_continue interleave_n(Compare&& compare, Func&& func, Rng&&... rng) noexcept {\n\t\treturn no_adl::SInterleaveImpl<Compare>(tc_move_if_owned(compare))(\n\t\t\ttc_move_if_owned(func),\n\t\t\tstd::index_sequence_for<Rng...>(),\n\t\t\tstd::make_pair(\n\t\t\t\ttc::begin(rng),\n\t\t\t\ttc::end(rng)\n\t\t\t)...\n\t\t);\n\t}\n\n\ttemplate <typename RngRng>\n\t[[nodiscard]] auto common_prefix(RngRng&& rngrng) noexcept {\n\t\tauto&& rngFront = tc::front(rngrng);\n\t\treturn tc::accumulate(\n\t\t\ttc::begin_next<tc::return_drop>(rngrng),\n\t\t\ttc::take(tc_move_if_owned(rngFront), tc::end(rngFront)),\n\t\t\t[&](auto& rngResult, auto const& rng) noexcept {\n\t\t\t\ttc::take_inplace(rngResult, boost::mismatch(rngResult, rng).first);\n\t\t\t}\n\t\t);\n\t}\n\n\ttemplate< typename T, typename Rng >\n\t[[nodiscard]] auto make_variant_range_filter(Rng&& rng) noexcept {\n\t\treturn tc::transform( \n\t\t\ttc::filter( \n\t\t\t\ttc_move_if_owned(rng), \n\t\t\t\ttc_fn(std::holds_alternative<T>)\n\t\t\t),\n\t\t\ttc_fn(tc::get<T>)\n\t\t);\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T> requires (!RangeReturn::requires_iterator)\n\t[[nodiscard]] constexpr decltype(auto) linear_at(Rng&& rng, T n) noexcept {\n\t\treturn tc::find_first_if<RangeReturn>(tc_move_if_owned(rng), [&](tc::unused) noexcept {\n\t\t\tif(0==n) {\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\t--n;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t}\n\n\t// Create an infinite range by repeatedly applying funcIterate to t\n\ttemplate <typename T, typename FuncIterate>\n\tauto iterate(T&& t, FuncIterate&& funcIterate) noexcept {\n\t\treturn tc::generator_range_output<tc::decay_t<T> const&>([funcIterate=tc::make_reference_or_value(tc_move_if_owned(funcIterate)),t_=tc::make_reference_or_value(tc_move_if_owned(t))](auto func) noexcept {\n\t\t\tauto t = *t_;\n\t\t\ttc_return_if_break(tc::continue_if_not_break(func,tc::as_const(t)))\n\t\t\tfor (;;) {\n\t\t\t\ttc_invoke(*funcIterate, t);\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(func,tc::as_const(t)))\n\t\t\t}\n\t\t});\n\t}\n\n\ttemplate<typename RngSep, typename... Rngs>\n\tdecltype(auto) concat_nonempty_with_separator(RngSep&& rngSep, Rngs&&... rngs) noexcept {\n\t\treturn tc::join_with_separator(\n\t\t\ttc_move_if_owned(rngSep),\n\t\t\ttc::filter(tc::make_range(tc_move_if_owned(rngs)...), std::not_fn(tc_fn(tc::empty)))\n\t\t);\n\t}\n\n\ttemplate<typename RngSep, typename Rng0, typename... Rngs>\n\tdecltype(auto) concat_with_separator(RngSep&& rngSep, Rng0&& rng0, Rngs&&... rngs) noexcept {\n\t\treturn tc::concat(tc_move_if_owned(rng0), tc::concat(/*copy if needed*/tc::implicit_cast<RngSep>(rngSep), tc_move_if_owned(rngs))...);\n\t}\n\n\ttemplate<typename Rng, typename Val>\n\tvoid fill(Rng&& rng, Val const& value) noexcept {\n\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&& element) noexcept {\n\t\t\ttc_move_if_owned(element) = value;\n\t\t});\n\t}\n\n}\n"
  },
  {
    "path": "tc/algorithm/algorithm.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../container/container.h\" // tc::vector\n#include \"../unittest.h\"\n#include \"../range/concat_adaptor.h\"\n#include \"../range/join_adaptor.h\"\n#include \"../range/repeat_n.h\"\n#include \"../string/spirit_algorithm.h\"\n#include \"interleave_ranges.h\"\n\n#include <random>\n\nnamespace {\n\t[[maybe_unused]] void static_tests() noexcept {\n\t\t// explicit_cast with explicit move constructor\n\t\tstruct SMove { explicit SMove(tc::vector<int>&&) noexcept {} };\n\t\tvoid(tc::explicit_cast<SMove>(tc::vector<int>{}));\n\n\t\t// explicit_cast with explicit constructor\n\t\tstruct SCopy { explicit SCopy(tc::vector<int>) noexcept {} };\n\t\tvoid(tc::explicit_cast<SCopy>(tc::vector<int>{}));\n\t}\n\nUNITTESTDEF( sort_accumulate_each_unique_range_2 ) {\n\tstruct SValAccu final {\n\t\tSValAccu(int val, int accu) noexcept : m_val(val), m_accu(accu) {}\n\t\tint m_val;\n\t\tint m_accu;\n\t};\n\t{\n\t\ttc::vector< SValAccu > vec;\n\t\tfor( int i=0; i < 5; ++i ) {\n\t\t\ttc::cont_emplace_back( vec, 1, 1 );\n\t\t}\n\t\ttc::sort_accumulate_each_unique_range(\n\t\t\tvec,\n\t\t\t[](SValAccu const& lhs, SValAccu const& rhs) noexcept { return lhs.m_val < rhs.m_val; },\n\t\t\t[](SValAccu& lhs, SValAccu const& rhs) noexcept { lhs.m_accu+=rhs.m_accu; }\n\t\t);\n\t\tTEST_EQUAL( 1, vec.size() );\n\t\tTEST_EQUAL( 1, tc::front(vec).m_val );\n\t\tTEST_EQUAL( 5, tc::front(vec).m_accu );\n\t}\n}\n\nUNITTESTDEF(filter_no_self_assignment_of_rvalues) {\n\tstruct S {\n\t\tS() {}\n\n\t\tS(S const&){}\n\n\t\tS& operator=(S&& other) {\n\t\t\t_ASSERT(&other != this);\n\t\t\treturn *this;\n\t\t}\n\t};\n\n\ttc::vector<S> vs{5,S{}};\n\ttc::sort_accumulate_each_unique_range(\n\t\tvs,\n\t\t[&](tc::unused, tc::unused) noexcept {\n\t\t\treturn false;\n\t\t},\n\t\t[&](auto&, tc::unused) noexcept {\n\t\t}\n\t);\n}\n\nUNITTESTDEF( trim_leftright_if ) {\n\ttc::vector<int> v{1,2,3,4,5,6,7,7,7};\n\n\tdecltype(auto) left = tc::trim_left_if<tc::return_drop>(v, [] (int const n) noexcept {return n<4;});\n\tSTATICASSERTSAME(decltype(left), tc::iterator_range_t<tc::vector<int>&>);\n\tTEST_RANGE_EQUAL(left, (tc::literal_range_of<4, 5, 6, 7, 7, 7>));\n\n\tdecltype(auto) left_then_right = tc::trim_right_if<tc::return_take>(tc_move(left), [] (int const n) noexcept {return n==7;});\n\tSTATICASSERTSAME(decltype(left_then_right), tc::iterator_range_t<tc::vector<int>&>&&);\n\tTEST_RANGE_EQUAL(left_then_right, (tc::literal_range_of<4, 5, 6>));\n\n\tdecltype(auto) both = tc::trim_if(v, [](int const n) { return n < 4 || n == 7; });\n\tSTATICASSERTSAME(decltype(both), tc::iterator_range_t<tc::vector<int>&>);\n\tTEST_RANGE_EQUAL(both, (tc::literal_range_of<4, 5, 6>));\n\n\tdecltype(auto) both_prvalue = tc::trim_if(tc::decay_copy(v), [](int const n) { return n < 4 || n == 7; });\n\tSTATICASSERTSAME(decltype(both_prvalue), tc::slice_t<tc::vector<int>>);\n\tTEST_RANGE_EQUAL(both_prvalue, (tc::literal_range_of<4, 5, 6>));\n}\n\nUNITTESTDEF( is_sorted ) {\n\t{\n\t\tint a[]={0};\n\t\t_ASSERT( tc::is_sorted(a) );\n\t}\n\t{\n\t\tint a[]={0,0};\n\t\t_ASSERT( tc::is_sorted(a) );\n\t}\n\t{\n\t\tint a[]={0,1};\n\t\t_ASSERT( tc::is_sorted(a) );\n\t}\n\t{\n\t\tint a[]={1,0};\n\t\t_ASSERT( !tc::is_sorted(a) );\n\t}\n\t{\n\t\tint a[]={0};\n\t\t_ASSERT( tc::is_strictly_sorted(a) );\n\t}\n\t{\n\t\tint a[]={0,0};\n\t\t_ASSERT( !tc::is_strictly_sorted(a) );\n\t}\n\t{\n\t\tint a[]={0,1};\n\t\t_ASSERT( tc::is_strictly_sorted(a) );\n\t}\n\t{\n\t\tint a[]={1,0};\n\t\t_ASSERT( !tc::is_strictly_sorted(a) );\n\t}\n}\n\nUNITTESTDEF( make_vector_on_r_vector_is_identity ) {\n\ttc::vector<int> v{1,2,3};\n\tauto pvecdata = tc::ptr_begin(v);\n\n\tauto vNew = tc::make_vector(tc_move(v));\n\t_ASSERTEQUAL(tc::ptr_begin(vNew), pvecdata);\n}\n\nUNITTESTDEF(is_strictly_sorted){\n\tint an[]={0,1,2,3,4,5};\n\t_ASSERT(tc::is_strictly_sorted(an));\n\t_ASSERT(!tc::is_strictly_sorted(tc::reverse(an)));\n}\n\nUNITTESTDEF(remove_inplace_parser) {\n\ttc::string<char> input = \"0123<font>4567<font10><font11><font12>89<font14><font\";\n\ttc::remove_inplace(input, tc::lit(tc_ascii(\"<font\")) > *(tc::one<char> - tc::lit(tc_ascii(\">\"))) > tc::lit(tc_ascii(\">\")));\n\t_ASSERTEQUAL(input, \"0123456789<font\");\n}\n\nUNITTESTDEF(Naryinterleave) {\n\ttc::vector<int> const vecnA({3,4,7,9});\n\ttc::vector<int> vecnB({2,4,8,9,11,17});\n\tauto const vecnBCopy = vecnB;\n\ttc::vector<int> const vecnC({-100,1000});\n\n\ttc::vector<int> vecnResult = tc::make_vector(vecnA, vecnB, vecnC);\n\ttc::sort_inplace(vecnResult);\n\tauto itResult = tc::begin(vecnResult);\n\n\t_ASSERTEQUAL(\n\t\ttc::continue_,\n\t\ttc::interleave_n(\n\t\t\ttc::fn_compare(),\n\t\t\t[&](auto const&... pairitb) noexcept {\n\t\t\t\tauto tplpairitb = tc::tie(pairitb...);\n\t\t\t\tif (tc::get<0>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult,*tc::get<0>(tplpairitb).first);\n\t\t\t\t\t++itResult;\n\t\t\t\t}\n\t\t\t\tif (tc::get<1>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult,*tc::get<1>(tplpairitb).first);\n\t\t\t\t\t*tc::get<1>(tplpairitb).first += 100;\n\t\t\t\t\t++itResult;\n\t\t\t\t}\n\t\t\t\tif (tc::get<2>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult,*tc::get<2>(tplpairitb).first);\n\t\t\t\t\t++itResult;\n\t\t\t\t}\n\t\t\t},\n\t\t\tvecnA, vecnB, vecnC\n\t\t)\n\t);\n\n\t_ASSERT(tc::equal(\n\t\ttc::transform(vecnBCopy, [](int const n) noexcept {return n+100;}),\n\t\tvecnB\n\t));\n}\n\nUNITTESTDEF(NaryinterleaveBreak) {\n\ttc::vector<int> const vecnA({ 3,4,7,9 });\n\ttc::vector<int> vecnB({ 2,4,8,9,11,17 });\n\tauto const vecnBCopy = vecnB;\n\ttc::vector<int> const vecnC({ -100,1000 });\n\n\ttc::vector<int> vecnResult = tc::make_vector(vecnA, vecnB, vecnC);\n\ttc::sort_inplace(vecnResult);\n\tauto itResult = tc::begin(vecnResult);\n\n\t_ASSERTEQUAL(\n\t\ttc::break_,\n\t\ttc::interleave_n(\n\t\t\ttc::fn_compare(),\n\t\t\t[&](auto const&... pairitb) noexcept {\n\t\t\t\tauto tplpairitb = tc::tie(pairitb...);\n\t\t\t\tif (tc::get<0>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult, *tc::get<0>(tplpairitb).first);\n\t\t\t\t\t++itResult;\n\t\t\t\t\tif (7 == *tc::get<0>(tplpairitb).first) return tc::break_;\n\t\t\t\t}\n\t\t\t\tif (tc::get<1>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult, *tc::get<1>(tplpairitb).first);\n\t\t\t\t\t*tc::get<1>(tplpairitb).first += 100;\n\t\t\t\t\t++itResult;\n\t\t\t\t}\n\t\t\t\tif (tc::get<2>(tplpairitb).second) {\n\t\t\t\t\t_ASSERTEQUAL(*itResult, *tc::get<2>(tplpairitb).first);\n\t\t\t\t\t++itResult;\n\t\t\t\t}\n\t\t\t\treturn tc::continue_;\n\t\t\t},\n\t\t\tvecnA, vecnB, vecnC\n\t\t)\n\t);\n\n\t_ASSERT(tc::equal(\n\t\ttc::transform(vecnBCopy, [](int const n) noexcept {return n < 7 ? n + 100 : n; }),\n\t\tvecnB\n\t));\n}\n\nUNITTESTDEF(InterleaveRanges) {\n\ttc::vector<tc::vector<int>> const vecvecn({\n\t\t{1,3,5,7,16,20},\n\t\t{2,3,5,7,9,17},\n\t\t{3,7,11,13,17},\n\t\t{4,5,11,12,16},\n\t\t{3,7,11,13,17},\n\t\t{3,4,10,11,16}\n\t});\n\ttc::vector<tc::vector<int>> const vecvecnResult({\n\t\t{1},\n\t\t{2},\n\t\t{3,3,3,3,3},\n\t\t{4,4},\n\t\t{5,5,5},\n\t\t{7,7,7,7},\n\t\t{9},\n\t\t{10},\n\t\t{11,11,11,11},\n\t\t{12},\n\t\t{13,13},\n\t\t{16,16,16},\n\t\t{17,17,17},\n\t\t{20}\n\t});\n\n\t_ASSERT(tc::equal(\n\t\ttc::make_vector(tc::join(\n\t\t\ttc::interleave_ranges(\n\t\t\t\ttc::transform(\n\t\t\t\t\ttc::iota(1,10),\n\t\t\t\t\t[](auto const n) noexcept {\n\t\t\t\t\t\treturn tc::iota(n,10);\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t)\n\t\t)),\n\t\ttc::make_vector(tc::join(\n\t\t\ttc::transform(\n\t\t\t\ttc::iota(1,10),\n\t\t\t\t[](auto const n) noexcept {return tc::repeat_n(n,tc::decay_copy(n));}\n\t\t\t)\n\t\t))\n\t));\n\n\t_ASSERT(tc::equal(\n\t\ttc::make_vector(tc::join(tc::interleave_ranges(vecvecn))),\n\t\ttc::make_vector(tc::join(vecvecnResult))\n\t));\n}\n\nUNITTESTDEF(plurality_element_test) {\n\tauto const str = \"abcdc\";\n\t_ASSERTEQUAL('c', tc::plurality_element<tc::return_value>(str));\n\tauto const str2 = \"\";\n\t_ASSERTEQUAL(std::nullopt, tc::plurality_element<tc::return_value_or_none>(str2));\n\tauto const str3 = \"a\";\n\t_ASSERTEQUAL(tc::begin(str3),tc::plurality_element<tc::return_element>(str3));\n\tint an[] = {1,2,3,4,3,4,3,5,6};\n\t_ASSERTEQUAL(std::optional(4), tc::plurality_element<tc::return_value_or_none>(tc::filter(an, [](auto const n) noexcept { return n % 2 == 0; })));\n}\n\nstatic_assert(std::is_move_constructible<decltype(tc::sort(std::declval<tc::string<char> const&>()))>::value);\nstatic_assert(!std::is_move_constructible<decltype(tc::sort(std::declval<tc::string<char>>()))>::value);\nstatic_assert(std::is_move_constructible<decltype(tc::sort(std::declval<tc::vector<int> const&>()))>::value);\nstatic_assert(std::is_move_constructible<decltype(tc::sort(std::declval<tc::vector<int>>()))>::value);\n\nUNITTESTDEF(sort_test) {\n\ttc::vector<int> vec1{6,1,2,9,5,0,3,4,7,8};\n\t_ASSERT(tc::equal(tc::sort(vec1), tc::iota(0, 10)));\n\tauto rngnSorted=tc::sort(tc::vector<int>{3,7,1,9,2,5,8,4,6,0});\n\t_ASSERT(tc::equal(rngnSorted, tc::iota(0, 10)));\n\ttc::vector<std::pair<int, int>> vecpairnn1{{5,0}, {3,0}, {0,0}, {6,0}, {1,0}, {5,1}, {1,1}, {5,2}, {3,1}, {0,1}, {0,2}, {6,1}};\n\ttc::vector<std::pair<int, int>> vecpairnn2{{0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {3,0}, {3,1}, {5,0}, {5,1}, {5,2}, {6,0}, {6,1}};\n\tauto const rngpairnnSorted=tc::stable_sort(tc_move(vecpairnn1),tc::projected(tc::fn_compare(),[](auto const& pairnn) noexcept { return pairnn.first; }));\n\t_ASSERT(tc::equal(rngpairnnSorted, vecpairnn2));\n}\n\n#ifdef __clang__ // remove if std::sort is constexpr in xcode\nUNITTESTDEF(constexpr_sort_test) {\n\tstd::mt19937 gen; // same sequence of numbers each time for reproducibility\n\tstd::uniform_int_distribution<> dist(0, 63);\n\n\ttc_static_auto_constexpr_lambda(Test) = [](auto rngn) noexcept {\n\t\tauto vecn = tc::explicit_cast<tc::vector<int>>(rngn);\n\t\t_ASSERTEQUAL(tc_modified(vecn, tc::sort_inplace(_)), tc_modified(vecn, tc::constexpr_sort_inplace_detail::constexpr_sort_inplace(tc::begin(_), tc::end(_), tc::fn_less())));\n\t};\n\n\tfor( int i = 0; i < 17; ++i ) {\n\t\tTest(tc::begin_next<tc::return_take>([&](auto sink) noexcept { for(;;) tc_return_if_break(tc::continue_if_not_break(sink, dist(gen))); }, dist(gen)));\n\t\tTest(tc::iota(0, i));\n\t\tTest(tc::reverse(tc::iota(0, i)));\n\t\tTest(tc::repeat_n(i, 0));\n\t\tfor( int j = 0; j < 7; ++j) {\n\t\t\tTest(tc::join(tc::repeat_n(i, tc::iota(0, j))));\n\t\t}\n\t}\n}\n#endif\n}\n"
  },
  {
    "path": "tc/algorithm/any_accu.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/inplace.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct any_accu final {\n\t\t\tconstexpr explicit any_accu() noexcept :\n\t\t\t\tm_b(false)\n\t\t\t{}\n\n\t\t\tconstexpr explicit any_accu(bool b) noexcept :\n\t\t\t\tm_b(b)\n\t\t\t{}\n\n\t\t\tconstexpr operator bool() const& noexcept {\n\t\t\t\treturn m_b;\n\t\t\t}\n\n\t\t\tconstexpr void operator()(bool const b) & noexcept {\n\t\t\t\ttc_inplace(m_b) || b;\n\t\t\t}\n\n\t\tprivate:\n\t\t\tbool m_b;\n\t\t};\n\t}\n\n\tusing no_adl::any_accu;\n}"
  },
  {
    "path": "tc/algorithm/append.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/construction_restrictiveness.h\"\n#include \"../base/inside_unwinding.h\"\n\n#include \"../container/container_traits.h\"\n#include \"../container/insert.h\"\n#include \"../container/cont_reserve.h\"\n#include \"../container/container.h\"\n#include \"../container/string.h\"\n#include \"../string/convert_enc.h\"\n\n#include \"../range/subrange.h\"\n#include \"../range/transform.h\"\n#include \"../range/repeat_n.h\"\n#include \"../range/concat_adaptor.h\"\n\n#include <boost/range/algorithm/copy.hpp>\n\nnamespace tc {\n\tnamespace append_detail {\n\t\ttemplate<typename Rng, typename TTarget>\n\t\tconcept conv_enc_needed =\n\t\t\ttc::char_type<TTarget> &&\n\t\t\ttc::range_with_iterators<Rng> &&\n\t\t\ttc::char_type<tc::range_value_t<Rng>> &&\n\t\t\t!std::is_same<TTarget, tc::range_value_t<Rng>>::value;\n\n\t\t// in general, do not use Cont::insert() or Cont(it, it)\n\t\t// iterators are slower than for_each in many cases (eg. filter ranges)\n\t\ttemplate<typename Rng, typename Cont>\n\t\tconcept range_insertable =\n\t\t\t(!conv_enc_needed<Rng, tc::range_value_t<Cont>>) &&\n\t\t\thas_mem_fn_reserve<Cont> &&\n\t\t\ttc::common_range<Rng> &&\n\t\t\tstd::convertible_to<\n\t\t\t\ttypename std::iterator_traits<tc::iterator_t<Rng>>::iterator_category,\n\t\t\t\tstd::random_access_iterator_tag\n\t\t\t> &&\n\t\t\t(!tc::prefers_for_each<Rng>) && // it might be more efficient to append by ranges than by iterators\n\t\t\ttc::econstructionIMPLICIT==tc::construction_restrictiveness<tc::range_value_t<Cont>, std::iter_reference_t<tc::iterator_t<Rng>>>::value;\n\t}\n\n\tnamespace append_no_adl {\n\t\ttemplate< typename Cont, bool bReserve = has_mem_fn_reserve<Cont>>\n\t\tstruct [[nodiscard]] appender_type;\n\n\t\ttemplate< typename Cont>\n\t\tstruct [[nodiscard]] appender_type<Cont, /*bReserve*/false> {\n\t\t\tusing guaranteed_break_or_continue = tc::constant<tc::continue_>;\n\t\t\tconstexpr explicit appender_type(Cont& cont) noexcept: m_cont(cont) {}\n\n\t\t\tCont& m_cont;\n\n\t\t\ttemplate<typename T>\n\t\t\tconstexpr void operator()(T&& t) const& noexcept(noexcept(tc::cont_emplace_back(m_cont, tc_move_if_owned(t))))\n\t\t\t\trequires\n\t\t\t\t\t(!tc::char_like<tc::range_value_t<Cont>> || tc::safely_convertible_to<T&&, tc::range_value_t<Cont>>) &&\n\t\t\t\t\trequires { tc::cont_emplace_back(std::declval<Cont&>(), tc_move_if_owned(t)); }\n\t\t\t{\n\t\t\t\ttc::cont_emplace_back(m_cont, tc_move_if_owned(t)); // MAYTHROW\n\t\t\t}\n\n\t\t\t// If appending random-access iterator range, use Cont::insert() to give insert the opportunity for optimizations.\n\t\t\tvoid chunk(append_detail::range_insertable<Cont> auto&& rng) const& noexcept(noexcept(\n\t\t\t\tm_cont.insert(tc::end(m_cont), tc::begin(rng), tc::end(rng))\n\t\t\t)) {\n\t\t\t\tNOBADALLOC(m_cont.insert(tc::end(m_cont), tc::begin(rng), tc::end(rng)));\n\t\t\t}\n\n\t\t\tvoid chunk(append_detail::conv_enc_needed<tc::range_value_t<Cont>> auto&& rng) const& return_MAYTHROW(\n\t\t\t\ttc::implicit_cast<void>(tc::for_each(tc::convert_enc<tc::range_value_t<Cont>>(tc_move_if_owned(rng)), *this))\n\t\t\t)\n\n\t\t\ttemplate<ENABLE_SFINAE> requires std::is_same<tc::range_value_t<SFINAE_TYPE(Cont)&>, unsigned char>::value\n\t\t\tauto write_offset(std::size_t n) const& noexcept {\n\t\t\t\tstruct stream_pos_writer final {\n\t\t\t\t\tCont& m_cont;\n\t\t\t\t\tdecltype(tc::size_raw(m_cont)) m_pos;\n\n\t\t\t\t\texplicit stream_pos_writer(Cont& cont) noexcept\n\t\t\t\t\t\t: m_cont(cont)\n\t\t\t\t\t\t, m_pos(tc::size_raw(m_cont))\n\t\t\t\t\t{}\n\n\t\t\t\t\tvoid mark() & noexcept {\n\t\t\t\t\t\t// The offset is counted from _after_ the written offset.\n\t\t\t\t\t\tboost::copy(tc::as_blob(tc::explicit_cast<std::uint32_t>(tc::size_raw(m_cont)-m_pos-sizeof(std::uint32_t))), tc::begin_next(m_cont, m_pos));\n\t\t\t\t\t\tm_pos+=sizeof(std::uint32_t);\n\t\t\t\t\t}\n\n\t\t\t\t\tvoid mark_null() & noexcept {\n\t\t\t\t\t\tboost::copy(tc::as_blob(std::numeric_limits<std::uint32_t>::max()), tc::begin_next(m_cont, m_pos));\n\t\t\t\t\t\tm_pos+=sizeof(std::uint32_t);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tstream_pos_writer ow(m_cont);\n\t\t\t\ttc::for_each(tc::repeat_n(sizeof(std::uint32_t)*n, tc::explicit_cast<unsigned char>(0)), *this);\n\t\t\t\treturn ow;\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Cont >\n\t\tstruct [[nodiscard]] appender_type<Cont, /*bReserve*/true> /*final*/: appender_type<Cont, /*bReserve*/false> {\n\t\t\tusing base_ = appender_type<Cont, /*bReserve*/false>;\n\t\t\tusing base_::base_;\n\t\t\tusing base_::chunk;\n\n\t\t\t// We use int = 0 in parameter list because variation of\n\t\t\t// https://stackoverflow.com/questions/51933397/sfinae-method-completely-disables-base-classs-template-method-in-clang\n\t\t\ttemplate< typename Rng, ENABLE_SFINAE, std::enable_if_t<\n\t\t\t\t!append_detail::conv_enc_needed<Rng, tc::range_value_t<Cont>> &&\n\t\t\t\ttc::has_size<Rng> &&\n\t\t\t\t!append_detail::range_insertable<Rng, Cont>\n\t\t\t>* = nullptr>\n\t\t\tconstexpr auto chunk(Rng&& rng, int = 0) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::cont_reserve(this->m_cont, this->m_cont.size()+tc::size(rng)),\n\t\t\t\ttc::implicit_cast<void>(tc::for_each(tc_move_if_owned(rng), tc::base_cast</*SFINAE_TYPE to workaround clang bug*/SFINAE_TYPE(base_)>(*this)))\n\t\t\t)\n\t\t};\n\t}\n\tusing append_no_adl::appender_type;\n\n\tnamespace appender_default {\n\t\ttemplate<typename Cont>\n\t\tconstexpr auto appender_impl(Cont& cont) noexcept {\n\t\t\treturn tc::appender_type<Cont>(cont);\n\t\t}\n\t}\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(appender)\n\n\ttemplate<typename Cont>\n\tusing appender_t = decltype(tc::appender(std::declval<Cont>()));\n\n\ttemplate<typename Rng, typename Cont>\n\tconcept appendable = tc::has_for_each<Rng, tc::appender_t<Cont>>;\n\n\t// Disallow 0 == sizeof...(Rng), so that overload taking single argument tc::tuple<Cont, Rng...> is rejected\n\ttemplate< typename RangeReturn = tc::return_void, typename Cont, tc::appendable<Cont&> Rng>\n\tconstexpr decltype(auto) append(Cont&& cont, Rng&& rng) MAYTHROW {\n\t\tstatic_assert( !std::is_const<Cont>::value, \"Cannot append to const container\" );\n\t\tstatic_assert( !tc::range_with_iterators<Cont> || std::is_lvalue_reference<Cont>::value, \"Append to rvalue intentional?\" );\n\n\t\tif constexpr( !tc::range_with_iterators<Cont> || (\n\t\t\tstd::is_same<RangeReturn, tc::return_void>::value &&\n\t\t\tnoexcept(tc::for_each(tc_move_if_owned(rng), tc::appender(cont)))\n\t\t) ) {\n\t\t\tstatic_assert( std::is_same<RangeReturn, tc::return_void>::value, \"RangeReturn not supported, if appending to stream.\" );\n\n\t\t\ttc::for_each(tc_move_if_owned(rng), tc::appender(cont));\n\t\t} else if constexpr( tc::random_access_range<Cont> || has_mem_fn_reserve<Cont> ) {\n\t\t\tauto const nOffset = tc::size_raw(cont);\n\t\t\ttry {\n\t\t\t\ttc::for_each(tc_move_if_owned(rng), tc::appender(cont));\n\t\t\t\tif constexpr( !std::is_same<RangeReturn, tc::return_void>::value ) {\n\t\t\t\t\treturn RangeReturn::pack_border(\n\t\t\t\t\t\ttc::begin_next<tc::return_border>(cont, nOffset),\n\t\t\t\t\t\tcont\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (...) {\n\t\t\t\ttc::take_first_inplace(cont, nOffset);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t} else {\n\t\t\t// assume iterators are stable to get iterator to first inserted element\n\t\t\tauto const it = tc::back<tc::return_element_or_null>(cont);\n\t\t\tauto const FirstAppendedElement = [&]() noexcept {\n\t\t\t\treturn it ? tc_modified(it, ++_) : tc::begin(cont);\n\t\t\t};\n\t\t\ttry {\n\t\t\t\ttc::for_each(tc_move_if_owned(rng), tc::appender(cont)); // MAYTHROW\n\t\t\t\tif constexpr( !std::is_same<RangeReturn, tc::return_void>::value ) {\n\t\t\t\t\treturn RangeReturn::pack_border(FirstAppendedElement(), cont);\n\t\t\t\t}\n\t\t\t} catch (...) {\n\t\t\t\ttc::take_inplace(cont, FirstAppendedElement());\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn = tc::return_void, typename Cont, tc::appendable<Cont&>... Rng> requires (1 < sizeof...(Rng))\n\tconstexpr decltype(auto) append(Cont&& cont, Rng&&... rng) MAYTHROW {\n\t\treturn tc::append<RangeReturn>(tc_move_if_owned(cont), tc::concat(tc_move_if_owned(rng)...));\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Cont, typename Rng>\n\t\tstruct append_on_dtor_t final : tc::noncopyable, tc::inside_unwinding {\n\t\t\ttc::optional<Cont&> m_ocont;\n\t\t\ttc::reference_or_value<Rng> m_rng;\n\n\t\t\tappend_on_dtor_t(Cont& cont, Rng&& rng) noexcept\n\t\t\t: m_ocont(cont), m_rng(tc::aggregate_tag, tc_move_if_owned(rng))\n\t\t\t{}\n\n\t\t\tappend_on_dtor_t(append_on_dtor_t&& other) noexcept\n\t\t\t: m_ocont(tc_move(other).m_ocont), m_rng(tc_move(other).m_rng)\n\t\t\t{\n\t\t\t\tother.m_ocont = std::nullopt;\n\t\t\t}\n\t\t\tASSIGN_BY_RENEW(append_on_dtor_t, append_on_dtor_t&&);\n\n\t\t\t~append_on_dtor_t() MAYTHROW {\n\t\t\t\tif(m_ocont && !inside_stack_unwinding()) {\n\t\t\t\t\ttc::append(*m_ocont, *tc_move(m_rng)); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Cont, tc::appendable<Cont&> Rng>\n\tconstexpr decltype(auto) make_append_on_dtor(Cont& cont, Rng&& rng) MAYTHROW {\n\t\treturn no_adl::append_on_dtor_t<Cont, Rng>(cont, tc_move_if_owned(rng));\n\t}\n\n\tnamespace explicit_convert_to_container_detail {\n\t\ttemplate<typename TTarget, typename Rng0, typename... RngN>\n\t\tusing use_ctor=tc::constant<\n\t\t\ttc::derived_from<std::remove_cvref_t<Rng0>, TTarget> &&\n\t\t\t(\n\t\t\t\t0==sizeof...(RngN) ||\n\t\t\t \t(!std::is_reference<Rng0>::value && !std::is_const<Rng0>::value)\n\t\t\t)\n\t\t>;\n\t}\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename Cont>\n\t\tconcept appendable_container = has_mem_fn_push_back<Cont> || has_emplace_back<Cont, tc::range_value_t<Cont>>::value;\n\n\t\ttemplate<appendable_container TTarget, typename Rng0, tc::appendable<TTarget&>... RngN>\n\t\t\trequires explicit_convert_to_container_detail::use_ctor<TTarget, Rng0, RngN...>::value\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, Rng0&& rng0, RngN&&... rngN) MAYTHROW {\n\t\t\tif constexpr(0<sizeof...(RngN)) {\n\t\t\t\tTTarget cont=tc_move_if_owned(rng0);\n \t\t\t\ttc::append(cont, tc_move_if_owned(rngN)...);\n\t\t\t\treturn cont;\n\t\t\t} else {\n\t\t\t\treturn tc_move_if_owned(rng0);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<appendable_container TTarget, tc::appendable<TTarget&> Rng0, tc::appendable<TTarget&>... RngN>\n\t\t\trequires (!explicit_convert_to_container_detail::use_ctor<TTarget, Rng0, RngN...>::value)\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, Rng0&& rng0, RngN&&... rngN) MAYTHROW {\n\t\t\tTTarget cont;\n \t\t\ttc::append(cont, tc_move_if_owned(rng0), tc_move_if_owned(rngN)...);\n\t\t\treturn cont;\n\t\t}\n\t}\n\n\ttemplate< typename... Rng >\n\t[[nodiscard]] auto make_vector(Rng&&... rng) MAYTHROW {\n\t\tstatic_assert(0 < sizeof...(Rng));\n\t\treturn tc::explicit_cast<tc::vector<tc::range_value_t<decltype(tc::concat(tc_move_if_owned(rng)...))>>>(tc_move_if_owned(rng)...);\n\t}\n\n\ttemplate< typename Char, typename... Rng >\n\t[[nodiscard]] auto make_str(Rng&&... rng) MAYTHROW {\n\t\tstatic_assert(0 < sizeof...(Rng));\n\t\treturn tc::explicit_cast<tc::string<Char>>(tc_move_if_owned(rng)...);\n\t}\n\n\ttemplate< typename... Rng >\n\t[[nodiscard]] auto make_str(Rng&&... rng) MAYTHROW {\n\t\tstatic_assert(0 < sizeof...(Rng));\n\t\treturn tc::make_str<tc::range_value_t<decltype(tc::concat(tc_move_if_owned(rng)...))>>(tc_move_if_owned(rng)...);\n\t}\n\n\ttemplate< typename T, typename Rng >\n\t[[nodiscard]] auto make_unique_unordered_set(Rng&& rng) MAYTHROW {\n\t\ttc::unordered_set<T> set;\n\t\ttc::cont_try_insert_range(set, tc_move_if_owned(rng));\n\t\treturn set;\n\t}\n\n\ttemplate< typename Rng >\n\t[[nodiscard]] auto make_unique_unordered_set(Rng&& rng) MAYTHROW {\n\t\treturn make_unique_unordered_set<tc::range_value_t<Rng>>(tc_move_if_owned(rng));\n\t}\n\n\ttemplate< typename T, typename Rng >\n\t[[nodiscard]] auto make_unordered_set(Rng&& rng) MAYTHROW {\n\t\ttc::unordered_set<T> set;\n\t\ttc::cont_must_insert_range(set, tc_move_if_owned(rng));\n\t\treturn set;\n\t}\n\n\ttemplate< typename Rng >\n\t[[nodiscard]] auto make_unordered_set(Rng&& rng) MAYTHROW {\n\t\treturn make_unordered_set<tc::range_value_t<Rng>>(tc_move_if_owned(rng));\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/append.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"append.h\"\n\n#include \"../unittest.h\"\n#include \"../string/format.h\"\n#include \"../static_vector.h\"\n#include \"../range/filter_adaptor.h\"\n\nstatic_assert(tc::appendable<char const*, tc::string<char>&>);\nstatic_assert(!tc::appendable<int, tc::string<char>&>);\nstatic_assert(tc::appendable<tc::char16 const*, tc::string<char>&>);\nstatic_assert(tc::appendable<decltype(tc::as_dec(5)), tc::string<char>&>);\nstatic_assert(!tc::appendable<tc::size_proxy<int>, tc::string<char>&>);\nstatic_assert(!tc::appendable<tc::vector<int>, tc::string<char>&>);\nstatic_assert(!tc::appendable<tc::static_vector<int, 3>, tc::string<char>&>);\n\nUNITTESTDEF(nonappendable) {\n\ttc::vector<int> vecnTest{1, 2, 3};\n\tauto rngTest1=tc::transform(vecnTest, [](auto const n) noexcept { return n + 1; });\n\tstatic_assert(!tc::appendable<decltype(rngTest1), tc::string<char>&>);\n\tauto rngTest2=tc::filter(vecnTest, [](auto const n) noexcept { return n%2==1; });\n\tstatic_assert(!tc::appendable<decltype(rngTest2), tc::string<char>&>);\n}\n\nUNITTESTDEF(append_on_dtor) {\n\t{\n\t\ttc::string<char> str;\n\t\ttc::append(str, \"Hello \");\n\t\t{\n\t\t\ttc::make_append_on_dtor(str, \"World!\");\n\t\t}\n\t\t_ASSERT(tc::equal(str, \"Hello World!\"));\n\t}\n\t{\n\t\ttc::string<char> str;\n\t\t{\n\t\t\ttc_auto_cref(a1, tc::make_append_on_dtor(str, \"World!\"));\n\t\t\ttc_auto_cref(a2, tc::make_append_on_dtor(str, \"Hello \"));\n\t\t}\n\t\t_ASSERT(tc::equal(str, \"Hello World!\"));\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/best_element.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../range/subrange.h\"\n#include \"../storage_for.h\"\n#include \"../base/change.h\"\n#include \"accumulate.h\"\n#include \"compare.h\"\n\nnamespace tc {\n\n\ttemplate< typename RangeReturn, typename Better, typename Rng>\n\t[[nodiscard]] constexpr decltype(auto) best_element_impl(Better better, Rng&& rng) MAYTHROW {\n\t\tif constexpr( RangeReturn::requires_iterator ) {\n\t\t\tauto const itEnd=tc::end(rng); // MAYTHROW\n\t\t\tdecltype(tc::begin(rng)) ait[2]={ tc::begin(rng) }; // MAYTHROW\n\t\t\tif(ait[0]==itEnd) {\n\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t\t} else {\n\t\t\t\ttc::storage_for< tc::reference_or_value<decltype(*ait[0])> > aoref[2];\n\t\t\t\taoref[0].ctor( aggregate_tag, *ait[0] ); // MAYTHROW\n\t\t\t\tfor(;;){\n\t\t\t\t\tfor( int i=0; i!=2; ++i ) { // we expect the compiler to unroll this loop\n\t\t\t\t\t\t// aoref[i] is constructed, aoref[1-i] is not constructed\n\t\t\t\t\t\ttc_scope_exit { aoref[i].dtor(); }; // also required in case of exception\n\t\t\t\t\t\tait[1-i]=ait[i];\n\t\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\t\t// aoref[i] is constructed, aoref[1-i] is not constructed\n\t\t\t\t\t\t\t++ait[1-i];\n\t\t\t\t\t\t\tif(ait[1-i]==itEnd) {\n\t\t\t\t\t\t\t\treturn RangeReturn::pack_element(tc_move_always(ait[i]),tc_move_if_owned(rng),**tc_move_always(aoref[i]));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\taoref[1-i].ctor( aggregate_tag, *ait[1-i] ); // MAYTHROW\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tif( tc_invoke(better, tc::as_const(**aoref[1-i]), tc::as_const(**aoref[i])) ) { // MAYTHROW\n\t\t\t\t\t\t\t\t\tbreak; // only path where aoref[1-i] is not destroyed\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch(...) {\n\t\t\t\t\t\t\t\taoref[1-i].dtor();\n\t\t\t\t\t\t\t\tthrow;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\taoref[1-i].dtor();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (auto ovalue = tc::accumulate_with_front(tc_move_if_owned(rng), [&](auto& valueBest, auto&& value) noexcept {\n\t\t\treturn tc::assign_better(better, valueBest, tc_move_if_owned(value));\n\t\t})) {\n\t\t\treturn RangeReturn::template pack_element<Rng>(*tc_move(ovalue));\n\t\t} else {\n\t\t\treturn RangeReturn::template pack_no_element<Rng>();\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename Better, typename Rng, typename Projection = tc::identity>\n\t[[nodiscard]] constexpr decltype(auto) best_element(Better&& better, Rng&& rng, Projection&& projection = Projection()) MAYTHROW {\n\t\treturn tc::best_element_impl<RangeReturn>(tc::projected(tc_move_if_owned(better), tc_move_if_owned(projection)), tc_move_if_owned(rng));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Projection = tc::identity >\n\t[[nodiscard]] constexpr decltype(auto) min_element(Rng&& rng, Projection&& projection = Projection()) MAYTHROW {\n\t\treturn tc::best_element<RangeReturn>(tc::fn_less(), tc_move_if_owned(rng), tc_move_if_owned(projection));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Projection = tc::identity >\n\t[[nodiscard]] constexpr decltype(auto) max_element(Rng&& rng, Projection&& projection = Projection()) MAYTHROW {\n\t\treturn tc::best_element<RangeReturn>(tc::fn_greater(), tc_move_if_owned(rng), tc_move_if_owned(projection));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] constexpr decltype(auto) closest_element(Rng&& rng, T const& t) MAYTHROW {\n\t\treturn tc::min_element<RangeReturn>(tc_move_if_owned(rng), [&](auto const& elem) MAYTHROW { return std::abs(t - elem); });\n\t}\n}\n\n"
  },
  {
    "path": "tc/algorithm/binary_operators.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"../base/derivable.h\"\n#include \"../base/generic_macros.h\"\n#include \"../base/modified.h\"\n#include \"../base/empty_chain.h\"\n#include \"round.h\"\n#ifdef MSVC_WORKAROUND\n#include <boost/preprocessor/punctuation/comma.hpp>\n#include <boost/preprocessor/punctuation/paren.hpp>\n#endif\n\nnamespace tc {\n\t#pragma push_macro(\"GENERIC_OP_BODY\")\n\t#define GENERIC_OP_BODY(op, operation_body) \\\n\t\ttemplate< typename Lhs, typename Rhs \\\n\t\t> \\\n\t\t\trequires is_operation_available<Lhs&&, Rhs&&> \\\n\t\t[[nodiscard]] friend constexpr auto operator op(Lhs&& lhs, Rhs&& rhs) noexcept { \\\n\t\t\tstatic_assert(tc::decayed<conversion_t<Lhs, Rhs>>); \\\n\t\t\tusing Result = std::conditional_t<std::is_same<conversion_t<Lhs, Rhs>, Lhs>::value, Lhs&&, conversion_t<Lhs, Rhs>>; \\\n\t\t\tResult _ = tc_move_if_owned(lhs); \\\n\t\t\toperation_body; \\\n\t\t\tif constexpr( std::is_same<Result, Lhs&&>::value ) { \\\n\t\t\t\treturn tc_move_if_owned(_); \\\n\t\t\t} else { \\\n\t\t\t\tstatic_assert( \\\n\t\t\t\t\tstd::is_same<Result, tc::decay_t<Lhs>>::value \\\n\t\t\t\t\t|| !is_compound_available<tc::decay_t<Lhs>, Rhs&&>, \\\n\t\t\t\t\t\"conversion_t provides a conversion, despite \" #op \"= being offered by the original type\" \\\n\t\t\t\t); \\\n\t\t\t\treturn _; \\\n\t\t\t} \\\n\t\t}\n\n\t#pragma push_macro(\"DEFINE_GENERIC_OP\")\n\t#define DEFINE_GENERIC_OP(name, op) \\\n\tnamespace binary_operator_conversions { \\\n\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\tstruct name##_conversion_type { \\\n\t\t\tusing type = Lhs; \\\n\t\t}; \\\n\t\ttemplate< typename Lhs, typename Rhs> \\\n\t\tstruct internal_##name##_conversion_type : name##_conversion_type<Lhs, Rhs> { }; \\\n\t} \\\n\tnamespace generic_operator_helper { \\\n\t\t/*Checks if (TThis&& op##= TOther&&) is defined*/ \\\n\t\tTC_HAS_EXPR(compound_##name, (TThis)(TOther), std::declval<TThis>() op##= std::declval<TOther>()); \\\n\t\t/*Checks if (TThis&&.operator op##=(TOther&&)) is defined*/ \\\n\t\tTC_HAS_EXPR(mem_fn_compound_##name, (TThis)(TOther), std::declval<TThis>().operator op##=(std::declval<TOther>())); \\\n\t} \\\n\tnamespace no_adl { \\\n\t\ttemplate< typename Base = void > \\\n\t\tstruct TC_EMPTY_BASES name : std::conditional_t<std::is_void<Base>::value, tc::empty_chain<name<void>>, Base> { \\\n\t\tprivate: \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tstatic constexpr bool is_compound_available = tc::generic_operator_helper::has_mem_fn_compound_ ##name<Lhs&, Rhs>; \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tusing conversion_t = typename binary_operator_conversions::internal_##name##_conversion_type<tc::decay_t<Lhs>, tc::decay_t<Rhs>>::type; \\\n\t\t\t/*If we're not forwarding an rvalue, we're calling the operator on the result of tc::decay_copy(Lhs&), which is tc::decay_t<Lhs>& \\\n\t\t\t\tIf we're forwarding an rvalue, we're calling the operator on remove_reference_t<Lhs>&. But is_same<tc::decay_t<Lhs>, remove_reference_t<Lhs>>::value. */ \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tstatic constexpr auto is_operation_available = \\\n\t\t\t\ttc::derived_from<conversion_t<Lhs, Rhs>, name> \\\n\t\t\t\t&& is_compound_available<conversion_t<Lhs, Rhs>, Rhs>; \\\n\t\tpublic: \\\n\t\t\tGENERIC_OP_BODY( op, _.operator op##=(tc_move_if_owned(rhs)) ); \\\n\t\t}; \\\n\t\t\\\n\t\ttemplate< typename Other, typename Base = void > \\\n\t\tstruct TC_EMPTY_BASES external_ ##name : std::conditional_t<std::is_void<Base>::value, tc::empty_chain<external_ ##name <void>>, Base> { \\\n\t\tprivate: \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tstatic constexpr bool is_compound_available = tc::generic_operator_helper::has_compound_ ##name<Lhs&, Rhs>; \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tusing conversion_t = tc::decay_t<Lhs>; \\\n\t\t\tstatic_assert( std::is_fundamental<Other>::value, \"external_\" #name \" is only meant for fundamental types\" ); \\\n\t\t\tSTATICASSERTSAME( tc::decay_t<Other>, Other ); \\\n\t\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\tstatic constexpr auto is_operation_available =  \\\n\t\t\t\ttc::derived_from<std::remove_reference_t<Lhs>, Other> \\\n\t\t\t\t&& tc::derived_from<std::remove_reference_t<Rhs>, external_ ##name<Other, Base>> \\\n\t\t\t\t/* Same reasoning as in the internal operator */ \\\n\t\t\t\t&& is_compound_available<tc::decay_t<Lhs>, Rhs>; \\\n\t\tpublic: \\\n\t\t\tGENERIC_OP_BODY( op, { \\\n\t\t\t\tstatic_assert(!tc::generic_operator_helper::has_mem_fn_compound_ ##name<decltype((_)), decltype(tc_move_if_owned(rhs))>); \\\n\t\t\t\t_ op##= tc_move_if_owned(rhs); \\\n\t\t\t} ); \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::name; \\\n\tusing no_adl::external_ ##name; \\\n\t\n\t// By default, tc::addable &co. allow operations for which there exists a corresponding lhs.operator op=(rhs) member operator\n\t// For cases where the left-hand side requires a promoting conversion before the operation can take place,\n\t//  specialize one of the tc::binary_operator_conversions::*_conversion_type structs\n\t// Example: if class A wants A+B to be performed by converting A to C:\n\t//\t1. both A and C need to derive from tc::addable (C needs it to satisfy SFINAE sanity checks, A needs it so that ADL can find the generic operator+)\n\t//\t\tNote: A wouldn't need to derive from addable, if the generic operators were global, but that would increase the complexity of compiling any operator call\n\t//\t2. C.operator+=(B) (with appropriate cvref qualifiers) must exist and be accessible\n\t//\t3. there must be a specialization for tc::binary_operator_conversions::addable_conversion_type<A, B> that defines the alias type=C;\n\n\tDEFINE_GENERIC_OP(addable, +);\n\tDEFINE_GENERIC_OP(subtractable, -);\n\tDEFINE_GENERIC_OP(multipliable, *);\n\tDEFINE_GENERIC_OP(dividable, /);\n\tDEFINE_GENERIC_OP(orable, |);\n\tDEFINE_GENERIC_OP(andable, &);\n\tDEFINE_GENERIC_OP(xorable, ^);\n\tDEFINE_GENERIC_OP(left_shiftable, <<);\n\t#pragma pop_macro(\"DEFINE_GENERIC_OP\")\n\t#pragma pop_macro(\"GENERIC_OP_BODY\")\n\n\ttemplate< typename Base = void >\n\tusing additive = addable<subtractable<Base>>;\n\n\ttemplate< typename Base = void >\n\tusing multiplicative = multipliable<dividable<Base>>;\n\n\ttemplate< typename Base = void >\n\tusing arithmetic = additive<multiplicative<Base>>;\n\n\ttemplate< typename Base = void >\n\tusing setlike = andable<orable<xorable<subtractable<Base>>>>;\n\n\ttemplate< typename Other, typename Base = void >\n\tusing external_additive = external_addable<Other, external_subtractable<Other, Base>>;\n\n\ttemplate< typename Other, typename Base = void >\n\tusing external_multiplicative = external_multipliable<Other, external_dividable<Other, Base>>;\n\n\ttemplate< typename Other, typename Base = void >\n\tusing external_arithmetic = external_additive<Other, external_multiplicative<Other, Base>>;\n\n\t// If the same conversion logic applies to multiple operations, you can specialize one of the grouped conversions defined here\n\tnamespace binary_operator_conversions {\n\t\t#pragma push_macro(\"PROXY_CONVERSION\")\n\t\t#define PROXY_CONVERSION(nameFrom, nameTo) \\\n\t\ttemplate< typename Lhs, typename Rhs > \\\n\t\t\trequires requires { typename nameTo##_conversion_type<Lhs, Rhs>::type; } \\\n\t\tstruct internal_##nameFrom##_conversion_type<Lhs, Rhs> \\\n\t\t\t: nameTo##_conversion_type<Lhs, Rhs> \\\n\t\t{}\n\n\t\ttemplate< typename Lhs, typename Rhs >\n\t\tstruct additive_conversion_type { };\n\t\tPROXY_CONVERSION(addable, additive);\n\t\tPROXY_CONVERSION(subtractable, additive);\n\t\t\n\t\t\n\t\ttemplate< typename Lhs, typename Rhs >\n\t\tstruct multiplicative_conversion_type { };\n\t\tPROXY_CONVERSION(multipliable, multiplicative);\n\t\tPROXY_CONVERSION(dividable, multiplicative);\n\n\t\ttemplate< typename Lhs, typename Rhs >\n\t\tstruct arithmetic_conversion_type { };\n\t\tPROXY_CONVERSION(addable, arithmetic);\n\t\tPROXY_CONVERSION(subtractable, arithmetic);\n\t\tPROXY_CONVERSION(multipliable, arithmetic);\n\t\tPROXY_CONVERSION(dividable, arithmetic);\n\n\t\ttemplate< typename Lhs, typename Rhs >\n\t\tstruct setlike_conversion_type { };\n\t\tPROXY_CONVERSION(andable, setlike);\n\t\tPROXY_CONVERSION(orable, setlike);\n\t\tPROXY_CONVERSION(xorable, setlike);\n\t\tPROXY_CONVERSION(subtractable, setlike);\n\t\t#pragma pop_macro(\"PROXY_CONVERSION\")\n\t}\n\n\n\tnamespace scalar_binary_op_detail::no_adl {\n\t\ttemplate<typename FnOp, typename Rhs>\n\t\tstruct func {\n\t\t\tRhs const& m_rhs;\n\n\t\t\ttemplate <typename LhsElement>\n\t\t\tconstexpr auto operator()(LhsElement&& lhselem) const& return_decltype_allow_xvalue_MAYTHROW( // should be NOEXCEPT, but NOEXCEPT does not allow xvalues.\n\t\t\t\ttc_invoke(FnOp(), tc_move_if_owned(lhselem), m_rhs)\n\t\t\t)\n\t\t};\n\n\t\tstruct no_prepost_scalar_operation {\n\t\t\tstatic constexpr void pre(tc::unused /*scalar*/) noexcept {}\n\t\t\tstatic constexpr void post(tc::unused /*lhs*/, tc::unused /*scalar*/) noexcept {}\n\t\t};\n\n\t\ttemplate<typename Pred>\n\t\tstruct assert_zero_to_scalar_relation final : no_prepost_scalar_operation {\n\t\t\ttemplate<typename Scalar>\n\t\t\tstatic constexpr void pre(Scalar const& scalar) noexcept {\n\t\t\t\t_ASSERTE( Pred()(tc::explicit_cast<Scalar>(0), scalar) );\n\t\t\t}\n\t\t};\n\t}\n\tusing scalar_binary_op_detail::no_adl::no_prepost_scalar_operation;\n\tusing assert_non_zero_scalar = scalar_binary_op_detail::no_adl::assert_zero_to_scalar_relation<fn_not_equal_to>;\n\tusing assert_non_negative_scalar = scalar_binary_op_detail::no_adl::assert_zero_to_scalar_relation<fn_less_equal>;\n\tusing assert_positive_scalar = scalar_binary_op_detail::no_adl::assert_zero_to_scalar_relation<fn_less>;\n\n#pragma push_macro(\"DEFINE_SCALAR_OP\")\n#define DEFINE_SCALAR_OP(name, op, fnop, fnassignop, prepostopdefault) \\\n\tnamespace no_adl { \\\n\t\ttemplate<typename Base = void, std::size_t nTransformDepth = 0, typename PrePostOperation = prepostopdefault> \\\n\t\tstruct TC_EMPTY_BASES scalar_ ## name : std::conditional_t<std::is_void<Base>::value, tc::empty_chain<scalar_ ## name<void, nTransformDepth, PrePostOperation>>, Base> { \\\n\t\t\ttemplate<tc::decayed_derived_from<scalar_ ## name> Lhs, typename Rhs \\\n\t\t\tIF_MSVC_WORKAROUND_ELSE( \\\n\t\t\t\tTC_FWD(BOOST_PP_COMMA() typename=decltype BOOST_PP_LPAREN()), /* workaround VS17.8 compiler bug: https://developercommunity.visualstudio.com/t/template-member-function-is-not-recogniz/10504199 */ \\\n\t\t\t\tTC_FWD(> requires requires {) \\\n\t\t\t) \\\n\t\t\t\tstd::declval<Lhs>().template transform<nTransformDepth>(std::declval<scalar_binary_op_detail::no_adl::func<fnop, Rhs>>())IF_NO_MSVC_WORKAROUND(;) \\\n\t\t\tIF_MSVC_WORKAROUND_ELSE( \\\n\t\t\t\tBOOST_PP_RPAREN()>, \\\n\t\t\t\t} \\\n\t\t\t) \\\n\t\t\t[[nodiscard]] friend constexpr decltype(auto) operator op(Lhs&& lhs, Rhs const& rhs) noexcept { \\\n\t\t\t\tPrePostOperation::pre(rhs); \\\n\t\t\t\tdecltype(auto) _ = tc_move_if_owned(lhs).template transform<nTransformDepth>(scalar_binary_op_detail::no_adl::func<fnop, Rhs>{rhs}); \\\n\t\t\t\tPrePostOperation::post(_, rhs); \\\n\t\t\t\treturn _; \\\n\t\t\t} \\\n\t\t\t\\\n\t\t\ttemplate<tc::decayed_derived_from<scalar_ ## name> Lhs, typename Rhs> requires requires { \\\n\t\t\t\ttc::for_each(std::declval<Lhs&>(), std::declval<scalar_binary_op_detail::no_adl::func<fnassignop, Rhs>>()); \\\n\t\t\t} \\\n\t\t\tfriend constexpr Lhs& operator op ## =(Lhs& lhs, Rhs const& rhs) noexcept { \\\n\t\t\t\tPrePostOperation::pre(rhs); \\\n\t\t\t\ttc::for_each(lhs, scalar_binary_op_detail::no_adl::func<fnassignop, Rhs>{rhs}); \\\n\t\t\t\tPrePostOperation::post(lhs, rhs); \\\n\t\t\t\treturn lhs; \\\n\t\t\t} \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::scalar_ ## name;\n\n\tDEFINE_SCALAR_OP(addable, +, tc::fn_plus, tc::fn_assign_plus, tc::no_prepost_scalar_operation)\n\tDEFINE_SCALAR_OP(subtractable, -, tc::fn_minus, tc::fn_assign_minus, tc::no_prepost_scalar_operation)\n\tDEFINE_SCALAR_OP(multipliable, *, tc::fn_mul, tc::fn_assign_mul, tc::no_prepost_scalar_operation)\n\tDEFINE_SCALAR_OP(dividable, /, tc::fn_div, tc::fn_assign_div, tc::assert_non_zero_scalar)\n#pragma pop_macro(\"DEFINE_SCALAR_OP\")\n\n\tnamespace no_adl {\n\t\ttemplate<typename Base = void, std::size_t nTransformDepth = 0>\n\t\tusing scalar_multiplicative = tc::scalar_multipliable<tc::scalar_dividable<Base, nTransformDepth>, nTransformDepth>;\n\t}\n\tusing no_adl::scalar_multiplicative;\n}\n"
  },
  {
    "path": "tc/algorithm/break_or_continue.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/enum.h\"\n#include \"../base/noncopyable.h\"\n#include \"../base/derivable.h\"\n\n#include <type_traits>\n#include <functional>\n\nnamespace tc {\n\n\tTC_DEFINE_ENUM(break_or_continue, BOOST_PP_EMPTY(), (break_)(continue_))\n\n\t[[nodiscard]] inline constexpr tc::break_or_continue continue_if(tc::bool_context bCondition) noexcept {\n\t\tif( bCondition ) {\n\t\t\treturn tc::continue_;\n\t\t} else {\n\t\t\treturn tc::break_;\n\t\t}\n\t}\n\n\t#define tc_return_if_break_impl(sometimes_break_value, ...) \\\n\t{ \\\n\t\tauto boc__ = (__VA_ARGS__); \\\n\t\t/* Inline constexpr bools as soon as \"constexpr if\" works properly in MSVC */ \\\n\t\tMODIFY_WARNINGS_BEGIN(((disable)(4189))) /* diable warning C4189 to workaround VS2022 17.0 compiler bug: https://developercommunity.visualstudio.com/t/unexpected-warning-c4189-with-vs170-preview-21/1489426 */ \\\n\t\tconstexpr bool bAlwaysBreaks = std::is_same<decltype(boc__), tc::constant<tc::break_>>::value; \\\n\t\tconstexpr bool bNeverBreaks = std::is_same<decltype(boc__), tc::constant<tc::continue_>>::value; \\\n\t\tMODIFY_WARNINGS_END \\\n\t\tif constexpr (bAlwaysBreaks) { \\\n\t\t\treturn tc::constant<tc::break_>(); \\\n\t\t} \\\n\t\telse if constexpr (!bNeverBreaks) { \\\n\t\t\tif( tc::break_ == boc__ ) { \\\n\t\t\t\treturn sometimes_break_value; \\\n\t\t\t} \\\n\t\t} \\\n\t}\n\t#define tc_return_if_break(...) \\\n\t\ttc_return_if_break_impl(tc::break_, __VA_ARGS__)\n\t\n\tnamespace continue_if_not_break_adl {\n\t\ttemplate<typename BreakOrContinueDefault = tc::constant<tc::continue_>>\n\t\tstruct impl_t final {\n\t\t\tBreakOrContinueDefault m_boc;\n\t\t};\n\t\tinline constexpr impl_t<> impl = {tc::constant<tc::continue_>()};\n\t\ttemplate<typename BreakOrContinue>\n\t\tusing is_break_or_continue = boost::mp11::mp_set_contains<boost::mp11::mp_list<tc::break_or_continue, tc::constant<tc::break_>, tc::constant<tc::continue_>>, BreakOrContinue>;\n\n\t\ttemplate<typename BreakOrContinue> requires is_break_or_continue<BreakOrContinue>::value\n\t\tconstexpr impl_t<BreakOrContinue> operator,(BreakOrContinue boc, impl_t<> const&) noexcept {\n\t\t\treturn {boc};\n\t\t}\n\t\t// The built-in \"operator,\" would be fine, but this is needed to protect against other libraries that overload \"operator,\" (e.g. boost::proto).\n\t\ttemplate<typename NotBreakOrContinue> requires (!is_break_or_continue<std::remove_cvref_t<NotBreakOrContinue>>::value)\n\t\tconstexpr impl_t<> const& operator,(NotBreakOrContinue&& /*notboc*/, impl_t<> const& _) noexcept {\n\t\t\treturn _;\n\t\t}\n\t\t// Built-in:\n\t\t//template<typename >\n\t\t//impl_t<> const& operator,(void, impl_t<> const& _) noexcept {\n\t\t//\treturn _;\n\t\t//}\n#define tc_internal_continue_if_not_break(...) tc::decay_copy(((__VA_ARGS__), tc::continue_if_not_break_adl::impl).m_boc)\n\t}\n\n\ttemplate<typename Void> requires std::is_void<Void>::value\n\tconstexpr Void implicit_cast(tc::constant<tc::continue_>) noexcept {}\n\n\n\t//////////////////////////////////////////////////////////////////////////\n\n\t//// continue_if_not_break ///////////////////////////////////////////////////////////////////////////\n\t// Func returns break_or_continue\n\n\ttemplate <typename Sink, typename ... Args>\n\tconcept sinkable = tc::invocable<std::remove_cvref_t<Sink> const&, Args...>;\n\ttemplate <typename Sink, typename ... Args>\n\tconcept nothrow_sinkable = tc::sinkable<Sink, Args...> && tc::nothrow_invocable<std::remove_cvref_t<Sink> const&, Args...>;\n\n\ttemplate<typename Sink, typename... Args>\n\tconstexpr auto continue_if_not_break(Sink const& sink, Args&&... args) return_decltype_MAYTHROW(\n\t\ttc_internal_continue_if_not_break(tc_invoke_pack(sink, tc_move_if_owned(args)))\n\t)\n\n\tnamespace no_adl {\n\n\t\t///////////////////////////////////////////////////\n\t\t// tc::move_only_function\n\n\t\t// Supports constructing tc::move_only_function<tc::break_or_continue_(...)> from a callable with return type other than break_or_continue_.\n\t\t// TODO: Implement on top of std::move_only_function once it becomes available\n\t\ttemplate<typename Func> requires (!std::is_final_v<tc::decay_t<Func>>) && std::move_constructible<tc::decay_t<Func>>\n\t\tstruct movable_functor_adaptor_base : tc::derivable_t<tc::decay_t<Func>> {\n\t\tprivate:\n\t\t\tusing base_t = tc::derivable_t<tc::decay_t<Func>>;\n\t\tpublic:\n\t\t\tmovable_functor_adaptor_base(Func&& func) noexcept requires tc::safely_constructible_from<base_t, Func&&>\n\t\t\t\t: base_t(tc_move_if_owned(func)) {}\n\t\t\tmovable_functor_adaptor_base(movable_functor_adaptor_base&&) = default; // not noexcept to \"inherit\" exception-specifier from base class\n\t\t\tmovable_functor_adaptor_base(movable_functor_adaptor_base const& mfa) noexcept\n\t\t\t\t: base_t(tc_move_always(tc::as_mutable(tc::base_cast<base_t>(mfa))))\n\t\t\t{\n\t\t\t\t// On the Mac, the std::function move ctor may actually copy our movable_functor_adaptor.\n\t\t\t\t// Since tc::move_only_function is noncopyable, we always move here.\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename /*Ret*/, typename Func> requires requires { typename movable_functor_adaptor_base<Func>; }\n\t\tstruct movable_functor_adaptor final : movable_functor_adaptor_base<Func> {\n\t\t\tusing movable_functor_adaptor_base<Func>::movable_functor_adaptor_base;\n\n\t\t\t// no return_decltype_..._MAYTHROW: type is still incomplete in function signature - tc::base_cast does not compile on clang\n\t\t\ttemplate<typename... Args> requires requires { std::declval<tc::decay_t<Func>&>()(std::declval<Args>()...); }\n\t\t\tdecltype(auto) operator()(Args&& ... args) & noexcept(noexcept(std::declval<tc::decay_t<Func>&>()(std::declval<Args>()...))) {\n\t\t\t\treturn tc::base_cast<tc::decay_t<Func>>(*this)(tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\t\t// no return_decltype_..._MAYTHROW: type is still incomplete in function signature - tc::base_cast does not compile on clang\n\t\t\ttemplate<typename... Args> requires requires { std::declval<tc::decay_t<Func> const&>()(std::declval<Args>()...); }\n\t\t\tdecltype(auto) operator()(Args&& ... args) const& noexcept(noexcept(std::declval<tc::decay_t<Func> const&>()(std::declval<Args>()...))) {\n\t\t\t\treturn tc::base_cast<tc::decay_t<Func>>(*this)(tc_move_if_owned(args)...);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Func> requires requires { typename movable_functor_adaptor_base<Func>; }\n\t\tstruct movable_functor_adaptor<tc::break_or_continue, Func> final : movable_functor_adaptor_base<Func> {\n\t\t\tusing movable_functor_adaptor_base<Func>::movable_functor_adaptor_base;\n\n\t\t\t// no return_decltype_..._MAYTHROW: type is still incomplete in function signature - tc::base_cast does not compile on clang\n\t\t\ttemplate<typename... Args> requires requires { tc::continue_if_not_break(std::declval<tc::decay_t<Func>&>(), std::declval<Args>()...); }\n\t\t\ttc::break_or_continue operator()(Args&& ... args) & noexcept(noexcept(\n\t\t\t\ttc::continue_if_not_break(std::declval<tc::decay_t<Func>&>(), std::declval<Args>()...)\n\t\t\t)) {\n\t\t\t\treturn tc::continue_if_not_break(tc::base_cast<tc::decay_t<Func>>(*this), tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\t\t// no return_decltype_..._MAYTHROW: type is still incomplete in function signature - tc::base_cast does not compile on clang\n\t\t\ttemplate<typename... Args> requires requires { tc::continue_if_not_break(std::declval<tc::decay_t<Func> const&>(), std::declval<Args>()...); }\n\t\t\ttc::break_or_continue operator()(Args&& ... args) const& noexcept(noexcept(\n\t\t\t\ttc::continue_if_not_break(std::declval<tc::decay_t<Func> const&>(), std::declval<Args>()...)\n\t\t\t)) {\n\t\t\t\treturn tc::continue_if_not_break(tc::base_cast<tc::decay_t<Func>>(*this), tc_move_if_owned(args)...);\n\t\t\t}\n\t\t};\n\n\t\ttemplate< bool bNoExcept, typename Ret, typename... Args >\n\t\tstruct move_only_function_base: tc::noncopyable {\n\t\tprivate:\n\t\t\tstd::function< Ret(Args...) > m_func;\n\t\tpublic:\n\t\t\tmove_only_function_base() noexcept {} // creates an empty function\n\t\t\tmove_only_function_base(std::nullptr_t) noexcept {} // creates an empty function\n\n\t\t\tmove_only_function_base(move_only_function_base&& func) noexcept : m_func(tc_move(func).m_func) {}\n\t\t\tmove_only_function_base& operator=(move_only_function_base&& func) noexcept {\n\t\t\t\tm_func=tc_move(func).m_func;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate< typename Func > requires\n\t\t\t\t(!tc::decayed_derived_from<Func, move_only_function_base>) &&\n\t\t\t\ttc::safely_constructible_from<movable_functor_adaptor<Ret, Func>, Func&&> &&\n\t\t\t\ttc::safely_constructible_from<decltype(m_func), movable_functor_adaptor<Ret, Func>>\n\t\t\tmove_only_function_base(Func&& func) noexcept \n\t\t\t\t: m_func(movable_functor_adaptor<Ret, Func>(tc_move_if_owned(func)))\n\t\t\t{\n\t\t\t\tstatic_assert(!tc::decayed_derived_from<Func, std::function< Ret(Args...) >>);\n\t\t\t\t// TODO: static_assert(!tc::decayed_derived_from<Func, std::move_only_function< Ret(Args...) >>);\n\t\t\t\t// Checking the noexcept value of the function call is commented out because\n\t\t\t\t// 1. std::ref(func)'s operator() is not noexcept\n\t\t\t\t// 2. tc::unordered_set's move ctor is not noexcept\n\t\t\t\t// 3. boost::bind overloaded operators are not noexcept\n\t\t\t\t//static_assert(!bNoExcept || noexcept(std::declval<tc::decay_t<Func>&>()(std::declval<Args>()...)));\n\t\t\t}\n\n\t\t\texplicit operator bool() const& noexcept { tc_return_cast(m_func); }\n\n\t\t\tRet operator()(Args ... args) const& noexcept(bNoExcept) {\n\t\t\t\treturn m_func(tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\t\tfriend decltype(auto) debug_output_impl(move_only_function_base const& self) noexcept {\n\t\t\t\treturn self.m_func.target_type().name();\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Signature >\n\t\tstruct move_only_function;\n\t\n\t\ttemplate< typename Ret, typename... Args >\n\t\tstruct move_only_function< Ret(Args...) > : tc::no_adl::move_only_function_base</*bNoExcept*/false, Ret, Args...>\n\t\t{\n\t\t\tusing base_ = typename move_only_function::move_only_function_base;\n\t\t\tusing base_::base_;\n\t\t};\n\n\t\ttemplate< typename Ret, typename... Args >\n\t\tstruct move_only_function< Ret(Args...) noexcept > : tc::no_adl::move_only_function_base</*bNoExcept*/true, Ret, Args...>\n\t\t{\n\t\t\tusing base_ = typename move_only_function::move_only_function_base;\n\t\t\tusing base_::base_;\n\t\t};\n\t} // no_adl\n\n\tusing no_adl::move_only_function;\n\n\tinline bool cyclic_improve_impl(int const n, int& nSkipRule) noexcept {\n\t\treturn false;\n\t}\n\n\ttemplate<typename F0, typename... F>\n\tbool cyclic_improve_impl(int n, int& nSkipRule, F0& f0, F&... f) {\n\t\tif (n != nSkipRule && f0()) {\n\t\t\tnSkipRule = n;\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn cyclic_improve_impl(n+1, nSkipRule, f...);\n\t\t}\n\t}\n\n\ttemplate< typename... F >\n\tbool cyclic_improve(F... f) noexcept {\n\t\tint nSkipRule=-1;\n\t\twhile(cyclic_improve_impl(0, nSkipRule, f...)) {}\n\t\treturn -1 != nSkipRule;\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/compare.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/return_decltype.h\"\n#include \"../base/chained.h\"\n#include \"../base/enum.h\"\n#include \"../base/functors.h\"\n#include \"../base/inplace.h\"\n#include \"../base/template_func.h\"\n#include \"../base/empty_chain.h\"\n#include \"../range/transform_adaptor.h\"\n\n#include \"../base/change.h\"\n#include \"find.h\"\n#include \"../interval_types.h\"\n#if defined(__clang__) && !defined(__cpp_lib_three_way_comparison) // three way comparison operators are not implemented for library types in Xcode13/14. TODO Xcode15\n#include \"../optional.h\"\n#include \"../variant.h\"\n#endif\n#include <boost/preprocessor/variadic/to_seq.hpp>\n#include <compare>\n#include <concepts>\n\nnamespace tc {\n\t// < involving NAN always returns false, so it is not even a partial order\n\ttemplate<typename T>\n\tconstexpr void assert_not_isnan(T const& t) noexcept {\n\t\tif constexpr( std::floating_point<T> ) {\n\t\t\t_ASSERTDEBUG( !std::isnan(t) );\n\t\t}\n\t}\n}\n\nnamespace tc {\n\t// we always use tc::compare to perform 3 way comparison and tc::compare tc::explicit_cast std::strong_ordering/partial_ordering result to std::weak_ordering\n\ttemplate<typename Cat>\n\tconcept is_comparison_category = std::same_as<Cat, std::weak_ordering>;\n\n\tnamespace no_adl {\n\t\t// class T derives from tc::equal_from_three_way if T has a user defined operator<=> and implements operator== with operator<=>\n\t\ttemplate< typename T >\n\t\tstruct TC_EMPTY_BASES equal_from_three_way {\n\t\t\ttemplate<ENABLE_SFINAE> // ENABLE_SFINAE is needed because of possible clang/regression gcc bug https://godbolt.org/z/z7z3nf34f. It will be fixed in clang 16.\n\t\t\tfriend constexpr bool operator==(SFINAE_TYPE(T) const& lhs, SFINAE_TYPE(T) const& rhs) noexcept(noexcept(lhs<=>rhs==0)) requires requires { {lhs<=>rhs==0} -> std::same_as<bool>; } {\n\t\t\t\treturn lhs<=>rhs==0;\n\t\t\t}\n\t\t};\n\n\t\t// Default primary comparison operators\n\t\t//   1. operator== requires that each base class and member has associated operator==\n\t\t//   2. operator<=>:\n\t\t//     1) with auto return type: requires that each base class and member has associated operator<=>\n\t\t//     2) with comparison category return type: requires that each base class and member has either associated operator<=>, or both operator== and operator<.\n\t\t// Our chained empty base classes are not comparable by default. If we want to define primary comparison operators as default for some class with empty base(s),\n\t\t// we need to wrap tc::comparable around the empty base chain to make the chain comparable.\n\t\ttemplate< typename EmptyBase=void >\n\t\tstruct TC_EMPTY_BASES comparable: std::conditional_t<std::is_void<EmptyBase>::value, tc::empty_chain<comparable<void>>, EmptyBase> {\n\t\t\tstatic_assert(std::is_empty<std::conditional_t<std::is_void<EmptyBase>::value, tc::empty_chain<comparable<void>>, EmptyBase>>::value);\n\t\t\t// tc::comparable offers primary operators only for itself, not for derived types. Therefore we cannot accidently compare 2 types derived from tc::comparable.\n\t\t\ttemplate<typename T> requires std::same_as<T, comparable>\n\t\t\tfriend constexpr bool operator==(T const&, T const&) noexcept { return true; }\n\t\t\ttemplate<typename T> requires std::same_as<T, comparable>\n\t\t\tfriend constexpr auto operator<=>(T const&, T const&) noexcept { return std::weak_ordering::equivalent; }\n\t\t};\n\t}\n\tusing no_adl::equal_from_three_way;\n\tusing no_adl::comparable;\n\n\tnamespace inplace_adl {\n\t\ttemplate<tc::is_comparison_category Cat>\n\t\tconstexpr auto operator-(inplace<Cat> inplaceorder) noexcept {\n\t\t\tinplaceorder.m_t = 0<=>inplaceorder.m_t;\n\t\t}\n\t}\n\n#ifndef __clang__\n\tusing std::is_eq;\n\tusing std::is_neq;\n#else // Xcode14 doesn't have std::is_eq & std::is_neq while Xcode13 does.\n\tconstexpr bool is_eq(std::partial_ordering order) noexcept { return order==0; }\n\tconstexpr bool is_neq(std::partial_ordering order) noexcept { return order!=0; }\n#endif\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<std::same_as<std::weak_ordering> TTarget, std::same_as<std::partial_ordering> TSource>\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, TSource const& order) noexcept {\n\t\t\tif(std::is_lt(order)) {\n\t\t\t\treturn std::weak_ordering::less;\n\t\t\t} else if(tc::is_eq(order)) {\n\t\t\t\treturn std::weak_ordering::equivalent;\n\t\t\t} else if(std::is_gt(order)) {\n\t\t\t\treturn std::weak_ordering::greater;\n\t\t\t} else {\n\t\t\t\t_ASSERTFALSE; // unordered is not supported\n\t\t\t\treturn std::weak_ordering::less;\n\t\t\t}\n\t\t}\n\t}\n\n\t// clang workaround\n\ttemplate<typename Lhs, typename Rhs>\n\tconcept has_operator_3way_compare = requires(Lhs const& lhs, Rhs const& rhs) { lhs<=>rhs; };\n\n\ttemplate<typename Lhs, typename Rhs>\n\tconstexpr std::weak_ordering compare(Lhs const& lhs, Rhs const& rhs) noexcept(noexcept(lhs<=>rhs)) requires has_operator_3way_compare<Lhs, Rhs> && (!tc::comparable_pointers<Lhs, Rhs>) {\n\t\t// We tc::explicit_cast std::partial_ordering/std::strong_ordering result to std::weak_ordering.\n\t\t// Comparisons that return std::partial_ordering:\n\t\t// 1. floating point comparison\n\t\t// 2. library types comparison may return std::partial_ordering if they contain floating point values. e.g. std::vector, std::pair, std::variant, std::tuple\n\t\ttc_return_cast(lhs<=>rhs);\n\t}\n\n\t// similar to Synthesized three-way comparison except with tc::less instead of operator<\n\t//   1. boost::multiprecision numbers don't support three-way comparison\n\t//   2. clang library iterators don't support three-way comparison\n\t//   3. pointers: std::compare_three_way doesn't support function pointer comparison and is not implemented in Xcode13/14\n\ttemplate<typename Lhs, typename Rhs>\n\tconstexpr std::weak_ordering compare(Lhs const& lhs, Rhs const& rhs) noexcept(noexcept(tc::less(lhs,rhs)) && noexcept(tc::less(rhs,lhs))) requires\n\t\t(!has_operator_3way_compare<Lhs, Rhs> || tc::comparable_pointers<Lhs, Rhs>) &&\n\t\trequires {\n\t\t\ttc::less(lhs,rhs);\n\t\t\ttc::less(rhs,lhs);\n\t\t}\n\t{\n\t\tif(tc::less(lhs,rhs)) {\n\t\t\treturn std::weak_ordering::less;\n\t\t} else if(tc::less(rhs, lhs)){\n\t\t\treturn std::weak_ordering::greater;\n\t\t} else {\n\t\t\treturn std::weak_ordering::equivalent;\n\t\t}\n\t}\n\n\ttc_define_fn(compare)\n\n\t//////////////////////////////////////////////////////////////\n\t// macros for implementing compare on compound types\n\n\t#define tc_return_if_not_equal( compare ) \\\n\t\tif ( auto const order_ = compare; tc::is_neq(order_) ) return order_;\n\n\t// auto&& triggers internal error for VS2017\n\t// decltype((lhs)) triggers internal error for VS2019 16.8.0 preview 3.0\n\t// Not using return_decltype_MAYTHROW because noexcept(noexcept(expr)) not needed and triggering ICE in MSVC 19.28.\n\t#define tc_internal_compare_expr(fcompare, lhs, rhs, expr) \\\n\t\t(fcompare)( \\\n\t\t\t([&](auto&& _) MAYTHROW -> decltype(auto) { return tc::lvalue_or_decay(VERIFYINITIALIZED(expr)); })(VERIFYINITIALIZED(lhs)), \\\n\t\t\t([&](auto&& _) MAYTHROW -> decltype(auto) { return tc::lvalue_or_decay(VERIFYINITIALIZED(expr)); })(VERIFYINITIALIZED(rhs)) \\\n\t\t)\n\n\t#define tc_compare_expr( expr ) tc_return_if_not_equal( tc_internal_compare_expr(tc::compare, lhs, rhs, expr) )\n\t#define tc_compare_expr_reverse( expr ) tc_return_if_not_equal( tc_internal_compare_expr(tc::compare, rhs, lhs, expr) )\n\t#define tc_compare_expr_reverse_if( cond, expr ) tc_return_if_not_equal( tc::negate_if(cond, tc_internal_compare_expr(tc::compare, lhs, rhs, expr)) )\n\t#define tc_compare_expr_times_sign( expr, sign ) tc_return_if_not_equal( tc_internal_compare_expr(tc::compare, lhs, rhs, expr)*(sign) )\n\n\t#define tc_compare_expr_lex( expr ) tc_return_if_not_equal( tc_internal_compare_expr(tc::lexicographical_compare_3way, lhs, rhs, expr) )\n\t#define tc_compare_expr_lex_reverse( expr ) tc_return_if_not_equal( tc_internal_compare_expr(tc::lexicographical_compare_3way, rhs, lhs, expr) )\n\t#define tc_compare_expr_lex_reverse_if( cond, expr ) tc_return_if_not_equal( tc::negate_if(cond, tc_internal_compare_expr(tc::lexicographical_compare_3way, lhs, rhs, expr)) )\n\t#define tc_compare_expr_lex_times_sign( expr, sign ) tc_return_if_not_equal( tc_internal_compare_expr(tc::lexicographical_compare_3way, lhs, rhs, expr)*(sign) )\n\n\t#define tc_compare_base( basetype ) \\\n\t\ttc_compare_expr( tc::base_cast<basetype>(_) );\n\n\t#define tc_compare_mask( maskmember, maskvalue ) \\\n\t\ttc_compare_expr( tc::explicit_cast<bool>((_.m_ ## maskmember) & (maskmember ## maskvalue)) )\n\n\t#define tc_compare_aspect_if_var( tplbb,  expr ) \\\n\t\tif (auto const tplbb = tc_internal_compare_expr(tc_fn(tc::make_tuple), lhs, rhs, tc::explicit_cast<bool>(expr)); tplbb != tc::make_tuple(true,true)) { \\\n\t\t\tif (tplbb == tc::make_tuple(false, true)) return std::weak_ordering::less; \\\n\t\t\telse if (tplbb == tc::make_tuple(true, false)) return std::weak_ordering::greater; \\\n\t\t} else \\\n\n\t#define tc_compare_aspect_if( expr ) tc_compare_aspect_if_var(UNIQUE_IDENTIFIER, expr)\n\n\t#define tc_compare_aspect( maskmember, maskvalue, member ) \\\n\t\ttc_compare_aspect_if((_.m_ ## maskmember) & (maskmember ## maskvalue)) tc_compare_expr( _.member )\n\n\t#define tc_compare_aspect_lex( maskmember, maskvalue, member ) \\\n\t\ttc_compare_aspect_if((_.m_ ## maskmember) & (maskmember ## maskvalue)) tc_compare_expr_lex( _.member )\n\n\t#define tc_hash_aspect( maskmember, maskvalue, member ) \\\n\t\tif((t.m_ ## maskmember) & (maskmember ## maskvalue)) { \\\n\t\t\ttc::hash_append(h, t.member ); \\\n\t\t\ttc::hash_append(h, true); \\\n\t\t} else { \\\n\t\t\ttc::hash_append(h, false); \\\n\t\t}\n\n\t///////////////////////////////////////////////////////////\n\t// compare on specific types\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr auto lexicographical_compare_3way(Rng const& rng) noexcept {\n#if 0 // TODO Xcode14\n\t\treturn tc::value_or(tc::find_first_if<tc::return_value_or_none>(rng, [](auto const order) {\n\t\t\treturn tc::is_neq(order);\n\t\t}), std::weak_ordering::equal);\n#else // constexpr workaround\n\t\ttc::range_value_t<Rng> order=std::weak_ordering::equivalent;\n\t\ttc::for_each(rng, [&](auto const& order2) noexcept {\n\t\t\tif(tc::is_neq(order2)) {\n\t\t\t\torder = order2;\n\t\t\t\treturn tc::break_;\n\t\t\t}\n\t\t\treturn tc::continue_;\n\t\t});\n\t\treturn order;\n#endif\n\t}\n\n\tnamespace lexicographical_compare_3way_detail {\n\t\tTC_DEFINE_ENUM(EPrefix, eprefix, (FORBID)(ALLOW)(EQUIVALENT))\n\t\ttemplate< EPrefix eprefix, typename Lhs, typename Rhs, typename FnCompare >\n\t\tconstexpr auto lexicographical_compare_3way_impl( Lhs const& lhs, Rhs const& rhs, FnCompare fnCompare) noexcept ->\n\t\t\tdecltype(fnCompare(*tc::begin(lhs), *tc::begin(rhs)))\n\t\t{\n\t\t\tauto itLhs=tc::begin( lhs );\n\t\t\tauto const itLhsEnd=tc::end( lhs );\n\t\t\tauto itRhs=tc::begin( rhs );\n\t\t\tauto const itRhsEnd=tc::end( rhs );\n\n\t\t\tfor(;;) {\n\t\t\t\tif( itLhs==itLhsEnd ) {\n\t\t\t\t\tif constexpr(eprefixEQUIVALENT==eprefix) {\n\t\t\t\t\t\treturn std::weak_ordering::equivalent; // if lhs is a prefix of rhs this is considered equivalent\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif( itRhs==itRhsEnd ) {\n\t\t\t\t\t\t\treturn std::weak_ordering::equivalent;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t_ASSERTE(eprefixALLOW==eprefix);\n\t\t\t\t\t\t\treturn std::weak_ordering::less; // lhs shorter than rhs, thus <\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( itRhs==itRhsEnd ) {\n\t\t\t\t\t_ASSERTE(eprefixFORBID!=eprefix);\n\t\t\t\t\treturn std::weak_ordering::greater; // rhs shorter than lhs, thus >\n\t\t\t\t}\n\t\t\t\ttc_return_if_not_equal( fnCompare( *itLhs, *itRhs ) );\n\t\t\t\t++itLhs;\n\t\t\t\t++itRhs;\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename Lhs, typename Rhs, typename FnCompare = tc::fn_compare >\n\t[[nodiscard]] constexpr auto lexicographical_compare_3way(Lhs const& lhs, Rhs const& rhs, FnCompare&& fnCompare = FnCompare()) noexcept {\n\t\treturn lexicographical_compare_3way_detail::lexicographical_compare_3way_impl<lexicographical_compare_3way_detail::eprefixALLOW>(lhs, rhs, tc_move_if_owned(fnCompare));\n\t}\n\ttemplate< typename Lhs, typename Rhs, typename FnCompare = tc::fn_compare >\n\t[[nodiscard]] constexpr auto lexicographical_compare_3way_noprefix(Lhs const& lhs, Rhs const& rhs, FnCompare&& fnCompare = FnCompare()) noexcept {\n\t\treturn lexicographical_compare_3way_detail::lexicographical_compare_3way_impl<lexicographical_compare_3way_detail::eprefixFORBID>(lhs, rhs, tc_move_if_owned(fnCompare));\n\t}\n\ttemplate< typename Lhs, typename Rhs, typename FnCompare = tc::fn_compare >\n\t[[nodiscard]] constexpr auto lexicographical_compare_3way_prefixequivalence(Lhs const& lhs, Rhs const& rhs, FnCompare&& fnCompare = FnCompare()) noexcept {\n\t\treturn lexicographical_compare_3way_detail::lexicographical_compare_3way_impl<lexicographical_compare_3way_detail::eprefixEQUIVALENT>(lhs, rhs, tc_move_if_owned(fnCompare));\n\t}\n\n\ttc_define_fn( lexicographical_compare_3way );\n\ttc_define_fn( lexicographical_compare_3way_noprefix );\n\ttc_define_fn( lexicographical_compare_3way_prefixequivalence );\n}\n\n#if defined(__clang__) && !defined(__cpp_lib_three_way_comparison) // three way comparison operators are not implemented for library types in Xcode13/14. TODO Xcode15\nnamespace std { // ADL\n\ttemplate<typename Char, typename CharTraits, typename Alloc>\n\t[[nodiscard]] auto operator<=>(std::basic_string<Char, CharTraits, Alloc> const& lhs, std::basic_string<Char, CharTraits, Alloc> const& rhs) noexcept {\n\t\treturn tc::lexicographical_compare_3way(lhs, rhs);\n\t}\n\n\ttemplate<typename Char, typename CharTraits, typename Alloc>\n\t[[nodiscard]] auto operator<=>(std::basic_string<Char, CharTraits, Alloc> const& lhs, Char const* rhs) noexcept {\n\t\treturn tc::lexicographical_compare_3way(lhs, rhs);\n\t}\n\n\ttemplate< typename First, typename Second >\n\t[[nodiscard]] constexpr auto operator<=>(std::pair<First, Second> const& lhs, std::pair<First, Second> const& rhs) noexcept requires requires {\n\t\ttc::compare(lhs.first, rhs.first);\n\t\ttc::compare(lhs.second, rhs.second);\n\t} {\n\t\ttc_compare_expr( _.first );\n\t\ttc_compare_expr( _.second );\n\t\treturn std::weak_ordering::equivalent;\n\t}\n\t\n\ttemplate<typename T, typename Alloc>\n\t[[nodiscard]] auto operator<=>(std::vector<T, Alloc> const& lhs, std::vector<T, Alloc> const& rhs) noexcept {\n\t\treturn tc::lexicographical_compare_3way(lhs, rhs);\n\t}\n\t\n\ttemplate<typename T, std::size_t N>\n\t[[nodiscard]] auto operator<=>(std::array<T, N> const& lhs, std::array<T, N> const& rhs) noexcept {\n\t\treturn tc::lexicographical_compare_3way(lhs, rhs);\n\t}\n\t\n\ttemplate<typename... T>\n\t[[nodiscard]] constexpr auto operator<=>(std::variant<T...> const& lhs, std::variant<T...> const& rhs) noexcept\n\t\trequires requires { typename boost::mp11::mp_list<decltype(tc::compare(std::declval<T const&>(), std::declval<T const&>()))...>; }\n\t{\n\t\tif(lhs.valueless_by_exception() && rhs.valueless_by_exception()) {\n\t\t\treturn std::weak_ordering::equivalent;\n\t\t} else if(lhs.valueless_by_exception()) {\n\t\t\treturn std::weak_ordering::less;\n\t\t} else if(rhs.valueless_by_exception()) {\n\t\t\treturn std::weak_ordering::greater;\n\t\t} else {\n\t\t\ttc_compare_expr(_.index());\n\t\t\treturn tc::fn_visit(\n\t\t\t\t[]<typename TVal>(TVal const& valLhs, TVal const& valRhs) noexcept {\n\t\t\t\t\treturn tc::compare(valLhs, valRhs);\n\t\t\t\t},\n\t\t\t\ttc::never_called<std::weak_ordering>()\n\t\t\t)(lhs, rhs);\n\t\t}\n\t}\n\n\ttemplate<typename T, typename U>\n\tconstexpr auto operator<=>(std::optional<T> const& lhs, std::optional<U> const& rhs ) noexcept -> decltype(tc::compare(*lhs, *rhs)) {\n\t\treturn lhs && rhs ? tc::compare(*lhs, *rhs) : tc::compare(static_cast<bool>(lhs), static_cast<bool>(rhs));\n\t}\n\n\ttemplate<typename T>\n\tconstexpr std::weak_ordering operator<=>(std::optional<T> const& opt, std::nullopt_t) noexcept {\n\t\treturn tc::compare(static_cast<bool>(opt), false);\n\t}\n\n\ttemplate<typename T, typename U, std::enable_if_t<!tc::instance<U, std::optional>>* = nullptr>\n\tconstexpr auto operator<=>(std::optional<T> const& opt, U const& value) noexcept -> decltype(tc::compare(*opt, value)) {\n\t\treturn opt ? tc::compare(*opt, value) : std::weak_ordering::less;\n\t}\n}\n#endif\n\nnamespace tc {\n\t///////////////////////////////////\n\t// argument-wise transformation\n\n\tnamespace no_adl {\n\t\t// cannot be implemented as a lambda because lambdas are not assignable\n\t\ttemplate< typename Func, typename Transform>\n\t\tstruct [[nodiscard]] projected_impl /*not final, containers may derive from predicates to benefit from EBCO*/\n\t\t{\n\t\t\ttc::verify_functor_t<tc::decay_t<Func>> m_func;\n\t\t\ttc::verify_functor_t<tc::decay_t<Transform>> m_transform;\n\n\t\t\ttemplate <typename... Args>\n\t\t\tconstexpr auto operator()(Args&&... args) const& return_decltype_allow_xvalue_slow_MAYTHROW(\n\t\t\t\ttc_invoke_pack(m_func, tc_invoke(m_transform, tc_move_if_owned(args)))\n\t\t\t)\n\n\t\t\tusing is_transparent = void;\n\t\t};\n\t}\n\n\ttemplate< typename Func, typename Transform >\n\tconstexpr decltype(auto) projected(Func&& func, Transform&& transform) noexcept {\n\t\tif constexpr( std::is_same<tc::decay_t<Transform>, tc::identity>::value ) {\n\t\t\treturn tc_move_if_owned(func);\n\t\t} else {\n\t\t\treturn no_adl::projected_impl<Func, Transform>{ tc_move_if_owned(func), tc_move_if_owned(transform) };\n\t\t}\n\t}\n\n\t///////////////////////////////////\n\t// converse_relation\n\n\ttemplate<typename Pred>\n\tauto reverse_binary_rel(Pred&& pred) noexcept {\n\t\treturn [pred=tc::decay_copy(tc_move_if_owned(pred))](auto const& lhs, auto const& rhs) noexcept {\n\t\t\treturn pred(rhs, lhs);\n\t\t};\n\t}\n\n\t////////////////////////////////\n\t// Provide adapter from 3-way compare to 2-way compare\n\n\ttemplate< typename FCompare>\n\tconstexpr auto lessfrom3way( FCompare&& fnCompare ) noexcept {\n\t\treturn tc::chained(tc_fn(std::is_lt), tc_move_if_owned(fnCompare));\n\t}\n\n\ttemplate< typename FCompare>\n\tconstexpr auto greaterfrom3way( FCompare&& fnCompare ) noexcept {\n\t\treturn tc::chained(tc_fn(std::is_gt), tc_move_if_owned(fnCompare));\n\t}\n\n\ttemplate< typename FCompare>\n\tconstexpr auto equalfrom3way( FCompare&& fnCompare ) noexcept {\n\t\treturn tc::chained(tc_fn(tc::is_eq), tc_move_if_owned(fnCompare));\n\t}\n\n\tnamespace tuple_adl {\n\t\ttemplate<typename... T, typename... U> requires requires { typename boost::mp11::mp_list<decltype(tc::compare(std::declval<T const&>(), std::declval<U const&>()))...>; }\n\t\tconstexpr auto operator<=>(tc::tuple<T...> const& lhs, tc::tuple<U...> const& rhs) noexcept {\n\t\t\tSTATICASSERTEQUAL(sizeof...(T), sizeof...(U));\n\t\t\treturn tc::lexicographical_compare_3way(\n\t\t\t\ttc::transform(std::index_sequence_for<T...>(), [&](auto const nconstIndex) noexcept -> std::weak_ordering {\n\t\t\t\t\treturn tc::compare(tc::get<nconstIndex()>(lhs), tc::get<nconstIndex()>(rhs));\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}\n} // namespace tc\n\n#define EQUAL_MEMBER_IMPL(member) (lhs.member == rhs.member)\n#define EQUAL_MEMBERS(...) (TC_PP_DELIMIT_TRANSFORMED_SEQ(EQUAL_MEMBER_IMPL, &&, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))\n"
  },
  {
    "path": "tc/algorithm/element.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"find.h\"\n#include \"../range/range_return.h\"\n\nnamespace tc {\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] constexpr decltype(auto) front(auto&& rng) noexcept {\n\t\treturn tc::find_first_if<RangeReturn>(tc_move_if_owned(rng), tc::constexpr_function<true>());\n\t}\n\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] constexpr decltype(auto) back(auto&& rng) noexcept {\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_void>::value );\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_bool>::value, \"Use tc::empty instead of tc::back<tc::return_bool>\" );\n\t\tstatic_assert( tc::bidirectional_range<std::remove_reference_t<decltype(rng)>> ); // TODO reverse generator would also be fine, but find_last_if is not specialized for this case yet.\n\t\treturn tc::find_last_if<RangeReturn>(tc_move_if_owned(rng), tc::constexpr_function<true>());\n\t}\n\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] decltype(auto) linear_back(auto&& rng) noexcept {\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_void>::value );\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_bool>::value, \"Use tc::empty instead of tc::linear_back<tc::return_bool>\" );\n\t\tstatic_assert( !tc::bidirectional_range<std::remove_reference_t<decltype(rng)>>, \"Use tc::back for bidirectional ranges\" );\n\t\tauto it = tc::begin(rng);\n\t\ttc_auto_cref(itEnd, tc::end(rng));\n\t\tif (it!=itEnd) {\n\t\t\tauto itNext = it;\n\t\t\twhile (itEnd!=++itNext) {\n\t\t\t\tit = itNext;\n\t\t\t}\n\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] constexpr auto at(auto&& rng, typename boost::range_size< std::remove_reference_t<decltype(rng)> >::type n) noexcept {\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_void>::value );\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_bool>::value, \"Use tc::size instead of tc::at<tc::return_bool>\" );\n\t\tif (n<tc::size_raw(rng)) {\n\t\t\t_ASSERTE(0<=n);\n\t\t\tauto it=tc::begin(rng);\n\t\t\tit += n;\n\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] constexpr auto linear_at(auto&& rng, typename boost::range_size< std::remove_reference_t<decltype(rng)> >::type n) noexcept {\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_void>::value );\n\t\tstatic_assert( !std::is_same<RangeReturn, tc::return_bool>::value, \"Use tc::size_bounded instead of tc::linear_at<tc::return_bool>\" );\n\t\tif constexpr (std::convertible_to<typename boost::range_traversal<decltype(rng)>::type, boost::iterators::random_access_traversal_tag>) {\n\t\t\treturn tc::at<RangeReturn>(tc_move_if_owned(rng), tc_move(n));\n\t\t} else {\n\t\t\t_ASSERTE(0<=n);\n\t\t\ttc_auto_cref(itEnd, tc::end(rng));\n\t\t\tfor (auto it=tc::begin(rng); it!=itEnd; ++it, --n) {\n\t\t\t\tif (0==n) {\n\t\t\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\ttemplate <typename RangeReturn>\n\t[[nodiscard]] constexpr auto reverse_at(auto&& rng, typename boost::range_size< std::remove_reference_t<decltype(rng)> >::type n) noexcept {\n\t\tif (n<tc::size_raw(rng)) {\n\t\t\t_ASSERTE(0<=n);\n\t\t\tauto it=tc::end(rng);\n\t\t\tit -= n+1;\n\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\tnamespace only_detail {\n\t\ttemplate<typename RangeReturn, typename Rng>\n\t\ttc::element_return_type_t<RangeReturn, Rng> only_not_X(Rng&& rng, auto func) MAYTHROW {\n\t\t\tif constexpr(RangeReturn::requires_iterator) {\n\t\t\t\tauto const itEnd = tc::end(rng);\n\t\t\t\tauto const itBegin = tc::begin(rng);\n\t\t\t\tif(itEnd != itBegin && (itEnd == tc_modified(itBegin, ++_) || tc::explicit_cast<bool>(func()))) {\n\t\t\t\t\treturn RangeReturn::pack_element(itBegin, tc_move_if_owned(rng));\n\t\t\t\t} else {\n\t\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstd::optional<tc::element_return_type_t<RangeReturn, Rng>> ot;\n\t\t\t\tauto const boc = tc::for_each(tc_move_if_owned(rng), [&](auto&& t) MAYTHROW {\n\t\t\t\t\tif(!ot) {\n\t\t\t\t\t\ttc::optional_emplace(ot, RangeReturn::template pack_element<Rng>(tc_move_if_owned(t))); // MAYTHROW\n\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif(ot && (tc::continue_ == boc || tc::explicit_cast<bool>(func()))) {\n\t\t\t\t\treturn *tc_move(ot);\n\t\t\t\t} else {\n\t\t\t\t\treturn RangeReturn::template pack_no_element<Rng>();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename RangeReturn>\n\t[[nodiscard]] constexpr decltype(auto) only(auto&& rng) MAYTHROW {\n\t\tstatic_assert(std::is_same<RangeReturn, tc::return_value>::value || std::is_same<RangeReturn, tc::return_element>::value, \"decide between tc::only_not_0<...> and tc::only_not_N<...>\"); // Exclude tc::return_XXX_or_YYY. TODO: make static_assert more generic\n\t\treturn tc::find_unique_if<RangeReturn>(tc_move_if_owned(rng), tc::constexpr_function<true>());\n\t}\n\n\ttemplate<typename RangeReturn>\n\t[[nodiscard]] decltype(auto) only_not_0(auto&& rng) MAYTHROW {\n\t\tstatic_assert(!std::is_same<RangeReturn, tc::return_value>::value && !std::is_same<RangeReturn, tc::return_element>::value, \"use tc::only<...> instead\"); // TODO: make static_assert more generic\n\t\treturn only_detail::only_not_X<RangeReturn>(tc_move_if_owned(rng), tc::never_called<tc::constant<true>>());\n\t}\n\n\ttemplate<typename RangeReturn>\n\t[[nodiscard]] decltype(auto) only_not_N(auto&& rng) MAYTHROW {\n\t\tstatic_assert(!std::is_same<RangeReturn, tc::return_value>::value && !std::is_same<RangeReturn, tc::return_element>::value, \"use tc::only<...> instead\"); // TODO: make static_assert more generic\n\t\treturn only_detail::only_not_X<RangeReturn>(tc_move_if_owned(rng), tc::constexpr_function<false>());\n\t}\n\n\tnamespace no_adl{\n\t\ttemplate<typename Element>\n\t\tstruct element_stash_impl final {\n\t\t\tstatic_assert(tc::decayed<Element>);\n\t\t\t[[nodiscard]] static constexpr decltype(auto) extract(Element&& elem) noexcept(noexcept(*tc_move(elem))) {\n#ifdef _DEBUG\n\t\t\t\tif constexpr(std::is_reference<decltype(*elem)>::value) {\n\t\t\t\t\t_ASSERTE(std::addressof(*tc::decay_copy(elem))==std::addressof(*elem)); // specialize is_stashing_element<Element>\n\t\t\t\t}\n#endif\n\t\t\t\treturn *tc_move(elem);\n\t\t\t}\n\t\t};\n\n#ifdef _MSC_VER\n\t\t// If Element is of type T(*)[N], MSVC erroneously deduces return type T(*)[N] for element_stash_impl<Element>::extract,\n\t\t// and then raises a compiler error that it cannot convert from T[N] to T(*)[N] in the return statement.\n\t\t// Clang correctly deduces return type T(&)[N]. Add specialization for array types to workaround this problem.\n\t\ttemplate<typename T, std::size_t N>\n\t\tstruct element_stash_impl<T(*)[N]> final {\n\t\t\tusing array_type=T[N];\n\t\t\t[[nodiscard]] static constexpr array_type& extract(T(*a)[N]) noexcept {\n\t\t\t\treturn *a;\n\t\t\t}\n\t\t};\n#endif\n\n\t\t// MSVC 19.31.31104 claims tc::is_stashing_element<Element>::value is not of type bool when directly used in a requires clause on element_stash_impl<Element>.\n\t\t// Outline to template variable to avoid silent bad codegen due to wrong sfinae.\n\t\ttemplate<typename Element>\n\t\tinline bool constexpr is_stashing_element_v = tc::is_stashing_element<Element>::value;\n\n\t\t// Lifetime of reference is bound to the iterator -> must keep iterator alive\n\t\ttemplate<typename Element> requires is_stashing_element_v<Element>\n\t\tstruct element_stash_impl<Element> final : tc::storage_for_dtor_at_end_of_scope<Element> {\n\t\t\tstatic_assert(tc::decayed<Element>);\n\t\t\t[[nodiscard]] constexpr decltype(auto) extract(Element&& elem) & noexcept(noexcept(*tc_move_always(this->operator*()))) { // note that constexpr only works for trivially constructible/assignable/destructible type\n\t\t\t\tthis->ctor(tc_move(elem));\n\t\t\t\treturn *tc_move_always(this->operator*());\n\t\t\t}\n\t\t};\n\t}\n\ttemplate<typename Rng>\n\tusing element_stash = no_adl::element_stash_impl<tc::iterator_t<Rng>>;\n\n#pragma push_macro(\"RETURN_REFERENCE_FROM_ELEMENT\")\n\t// Make first template argument non-type to avoid name(rng) instantiating name<tc::return_element, Rng> and then name<tc::return_element, tc::return_element> which leads to hard error.\n#define RETURN_REFERENCE_FROM_ELEMENT(name) \\\n\ttemplate <int = 0, typename Rng> \\\n\t[[nodiscard]] constexpr decltype(auto) name( \\\n\t\tRng&& rng, \\\n\t\ttc::element_stash<Rng>&& stash={} \\\n\t) return_MAYTHROW( \\\n\t\tstash.extract(tc::name<tc::return_element>(tc_move_if_owned(rng))) \\\n\t) \\\n\t\\\n\t/* Use tc::fn_front() instead of tc_fn(tc::front) because the latter returns a dangling xvalue reference when used with counting ranges. */ \\\n\t/* Support tc::fn_front<tc::return_xxx>() for consistency*/ \\\n\tnamespace no_adl { \\\n\t\ttemplate<typename RangeReturn=void> \\\n\t\tstruct [[nodiscard]] fn_ ## name final { \\\n\t\t\ttemplate <typename Rng> requires tc::borrowed_range<Rng> \\\n\t\t\tauto operator()(Rng&& rng) const& return_decltype_allow_xvalue_MAYTHROW( \\\n\t\t\t\ttc::name<RangeReturn>(tc_unwrap_temporary(tc_move_if_owned(rng))) \\\n\t\t\t) \\\n\t\t\ttemplate <typename Rng> \\\n\t\t\tauto operator()(Rng&& rng) const& return_decltype_allow_xvalue_MAYTHROW( \\\n\t\t\t\ttc_rewrap_temporary(Rng, tc::name<RangeReturn>(tc_unwrap_temporary(tc_move_if_owned(rng)))) \\\n\t\t\t) \\\n\t\t}; \\\n\t\ttemplate<> \\\n\t\tstruct [[nodiscard]] fn_ ## name<void> final { \\\n\t\t\ttemplate <typename Rng> requires tc::borrowed_range<Rng> || tc::is_stashing_element<tc::iterator_t<Rng>>::value \\\n\t\t\tauto operator()(Rng&& rng, tc::element_stash<Rng>&& stash={}) const& return_decltype_allow_xvalue_MAYTHROW( \\\n\t\t\t\ttc::name(tc_unwrap_temporary(tc_move_if_owned(rng)), tc_move(stash)) \\\n\t\t\t) \\\n\t\t\ttemplate <typename Rng> \\\n\t\t\tauto operator()(Rng&& rng, tc::element_stash<Rng>&& stash={}) const& return_decltype_allow_xvalue_MAYTHROW( \\\n\t\t\t\ttc_rewrap_temporary(Rng, tc::name(tc_unwrap_temporary(tc_move_if_owned(rng)), tc_move(stash))) \\\n\t\t\t) \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_ ## name;\n\n\tRETURN_REFERENCE_FROM_ELEMENT(front)\n\tRETURN_REFERENCE_FROM_ELEMENT(back)\n\tRETURN_REFERENCE_FROM_ELEMENT(linear_back)\n\tRETURN_REFERENCE_FROM_ELEMENT(only)\n#pragma pop_macro(\"RETURN_REFERENCE_FROM_ELEMENT\")\n\n#pragma push_macro(\"RETURN_REFERENCE_FROM_INDEXED_ELEMENT\")\n#define RETURN_REFERENCE_FROM_INDEXED_ELEMENT(fn) \\\n\ttemplate <int = 0, typename Rng> \\\n\t[[nodiscard]] constexpr decltype(auto) fn( \\\n\t\tRng&& rng, \\\n\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type i, \\\n\t\ttc::element_stash<Rng>&& stash={} \\\n\t) return_MAYTHROW( \\\n\t\tstash.extract(tc::fn<tc::return_element>(tc_move_if_owned(rng), tc_move(i))) \\\n\t)\n\n\tRETURN_REFERENCE_FROM_INDEXED_ELEMENT(at)\n\tRETURN_REFERENCE_FROM_INDEXED_ELEMENT(linear_at)\n\tRETURN_REFERENCE_FROM_INDEXED_ELEMENT(reverse_at)\n#pragma pop_macro(\"RETURN_REFERENCE_FROM_INDEXED_ELEMENT\")\n\n// Write as macros to keep temporary iterators alive.\n// By standard, the lifetime of a reference is limited to the lifetime of the iterator.\n#define tc_front_nodebug(rng) (*tc::begin(rng))\n#define tc_at_nodebug(rng, i) *(tc::begin(rng) + static_cast<decltype(tc::begin(rng) - tc::begin(rng))>(i))\n\n\ttemplate<typename Rng, typename Func>\n\tbool if_nonempty_with_only(Rng&& rng, Func func) MAYTHROW {\n\t\tbool bCalled=false;\n\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&&... args) MAYTHROW {\n\t\t\tVERIFY(tc::change(bCalled, true)); // only a single element is allowed\n\n\t\t\tRETURNS_VOID( func(tc_move_if_owned(args)...) ); // MAYTHROW\n\n\t\t\treturn tc::constant<tc::continue_>();\n\t\t});\n\t\treturn bCalled;\n\t}\n\n\ttemplate<typename Rng, typename Func>\n\tbool if_nonempty_with_front(Rng&& rng, Func func) MAYTHROW {\n\t\treturn tc::break_==tc::for_each(tc_move_if_owned(rng), [&](auto&&... args) MAYTHROW{\n\t\t\tRETURNS_VOID(func(tc_move_if_owned(args)...)); // MAYTHROW\n\t\t\treturn tc::constant<tc::break_>();\n\t\t});\n\t}\n\n\ttemplate<typename RangeReturn, typename T, typename Rng>\n\t[[nodiscard]] std::pair<tc::element_return_type_t<RangeReturn, Rng>, T> front_and_size_bounded(Rng&& rng, T nMax) MAYTHROW {\n\t\tstatic_assert(!RangeReturn::requires_iterator, \"implement iterator version if needed\");\n\t\ttc::storage_for<tc::element_return_type_t<RangeReturn, Rng>> ot;\n\t\tT n=0;\n\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&& t) MAYTHROW {\n\t\t\tif (0==n) {\n\t\t\t\tot.ctor(RangeReturn::template pack_element<Rng>(tc_move_if_owned(t)));\n\t\t\t}\n\t\t\t++n;\n\t\t\treturn (nMax<=n) ? tc::break_ : tc::continue_;\n\t\t});\n\t\tif (0==n) {\n\t\t\ttc_return_cast(RangeReturn::template pack_no_element<Rng>(), tc_move(n));\n\t\t} else {\n\t\t\ttc_scope_exit { ot.dtor(); };\n\t\t\ttc_return_cast(*tc_move(ot), tc_move(n));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/element.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"element.h\"\n#include \"../unittest.h\"\n#include \"../array.h\"\n\nnamespace {\n\tUNITTESTDEF( front ) {\n\t\t_ASSERTEQUAL(tc::front<tc::return_value>(tc::single(1)), 1);\n\t\t_ASSERTEQUAL(*tc::front<tc::return_element>(tc::single(1)), 1);\n\t\t_ASSERTEQUAL(tc::front<tc::return_value_or_none>(tc::make_empty_range<int>()), std::nullopt);\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/empty.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/trivial_functors.h\"\n#include \"for_each.h\"\n\nnamespace tc {\n\tnamespace empty_internal {\n\t\t// TODO: inline when clang supports lambdas in unevaluated contexts\n\t\ttemplate<typename Rng>\n\t\tconstexpr auto empty(Rng&& rng) noexcept {\n\t\t\tif constexpr(has_constexpr_size<Rng>) {\n\t\t\t\treturn [&]() return_decltype_noexcept(0==constexpr_size<Rng>());\n\t\t\t} else if constexpr(has_mem_fn_empty<Rng>) {\n\t\t\t\treturn [&]() return_MAYTHROW(tc_move_if_owned(rng).empty());\n\t\t\t} else if constexpr(tc::range_with_iterators<Rng>) {\n\t\t\t\treturn [&]() return_MAYTHROW(tc::at_end_index(rng, tc::begin_index(rng)));\n\t\t\t} else if constexpr(has_size<Rng>) {\n\t\t\t\treturn [&]() return_MAYTHROW(0==tc::size(tc_move_if_owned(rng))); // tc::size on files may throw\n\t\t\t} else {\n\t\t\t\treturn [&]() return_MAYTHROW(tc::continue_==tc::for_each(tc_move_if_owned(rng), tc::constexpr_function<tc::constant<tc::break_>{}>()));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr bool empty(Rng&& rng) return_MAYTHROW(\n\t\tempty_internal::empty(tc_move_if_owned(rng))()\n\t)\n}\n"
  },
  {
    "path": "tc/algorithm/empty.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/empty.h\"\n#include \"../container/insert.h\"\n\nnamespace {\n\nstruct empty_generator { \n  template<typename Func> tc::break_or_continue operator()(Func) const { return tc::continue_; }\n};\n\nstruct non_empty_generator { \n  template<typename Func> tc::break_or_continue operator()(Func func) const { return tc::continue_if_not_break(func, 1); }\n};\n\nUNITTESTDEF( empty_range ) {\n\t{ // test container with empty() method\n\t\ttc::vector<int> vec;\n\t\tstatic_assert( has_mem_fn_empty<decltype(vec)> );\n\t\t_ASSERT( tc::empty(vec) );\n\t\t_ASSERT( tc::empty(vec) );\n\n\t\ttc::cont_emplace_back(vec, 1);\n\t\t_ASSERT( !tc::empty(vec) );\n\t\t_ASSERT( !tc::empty(vec) );\n\t}\n\t{ // test iterator range\n\t\tstatic_assert( !has_mem_fn_empty<tc::decay_t<decltype(\"\")> > );\n\t\tstatic_assert( tc::range_with_iterators<decltype(\"\")> );\n\t\t_ASSERT( tc::empty(\"\") );\n\n\t\tstatic_assert( !has_mem_fn_empty<tc::decay_t<decltype(\"x\")> > );\n\t\tstatic_assert( tc::range_with_iterators<decltype(\"x\")> );\n\t\t_ASSERT( !tc::empty(\"x\") );\n\t}\n\t{ // test generator range\n\t\t_ASSERT( tc::empty( empty_generator() ) );\n\t\t_ASSERT( !tc::empty( non_empty_generator() ) );\n\t}\n}\n\n}\n\n"
  },
  {
    "path": "tc/algorithm/equal.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/noncopyable.h\"\n#include \"../base/as_lvalue.h\"\n#include \"../base/modified.h\"\n\n#include \"for_each.h\"\n#include \"../base/change.h\"\n\n#include <boost/range/iterator.hpp>\n\n#include <functional>\n#include <unordered_set>\n#include <unordered_map>\n\nnamespace tc{\n\tnamespace no_adl {\n\t\ttemplate< typename Lhs, typename Rhs>\n\t\tstruct has_parse_match final : tc::constant<false> {};\n\n\t\ttemplate< typename Lhs, typename Rhs >\n\t\t\trequires requires (Lhs const& lhs, Rhs const& rhs) { lhs.parse_match(rhs); }\n\t\tstruct has_parse_match<Lhs, Rhs> final : tc::constant<true> {};\n\t}\n\n\ttemplate<typename Lhs, typename Rhs, std::enable_if_t<!no_adl::has_parse_match<Lhs, Rhs>::value && !no_adl::has_parse_match<Rhs, Lhs>::value>* =nullptr>\n\t[[nodiscard]] constexpr auto equal_to_or_parse_match(Lhs const& lhs, Rhs const& rhs) return_decltype_MAYTHROW( tc::equal_to(lhs,rhs) )\n\n\ttemplate<typename Lhs, typename Rhs, std::enable_if_t<no_adl::has_parse_match<Lhs, Rhs>::value && !no_adl::has_parse_match<Rhs, Lhs>::value>* =nullptr>\n\t[[nodiscard]] constexpr auto equal_to_or_parse_match(Lhs const& lhs, Rhs const& rhs) return_decltype_MAYTHROW( tc::implicit_cast<bool>(lhs.parse_match(rhs)) )\n\n\ttemplate<typename Lhs, typename Rhs, std::enable_if_t<!no_adl::has_parse_match<Lhs, Rhs>::value && no_adl::has_parse_match<Rhs, Lhs>::value>* =nullptr>\n\t[[nodiscard]] constexpr auto equal_to_or_parse_match(Lhs const& lhs, Rhs const& rhs) return_decltype_MAYTHROW( tc::implicit_cast<bool>(rhs.parse_match(lhs)) )\n\n\ttc_define_fn( equal_to_or_parse_match );\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// equal - check whether two ranges are equal - overloaded for combinations of generator and iterator based ranges\n\n\tnamespace equal_impl {\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Pred>\n\t\t\tstruct reverse_pred {\n\t\t\t\tPred& m_pred;\n\n\t\t\t\tconstexpr reverse_pred(Pred& pred) noexcept\n\t\t\t\t\t: m_pred(pred)\n\t\t\t\t{}\n\n\t\t\t\ttemplate<typename Arg1, typename Arg2>\n\t\t\t\tconstexpr auto operator()(Arg1&& arg1, Arg2&& arg2) const& noexcept {\n\t\t\t\t\treturn m_pred(tc_move_if_owned(arg2), tc_move_if_owned(arg1));\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate<typename It, typename ItEnd, typename Pred>\n\t\t\tstruct is_equal_elem /*final*/ {\n\t\t\t\tconstexpr explicit is_equal_elem(\n\t\t\t\t\tIt& it,\n\t\t\t\t\tItEnd itEnd,\n\t\t\t\t\tPred& pred\n\t\t\t\t) noexcept\n\t\t\t\t\t: m_it(it)\n\t\t\t\t\t, m_itEnd(tc_move(itEnd))\n\t\t\t\t\t, m_pred(pred)\n\t\t\t\t{}\n\n\t\t\t\ttemplate<typename Elem> requires requires(Pred& pred, It& it, Elem const& elem) { tc_invoke(pred, tc::as_const(*it), elem); }\n\t\t\t\tconstexpr break_or_continue operator()(Elem const& elem) const& noexcept {\n\t\t\t\t\tif (m_it == m_itEnd || !tc::explicit_cast<bool>(tc_invoke(m_pred, tc::as_const(*m_it), elem))) { return tc::break_; }\n\t\t\t\t\t++m_it;\n\t\t\t\t\treturn tc::continue_;\n\t\t\t\t}\n\n\t\t\tprivate:\n\t\t\t\tIt& m_it;\n\t\t\t\tItEnd m_itEnd;\n\t\t\t\tPred& m_pred;\n\t\t\t};\n\n\t\t\t// TODO: this does not protect us against inputs such as transform(unordered_set)\n\t\t\ttemplate<typename X> struct is_unordered_range : tc::constant<false> {};\n\t\t\ttemplate<typename... X> struct is_unordered_range<std::unordered_set<X...>> : tc::constant<true> {};\n\t\t\ttemplate<typename... X> struct is_unordered_range<std::unordered_map<X...>> : tc::constant<true> {};\n\t\t}\n\n\t\ttemplate<typename It, typename ItEnd, typename RRng, typename Pred>\n\t\t[[nodiscard]] constexpr bool starts_with(It& it, ItEnd itEnd, RRng&& rrng, Pred pred) noexcept(noexcept(tc::continue_ == tc::for_each(tc_move_if_owned(rrng), no_adl::is_equal_elem<It, ItEnd, Pred>(it, tc_move(itEnd), pred)))) {\n\t\t\tstatic_assert(!no_adl::is_unordered_range<tc::decay_t<RRng>>::value);\n\t\t\treturn tc::continue_ == tc::for_each(tc_move_if_owned(rrng), no_adl::is_equal_elem<It, ItEnd, Pred>(it, tc_move(itEnd), pred)); // MAYTHROW\n\t\t}\n\t}\n\n\ttemplate<typename RangeReturn, typename LRng, typename RRng, typename Pred>\n\t[[nodiscard]] constexpr decltype(auto) starts_with(LRng&& lrng, RRng const& rrng, Pred&& pred) noexcept {\n\t\tstatic_assert(!equal_impl::no_adl::is_unordered_range<tc::decay_t<LRng>>::value);\n\t\tauto itlrng = tc::begin(lrng);\n\t\treturn equal_impl::starts_with(itlrng, tc::end(lrng), rrng, tc_move_if_owned(pred))\n\t\t\t? RangeReturn::pack_border(itlrng, tc_move_if_owned(lrng))\n\t\t\t: RangeReturn::pack_no_border(tc_move_if_owned(lrng));\n\t}\n\n\ttemplate<typename RangeReturn, typename LRng, typename RRng>\n\t[[nodiscard]] constexpr decltype(auto) starts_with(LRng&& lrng, RRng const& rrng) noexcept {\n\t\treturn starts_with<RangeReturn>(tc_move_if_owned(lrng), rrng, tc::fn_equal_to_or_parse_match());\n\t}\n\n\ttemplate<tc::range_with_iterators LRng, typename RRng, typename Pred>\n\t\trequires (tc::prefers_for_each<std::remove_reference_t<RRng>> || (!tc::prefers_for_each<LRng>))\n\t\t\t&& requires(LRng const& lrng, RRng&& rrng){ equal_impl::starts_with(tc::as_lvalue(tc::begin(lrng)), tc::as_const(tc::as_lvalue(tc::end(lrng))), tc_move_if_owned(rrng), std::declval<Pred>()); }\n\t[[nodiscard]] constexpr bool equal(LRng const& lrng, RRng&& rrng, Pred&& pred) MAYTHROW {\n\t\tstatic_assert(!equal_impl::no_adl::is_unordered_range<tc::decay_t<LRng>>::value);\n\t\tconstexpr bool bHasSize=tc::has_size<LRng> && tc::has_size<RRng>;\n\t\tif constexpr(bHasSize) {\n\t\t\tif(tc::size(lrng)!=tc::size(rrng)) return false;\n\t\t}\n\t\tauto it = tc::begin(lrng);\n\t\ttc_auto_cref(itEnd, tc::end(lrng));\n\t\treturn equal_impl::starts_with(it,itEnd,tc_move_if_owned(rrng),tc_move_if_owned(pred)) && (bHasSize || itEnd==it); // MAYTHROW\n\t}\n\n\t// forward to the symmetric case above\n\ttemplate<typename LRng, tc::range_with_iterators RRng, typename Pred>\n\t\trequires tc::prefers_for_each<std::remove_reference_t<LRng>>\n\t\t\t&& (!tc::prefers_for_each<RRng>)\n\t[[nodiscard]] constexpr bool equal(LRng&& lrng, RRng const& rrng, Pred pred) noexcept {\n\t\treturn tc::equal(rrng, tc_move_if_owned(lrng), equal_impl::no_adl::reverse_pred<Pred>(pred));\n\t}\n\n\t// is_arithmetic helpful for generic programming\n\t// only do if semantics are clear-cut\n\ttemplate<typename T, typename Pred> requires std::is_arithmetic< T >::value\n\t[[nodiscard]] constexpr bool equal(T const& lhs, T const& rhs, Pred pred) noexcept {\n\t\treturn pred(lhs,rhs);\n\t}\n\n\ttemplate<typename R, typename S, typename T, typename U, typename Pred>\n\t[[nodiscard]] constexpr bool equal(std::pair<R,S> const& lhs, std::pair<T,U> const& rhs, Pred pred) noexcept {\n\t\treturn tc::equal(lhs.first, rhs.first, pred) && tc::equal(lhs.second, rhs.second, pred);\n\t}\n\n\t// forward the non predicate version\n\ttemplate<typename LRng, typename RRng>\n\t[[nodiscard]] constexpr bool equal(LRng&& lrng, RRng&& rrng) return_MAYTHROW(\n\t\ttc::equal(tc_move_if_owned(lrng), tc_move_if_owned(rrng), tc::fn_equal_to_or_parse_match())\n\t)\n\n\tDEFINE_FN2(tc::equal, fn_equal) // no tc_define_fn to avoid ADL\n\n\t// boost::ends_with does not work with boost::range_iterator<transform_range>::type returning by value because it has input_iterator category\n\ttemplate<typename RangeReturn, typename LRng, typename RRng, typename Pred=tc::fn_equal_to_or_parse_match>\n\t[[nodiscard]] constexpr decltype(auto) ends_with(LRng&& lrng, RRng const& rrng, Pred pred=Pred()) noexcept {\n\t\tauto itL=tc::end(lrng);\n\t\tauto itR=tc::end(rrng);\n\t\tauto const itBeginL=tc::begin(lrng);\n\t\tauto const itBeginR=tc::begin(rrng);\n\t\tfor(;;) {\n\t\t\tif( itR==itBeginR ) return RangeReturn::pack_border(itL, tc_move_if_owned(lrng));\n\t\t\tif( itL==itBeginL ) return RangeReturn::pack_no_border(tc_move_if_owned(lrng));\n\t\t\t--itR;\n\t\t\t--itL;\n\t\t\tif( !tc::explicit_cast<bool>(pred(tc::as_const(*itL),tc::as_const(*itR))) ) return RangeReturn::pack_no_border(tc_move_if_owned(lrng));\n\t\t}\n\t}\n\n\tnamespace value_equal_to_detail {\n\t\ttemplate<typename T>\n\t\tconcept safe_value =\n\t\t\t!tc::range_with_iterators<T> ||\n\t\t\t!tc::range_with_iterators<tc::mp_only<typename tc::is_instance<T, std::optional>::arguments>>;\n\t}\n\n\ttemplate <typename Lhs, typename Rhs>\n\t[[nodiscard]] constexpr bool value_equal_to(Lhs const& lhs, Rhs const& rhs) noexcept {\n\t\tif constexpr( tc::range_with_iterators<Lhs> && tc::range_with_iterators<Rhs> ) {\n\t\t\tSTATICASSERTEQUAL( TC_FWD(tc::instance<Lhs, std::optional>), TC_FWD(tc::instance<Rhs, std::optional>) );\n\t\t\treturn tc::equal(lhs, rhs, tc::equal_to);\n\t\t} else {\n\t\t\tstatic_assert( value_equal_to_detail::safe_value<Lhs> );\n\t\t\tstatic_assert( value_equal_to_detail::safe_value<Rhs> );\n\t\t\treturn tc::equal_to(lhs, rhs);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "tc/algorithm/equal.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n\nnamespace {\n\n//---- Equal with vector<int> -------------------------------------------------------------------------------------------------\nUNITTESTDEF( equal_vec_int ) {\n\ttc::vector<int> ve;\n\ttc::vector<int> ve_1;\n\tTEST_init_hack(tc::vector, int, v123, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v123_1, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v143, {1,4,3});\n\tTEST_init_hack(tc::vector, int, v1234, {1,2,3,4});\n\n\tTEST_RANGE_EQUAL(ve, ve);\n\tTEST_RANGE_EQUAL(ve, ve_1);\n\n\tTEST_RANGE_NOT_EQUAL(ve, v123);\n\tTEST_RANGE_NOT_EQUAL(v123, ve);\n\n\tTEST_RANGE_EQUAL(v123, v123);\n\tTEST_RANGE_EQUAL(v123, v123_1);\n\n\tTEST_RANGE_NOT_EQUAL(v123, v143);\n\tTEST_RANGE_NOT_EQUAL(v123, v1234);\n\tTEST_RANGE_NOT_EQUAL(v1234, v123);\n}\n\nUNITTESTDEF( equal_vec_int_pred ) {\n\tTEST_init_hack(tc::vector, int, v123, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v234, {2,3,4});\n\n\ttc_static_auto_constexpr_lambda(ofByOne) = [](int const lhs, int const rhs) noexcept { return (lhs + 1) == rhs; }; // unsymmetrical to uncover wrong order of argument application to the predicate\n\n\t_ASSERT(tc::equal(v123, v234, ofByOne));\n\t_ASSERT(!tc::equal(v234, v123, ofByOne));\n\t_ASSERT(!tc::equal(v123, v123, ofByOne));\n\n}\n\n//---- Equal with generators --------------------------------------------------------------------------------------------------\n\nUNITTESTDEF( equal_generator ) {\n\ttc::vector<int> ve;\n\ttc::vector<int> ve_1;\n\tTEST_init_hack(tc::vector, int, v123, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v123_1, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v143, {1,4,3});\n\tTEST_init_hack(tc::vector, int, v1234, {1,2,3,4});\n\n\tauto ge = tc::make_generator_range(ve);\n\tauto g123 = tc::make_generator_range(v123);\n\tauto g143 = tc::make_generator_range(v143);\n\tauto g1234 = tc::make_generator_range(v1234);\n\n\tSTATIC_ASSERT(tc::range_with_iterators<decltype(ve)>);\n\tSTATIC_ASSERT(!tc::range_with_iterators<decltype(ge)>);\n\n\tTEST_RANGE_EQUAL(ve, ge);\n\tTEST_RANGE_EQUAL(ge, ve);\n\t//TEST_RANGE_EQUAL(ge, ge); // Fails to compile with proper msg, as it should be.\n\n\tTEST_RANGE_EQUAL(v123, g123);\n\tTEST_RANGE_EQUAL(g123, v123);\n\tTEST_RANGE_EQUAL(v1234, g1234);\n\tTEST_RANGE_EQUAL(g1234, v1234);\n\n\tTEST_RANGE_NOT_EQUAL(v123, g143);\n\tTEST_RANGE_NOT_EQUAL(g123, v143);\n\tTEST_RANGE_NOT_EQUAL(v123, g1234);\n\tTEST_RANGE_NOT_EQUAL(g123, v1234);\n\tTEST_RANGE_NOT_EQUAL(v1234, g123);\n\tTEST_RANGE_NOT_EQUAL(g1234, v123);\n\n}\n\nUNITTESTDEF( equal_generator_pred ) {\n\tTEST_init_hack(tc::vector, int, v123, {1,2,3});\n\tTEST_init_hack(tc::vector, int, v234, {2,3,4});\n\n\tauto g123 = tc::make_generator_range(v123);\n\tauto g234 = tc::make_generator_range(v234);\n\n\ttc_static_auto_constexpr_lambda(ofByOne) = [](int const lhs, int const rhs) noexcept { return (lhs + 1) == rhs; };  // unsymmetrical to uncover wrong order of argument application to the predicate\n\n\t//_ASSERT(tc::equal(g123, g234, ofByOne)); // Fails to compile with proper msg, as it should be.\n\n\t_ASSERT(tc::equal(v123, g234, ofByOne));\n\t_ASSERT(!tc::equal(v234, g123, ofByOne));\n\t_ASSERT(!tc::equal(v123, g123, ofByOne));\n\n\t_ASSERT(tc::equal(g123, v234, ofByOne));\n\t_ASSERT(!tc::equal(g234, v123, ofByOne));\n\t_ASSERT(!tc::equal(g123, v123, ofByOne));\n}\n\nUNITTESTDEF( variadic_assign_better ) {\n\tint nVar = 5;\n\tbool b=tc::assign_better(tc::fn_less(), nVar, 6, 5, 9);\n\t_ASSERT(!b);\n\t_ASSERTEQUAL(nVar, 5);\n\tb=tc::assign_better(tc::fn_less(), nVar, 3);\n\t_ASSERT(b);\n\t_ASSERTEQUAL(nVar, 3);\n\tb=tc::assign_better(tc::fn_less(), nVar, 5, 2, 8, 0);\n\t_ASSERT(b);\n\t_ASSERTEQUAL(nVar, 0);\n}\n\nnamespace no_adl {\n\ttemplate<typename Better, typename List>\n\tstruct has_assign_better_impl final: tc::constant<false> {};\n\n\ttemplate<typename Better, typename Var, typename... Val>\n\t\trequires requires(Better&& better, Var&& var, Val&&... val) { tc::assign_better(tc_move_if_owned(better), tc_move_if_owned(var), tc_move_if_owned(val)...);}\n\tstruct has_assign_better_impl<Better, boost::mp11::mp_list<Var, Val...>> final: tc::constant<true> {};\n\n\ttemplate<typename Better, typename... T>\n\tusing has_assign_better = has_assign_better_impl<Better, boost::mp11::mp_list<T...>>;\n}\n#ifndef __EMSCRIPTEN__\nstatic_assert(!no_adl::has_assign_better<tc::fn_less, std::atomic<int>, int>::value);\nstatic_assert(!no_adl::has_assign_better<tc::fn_less, std::atomic<int>, int, int>::value);\nstatic_assert(no_adl::has_assign_better<tc::fn_less, std::atomic<int>&, int>::value);\nstatic_assert(no_adl::has_assign_better<tc::fn_less, std::atomic<int>&, int, int>::value);\n#endif\nstatic_assert(no_adl::has_assign_better<tc::fn_less, int&, int>::value);\nstatic_assert(no_adl::has_assign_better<tc::fn_less, int&, int, int>::value);\n}\n"
  },
  {
    "path": "tc/algorithm/filter_inplace.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../range/meta.h\"\n#include \"../range/range_return.h\"\n#include \"../container/container_traits.h\"\n#include \"../storage_for.h\"\n#include \"restrict_size_decrement.h\"\n\nnamespace tc {\n\n\ttemplate <typename T>\n\tstruct range_filter_by_move_element : tc::constant<\n\t\ttc::instance<T, std::basic_string> || tc::instance<T, std::vector>\n\t> {};\n\n\ttemplate<typename Cont>\n\tstruct range_filter;\n\n\ttemplate<typename Cont> requires\n\t\thas_efficient_erase<Cont>::value ||\n\t\thas_mem_fn_lower_bound<Cont> ||\n\t\thas_mem_fn_hash_function<Cont>\n\tstruct range_filter<Cont> : tc::noncopyable {\n\t\tstatic_assert(tc::decayed<Cont>);\n\n\tprivate:\n\t\tCont& m_cont;\n\t\ttc::iterator_t<Cont> m_itOutputEnd;\n\n\tpublic:\n\t\texplicit constexpr range_filter(Cont& cont) noexcept\n\t\t\t: m_cont(cont)\n\t\t\t, m_itOutputEnd(tc::begin(cont))\n\t\t{}\n\n\t\tconstexpr range_filter(Cont& cont, tc::iterator_t<Cont> const& itStart) noexcept\n\t\t\t: m_cont(cont)\n\t\t\t, m_itOutputEnd(itStart)\n\t\t{}\n\n\t\tconstexpr ~range_filter() {\n\t\t\ttc::take_inplace(m_cont, m_itOutputEnd);\n\t\t}\n\n\t\tconstexpr void keep(tc::iterator_t<Cont> it) & noexcept {\n#ifdef _CHECKS\n\t\t\tauto const nDistance = std::distance(m_itOutputEnd, it);\n\t\t\t_ASSERTE( 0<=nDistance );\n\t\t\tauto const rsize = restrict_size_decrement(m_cont, nDistance, nDistance);\n#endif\n\t\t\tm_itOutputEnd=m_cont.erase(m_itOutputEnd,it);\n\t\t\t++m_itOutputEnd;\n\t\t}\n\n\t\t///////////////////////////////////////////\n\t\t// range interface for output range\n\t\t// no deep constness (analog to subrange)\n\n\t\tconstexpr auto begin() const& noexcept {\n\t\t\treturn tc::begin(m_cont);\n\t\t}\n\n\t\tconstexpr auto end() const& noexcept {\n\t\t\treturn m_itOutputEnd;\n\t\t}\n\n\t\tconstexpr void pop_back() & noexcept requires (!has_mem_fn_hash_function<Cont>) {\n\t\t\t_ASSERTE( m_itOutputEnd!=tc::begin(m_cont) );\n\t\t\tauto const rsize = restrict_size_decrement(m_cont);\n\t\t\t--m_itOutputEnd;\n\t\t\tm_itOutputEnd=m_cont.erase(m_itOutputEnd);\n\t\t}\n\t};\n\n\ttemplate<has_mem_fn_splice Cont>\n\tstruct range_filter<Cont> : Cont, private tc::noncopyable {\n\t\tstatic_assert(tc::decayed<Cont>);\n\t\tCont& m_contInput;\n\n\t\texplicit constexpr range_filter(Cont& cont) noexcept\n\t\t\t: m_contInput(cont)\n\t\t{}\n\n\t\tconstexpr range_filter(Cont& cont, tc::iterator_t<Cont> const& itStart) noexcept\n\t\t\t: m_contInput(cont)\n\t\t{\n\t\t\tthis->splice( tc::end(*this), m_contInput, tc::begin(m_contInput), itStart );\n\t\t}\n\n\t\tconstexpr ~range_filter() {\n\t\t\tm_contInput=tc_move_always( tc::base_cast<Cont>(*this) );\n\t\t}\n\n\t\tconstexpr void keep(tc::iterator_t<Cont> it) & noexcept {\n\t\t\t_ASSERTE( it!=tc::end(m_contInput) );\n\t\t\tthis->splice( \n\t\t\t\ttc::end(*this),\n\t\t\t\tm_contInput,\n\t\t\t\tm_contInput.erase( tc::begin(m_contInput), it )\n\t\t\t);\n\t\t}\n\t};\n\n\ttemplate<typename Cont> requires range_filter_by_move_element<Cont>::value\n\tstruct range_filter<Cont> : tc::noncopyable {\n\t\tstatic_assert(tc::decayed<Cont>);\n\n\tprotected:\n\t\tCont& m_cont;\n\t\ttc::iterator_t<Cont> m_itOutput;\n\n\tprivate:\n#ifdef _CHECKS\n\t\ttc::iterator_t<Cont> m_itFirstValid;\n#endif\n\n\tpublic:\n\t\texplicit constexpr range_filter(Cont& cont) noexcept\n\t\t\t: m_cont(cont)\n\t\t\t, m_itOutput(tc::begin(cont))\n#ifdef _CHECKS\n\t\t\t, m_itFirstValid(tc::begin(cont))\n#endif\n\t\t{}\n\n\t\texplicit constexpr range_filter(Cont& cont, tc::iterator_t<Cont> itStart) noexcept\n\t\t\t: m_cont(cont)\n\t\t\t, m_itOutput(itStart)\n#ifdef _CHECKS\n\t\t\t, m_itFirstValid(itStart)\n#endif\n\t\t{}\n\n\t\tconstexpr ~range_filter() {\n\t\t\ttc::take_inplace( m_cont, m_itOutput );\n\t\t}\n\n\t\tconstexpr void keep(tc::iterator_t<Cont> it) & noexcept {\n#ifdef _CHECKS\n\t\t\t// Filter without reordering \n\t\t\t_ASSERTE( 0<=std::distance(m_itFirstValid, it) );\n\t\t\tm_itFirstValid=it;\n\t\t\t++m_itFirstValid;\n#endif\n\t\t\tif (it != m_itOutput) { // self assignment with r-value-references is not allowed (17.6.4.9)\n\t\t\t\t*m_itOutput=tc_move_always(*it);\n\t\t\t}\n\t\t\t++m_itOutput;\n\t\t}\n\n\t\t///////////////////////////////////\n\t\t// range interface for output range\n\t\t// no deep constness (analog to subrange)\n\n\t\tconstexpr auto begin() const& noexcept {\n\t\t\treturn tc::begin(m_cont);\n\t\t}\n\n\t\tconstexpr auto end() const& noexcept {\n\t\t\treturn m_itOutput;\n\t\t}\n\n\t\tconstexpr void pop_back() & noexcept {\n\t\t\t_ASSERTE( tc::begin(m_cont)!=m_itOutput );\n\t\t\t--m_itOutput;\n\t\t}\n\n\t\ttemplate <typename... Ts>\n\t\tconstexpr void emplace_back(Ts&&... ts) & MAYTHROW {\n\t\t\t_ASSERTE( tc::end(m_cont)!=m_itOutput );\n\t\t\ttc::assign_explicit_cast(*m_itOutput, tc_move_if_owned(ts)...); // MAYTHROW\n\t\t\t++m_itOutput;\n\t\t}\n\t};\n\n\t/////////////////////////////////////////////////////\n\t// filter_inplace\n\n\ttemplate<typename Cont, typename Pred = tc::identity>\n\tvoid filter_inplace(Cont & cont, tc::iterator_t<Cont> it, Pred pred = Pred()) noexcept(noexcept(tc_invoke(pred, *it))) {\n\t\tfor (auto const itEnd = tc::end(cont); it != itEnd; ++it) {\n\t\t\tif (!tc::explicit_cast<bool>(tc_invoke(pred, *it))) {\n\t\t\t\ttc::range_filter< tc::decay_t<Cont> > rngfilter(cont, it);\n\t\t\t\t++it;\n\t\t\t\twhile (it != itEnd) {\n\t\t\t\t\t// taking further action to destruct *it when returning false is legitimate use case, so do do not enforce const\n\t\t\t\t\tif (tc_invoke(pred, *it)) {\n\t\t\t\t\t\trngfilter.keep(it++); // may invalidate it, so move away first\n\t\t\t\t\t} else {\n\t\t\t\t\t\t++it;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Cont, typename Pred = tc::identity>\n\tvoid filter_inplace(Cont& cont, Pred&& pred = Pred()) return_MAYTHROW(\n\t\ttc::filter_inplace(cont, tc::begin(cont), tc_move_if_owned(pred))\n\t)\n}\n"
  },
  {
    "path": "tc/algorithm/find.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../range/meta.h\"\n#include \"../range/iterator_cache.h\"\n#include \"../base/scope.h\"\n#include \"../base/trivial_functors.h\"\n#include \"../storage_for.h\"\n\n#include \"equal.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n#ifdef _MSC_VER\n\t\ttemplate<typename RangeReturn, typename Rng>\n\t\tstruct element_return_type : std::type_identity<decltype(RangeReturn::pack_no_element(std::declval<Rng>()))> {};\n#endif\n\t}\n\n#ifdef _MSC_VER // MSVC has problems with decltype in alias templates.\n\ttemplate<typename RangeReturn, typename Rng>\n\tusing element_return_type_t = typename no_adl::element_return_type<RangeReturn, Rng>::type;\n#else\n\ttemplate<typename RangeReturn, typename Rng>\n\tusing element_return_type_t = decltype(RangeReturn::pack_no_element(std::declval<Rng>()));\n#endif\n\n\tnamespace find_first_if_detail {\n\t\ttemplate< typename RangeReturn, IF_TC_CHECKS(bool c_bCheckUnique,) typename Rng >\n\t\t[[nodiscard]] constexpr tc::element_return_type_t<RangeReturn, Rng> find_first_if(Rng&& rng, auto pred) MAYTHROW {\n\t\t\tif constexpr( RangeReturn::requires_iterator ) {\n\t\t\t\tauto const itEnd=tc::end(rng); // MAYTHROW\n\t\t\t\tfor( auto it=tc::begin(rng) /*MAYTHROW*/; it!=itEnd; ++it /*MAYTHROW*/ ) {\n\t\t\t\t\tif constexpr(std::same_as<decltype(pred), tc::constexpr_function<true>>) { // tc::front\n#ifdef _CHECKS\n\t\t\t\t\t\tif constexpr( c_bCheckUnique ) { // tc::only\n\t\t\t\t\t\t\t_ASSERTE( tc_modified(it, ++_) == itEnd );\n\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\treturn RangeReturn::pack_element(tc_move(it),tc_move_if_owned(rng)); // MAYTHROW\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdecltype(auto) ref = *it; // MAYTHROW\n\t\t\t\t\t\tif (tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(ref)) /*MAYTHROW*/)) {\n#ifdef _CHECKS\n\t\t\t\t\t\t\tif constexpr( c_bCheckUnique ) {\n\t\t\t\t\t\t\t\tfor( auto it2 = tc_modified(it, ++_); it2!=itEnd; ++it2 ) { // hand-rolled loop to avoid dependency to subrange\n\t\t\t\t\t\t\t\t\t_ASSERTE( !tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(*it2))) );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\t\treturn RangeReturn::pack_element(tc_move(it),tc_move_if_owned(rng),tc_move_if_owned(ref)); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t\t} else {\n#ifdef _CHECKS\n\t\t\t\tif constexpr( c_bCheckUnique ) {\n\t\t\t\t\tstd::optional<tc::element_return_type_t<RangeReturn, Rng>> ot;\n\t\t\t\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&& t) MAYTHROW {\n\t\t\t\t\t\tif( tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(t)) /*MAYTHROW*/) ) {\n\t\t\t\t\t\t\tVERIFYCRITICALPRED(ot, !_).emplace(RangeReturn::template pack_element<Rng>(tc_move_if_owned(t)) /* MAYTHROW */);\n\t\t\t\t\t\t}\n\t\t\t\t\t}); // MAYTHROW\n\t\t\t\t\tif( ot ) return *tc_move(ot);\n\t\t\t\t} else\n#endif\n\t\t\t\t{\n\t\t\t\t\ttc::storage_for_without_dtor<tc::element_return_type_t<RangeReturn, Rng>> ot;\n\t\t\t\t\tif( tc::break_ == tc::for_each(tc_move_if_owned(rng), [&](auto&& t) MAYTHROW {\n\t\t\t\t\t\tif (tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(t)) /*MAYTHROW*/)) {\n\t\t\t\t\t\t\tot.ctor(RangeReturn::template pack_element<Rng>(tc_move_if_owned(t)) /* MAYTHROW */);\n\t\t\t\t\t\t\treturn tc::break_; // We assume for_each never throws exceptions after the sink returned break_.\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t}\n\t\t\t\t\t}) /* MAYTHROW */ ) {\n\t\t\t\t\t\ttc_scope_exit { ot.dtor(); };\n\t\t\t\t\t\treturn *tc_move(ot);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn RangeReturn::template pack_no_element<Rng>();\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Pred = tc::identity >\n\t[[nodiscard]] constexpr decltype(auto) find_first_if(Rng&& rng, Pred&& pred = Pred()) MAYTHROW {\n\t\treturn find_first_if_detail::find_first_if<RangeReturn IF_TC_CHECKS(, /*c_bCheckUnique*/false)>(tc_move_if_owned(rng), tc_move_if_owned(pred));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Pred = tc::identity >\n\t[[nodiscard]] constexpr decltype(auto) find_unique_if(Rng&& rng, Pred&& pred = Pred()) MAYTHROW {\n\t\treturn find_first_if_detail::find_first_if<RangeReturn IF_TC_CHECKS(, /*c_bCheckUnique*/true)>(tc_move_if_owned(rng), tc_move_if_owned(pred));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename Pred = tc::identity >\n\t[[nodiscard]] constexpr decltype(auto) find_last_if(Rng&& rng, Pred pred = Pred()) MAYTHROW {\n\t\tif constexpr( tc::bidirectional_range<Rng> && tc::common_range<Rng> ) {\n\t\t\tauto const itBegin=tc::begin(rng);\n\t\t\tfor( auto it=tc::end(rng); it!=itBegin; ) {\n\t\t\t\t--it;\n\t\t\t\tif constexpr(std::same_as<Pred, tc::constexpr_function<true>>) { // tc::back\n\t\t\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng));\n\t\t\t\t} else {\n\t\t\t\t\tdecltype(auto) ref = *it;\n\t\t\t\t\tif (tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(ref)))) {\n\t\t\t\t\t\treturn RangeReturn::pack_element(tc_move(it), tc_move_if_owned(rng), tc_move_if_owned(ref));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tauto const itEnd=tc::end(rng);\n\t\t\tfor( auto it=tc::begin(rng); it!=itEnd; ++it ) {\n\t\t\t\tstd::array<tc::storage_for_without_dtor<tc::iterator_cache<decltype(it)>>, 2> aic; // tc::storage_for was too slow in debug builds\n\t\t\t\tint iFound = 0;\n\t\t\t\taic[iFound].ctor(it);\n\t\t\t\ttc_scope_exit { aic[iFound].dtor(); }; //iFound captured by reference\n\t\t\t\tif (tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(**aic[iFound])))) {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\t++it;\n\t\t\t\t\t\tif (itEnd==it) break;\n\t\t\t\t\t\taic[1 - iFound].ctor(it);\n\t\t\t\t\t\ttc_scope_exit { aic[1 - iFound].dtor(); };\n\t\t\t\t\t\tif (tc_invoke(pred, tc::as_const(**aic[1 - iFound]))) {\n\t\t\t\t\t\t\tiFound = 1 - iFound;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\treturn RangeReturn::pack_element(\n\t\t\t\t\t\ttc_move_always(*aic[iFound]).m_it_(), // pack_element must not take iterator by value\n\t\t\t\t\t\ttc_move_if_owned(rng),\n\t\t\t\t\t\t*tc_move_always(*aic[iFound])\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t}\n\n\tnamespace no_adl {\n\t\tBOOST_MPL_HAS_XXX_TRAIT_DEF(key_type)\n\t}\n\tusing no_adl::has_key_type;\n\n\tnamespace find_first_or_unique_default {\n\t\ttemplate< typename RangeReturn, IF_TC_CHECKS(bool c_bCheckUnique,) typename Rng, typename T >\n\t\t[[nodiscard]] constexpr decltype(auto) find_first_or_unique_impl(std::type_identity<RangeReturn>, IF_TC_CHECKS(tc::constant<c_bCheckUnique>,) Rng&& rng, T const& t) MAYTHROW {\n\t\t\tstatic_assert(\n\t\t\t\t!tc::has_key_type<std::remove_cvref_t<Rng>>::value,\n\t\t\t\t\"Do you want to use tc::cont_find?\"\n\t\t\t);\n\t\t\treturn find_first_if_detail::find_first_if<RangeReturn IF_TC_CHECKS(, c_bCheckUnique)>(tc_move_if_owned(rng), [&](auto const& _) MAYTHROW { return tc::equal_to(_, t); });\n\t\t}\n\t}\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(find_first_or_unique)\n\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] constexpr decltype(auto) find_unique(Rng&& rng, T&& t) MAYTHROW {\n\t\treturn find_first_or_unique(std::type_identity<RangeReturn>(), IF_TC_CHECKS(tc::constant<true>(),) tc_move_if_owned(rng), tc_move_if_owned(t));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] constexpr decltype(auto) find_first(Rng&& rng, T&& t) MAYTHROW {\n\t\treturn find_first_or_unique(std::type_identity<RangeReturn>(), IF_TC_CHECKS(tc::constant<false>(),) tc_move_if_owned(rng), tc_move_if_owned(t));\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng, typename T >\n\t[[nodiscard]] constexpr decltype(auto) find_last(Rng&& rng, T const& t) noexcept {\n\t\treturn tc::find_last_if<RangeReturn>( tc_move_if_owned(rng), [&](auto const& _) noexcept { return tc::equal_to(_, t); } );\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/find_closest_if.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"element.h\"\n\nnamespace tc {\n\ttemplate< typename Rng, typename It, typename Func >\n\tauto for_each_iterator_pair_outwards(Rng&& rng, It itOrigin, bool bSkipSelf, Func func) noexcept\n\t\t-> tc::common_type_t<decltype(tc::continue_if_not_break(func, std::declval<tc::span<It> const&>())), tc::constant<tc::continue_>>\n\t{\n\t\tstd::array<It, 2> const aitLimit = { tc::begin(rng), tc::end(rng) };\n\t\tstd::array<It, 2> ait = { itOrigin, itOrigin };\n\n\t\tif (!bSkipSelf) {\n\t\t\t_ASSERT(tc::back(aitLimit) != tc::back(ait));\n\t\t\ttc_return_if_break(tc::continue_if_not_break(func, tc::begin_next<tc::return_take>(tc::as_const(ait))))\n\t\t\t++tc::back(ait);\n\t\t} else if(tc::back(aitLimit) != tc::back(ait)) {\n\t\t\t++tc::back(ait);\n\t\t}\n\n\t\tfor (;;) {\n\t\t\tif (tc::front(aitLimit) == tc::front(ait)) {\n\t\t\t\tfor (; tc::back(ait) != tc::back(aitLimit); ++tc::back(ait)) {\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(func, tc::begin_next<tc::return_drop>(tc::as_const(ait))))\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t\tif (tc::back(aitLimit) == tc::back(ait)) {\n\t\t\t\twhile (tc::front(ait) != tc::front(aitLimit)) {\n\t\t\t\t\t--tc::front(ait);\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(func, tc::begin_next<tc::return_take>(tc::as_const(ait))))\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t\t--tc::front(ait);\n\t\t\ttc_return_if_break(tc::continue_if_not_break(func, tc::as_const(ait)))\n\t\t\t++tc::back(ait);\n\t\t}\n\t}\n\n\n\ttemplate < typename RangeReturn, typename Rng, typename It, typename Pred = tc::identity>\n\t[[nodiscard]] constexpr decltype(auto) find_closest_if(Rng&& rng, It it, bool const bSkipSelf, Pred pred = Pred()) noexcept {\n\t\ttc::storage_for<tc::iterator_cache<It>> oitc;\n\t\tif (tc::break_ == tc::for_each_iterator_pair_outwards(rng, tc_move(it), bSkipSelf, [&](auto const& rngit) noexcept {\n\t\t\treturn tc::for_each(rngit, [&](auto const& it) noexcept {\n\t\t\t\toitc.ctor(it);\n\t\t\t\tif (tc::explicit_cast<bool>(tc_invoke(pred, tc::as_const(**oitc)))) { return tc::break_; }\n\t\t\t\toitc.dtor();\n\t\t\t\treturn tc::continue_;\n\t\t\t});\n\t\t})) {\n\t\t\ttc_scope_exit { oitc.dtor(); };\n\t\t\treturn RangeReturn::pack_element(oitc->m_it_(), tc_move_if_owned(rng), **tc_move(oitc));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t\t}\n\t}\n\n\ttemplate < typename RangeReturn, typename Rng, typename Index, typename Pred = tc::identity>\n\t[[nodiscard]] decltype(auto) find_closest_if_with_index(Rng&& rng, Index&& n, bool const bSkipSelf, Pred&& pred = Pred()) noexcept {\n\t\treturn find_closest_if<RangeReturn>(tc_move_if_owned(rng), tc::begin_next<tc::return_border>(rng, tc_move_if_owned(n)), bSkipSelf, tc_move_if_owned(pred));\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/find_closest_if.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"find_closest_if.h\"\n#include \"../unittest.h\"\n\nUNITTESTDEF(find_closest_if) {\n\tstruct IntCompareOnce final : boost::noncopyable {\n\t\tIntCompareOnce(int n) noexcept :m_n(n) { }\n\t\tbool operator==(int const n) const& noexcept {\n\t\t\t_ASSERT( tc::change(m_bCompared, true) );\n\t\t\treturn m_n==n;\n\t\t}\n\tprivate:\n\t\tint m_n;\n\t\tbool mutable m_bCompared = false;\n\t};\n\n\ttc_static_auto_constexpr_lambda(find) = [](auto const& rngn, int const iStart, int const nTarget, int const nComparisonsMax) noexcept {\n\t\tint nComparisons = 0;\n\t\treturn tc::find_closest_if_with_index<tc::return_element_index_or_none>(rngn, iStart, /*bSkipSelf*/false, [&](IntCompareOnce const& n) noexcept {\n\t\t\t_ASSERT(++nComparisons<=nComparisonsMax);\n\t\t\treturn n==nTarget;\n\t\t});\n\t};\n\n\tfor (int iStart = 0; iStart < 4; ++iStart) {\n\t\tfor (int nTarget = -1; nTarget < 4; ++nTarget) {\n\t\t\tint nComparisonsMax = -1==nTarget ? 5 : nTarget<iStart ? 2*(iStart-nTarget) : 1+2*(nTarget-iStart);\n\t\t\t_ASSERTEQUAL(find(tc::make_array<IntCompareOnce>(tc::aggregate_tag, 0, 1, 2, 3, 4), iStart, nTarget, nComparisonsMax), -1==nTarget ? std::nullopt : std::make_optional(nTarget));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/for_each.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/utility.h\"\n\n#include \"../range/index_range.h\"\n#include \"../range/meta.h\"\n#include \"../tuple.h\"\n#include \"../base/modified.h\"\n\n#include \"break_or_continue.h\"\n\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename... T>\n\t\tstruct common_type_break_or_continue;\n\n\t\ttemplate<>\n\t\tstruct common_type_break_or_continue<> final {\n\t\t\tusing type = tc::constant<tc::continue_>;\n\t\t};\n\n\t\ttemplate<typename... T>\n\t\tstruct common_type_break_or_continue<tc::constant<tc::continue_>, T...> {\n\t\t\tusing type = typename common_type_break_or_continue<T...>::type;\n\t\t};\n\n\t\ttemplate<typename... T>\n\t\tstruct common_type_break_or_continue<tc::constant<tc::break_>, T...> {\n\t\t\tusing type = tc::constant<tc::break_>;\n\t\t};\n\n\t\ttemplate<typename... T>\n\t\tstruct common_type_break_or_continue<tc::break_or_continue, T...> {\n\t\t\tusing type = std::conditional_t<\n\t\t\t\tstd::is_same<tc::constant<tc::break_>, typename common_type_break_or_continue<T...>::type>::value,\n\t\t\t\ttc::constant<tc::break_>,\n\t\t\t\ttc::break_or_continue\n\t\t\t>;\n\t\t};\n\t}\n\ttemplate<typename... T>\n\tusing common_type_break_or_continue_t = typename no_adl::common_type_break_or_continue<T...>::type;\n\n\ttemplate<typename Sink, typename Rng>\n\tconcept has_mem_fn_chunk = requires { std::declval<Sink>().chunk(std::declval<Rng>()); };\n\n\tDEFINE_MEM_FN(chunk);\n\n\tnamespace void_generator_type_check_no_adl {\n\t\ttemplate<typename BreakOrContinue, tc::break_or_continue>\n\t\tstruct check_sink_result;\n\n\t\ttemplate<typename BreakOrContinue>\n\t\tstruct check_sink_result<BreakOrContinue, tc::continue_> {\n\t\t\tstatic_assert(\n\t\t\t\t!std::is_same<BreakOrContinue, tc::break_or_continue>::value &&\n\t\t\t\t!std::is_same<BreakOrContinue, tc::constant<tc::break_>>::value,\n\t\t\t\t\"Functor may return break_, but range does not support it.\"\n\t\t\t);\n\t\t};\n\n\t\ttemplate<typename BreakOrContinue>\n\t\tstruct check_sink_result<BreakOrContinue, tc::break_> {\n\t\t\tstatic_assert(\n\t\t\t\tstd::is_same<BreakOrContinue, tc::constant<tc::break_>>::value,\n\t\t\t\t\"Functor does not always break, but range does (broken range implementation).\"\n\t\t\t);\n\t\t};\n\n\t\ttemplate<tc::break_or_continue boc, typename Sink>\n\t\tstruct verify_sink_result_impl final : Sink {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tusing guaranteed_break_or_continue = tc::constant<boc>;\n\n\t\t\ttemplate<typename... Args, typename R = decltype(std::declval<Sink const&>()(std::declval<Args>()...))>\n\t\t\tconstexpr tc::constant<boc> operator()(Args&&... args) const& noexcept(noexcept(\n\t\t\t\ttc::base_cast<Sink>(*this)(std::declval<Args&&>()...)\n\t\t\t)) {\n\t\t\t\tcheck_sink_result<R, boc>();\n\t\t\t\ttc::base_cast<Sink>(*this)(tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\treturn {};\n\t\t\t}\n\n\t\t\ttemplate<typename Rng> requires tc::has_mem_fn_chunk<Sink const&, Rng>\n\t\t\tconstexpr tc::constant<boc> chunk(Rng&& rng) const& noexcept(noexcept(\n\t\t\t\ttc::base_cast<Sink>(*this).chunk(tc_move_if_owned(rng))\n\t\t\t)) {\n\t\t\t\tcheck_sink_result<decltype(tc::base_cast<Sink>(*this).chunk(tc_move_if_owned(rng))), boc>();\n\t\t\t\ttc::base_cast<Sink>(*this).chunk(tc_move_if_owned(rng)); // MAYTHROW\n\t\t\t\treturn {};\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Sink>\n\t\tstruct guaranteed_break_or_continue final {\n\t\t\tusing type = tc::break_or_continue;\n\t\t};\n\n\t\ttemplate<typename Sink> requires requires { typename std::remove_reference_t<Sink>::guaranteed_break_or_continue; }\n\t\tstruct guaranteed_break_or_continue<Sink> final {\n\t\t\tusing type = typename std::remove_reference_t<Sink>::guaranteed_break_or_continue;\n\t\t};\n\t}\n\ttemplate<typename Sink>\n\tusing guaranteed_break_or_continue_t = typename void_generator_type_check_no_adl::guaranteed_break_or_continue<Sink>::type;\n\n\ttemplate<typename BreakOrContinue, typename Sink>\n\t\trequires std::is_same<BreakOrContinue, tc::break_or_continue>::value\n\t\t\t|| std::is_same<BreakOrContinue, tc::guaranteed_break_or_continue_t<Sink>>::value\n\tconstexpr decltype(auto) verify_sink_result(Sink&& sink) noexcept {\n\t\treturn tc_move_if_owned(sink);\n\t}\n\n\ttemplate<typename BreakOrContinue, typename Sink>\n\tconstexpr void_generator_type_check_no_adl::verify_sink_result_impl<BreakOrContinue::value, tc::decay_t<Sink>> verify_sink_result(Sink&& sink) noexcept {\n\t\tstatic_assert( std::is_same<guaranteed_break_or_continue_t<Sink>, tc::break_or_continue>::value, \"Mismatch between range and sink result types (broken range implementation).\" );\n\t\treturn {tc_move_if_owned(sink)};\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// for_each\n\n\tnamespace for_each_adl {\n\t\tDEFINE_ADL_TAG_TYPE(adl_tag)\n\t}\n\ttemplate<typename> \\\n\tvoid for_each_impl() noexcept; /*TODO c++20: workaround for c++17*/\n\n\tnamespace for_each_detail {\n\t\tTC_DEFINE_ENUM(EOverload, eoverload, (CHUNK)(ADL)(INVOKERNG)(ADLTAG)(INDEX)(ITERATOR)(NONE))\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename BreakOrContinue>\n\t\t\tstruct make_break_or_continue;\n\t\t\ttemplate<> struct make_break_or_continue<tc::constant<tc::continue_>> { using type = tc::constant<tc::continue_>; };\n\t\t\ttemplate<> struct make_break_or_continue<tc::constant<tc::break_>> { using type = tc::constant<tc::break_>; };\n\t\t\ttemplate<> struct make_break_or_continue<tc::break_or_continue> { using type = tc::break_or_continue; };\n\t\t\ttemplate<> struct make_break_or_continue<void> { using type = tc::constant<tc::continue_>; };\n\t\t}\n\t\ttemplate<typename BreakOrContinue>\n\t\tusing make_break_or_continue_t = typename no_adl::make_break_or_continue<BreakOrContinue>::type;\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Rng, typename Sink, int nPriority = 0>\n\t\t\tstruct select_overload : select_overload<Rng, Sink, nPriority + 1> {};\n\n#pragma push_macro(\"SELECT_OVERLOAD_IF\")\n#define SELECT_OVERLOAD_IF(priority, eoverload, requires_clause) \\\n\t\t\ttemplate<typename Rng, typename Sink> requires_clause \\\n\t\t\tstruct select_overload<Rng, Sink, priority> : tc::constant<eoverload> {};\n\n\t\t\tSELECT_OVERLOAD_IF(0, eoverloadCHUNK, TC_FWD(requires tc::has_mem_fn_chunk<tc::decay_t<Sink> const&, Rng>))\n\t\t\tSELECT_OVERLOAD_IF(1, eoverloadADL, TC_FWD(requires requires { for_each_impl(std::declval<Rng>(), std::declval<Sink>()); }))\n\t\t\tSELECT_OVERLOAD_IF(1, eoverloadINVOKERNG, TC_FWD(requires requires { typename make_break_or_continue_t<decltype(std::declval<Rng>()(std::declval<Sink>()))>; }))\n\t\t\tSELECT_OVERLOAD_IF(2, eoverloadADLTAG, TC_FWD(requires requires { for_each_impl(for_each_adl::adl_tag, std::declval<Rng>(), std::declval<Sink>()); }))\n\t\t\tSELECT_OVERLOAD_IF(2, eoverloadINDEX, requires tc::has_index<std::remove_reference_t<Rng>>)\n\t\t\tSELECT_OVERLOAD_IF(3, eoverloadITERATOR, requires tc::range_with_iterators<Rng>)\n\t\t\tSELECT_OVERLOAD_IF(4, eoverloadNONE, /*none*/)\n#pragma pop_macro(\"SELECT_OVERLOAD_IF\")\n\t\t}\n\t\tusing no_adl::select_overload;\n\t}\n\n\ttemplate<typename Rng, typename Sink> requires (for_each_detail::eoverloadCHUNK == for_each_detail::select_overload<Rng, Sink>::value)\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink) return_MAYTHROW(\n\t\ttc_internal_continue_if_not_break(/*do we really need that copy?*/tc::as_const(tc::as_lvalue(tc::decay_copy(sink))).chunk(tc_move_if_owned(rng)))\n\t)\n\n\ttemplate<typename Rng, typename Sink> requires (for_each_detail::eoverloadADL == for_each_detail::select_overload<Rng, Sink>::value)\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink) return_MAYTHROW(\n\t\tfor_each_impl(tc_move_if_owned(rng), tc_move_if_owned(sink))\n\t)\n\n\ttemplate<typename Rng, typename Sink> requires (for_each_detail::eoverloadADLTAG == for_each_detail::select_overload<Rng, Sink>::value)\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink) return_MAYTHROW(\n\t\tfor_each_impl(for_each_adl::adl_tag, tc_move_if_owned(rng), tc_move_if_owned(sink))\n\t)\n\n\ttemplate<typename Rng, typename Sink> requires (for_each_detail::eoverloadINVOKERNG == for_each_detail::select_overload<Rng, Sink>::value)\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink) return_MAYTHROW(\n\t\ttc_internal_continue_if_not_break(tc_move_if_owned(rng)(tc::verify_sink_result<for_each_detail::make_break_or_continue_t<decltype(std::declval<Rng>()(std::declval<Sink>()))>>(tc_move_if_owned(sink))))\n\t)\n\n\ttemplate<typename Rng, typename Sink, /*not requires because of CWG issue 2369*/std::enable_if_t<for_each_detail::eoverloadINDEX == for_each_detail::select_overload<Rng, Sink>::value>* = nullptr>\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink_) noexcept(\n\t\tnoexcept(rng.at_end_index(tc::as_lvalue(tc::decay_copy(rng.begin_index())))) &&\n\t\tnoexcept(rng.increment_index(tc::as_lvalue(rng.begin_index()))) &&\n\t\tnoexcept(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), rng.dereference_index(tc::as_lvalue(rng.begin_index()))))\n\t) -> tc::common_type_t<decltype(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), rng.dereference_index(tc::as_lvalue(rng.begin_index())))), tc::constant<tc::continue_>> {\n\t\ttc::decay_t<Sink> const sink = sink_; // do we really need that copy?\n\t\tfor (auto i = rng.begin_index(); !rng.at_end_index(i); rng.increment_index(i)) {\n\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, rng.dereference_index(i)))\n\t\t}\n\t\treturn tc::constant<tc::continue_>();\n\t}\n\n\ttemplate<typename Rng, typename Sink, /*not requires because of CWG issue 2369*/std::enable_if_t<for_each_detail::eoverloadITERATOR == for_each_detail::select_overload<Rng, Sink>::value>* = nullptr>\n\tconstexpr auto for_each(Rng&& rng, Sink&& sink_) noexcept(\n\t\tnoexcept(tc::end(rng)) && \n\t\tnoexcept(++tc::as_lvalue(tc::begin(rng))) && \n\t\tnoexcept(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), *tc::as_lvalue(tc::begin(rng))))\n\t) -> tc::common_type_t<decltype(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), *tc::as_lvalue(tc::begin(rng)))), tc::constant<tc::continue_>> {\n\t\ttc::decay_t<Sink> const sink = sink_; // do we really need that copy?\n\t\tauto const itEnd = tc::end(rng);\n\t\tfor(auto it = tc::begin(rng); it!= itEnd; ++it) {\n\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, *it))\n\t\t}\n\t\treturn tc::constant<tc::continue_>();\n\t}\n\n\tnamespace for_each_detail {\n\t\ttemplate<typename T>\n\t\tconstexpr auto type_value = std::type_identity<T>{};\n\n\t\ttemplate<auto Value>\n\t\tconstexpr auto type_value<tc::constant<Value>> = tc::constant<Value>{};\n\n\t\t// If the type is a type list, we turn it into a tuple of type values.\n\t\t// That way `tc::for_each(tc::zip(list1, list2), []<typename U, typename V>(std::type_identity<U>, std::type_identity<V>) { ... })` just works.\n\t\ttemplate<typename ... T>\n\t\tconstexpr auto type_value<boost::mp11::mp_list<T...>> = tc::make_tuple(type_value<T>...);\n\n\t\ttemplate<typename... T, typename Sink, typename R = typename tc::common_type_break_or_continue_t<decltype(tc::continue_if_not_break(std::declval<Sink>(), type_value<T>))...>>\n\t\tconstexpr R for_each_parameter_pack(boost::mp11::mp_list<T...>, Sink const sink) noexcept((noexcept(tc::continue_if_not_break(sink, type_value<T>)) && ...)) {\n\t\t\tif constexpr (std::is_same<tc::constant<tc::continue_>, R>::value) {\n\t\t\t\t(tc_invoke(sink, type_value<T>), ...);\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t} else {\n\t\t\t\tauto const boc = tc::continue_if(((tc::continue_ == tc_internal_continue_if_not_break(tc_invoke(sink, type_value<T>))) && ...));\n\n\t\t\t\tif constexpr (std::is_same<tc::constant<tc::break_>, R>::value) {\n\t\t\t\t\treturn tc::constant<tc::break_>();\n\t\t\t\t} else {\n\t\t\t\t\treturn boc;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Tuple, typename Sink>\n\t\t\tstruct tuple_index_sink final {\n\t\t\t\tTuple&& m_tuple;\n\t\t\t\tSink m_sink;\n\t\t\t\ttemplate<std::size_t I>\n\t\t\t\tconstexpr auto operator()(tc::constant<I>) const& return_decltype_MAYTHROW(\n\t\t\t\t\ttc_invoke(m_sink, tc::get<I>(tc_move_if_owned(m_tuple)))\n\t\t\t\t)\n\t\t\t};\n\t\t}\n\t\tusing no_adl::tuple_index_sink;\n\t}\n\n\tnamespace for_each_adl {\n\t\ttemplate<typename TIndex, TIndex... Is, typename Sink>\n\t\tconstexpr auto for_each_impl(adl_tag_t, std::integer_sequence<TIndex, Is...>, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\tfor_each_detail::for_each_parameter_pack(boost::mp11::mp_list<tc::constant<Is>...>(), tc_move_if_owned(sink))\n\t\t)\n\n\t\ttemplate<typename... Ts, typename Sink>\n\t\tconstexpr auto for_each_impl(adl_tag_t, boost::mp11::mp_list<Ts...>, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\tfor_each_detail::for_each_parameter_pack(boost::mp11::mp_list<Ts...>(), tc_move_if_owned(sink))\n\t\t)\n\n\t\ttemplate<tc::tuple_like Tuple, typename Sink,\n\t\t\ttypename IndexList = tc::mp_integer_list<std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>>\n\t\t\tTC_REQUIRES_CWG2369_WORKAROUND(!tc::range_with_iterators<Tuple>)\n\t\tconstexpr auto for_each_impl(adl_tag_t, Tuple&& tuple, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\tfor_each_detail::for_each_parameter_pack(IndexList(), for_each_detail::tuple_index_sink<Tuple, tc::decay_t<Sink>>{tc_move_if_owned(tuple), tc_move_if_owned(sink)})\n\t\t)\n\n\t\ttemplate<typename Rng, typename Sink, /*not requires because of CWG issue 2369*/std::enable_if_t<!std::is_reference<Rng>::value>* = nullptr>\n\t\tconstexpr auto for_each_impl(adl_tag_t, Rng&& rng, Sink&& sink_) noexcept(\n\t\t\tnoexcept(tc::end(rng)) &&\n\t\t\tnoexcept(++tc::as_lvalue(tc::begin(rng))) &&\n\t\t\tnoexcept(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), tc_move_always(rng.extract(tc::begin(rng)).value())))\n\t\t) -> tc::common_type_t<decltype(tc::continue_if_not_break(std::declval<tc::decay_t<Sink> const&>(), tc_move_always(rng.extract(tc::begin(rng)).value()))), tc::constant<tc::continue_>> {\n\t\t\ttc::decay_t<Sink> const sink = sink_; // do we really need that copy?\n\n\t\t\tauto it = tc::begin(rng);\n\t\t\tauto const itEnd = tc::end(rng);\n\t\t\twhile (it != itEnd) {\n\t\t\t\tauto itNext = tc_modified(it, ++_);\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc_move_always(rng.extract(it).value())))\n\t\t\t\tit = itNext;\n\t\t\t}\n\t\t\treturn tc::constant<tc::continue_>();\n\t\t}\n\t}\n\n\tnamespace range_output_tuple_impl::no_adl {\n\t\tstruct fn_range_output final {\n\t\t\ttemplate<typename... Ts> boost::mp11::mp_unique<boost::mp11::mp_list<Ts...>> operator()(Ts&&...) const& {\n\t\t\t\treturn {}; // unevaluated, not declaration only because of return_invoke workaround\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace range_output_t_adl {\n\t\ttemplate<typename... Ts>\n\t\tauto range_output_t_impl(adl_tag_t, boost::mp11::mp_list<Ts...>)\n\t\t\t-> boost::mp11::mp_unique<boost::mp11::mp_list<std::remove_const_t<decltype(for_each_detail::type_value<Ts>)>...>>; // declaration only\n\n\t\ttemplate<tc::tuple_like Tuple TC_REQUIRES_CWG2369_WORKAROUND(!tc::range_with_iterators<Tuple>)\n\t\tauto range_output_t_impl(adl_tag_t, Tuple&& tpl)\n\t\t\t-> decltype(tc_apply(range_output_tuple_impl::no_adl::fn_range_output(), std::declval<Tuple>())); // declaration only\n\t}\n\t\n\tnamespace make_lazy_adl {\n\t\ttemplate<typename Lazy, typename Sink,\n\t\t\tstd::enable_if_t<tc::instance<std::remove_reference_t<Lazy>, tc::make_lazy>>* = nullptr\n\t\t>\n\t\tconstexpr auto for_each_impl(Lazy&& lazy, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\ttc::for_each(tc_move_if_owned(lazy)(),tc_move_if_owned(sink))\n\t\t)\n\t}\n\n\tTC_HAS_EXPR(for_each, (Rng)(Sink), tc::for_each(std::declval<Rng>(), std::declval<Sink>()))\n}\n\n#define TC_RETURN_BREAK_OR_CONTINUE_SEQUENCE_TYPE(state, _, elem) \\\n\tdecltype(elem),\n#define TC_RETURN_BREAK_OR_CONTINUE_SEQUENCE_EVAL(state, _, i, elem) \\\n\ttc_return_if_break_impl( \\\n\t\ttc::implicit_cast<BreakOrContinue>(tc::constant<tc::break_>()), \\\n\t\telem \\\n\t)\n\n#define tc_return_break_or_continue_impl(exprseq) \\\n\tusing BreakOrContinue = tc::common_type_break_or_continue_t< \\\n\t\tBOOST_PP_SEQ_FOR_EACH(TC_RETURN_BREAK_OR_CONTINUE_SEQUENCE_TYPE, _, exprseq) \\\n\t\ttc::constant<tc::continue_> \\\n\t>; \\\n\tBOOST_PP_SEQ_FOR_EACH_I(TC_RETURN_BREAK_OR_CONTINUE_SEQUENCE_EVAL, _, exprseq) \\\n\tif constexpr(!std::same_as<BreakOrContinue, tc::constant<break_>>) { \\\n\t\treturn tc::implicit_cast<BreakOrContinue>(tc::constant<tc::continue_>()); \\\n\t}\n\n#define tc_return_break_or_continue(exprseq) \\\n\ttc_return_break_or_continue_impl(exprseq)\n"
  },
  {
    "path": "tc/algorithm/for_each.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../base/ref.h\"\n#include \"../range/adjacent_adaptor.h\"\n#include \"../range/ordered_pairs.h\"\n#include \"../container/insert.h\"\n#include \"for_each_xxx.h\"\n\n#include <tuple>\n\nSTATICASSERTEQUAL(tc_internal_continue_if_not_break(tc::break_), tc::break_);\nSTATICASSERTEQUAL(tc_internal_continue_if_not_break(tc::continue_), tc::continue_);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(tc::break_)), tc::break_or_continue);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(tc::continue_)), tc::break_or_continue);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(tc::constant<tc::break_>())), tc::constant<tc::break_>);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(tc::constant<tc::continue_>())), tc::constant<tc::continue_>);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(23)), tc::constant<tc::continue_>);\nSTATICASSERTSAME(decltype(tc_internal_continue_if_not_break(void())), tc::constant<tc::continue_>);\n\n\n//---- for_each ---------------------------------------------------------------------------------------------------------------\nnamespace {\n\tstruct all_called_mock final {\n\t\tall_called_mock() noexcept : m_expect(0), m_index(0), m_break_at(0), m_copyed_or_moved_from(false) {}\n\t\tall_called_mock(tc::vector<int> const& v, std::size_t break_at = 0, bool expect_break = true) noexcept\n\t\t\t: m_expect(v),\n\t\t\t  m_index(0),\n\t\t\t  m_break_at((break_at == 0) ? v.size() : break_at),\n\t\t\t  m_expect_break((break_at != 0) && expect_break),\n\t\t\t  m_copyed_or_moved_from(false)\n\t\t{}\n\t\tall_called_mock(all_called_mock const& copy) noexcept :\n\t\t\t  m_expect(copy.m_expect),\n\t\t\t  m_index(copy.m_index),\n\t\t\t  m_break_at(copy.m_break_at),\n\t\t\t  m_expect_break(copy.m_expect_break),\n\t\t\t  m_copyed_or_moved_from(false)\n\t\t{\n\t\t\tcopy.m_copyed_or_moved_from = true;\n\t\t}\n\t\tall_called_mock(all_called_mock&& move) noexcept :\n\t\t\t  m_expect(move.m_expect),\n\t\t\t  m_index(move.m_index),\n\t\t\t  m_break_at(move.m_break_at),\n\t\t\t  m_expect_break(move.m_expect_break),\n\t\t\t  m_copyed_or_moved_from(false)\n\t\t{\n\t\t\tmove.m_copyed_or_moved_from = true;\n\t\t}\n\t\t~all_called_mock() {\n\t\t\tmock_reset();\n\t\t}\n\n\t\tvoid mock_reset(tc::vector<int> const& v = tc::vector<int>(), std::size_t const break_at = 0, bool expect_break = true) & noexcept {\n\t\t\tif(!m_copyed_or_moved_from && !(m_index == tc::min(m_expect.size(), (m_expect_break) ? m_break_at + 1 : m_expect.size()))) {\n\t\t\t\tTEST_OUTPUT( << \"unexpectedly terminated before index \" << m_index\n\t\t\t\t\t\t\t << \" went to the expected index \" << tc::min(m_expect.size(), m_break_at + 1) << '\\n');\n\t\t\t\t_ASSERTEQUAL(m_index, tc::min(m_expect.size(), m_break_at + 1));\n\t\t\t}\n\t\t\tm_index = 0;\n\t\t\tm_expect = v;\n\t\t\tm_break_at = (break_at == 0) ? v.size() : break_at;\n\t\t\tm_expect_break = (break_at != 0) && expect_break;\n\t\t\tm_copyed_or_moved_from = false;\n\t\t}\n\n\t\ttc::break_or_continue operator()(int const val) const& noexcept {\n\t\t\tif (m_copyed_or_moved_from) {\n\t\t\t\tTEST_OUTPUT(<< \"used copyed or moved consumer for real work!\\n\");\n\t\t\t}\n\t\t\tif(!(m_index < m_expect.size())) {\n\t\t\t\tTEST_OUTPUT( << \"unexpectedly called for index \" << m_index\n\t\t\t\t\t\t\t << \" when expect has size \" << m_expect.size() << '\\n');\n\t\t\t\t_ASSERT(m_index < m_expect.size());\n\t\t\t}\n\t\t\tif (val != m_expect[m_index]) {\n\t\t\t\tTEST_OUTPUT( << \"unexpected value \" << val << \" at index \" << m_index\n\t\t\t\t\t\t\t << \", should be \" << m_expect[m_index] << '\\n');\n\t\t\t\t_ASSERTEQUAL(val, m_expect[m_index]);\n\t\t\t}\n\t\t\t++m_index;\n\t\t\treturn tc::continue_if(m_index <= m_break_at);\n\t\t}\n\n\t\tprivate:\n\t\t\ttc::vector<int> m_expect;\n\t\t\tmutable std::size_t m_index;\n\t\t\tstd::size_t m_break_at;\n\t\t\tbool m_expect_break;\n\t\t\tmutable bool m_copyed_or_moved_from; // so that the copy ctor can mark the copyied from instance\n\t};\n\n\tall_called_mock g_mock;\n\n\tvoid foo(int const i) noexcept { g_mock(i); }\n\n//-----------------------------------------------------------------------------------------------------------------------------\nUNITTESTDEF( for_each ) {\n\tusing std::placeholders::_1;\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9,10});\n\tTEST_init_hack(tc::vector, int, exp, {1,2,3,4,5,6,7,8,9,10});\n\n\tauto gv = tc::make_generator_range(v);\n\n\t// call with functor object.\n\ttc::for_each(v, all_called_mock(exp));\n\ttc::for_each(gv, all_called_mock(exp));\n\n\t// test if break_ works\n\ttc::for_each(gv, all_called_mock(exp, 5));\n\n\t// call with function\n\tg_mock.mock_reset(exp); tc::for_each(v, foo);\n\t//g_mock.mock_reset(exp); tc::for_each(gv, foo);\n\tg_mock.mock_reset(exp); tc::for_each(gv, tc_fn(foo));\n\n\t//call with pointer to function\n\tg_mock.mock_reset(exp); tc::for_each(v, &foo);\n\t//g_mock.mock_reset(exp); tc::for_each(gv, &foo);\n\n\t// call with lambda\n\tg_mock.mock_reset(exp); tc::for_each(v, [](int const i) noexcept { g_mock(i); });\n\tg_mock.mock_reset(exp); tc::for_each(gv, [](int const i) noexcept { g_mock(i); });\n\n\t// Todo: call with mem func, std::function and bind\n}\n\n\n//---- test break behavior  ---------------------------------------------------------------------------------------------------\n\tstruct iterate final {\n\t\ttc::break_or_continue generator_break_consumer_break(tc::function_ref< tc::break_or_continue(int) noexcept > func) const& noexcept {\n\t\t\tfor(int i = 1; i<11; ++i) {\n\t\t\t\tif(func(i) == tc::break_) { return tc::break_; }\n\t\t\t}\n\t\t\treturn tc::continue_;\n\t\t}\n\n\t\ttc::break_or_continue generator_break_consumer_nobreak(tc::function_ref<void (int) noexcept> func) const& noexcept {\n\t\t\tfor(int i = 1; i<11; ++i) {\n\t\t\t\tfunc(i);\n\t\t\t}\n\t\t\treturn tc::continue_;\n\t\t}\n\n\t\tvoid generator_nobreak_consumer_nobreak(tc::function_ref<void (int) noexcept> func) const& noexcept {\n\t\t\tfor(int i = 1; i<11; ++i) {\n\t\t\t\tfunc(i);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tvoid generator_nobreak_consumer_break_correct(tc::function_ref< tc::break_or_continue(int) noexcept > func) const& noexcept {\n\t\t\tfor(int i = 1; i<11; ++i) {\n\t\t\t\tif(func(i) == tc::break_) { return; }\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tvoid generator_nobreak_consumer_break_incorrect(tc::function_ref< tc::break_or_continue(int) noexcept > func) const& noexcept {\n\t\t\tfor(int i = 1; i<11; ++i) {\n\t\t\t\tfunc(i);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t};\n\n\tstruct consumer_break /*final*/ {\n\t\tconsumer_break(tc::vector<int> const& v, std::size_t break_at = 0, bool expect_break = true) noexcept : m_mock(v, break_at, expect_break) {}\n\n\t\ttc::break_or_continue operator()(int const i) const& noexcept { return m_mock(i); }\n\t\tprivate:\n\t\t\tall_called_mock m_mock;\n\t};\n\n\tstruct consumer_nobreak /*final*/ {\n\t\tconsumer_nobreak(tc::vector<int> const& v, std::size_t break_at = 0, bool expect_break = true) noexcept : m_mock(v, break_at, expect_break) {}\n\t\t~consumer_nobreak() {}\n\n\t\tvoid operator()(int const i) const& noexcept { m_mock(i); }\n\n\t\tprivate:\n\t\t\tall_called_mock m_mock;\n\t};\n\n//-----------------------------------------------------------------------------------------------------------------------------\nUNITTESTDEF( break_behavior ) {\n\tTEST_init_hack(tc::vector, int, exp, {1,2,3,4,5,6,7,8,9,10});\n\n\t// call on various implicit ranges\n\ttc::for_each([](auto&& func) noexcept { return iterate().generator_break_consumer_break(tc_move_if_owned(func)); }, consumer_break(exp, 4));\n\ttc::for_each([](auto&& func) noexcept { return iterate().generator_break_consumer_nobreak(tc_move_if_owned(func)); }, consumer_nobreak(exp, 5, false));\n\ttc::for_each([](auto&& func) noexcept { iterate().generator_nobreak_consumer_nobreak(tc_move_if_owned(func)); }, consumer_nobreak(exp, 6, false));\n\n\t// these two are undefined and must not compile\n//\ttc::for_each([](auto&& func) noexcept { iterate().generator_nobreak_consumer_break_correct(tc_move_if_owned(func)); }, all_called_mock(exp, 7));\n//\ttc::for_each([](auto&& func) noexcept { iterate().generator_nobreak_consumer_break_incorrect(tc_move_if_owned(func)); }, all_called_mock(exp, 8, false));\n}\n\nUNITTESTDEF(for_each_adjacent_tuple_deref) {\n\tstruct lr_overloads final{\n\t\tstd::array<int,3> m_n;\n\n\t\tlr_overloads() noexcept {\n\t\t\ttc::at(m_n, 0) = 0;\n\t\t\ttc::at(m_n, 1) = 0;\n\t\t\ttc::at(m_n, 2) = 0;\n\t\t}\n\n\t\tvoid operator()(int const&, int const&, int const&) & noexcept { ++tc::at(m_n, 0);}\n\t\tvoid operator()(int&&, int const&, int const&) & noexcept { ++tc::at(m_n, 1); }\n\t\tvoid operator()(int&&, int&&, int&&) & noexcept { ++tc::at(m_n, 2); }\n\t};\n\n\ttc::vector<int> vecn{0,0,0,0,0};\n\ttc::for_each(\n\t\ttc::adjacent<3>(vecn),\n\t\t[](int& n0, int& n1, int& n2) noexcept {\n\t\t\t++n0;\n\t\t\t++n1;\n\t\t\t++n2;\n\t\t}\n\t);\n\n\tTEST_RANGE_EQUAL(\n\t\tvecn,\n\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,2,1))\n\t);\n\n\tint nTransforms = 0;\n\ttc::for_each(\n\t\ttc::adjacent<3>(\n\t\t\ttc::transform(\n\t\t\t\tvecn,\n\t\t\t\t[&](int const n) noexcept {++nTransforms; return n;}\n\t\t\t)\n\t\t),\n\t\t[](int n0, int n1, int n2) noexcept {\n\t\t\t++n0;\n\t\t\t++n1;\n\t\t\t++n2;\n\t\t}\n\t);\n\t_ASSERTEQUAL(nTransforms,5);\n\n\t{\n\t\tlr_overloads overloads;\n\t\ttc::for_each(\n\t\t\ttc::adjacent<3>(vecn),\n\t\t\tstd::ref(overloads)\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(overloads.m_n, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 3,0,0)));\n\t}\n\n\t{\n\t\tlr_overloads overloads;\n\t\ttc::for_each(\n\t\t\ttc::adjacent<3>(\n\t\t\t\ttc::transform(vecn, [](int const n) noexcept {return n;})\n\t\t\t),\n\t\t\tstd::ref(overloads)\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(overloads.m_n, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 0,2,1)));\n\t}\n}\n\nUNITTESTDEF(ordered_pairs) {\n\t_ASSERT(tc::equal(\n\t\ttc::ordered_pairs(tc::make_array(tc::aggregate_tag, 1,2,3,4)),\n\t\ttc::make_array(tc::aggregate_tag,\n\t\t\ttc::make_tuple(1, 2), tc::make_tuple(1, 3), tc::make_tuple(1, 4),\n\t\t\ttc::make_tuple(2, 3), tc::make_tuple(2, 4),\n\t\t\ttc::make_tuple(3, 4)\n\t\t)\n\t));\n\t_ASSERT(tc::empty(tc::ordered_pairs(tc::make_empty_range<int>())));\n\t_ASSERT(tc::empty(tc::ordered_pairs(tc::single(1))));\n}\n\n//-----------------------------------------------------------------------------------------------------------------------------\n\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<tc::tuple<int, double&, int, char&&>>), TC_FWD(boost::mp11::mp_list<int, double&, char>));\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<tc::tuple<int, double&, int, char&&>&>), TC_FWD(boost::mp11::mp_list<int&, double&, char&>));\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<std::pair<int, double&>>), TC_FWD(boost::mp11::mp_list<int, double&>));\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<std::pair<int, int>&>), TC_FWD(boost::mp11::mp_list<int&>));\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<std::pair<int, int&>&>), TC_FWD(boost::mp11::mp_list<int&>));\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<std::pair<int*, int*>>), TC_FWD(boost::mp11::mp_list<int&>)); // Beware! pair<It, It> has semantics of range [first, second[\n\nUNITTESTDEF(for_each_tuple) {\n\tauto const CheckTuple = [](auto&& tpl) noexcept {\n\t\tint i = 0;\n\t\ttc::for_each(tc_move_if_owned(tpl), [&](auto&& x) {\n\t\t\tswitch_no_default(i++) {\n#pragma push_macro(\"CASE\")\n#define CASE(k, type, val) \\\n\t\tcase k: \\\n\t\t\tif constexpr(std::same_as<tc::remove_rvalue_reference_t<decltype(x)>, tc::remove_rvalue_reference_t<decltype(val)>>) { \\\n\t\t\t\t_ASSERTEQUAL(x, TC_FWD(val)); \\\n\t\t\t} else { \\\n\t\t\t\t_ASSERTFALSE; \\\n\t\t\t} \\\n\t\t\tbreak;\n\n\t\t\t\tCASE(0, int, 3)\n\t\t\t\tCASE(1, double, tc::as_lvalue(1.4))\n\t\t\t\tCASE(2, int, 59)\n\t\t\t\tCASE(3, char, std::move('f'))\n#pragma pop_macro(\"CASE\")\n\t\t\t}\n\t\t});\n\t\t_ASSERTEQUAL(i, tc::size(tpl));\n\t};\n\n\tCheckTuple(tc::tuple<int, double&, int, char&&>{3, tc::as_lvalue(1.4), 59, std::move('f')});\n\tCheckTuple(std::tuple<int, double&, int, char&&>{3, tc::as_lvalue(1.4), 59, std::move('f')});\n\tCheckTuple(std::pair<int, double&>{3, tc::as_lvalue(1.4)});\n}\n\n//-----------------------------------------------------------------------------------------------------------------------------\nUNITTESTDEF(for_each_mp_list) {\n\tauto i = 0;\n\ttc::for_each(boost::mp11::mp_list<int, float, char>{}, [&]<typename T>(std::type_identity<T>) {\n\t\tswitch_no_default(i) {\n\t\tcase 0:\n\t\t\t_ASSERT(std::same_as<T, int>);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t_ASSERT(std::same_as<T, float>);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t_ASSERT(std::same_as<T, char>);\n\t\t\tbreak;\n\t\t}\n\t\t++i;\n\t});\n\n\ti = 0;\n\ttc::for_each(tc::zip(boost::mp11::mp_list<int, float, char>{}, boost::mp11::mp_list<int*, float*, char*>{}), [&]<typename T>(std::type_identity<T>, std::type_identity<T*>) {\n\t\tswitch_no_default(i) {\n\t\tcase 0:\n\t\t\t_ASSERT(std::same_as<T, int>);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t_ASSERT(std::same_as<T, float>);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t_ASSERT(std::same_as<T, char>);\n\t\t\tbreak;\n\t\t}\n\t\t++i;\n\t});\n\n\ti = 0;\n\ttc::for_each(tc::enumerate(boost::mp11::mp_list<int, float, char>{}), [&]<int I, typename T>(tc::constant<I>, std::type_identity<T>) {\n\t\t_ASSERTEQUAL(I, i);\n\t\tswitch_no_default(i) {\n\t\tcase 0:\n\t\t\t_ASSERT(std::same_as<T, int>);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t_ASSERT(std::same_as<T, float>);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t_ASSERT(std::same_as<T, char>);\n\t\t\tbreak;\n\t\t}\n\t\t++i;\n\t});\n}\n}\n"
  },
  {
    "path": "tc/algorithm/for_each_xxx.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../array.h\"\n#include \"filter_inplace.h\"\n#include \"restrict_size_decrement.h\"\n\n\nnamespace tc {\n\t/////////////////////////////////////////////////////\n\t// may_remove_current\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] may_remove_current_impl final { // TODO VS2019: if constexpr does not work well in lambda in VS15.8.0\n\t\t\ttc::reference_or_value<Rng> m_rng;\n\t\t\tconstexpr explicit may_remove_current_impl(Rng&& rng) noexcept: m_rng(tc::aggregate_tag, tc_move_if_owned(rng)) {}\n\n\t\t\ttemplate<typename Func>\n\t\t\tconstexpr auto operator()(Func func) /* no & */ MAYTHROW -> tc::common_type_t<decltype(tc::continue_if_not_break(func, *tc::begin(*m_rng))), tc::constant<tc::continue_>> {\n\t\t\t\tauto it=tc::begin(*m_rng);\n\t\t\t\tauto const itEnd=tc::end(*m_rng);\n\t\t\t\twhile( it!=itEnd ) {\n\t\t\t\t\tauto const rsize = restrict_size_decrement(*m_rng, 0, 1);\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(func, *it++))\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t};\n\t}\n\n\t// enable_if to ensure that removal preserves iterators would be nice, but is difficult for adapted ranges.\n\ttemplate< typename Rng >\n\t[[nodiscard]] constexpr auto may_remove_current(Rng&& rng) noexcept code_return_decltype(\n\t\tstatic_assert( !tc::range_filter_by_move_element< std::remove_reference_t<Rng> >::value );,\n\t\tno_adl::may_remove_current_impl<Rng>(tc_move_if_owned(rng))\n\t)\n}\n"
  },
  {
    "path": "tc/algorithm/interleave_ranges.h",
    "content": "// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../range/subrange.h\"\n#include \"../range/filter_adaptor.h\"\n#include \"../range/iota_range.h\"\n#include \"../container/container.h\"\n#include \"empty.h\"\n#include \"element.h\"\n#include \"filter_inplace.h\"\n\n#include <boost/range/algorithm/heap_algorithm.hpp>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\t\n\t\ttemplate<typename RngRng>\n\t\tusing RangeView = decltype(*std::declval<tc::iterator_t<RngRng const&>>());\n\n\t\ttemplate<typename RngRng, bool bHasStashingElement = tc::is_stashing_element<tc::iterator_t<RngRng const&>>::value>\n\t\tstruct SIteratorView;\n\t\t\n\t\ttemplate<typename RngRng>\n\t\tstruct SIteratorView<RngRng, false> : std::conditional_t<std::is_lvalue_reference<RangeView<RngRng>>::value, tc::copyable, tc::noncopyable>\n\t\t{\n\t\t\tstatic_assert( tc::stable_index_on_move<RangeView<RngRng>> );\n\n\t\t\texplicit SIteratorView(tc::iterator_t<RngRng const&> const& itrng) noexcept\n\t\t\t\t: m_rng(tc::aggregate_tag, *itrng)\n\t\t\t\t, m_idx(tc::begin_index(*m_rng))\n\t\t\t{}\n\n\t\t\tvoid increment_index() & noexcept {\n\t\t\t\ttc::increment_index(*m_rng, m_idx);\n\t\t\t}\n\n\t\t\tbool empty() const& noexcept {\n\t\t\t\treturn tc::at_end_index(*m_rng, m_idx);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstatic decltype(auto) dereference_(auto&& self) return_MAYTHROW(\n\t\t\t\ttc::dereference_index(*tc_move_if_owned(self).m_rng, tc_move_if_owned(self).m_idx)\n\t\t\t)\n\n\t\tpublic:\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(dereference)\n\n\t\tprivate:\n\t\t\ttc::reference_or_value<RangeView<RngRng>> m_rng;\n\t\t\ttc::index_t<std::remove_reference_t<decltype(*m_rng)>> m_idx;\n\t\t};\n\n\t\ttemplate<typename RngRng>\n\t\tstruct SIteratorView<RngRng, true> // Stashing iterator\n\t\t\t: private tc::iterator_t<RngRng const&>\n\t\t\t, public SIteratorView<RngRng, false>\n\t\t{\n\t\t\texplicit SIteratorView(tc::iterator_t<RngRng const&> itrng) noexcept\n\t\t\t\t: tc::iterator_t<RngRng const&>(tc_move(itrng))\n\t\t\t\t, SIteratorView<RngRng, false>(tc::base_cast<tc::iterator_t<RngRng const&>>(*this))\n\t\t\t{}\n\t\t};\n\t\t\n\t\ttemplate<typename RngRng>\n\t\tstruct interleave_ranges_index {\n\t\t\ttc::vector<SIteratorView<RngRng>> m_vecview;\n\t\t\tstd::size_t m_nLast;\n\n\t\t\tstatic_assert(!tc::is_stashing_element<tc::iterator_t<RngRng const&>>::value || std::is_copy_constructible<tc::iterator_t<RngRng const&>>::value);\n\n\t\t\tinterleave_ranges_index(tc::empty_range) noexcept\n\t\t\t\t: m_nLast(0) {}\n\t\t\tinterleave_ranges_index(RngRng const& rng) noexcept\n\t\t\t\t: tc_member_init(m_vecview, tc::filter(\n\t\t\t\t\ttc::make_range_of_iterators(rng),\n\t\t\t\t\t[](auto const& it) noexcept {\n\t\t\t\t\t\treturn !tc::empty(*it);\n\t\t\t\t\t}\n\t\t\t\t))\n\t\t\t{}\n\t\t};\n\n\t\ttemplate<typename RngRng, typename Less>\n\t\tstruct interleave_ranges_adaptor\n\t\t\t: tc::range_adaptor_base_range<RngRng>\n\t\t\t, tc::range_iterator_from_index<\n\t\t\t\tinterleave_ranges_adaptor<RngRng, Less>,\n\t\t\t\tinterleave_ranges_index<RngRng>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = interleave_ranges_adaptor;\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex = true;\n\n\t\t\tLess m_less;\n\n\t\t\ttemplate<typename RngRng_, typename Less_>\n\t\t\tinterleave_ranges_adaptor(RngRng_&& rngrng, Less_&& less) noexcept\n\t\t\t\t: tc::range_adaptor_base_range<RngRng>(tc::aggregate_tag, tc_move_if_owned(rngrng))\n\t\t\t\t, m_less(tc_move_if_owned(less))\n\t\t\t{}\n\n\t\t\tconstexpr auto greater() const& noexcept {\n\t\t\t\treturn tc::reverse_binary_rel(tc::projected(m_less, tc_mem_fn(.dereference)));\n\t\t\t}\n\n\t\t\tconstexpr void prepare_index(tc_index& idx) const& noexcept {\n\t\t\t\ttc_auto_cref(greater, this->greater());\n\t\t\t\tidx.m_nLast = tc::size(idx.m_vecview);\n\t\t\t\tdo {\n\t\t\t\t\tboost::range::pop_heap(tc::begin_next<tc::return_take>(idx.m_vecview, idx.m_nLast), greater);\n\t\t\t\t\t--idx.m_nLast;\n\t\t\t\t} while (0 < idx.m_nLast && !greater(tc::front(idx.m_vecview), tc::at(idx.m_vecview,idx.m_nLast) ));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\ttc_index idx(this->base_range());\n\t\t\t\tif (!this->at_end_index(idx)) {\n\t\t\t\t\tboost::range::make_heap(idx.m_vecview, this->greater());\n\t\t\t\t\tprepare_index(idx);\n\t\t\t\t}\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn tc::empty_range();\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn tc::empty(idx.m_vecview);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERTE(!this->at_end_index(idx));\n\n\t\t\t\ttc_auto_cref(greater, this->greater());\n\n\t\t\t\ttc::filter_inplace(idx.m_vecview, tc::begin_next<tc::return_border>(idx.m_vecview, idx.m_nLast), [](auto& view) noexcept{\n\t\t\t\t\tview.increment_index();\n\t\t\t\t\treturn !tc::empty(view);\n\t\t\t\t});\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::iota(idx.m_nLast, tc::size(idx.m_vecview)),\n\t\t\t\t\t[&](auto const n) noexcept {\n\t\t\t\t\t\tboost::range::push_heap(tc::begin_next<tc::return_take>(idx.m_vecview, n+1), greater);\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tif (!this->at_end_index(idx)) {\n\t\t\t\t\tprepare_index(idx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(static constexpr, dereference_index)(auto&& idx) noexcept {\n\t\t\t\treturn tc::transform(\n\t\t\t\t\ttc::begin_next<tc::return_drop>(tc_move_if_owned(idx).m_vecview, tc_move_if_owned(idx).m_nLast),\n\t\t\t\t\ttc_mem_fn(.dereference)\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename RngRng,  typename Less = tc::fn_less>\n\tauto interleave_ranges(RngRng&& rngrng, Less&& less = Less()) {\n\t\treturn no_adl::interleave_ranges_adaptor<RngRng, tc::decay_t<Less>>(tc_move_if_owned(rngrng), tc_move_if_owned(less));\n\t}\n\n}\n"
  },
  {
    "path": "tc/algorithm/longest_common_prefix.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"equal.h\"\n\nnamespace tc {\n\ttemplate< typename RangeReturn, typename RngLhs, typename RngRhs, typename Pred=tc::fn_equal_to_or_parse_match>\n\t[[nodiscard]] constexpr decltype(auto) longest_common_prefix(RngLhs&& rnglhs, RngRhs&& rngrhs, Pred pred=Pred()) MAYTHROW {\n\t\tstatic_assert(RangeReturn::allowed_if_always_has_border);\n\n\t\ttc_auto_cref(itlhsEnd, tc::end(rnglhs));\n\t\ttc_auto_cref(itrhsEnd, tc::end(rngrhs));\n\t\tauto itlhs=tc::begin(rnglhs);\n\t\tauto itrhs=tc::begin(rngrhs);\n\t\twhile(itlhs < itlhsEnd && itrhs < itrhsEnd && tc_invoke(pred, *itlhs, *itrhs)) {\n\t\t\t++itlhs;\n\t\t\t++itrhs;\n\t\t}\n\t\treturn std::make_pair(\n\t\t\tRangeReturn::pack_border(itlhs, tc_move_if_owned(rnglhs)),\n\t\t\tRangeReturn::pack_border(itrhs, tc_move_if_owned(rngrhs))\n\t\t);\n\t}\n\n\ttemplate< typename RangeReturn, typename RngLhs, typename RngRhs, typename Pred=tc::fn_equal_to_or_parse_match>\n\t[[nodiscard]] constexpr decltype(auto) longest_common_prefix_lhs(RngLhs&& rnglhs, RngRhs&& rngrhs, Pred pred=Pred()) MAYTHROW {\n\t\tstatic_assert(RangeReturn::allowed_if_always_has_border);\n\n\t\ttc_auto_cref(itlhsEnd, tc::end(rnglhs));\n\t\tauto itlhs=tc::begin(rnglhs);\n\t\ttc::for_each(rngrhs, [&](auto const& rhs) noexcept {\n\t\t\tif (itlhs!=itlhsEnd && tc_invoke(pred,*itlhs, rhs)) {\n\t\t\t\t++itlhs;\n\t\t\t\treturn tc::continue_;\n\t\t\t} else {\n\t\t\t\treturn tc::break_;\n\t\t\t}\n\t\t});\n\t\treturn RangeReturn::pack_border(itlhs, tc_move_if_owned(rnglhs));\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/longest_common_prefix.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"longest_common_prefix.h\"\n#include \"../unittest.h\"\n\nnamespace {\nUNITTESTDEF( longest_common_prefix ) {\n\ttc_static_auto_constexpr_lambda(CheckLCP) = [](auto const& strLhs, auto const& strRhs, auto const& strPrefix, auto const& strSuffixLhs, auto const& strSuffixRhs) noexcept {\n\t\ttc_auto_cref(pairstrstrPrefix, tc::longest_common_prefix<tc::return_take>(strLhs, strRhs));\n\t\t_ASSERT(tc::equal(pairstrstrPrefix.first, pairstrstrPrefix.second));\n\t\t_ASSERT(tc::equal(pairstrstrPrefix.first, strPrefix));\n\t\ttc_auto_cref(pairstrstrSuffix, tc::longest_common_prefix<tc::return_drop>(strLhs, strRhs));\n\t\t_ASSERT(tc::equal(pairstrstrSuffix.first, strSuffixLhs));\n\t\t_ASSERT(tc::equal(pairstrstrSuffix.second, strSuffixRhs));\n\t};\n\tCheckLCP(\"abcd\", \"ab\", \"ab\", \"cd\", \"\");\n\tCheckLCP(\"ac\", \"abcd\", \"a\", \"c\", \"bcd\");\n\tCheckLCP(\"x\", \"abcd\", \"\", \"x\", \"abcd\");\n}\n}\n\n"
  },
  {
    "path": "tc/algorithm/minmax.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/conditional.h\"\n#include \"../base/change.h\"\n#include \"size.h\"\n\nnamespace tc {\n\tnamespace no_adl {\t\n\t\ttemplate <typename Better>\n\t\tstruct TC_EMPTY_BASES fn_best : private std::remove_cvref_t<Better> {\n\t\t\tconstexpr fn_best() noexcept = default;\n\t\t\ttemplate<typename BetterRef>\n\t\t\tconstexpr fn_best(BetterRef&& better) noexcept : std::remove_cvref_t<Better>(tc_move_if_owned(better))\n\t\t\t{}\n\n\t\t\ttemplate <typename T>\n\t\t\t[[nodiscard]] constexpr decltype(auto) operator()(T&& t) const& noexcept {\n\t\t\t\treturn tc_move_if_owned(t);\n\t\t\t}\n\t\t\t\n\t\t\ttemplate <typename T0, typename T1, typename... Args>\n\t\t\t[[nodiscard]] constexpr decltype(auto) operator()(T0&& t0, T1&& t1, Args&&... args) const& noexcept {\n\t\t\t\t// analogous to std::min/std::max: if equivalent, return the first parameter\n\t\t\t\tauto b = tc_invoke(static_cast<std::remove_cvref_t<Better> const&>(*this), tc::as_const(t1), tc::as_const(t0));\n\t\t\t\tif constexpr (std::is_same<tc::constant<true>, decltype(b)>::value) {\n\t\t\t\t\t// t1 is better\n\t\t\t\t\treturn operator()(tc_move_if_owned(t1), tc_move_if_owned(args)...);\n\t\t\t\t} else if constexpr (std::is_same<tc::constant<false>, decltype(b)>::value) {\n\t\t\t\t\t// t0 is better or equal\n\t\t\t\t\treturn operator()(tc_move_if_owned(t0), tc_move_if_owned(args)...);\n\t\t\t\t} else {\n\t\t\t\t\tSTATICASSERTSAME(decltype(b), bool);\n\t\t\t\t\treturn tc_conditional_prvalue_as_val(\n\t\t\t\t\t\tb,\n\t\t\t\t\t\t/*t1 is better*/operator()(tc_move_if_owned(t1), tc_move_if_owned(args)...),\n\t\t\t\t\t\t/*t0 is better or equal*/operator()(tc_move_if_owned(t0), tc_move_if_owned(args)...)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::fn_best;\n\tusing fn_min = fn_best<tc::fn_less>;\n\tusing fn_max = fn_best<tc::fn_greater>;\n\n\ttemplate <typename Better, typename ... Args>\n\t[[nodiscard]] constexpr auto best(Better&& better, Args&&... args) return_decltype_allow_xvalue_noexcept(\n\t\tfn_best<std::remove_cvref_t<Better>>(tc_move_if_owned(better))(tc_move_if_owned(args)...)\n\t)\n\n\ttemplate <typename ... Args>\n\t[[nodiscard]] constexpr auto min(Args&&... args) return_decltype_allow_xvalue_noexcept(\n\t\tbest(tc::fn_less(), tc_move_if_owned(args)...)\n\t)\n\n\ttemplate <typename ... Args>\n\t[[nodiscard]] constexpr auto max(Args&&... args) return_decltype_allow_xvalue_noexcept(\n\t\tbest(tc::fn_greater(), tc_move_if_owned(args)...)\n\t)\n}\n\n"
  },
  {
    "path": "tc/algorithm/partition_iterator.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../container/insert.h\"\n#include \"../static_vector.h\"\n#include \"../interval_types.h\"\n#include \"../range/reverse_adaptor.h\"\n\n#include <boost/iterator/transform_iterator.hpp>\n#include <boost/next_prior.hpp>\n#include <boost/range/algorithm/mismatch.hpp>\n\n#include <boost/multi_index/ordered_index.hpp>\n\n#include <functional>\n\nnamespace tc {\n\n\tnamespace iterator {\n\n\t\ttemplate<typename It> constexpr It middle_point(It const&, It const&) noexcept;\n\n\t\tnamespace adl {\n\t\t\t// default forward iterator implementation\n\t\t\ttemplate<typename It> requires true // to make it more constrained than tc::iterator::middle_point\n\t\t\tIt \n\t\t\tmiddle_point( It const& itBegin, It const& itEnd ) noexcept {\n\t\t\t\t// SEnumerateGapConstraints::SEnumerateGapConstraints calls intersect on transforms of counting ranges of tree iterators\n\t\t\t\t// intersect calls tc::upper_bound\n\t\t\t\t// TODO efficient implementation for tree iterators\n\t\t\t\t// static_assert(!std::is_same<It, It>::value, \"provide more efficient middle_point or apply linear search\");\n\t\t\t\treturn itBegin;\n\t\t\t}\n\n\t\t\ttemplate< typename It, typename UnaryPred >\n\t\t\tstd::reverse_iterator<It>\n\t\t\tmiddle_point(std::reverse_iterator<It> const& itBegin, std::reverse_iterator<It> const& itEnd ) noexcept {\n\t\t\t\tstatic_assert(!std::is_same<It, It>::value, \"This code has never been tested\");\n\t\t\t\treturn std::reverse_iterator<It>(\n\t\t\t\t\ttc::iterator::middle_point(\n\t\t\t\t\t\titEnd.base(),\n\t\t\t\t\t\titBegin.base()\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// NodeBase is a base type of the multi_index_container's node (internal data\n\t\t\t// structure used to store elements).\n\t\t\t#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)\n\t\t\t\ttemplate< typename AugmentPolicy, typename NodeBase >\n\t\t\t\tboost::multi_index::safe_mode::safe_iterator<\n\t\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >\n\t\t\t\t>\n\t\t\t\tmiddle_point( \n\t\t\t\t\tboost::multi_index::safe_mode::safe_iterator<\n\t\t\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >\n\t\t\t\t\t> itBegin,\n\t\t\t\t\tboost::multi_index::safe_mode::safe_iterator<\n\t\t\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >\n\t\t\t\t\t> itEnd\n\t\t\t\t)\n\t\t\t#else\n\t\t\t\ttemplate< typename AugmentPolicy, typename NodeBase >\n\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >\n\t\t\t\tmiddle_point( \n\t\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> > itBegin,\n\t\t\t\t\tboost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> > itEnd\n\t\t\t\t) noexcept\n\t\t\t#endif\n\t\t\t{\n\t\t\t\tusing node_type = boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase>;\n\t\t\t\tusing TNodeVector = typename tc::static_vector<\n\t\t\t\t\tnode_type*, \n\t\t\t\t\t2* // 2*log(N) is maximum hight of RB tree\n\t\t\t\t\t\t(CHAR_BIT*sizeof(std::size_t)-3) // 2^3==8 roughly minimum size of node\n\t\t\t\t>;\n\n\t\t\t\t// The parent of the root of the tree is a special header node (representing end()) whose\n\t\t\t\t// parent is again the root node.\n\t\t\t\ttc_static_auto_constexpr_lambda(PathToRoot) = []( node_type* pnode ) noexcept ->TNodeVector {\n\t\t\t\t\tTNodeVector vecpnode;\n\t\t\t\t\tnode_type* pnodeParent=node_type::from_impl(pnode->parent());\n\n\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\ttc::cont_emplace_back(vecpnode, pnode);\n\t\t\t\t\t\tnode_type* pnodeGrandparent=node_type::from_impl(pnodeParent->parent());\n\t\t\t\t\t\tif(pnode==pnodeGrandparent) return vecpnode; // abort if pnode is root\n\t\t\t\t\t\tpnode=pnodeParent;\n\t\t\t\t\t\tpnodeParent=pnodeGrandparent;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tTNodeVector vecpnodeBegin=PathToRoot(itBegin.get_node());\n\t\t\t\tTNodeVector vecpnodeEnd=PathToRoot(tc_modified(itEnd, --_).get_node());\n\t\t\t\t_ASSERTEQUAL( tc::back(vecpnodeBegin), tc::back(vecpnodeEnd) ); // both paths terminate at the root\n\t\t\t\tnode_type* pnodeCommon=*tc_modified( boost::mismatch(\n\t\t\t\t\ttc::reverse(vecpnodeBegin),\n\t\t\t\t\ttc::reverse(vecpnodeEnd)\n\t\t\t\t).first, --_ ); // or second, same thing\n\t\t\t\t#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)\n\t\t\t\t\treturn boost::multi_index::safe_mode::safe_iterator<boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >>(pnodeCommon, tc::as_mutable_ptr(itBegin.owner()));\n\t\t\t\t#else\n\t\t\t\t\treturn boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<AugmentPolicy, NodeBase> >(pnodeCommon);\n\t\t\t\t#endif\n\t\t\t}\n\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr It middle_point_dispatch( It const& itBegin, It const& itEnd, boost::iterators::forward_traversal_tag ) noexcept {\n\t\t\t\treturn middle_point(itBegin,itEnd);\n\t\t\t}\n\n\t\t\t// default random-access iterator implementation\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr It middle_point_dispatch( It const& itBegin, It const& itEnd, boost::iterators::random_access_traversal_tag ) noexcept {\n\t\t\t\treturn itBegin+(itEnd-itBegin)/2;\n\t\t\t}\n\n\t\t}\n\n\t\ttemplate<typename It>\n\t\t[[nodiscard]] constexpr It middle_point( It const& itBegin, It const& itEnd ) noexcept {\n\t\t\treturn adl::middle_point_dispatch( itBegin, itEnd, typename boost::iterator_traversal<It>::type() );\n\t\t}\n\n\t\ttemplate<typename It, typename UnaryPred>\n\t\t[[nodiscard]] constexpr It internal_partition_point( It itBegin, It itEnd, UnaryPred pred ) noexcept {\n\t\t#ifdef _DEBUG /* is pred a partitioning? All true must be before all false. */\n\t\t\tIt itPartitionPoint = itBegin;\n\t\t\twhile( itPartitionPoint!=itEnd && pred(tc::as_const(itPartitionPoint)) ) ++itPartitionPoint;\n\t\t\tfor( It itRest=itPartitionPoint; itRest!=itEnd; ++itRest ) {\n\t\t\t\t_ASSERT( !tc::explicit_cast<bool>(pred(tc::as_const(itRest))) );\n\t\t\t}\n\t\t#endif\n\t\t\twhile( itBegin!=itEnd ) {\n\t\t\t\tIt itMid = iterator::middle_point( itBegin, itEnd ); // may return any itMid in [itBegin,itEnd[\n\t\t\t\t_ASSERTDEBUG(itMid != itEnd);\n\t\t\t\tif( pred(tc::as_const(itMid)) ) {\n\t\t\t\t\titBegin=tc_move(itMid);\n\t\t\t\t\t++itBegin;\n\t\t\t\t} else {\n\t\t\t\t\titEnd=tc_move(itMid);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// we have already found the partition point; compare result\n\t\t\t_ASSERTDEBUGEQUAL(itBegin, itPartitionPoint);\n\t\t\treturn itBegin;\n\t\t}\n\n\t\ttemplate<typename It, typename UnaryPred>\n\t\t[[nodiscard]] constexpr It partition_point( It itBegin, It itEnd, UnaryPred pred ) noexcept {\n\t\t\treturn internal_partition_point( tc_move(itBegin), tc_move(itEnd), [&pred](It it) noexcept {\n\t\t\t\treturn pred(tc::as_const(*it));\n\t\t\t} );\n\t\t}\n\n\t\ttemplate<typename It, typename UnaryPred>\n\t\t[[nodiscard]] It partition_pair( It itBegin, It itEnd, UnaryPred pred ) noexcept {\n\t\t\t_ASSERT( itBegin!=itEnd );\n\t\t\t--itEnd;\n\t\t\treturn internal_partition_point( tc_move(itBegin), tc_move(itEnd), [&pred](It it) noexcept {\n\t\t\t\treturn pred(tc::as_const(*it),tc::as_const(*tc_modified(it, ++_)));\n\t\t\t} );\n\t\t}\n\n\t\t////////////////////////////////////////////////////////////////////////\n\t\t// Iterator functions forwarding to partition_point\n\n\t\ttemplate <typename It, typename Value, typename UnaryPredicate = tc::fn_less>\n\t\t[[nodiscard]] It lower_bound(It itBegin,It itEnd,Value const& val,UnaryPredicate pred = {}) noexcept {\n\t\t\treturn iterator::partition_point(\n\t\t\t\titBegin,\n\t\t\t\titEnd,\n\t\t\t\t[&](auto const& _) noexcept { return pred(_, val); }\n\t\t\t);\n\t\t}\n\n\t\ttemplate <typename It, typename Value, typename UnaryPredicate = tc::fn_less>\n\t\t[[nodiscard]] It upper_bound(It itBegin,It itEnd,Value const& val,UnaryPredicate&& pred = {}) noexcept {\n\t\t\treturn iterator::partition_point(itBegin,itEnd,[&](auto const& _) noexcept { return !pred(val, _); });\n\t\t}\n\n\t\ttemplate <typename It, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] std::pair<It,It> equal_range(It itBegin,It itEnd,Value const& val,SortPredicate pred = {}) noexcept {\n\t\t\t// Construct std::pair<It,It> initialized so that transform_iterator functor\n\t\t\t// does have to be neither default-constructible nor assignable. This is non-standard conformant,\n\t\t\t// but may be practical.\n\t\t\tIt itEqualBegin=iterator::lower_bound(itBegin,itEnd,val,pred);\n\t\t\treturn std::pair<It,It>( itEqualBegin, iterator::upper_bound(itEqualBegin,itEnd,val,pred) );\n\t\t}\n\t}\n\tusing namespace iterator;\n\tusing iterator::middle_point;\n}\n\n"
  },
  {
    "path": "tc/algorithm/partition_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"partition_iterator.h\"\n#include \"../range/subrange.h\"\n\nnamespace tc {\n\n\t////////////////////////////////////////////////////////////////////////\n\t// Range functions\n\n\tnamespace range {\n\t\ttemplate<typename RangeReturn, typename Rng, typename UnaryPredicate>\n\t\t[[nodiscard]] constexpr decltype(auto) partition_point(Rng&& rng, UnaryPredicate&& pred) noexcept {\n\t\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\t\treturn tc_rewrap_temporary(Rng&&, RangeReturn::pack_border(\n\t\t\t\titerator::partition_point(tc::begin(tc_unwrap_temporary(rng)), tc::end(tc_unwrap_temporary(rng)), tc_move_if_owned(pred)),\n\t\t\t\ttc_unwrap_temporary(tc_move_if_owned(rng))\n\t\t\t));\n\t\t}\n\n\t\ttemplate<typename RangeReturn, typename Rng, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] decltype(auto) lower_bound(Rng&& rng, Value const& val, SortPredicate&& pred = {}) noexcept {\n\t\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\t\treturn tc_rewrap_temporary(Rng&&, RangeReturn::pack_border(\n\t\t\t\titerator::lower_bound(tc::begin(tc_unwrap_temporary(rng)), tc::end(tc_unwrap_temporary(rng)), val, tc_move_if_owned(pred)),\n\t\t\t\ttc_unwrap_temporary(tc_move_if_owned(rng))\n\t\t\t));\n\t\t}\n\n\t\ttemplate<typename RangeReturn, typename Rng, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] decltype(auto) upper_bound(Rng&& rng, Value const& val, SortPredicate&& pred = {}) noexcept {\n\t\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\t\treturn tc_rewrap_temporary(Rng&&, RangeReturn::pack_border(\n\t\t\t\titerator::upper_bound(tc::begin(tc_unwrap_temporary(rng)), tc::end(tc_unwrap_temporary(rng)), val, tc_move_if_owned(pred)),\n\t\t\t\ttc_unwrap_temporary(tc_move_if_owned(rng))\n\t\t\t));\n\t\t}\n\n\t\ttemplate<typename Rng, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] decltype(auto) equal_range(Rng&& rng, Value const& val, SortPredicate&& pred = {}) noexcept {\n\t\t\tauto pairit = iterator::equal_range(tc::begin(rng), tc::end(rng), val, tc_move_if_owned(pred));\n\t\t\treturn tc::slice( tc_move_if_owned(rng), tc_move(pairit).first, tc_move(pairit).second );\n\t\t}\n\n\t\ttemplate<typename Rng, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] decltype(auto) range_in_interval_inclusive(Rng&& rng, tc::interval<Value> const& intvlval, SortPredicate&& pred = {}) noexcept {\n\t\t\treturn tc_invoke(tc::chained(\n\t\t\t\t// clang crashes if we use return_decltype_allow_xvalue\n\t\t\t\t[&](auto&& rng) noexcept -> decltype(auto) { return upper_bound<tc::return_take>(tc_move_if_owned(rng), intvlval[tc::hi], tc_move_if_owned(pred)); },\n\t\t\t\t[&](auto&& rng) noexcept -> decltype(auto) { return lower_bound<tc::return_drop>(tc_move_if_owned(rng), intvlval[tc::lo], pred); }\n\t\t\t), tc_move_if_owned(rng));\n\t\t}\n\n\t\ttemplate<typename Rng, typename Value, typename SortPredicate = tc::fn_less>\n\t\t[[nodiscard]] decltype(auto) range_in_interval(Rng&& rng, tc::interval<Value> const& intvlval, SortPredicate&& pred = {}) noexcept {\n\t\t\treturn tc_invoke(tc::chained(\n\t\t\t\t// clang crashes if we use return_decltype_allow_xvalue\n\t\t\t\t[&](auto&& rng) noexcept -> decltype(auto) { return lower_bound<tc::return_take>(tc_move_if_owned(rng), intvlval[tc::hi], tc_move_if_owned(pred)); },\n\t\t\t\t[&](auto&& rng) noexcept -> decltype(auto) { return upper_bound<tc::return_drop>(tc_move_if_owned(rng), intvlval[tc::lo], pred); }\n\t\t\t), tc_move_if_owned(rng));\n\t\t}\n\t}\n\tusing namespace range;\n}\n\n"
  },
  {
    "path": "tc/algorithm/quantifier.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/invoke.h\"\n#include \"../range/transform_adaptor.h\"\n#include \"../variant.h\"\n#include \"for_each.h\"\n#include \"find.h\"\n#include \"compare.h\"\n#include \"any_accu.h\"\n#include <utility>\n\n/////////////////////////////////////////////\n// std::all/any/none_of on ranges\n\nnamespace tc {\n\ntemplate< typename Rng, typename Pred = tc::identity >\n[[nodiscard]] constexpr bool any_of(Rng&& rng, Pred&& pred = Pred()) MAYTHROW {\n\treturn tc::find_first_if<tc::return_bool>(tc_move_if_owned(rng), tc_move_if_owned(pred));\n}\n\ntemplate< typename Rng, typename Pred = tc::identity >\n[[nodiscard]] constexpr bool all_of(Rng&& rng, Pred&& pred = Pred()) MAYTHROW {\n\treturn !tc::any_of(tc_move_if_owned(rng), std::not_fn(tc_move_if_owned(pred)));\n}\n\n// pair is in same order as if minmax_element( ..., operator<( bool, bool ) ) would have been used.\ntemplate< typename Rng >\n[[nodiscard]] std::pair<bool,bool> all_any_of( Rng const& rng ) MAYTHROW {\n\tstd::pair<bool,bool> pairb(true,false);\n\ttc::for_each(rng, [&](bool const b) noexcept {\n\t\tpairb.first=pairb.first && b;\n\t\tpairb.second=pairb.second || b;\n\t\treturn continue_if( pairb.first || !pairb.second );\n\t} );\n\treturn pairb;\n}\n\ntemplate< typename Rng, typename Pred >\n[[nodiscard]] std::pair<bool,bool> all_any_of(Rng const& rng, Pred&& pred) MAYTHROW {\n\treturn all_any_of( tc::transform(rng,tc_move_if_owned(pred)) );\n}\n\n[[nodiscard]] inline bool eager_or(std::initializer_list<tc::bool_context> ab) MAYTHROW {\n\t// use initializer list instead of variadic template: initializer list guarantees evaluation in order of appearance\n\treturn tc::any_of(ab);\n}\n\n[[nodiscard]] inline bool eager_and(std::initializer_list<tc::bool_context> ab) MAYTHROW {\n\t// use initializer list instead of variadic template: initializer list guarantees evaluation in order of appearance\n\treturn tc::all_of(ab);\n}\n\ntemplate< typename Rng, typename Pred >\n[[nodiscard]] bool eager_any_of(Rng&& rng, Pred&& pred) MAYTHROW {\n\ttc::any_accu any;\n\ttc::for_each(tc::transform(rng, tc_move_if_owned(pred)), std::ref(any));\n\treturn any;\n}\n\ntemplate< typename Rng, typename Pred >\n[[nodiscard]] bool eager_all_of(Rng&& rng, Pred&& pred) MAYTHROW {\n\treturn !tc::eager_any_of(tc_move_if_owned(rng), std::not_fn(tc_move_if_owned(pred)));\n}\n\n// all_same_element\nnamespace all_same_result {\n\tstruct empty_t final {};\n\tstruct not_same_t final {};\n\n\ttemplate<typename T=void>\n\tstruct never_empty /*final*/ {\n\t\tconstexpr T operator()(empty_t) const& noexcept { _ASSERTFALSE; return tc::construct_default_or_terminate<T>(); }\n\t};\n}\n\nnamespace no_adl {\n\ttemplate<typename T, typename Equal=tc::decay_t<decltype(tc::equal_to)>>\n\tstruct [[nodiscard]] accumulator_all_same final {\n\t\tstatic_assert(tc::decayed<Equal>);\n\n\t\tusing result_type = std::variant<all_same_result::empty_t, T, all_same_result::not_same_t>;\n\n\t\tconstexpr accumulator_all_same() noexcept = default;\n\t\tconstexpr accumulator_all_same(auto&& equal) noexcept : m_equal(tc_move_if_owned(equal)) {}\n\n\t\ttemplate<typename U>\n\t\tconstexpr auto operator()(U&& u) & MAYTHROW {\n\t\t\tif constexpr( std::is_same<accumulator_all_same, tc::decay_t<U>>::value ) {\n\t\t\t\treturn tc::fn_visit(\n\t\t\t\t\t[&](all_same_result::empty_t) noexcept {\n\t\t\t\t\t\treturn tc::continue_if(!std::holds_alternative<all_same_result::not_same_t>(m_result));\n\t\t\t\t\t},\n\t\t\t\t\t[&](auto&& t) MAYTHROW {\n\t\t\t\t\t\treturn operator()(tc_move_if_owned(t)); // MAYTHROW\n\t\t\t\t\t},\n\t\t\t\t\t[&](all_same_result::not_same_t) noexcept {\n\t\t\t\t\t\tm_result=all_same_result::not_same_t();\n\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t}\n\t\t\t\t)(tc_move_if_owned(u).m_result_());\n\t\t\t} else {\n\t\t\t\treturn tc::fn_visit(\n\t\t\t\t\t[&](all_same_result::empty_t) MAYTHROW {\n\t\t\t\t\t\tm_result=tc_move_if_owned(u); // MAYTHROW\n\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t},\n\t\t\t\t\t[&](T const& t) noexcept {\n\t\t\t\t\t\tif(m_equal(t, tc::as_const(u))) {\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tm_result=all_same_result::not_same_t();\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t[](all_same_result::not_same_t) noexcept {\n\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t}\n\t\t\t\t)(m_result);\n\t\t\t}\n\t\t}\n\n\tprivate:\n\t\tPRIVATE_MEMBER_PUBLIC_ACCESSOR(result_type, m_result)\n\t\tEqual m_equal;\n\t};\n\n\tstruct return_all_same_result;\n\n\ttemplate<typename RangeReturn, typename Rng, typename Equal>\n\tstruct all_same_element_impl;\n\n\ttemplate<typename Rng, typename Equal>\n\tstruct all_same_element_impl<return_all_same_result, Rng, Equal> final {\n\t\tstatic constexpr auto fn(Rng&& rng, Equal&& equal) MAYTHROW {\n\t\t\taccumulator_all_same<tc::range_value_t<Rng>, tc::decay_t<Equal>> accu(tc_move_if_owned(equal));\n\t\t\ttc::for_each(tc_move_if_owned(rng), std::ref(accu));\n\t\t\treturn accu.m_result_();\n\t\t}\n\t};\n\n\ttemplate<typename RangeReturn, typename Rng, typename Equal>\n\tstruct all_same_element_impl final {\n\t\tstatic constexpr decltype(auto) fn(Rng&& rng, Equal&& equal) MAYTHROW {\n\t\t\t// TODO: For RangeReturn return_value, without _CHECKS, the algorithm should not loop but compute the result in O(1) time.\n\t\t\treturn tc::fn_visit(\n\t\t\t\t[](auto&& t) noexcept -> decltype(auto) {\n\t\t\t\t\treturn RangeReturn::template pack_element<Rng>(tc_move_if_owned(t));\n\t\t\t\t},\n\t\t\t\t[](tc::all_same_result::empty_t) noexcept -> decltype(auto) {\n\t\t\t\t\treturn RangeReturn::template pack_no_element<Rng>();\n\t\t\t\t},\n\t\t\t\t[](tc::all_same_result::not_same_t) noexcept -> decltype(auto) {\n\t\t\t\t\treturn RangeReturn::template pack_no_element<Rng>();\n\t\t\t\t}\n\t\t\t)(all_same_element_impl<return_all_same_result, Rng, Equal>::fn(tc_move_if_owned(rng), tc_move_if_owned(equal)) /*MAYTHROW*/);\n\t\t}\n\t};\n}\nusing no_adl::accumulator_all_same;\nusing no_adl::return_all_same_result;\n\ntemplate<typename RangeReturn, typename Rng, typename Equal = decltype(tc::equal_to)>\n[[nodiscard]] constexpr decltype(auto) all_same_element(Rng&& rng, Equal&& equal = {}) MAYTHROW {\n\treturn no_adl::all_same_element_impl<RangeReturn, Rng, Equal>::fn(tc_move_if_owned(rng), tc_move_if_owned(equal));\n}\n\ntemplate< typename Rng, typename Equal = tc::decay_t<decltype(tc::equal_to)>>\n[[nodiscard]] constexpr bool all_same(Rng&& rng, Equal equal = {}) noexcept {\n\tif constexpr(tc::range_with_iterators<Rng>) {\n\t\tauto const itBegin = tc::begin(rng);\n\t\tauto const itEnd = tc::end(rng);\n\t\tif(itBegin != itEnd) {\n\t\t\ttc_auto_cref(front, *itBegin);\n\t\t\tfor(auto it = itBegin; ++it != itEnd;) {\n\t\t\t\tif(!equal(front, *it)) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t} else {\n\t\treturn !std::holds_alternative<tc::all_same_result::not_same_t>(\n\t\t\ttc::all_same_element<tc::return_all_same_result>(tc_move_if_owned(rng), tc_move(equal))\n\t\t);\n\t}\n}\n}\n"
  },
  {
    "path": "tc/algorithm/quantifier.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../container/container.h\" // tc::vector\n#include \"../unittest.h\"\n#include \"quantifier.h\"\n\nUNITTESTDEF( quantifiers ) {\n\n\ttc::vector<int> v{1,2,3,4,5,6,7};\n\n\ttc::vector<int> all_even{2,4,6,8};\n\ttc::vector<int> all_odd{3,5,7,9};\n\n\ttc_static_auto_constexpr_lambda(even) = [](int const i) noexcept { return i%2==0; };\n\n\tint const existing_value = 5;\n\tint const non_existing_value = 9;\n\n\tauto const_range = tc::all(tc::as_const(v)); TEST_RANGE_LENGTH(const_range, 7);\n\n\t_ASSERT( tc::find_first<tc::return_bool>(const_range, existing_value));\n\t_ASSERT(!tc::find_first<tc::return_bool>(const_range, non_existing_value));\n\n\t_ASSERT(! tc::all_of(const_range, even));\n\t_ASSERT(  tc::any_of(const_range, even));\n\n\t_ASSERT(  tc::all_of(all_even, even));\n\t_ASSERT(  tc::any_of(all_even, even));\n\n\t_ASSERT(! tc::all_of(all_odd, even));\n\t_ASSERT(! tc::any_of(all_odd, even));\n}\n\nUNITTESTDEF( all_same ) {\n\ttc::vector<int> const v_empty{};\n\ttc::vector<int> const v_same{1, 1, 1, 1, 1};\n\ttc::vector<int> const v_different{1, 1, 2, 1, 1};\n\n\t_ASSERT(tc::all_same(v_empty));\n\t_ASSERT(!tc::all_same_element<tc::return_bool>(v_empty));\n\n\t_ASSERT(tc::all_same(v_same));\n\t_ASSERT(tc::all_same_element<tc::return_bool>(v_same));\n\t_ASSERTEQUAL(tc::all_same_element<tc::return_value>(v_same), 1);\n\n\t_ASSERT(!tc::all_same(v_different));\n\t_ASSERT(!tc::all_same_element<tc::return_bool>(v_different));\n}\n"
  },
  {
    "path": "tc/algorithm/restrict_size_decrement.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"size.h\"\n\nnamespace tc\n{\n\tnamespace no_adl\n\t{\n\t\tstruct[[maybe_unused]] SRestrictSizeDummy {\n\t\t};\n\n#ifdef _CHECKS\n\t\ttemplate< typename Rng >\n\t\tstruct[[maybe_unused]] SRestrictSize {\n\t\t\texplicit constexpr SRestrictSize(Rng const& rng, typename boost::range_size<Rng>::type nSizeMin, typename boost::range_size<Rng>::type nSizeMax) noexcept\n\t\t\t\t: m_rng(rng)\n\t\t\t\t, m_nSizeMin(tc_move(nSizeMin))\n\t\t\t\t, m_nSizeMax(tc_move(nSizeMax)) {\n\t\t\t}\n\n\t\t\tconstexpr ~SRestrictSize() {\n\t\t\t\tauto const nSize = tc::size(m_rng);\n\t\t\t\t_ASSERTE(m_nSizeMin <= nSize);\n\t\t\t\t_ASSERTE(nSize <= m_nSizeMax);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tRng const& m_rng;\n\t\t\ttypename boost::range_size<Rng>::type m_nSizeMin;\n\t\t\ttypename boost::range_size<Rng>::type m_nSizeMax;\n\t\t};\n#endif\n\t}\n\n\ttemplate< typename Rng >\n\tconstexpr auto restrict_size_decrement(Rng const& rng, typename boost::range_size<Rng>::type nDecrementMin, typename boost::range_size<Rng>::type nDecrementMax) {\n#ifdef _CHECKS\n\t\tif constexpr (tc::has_size<Rng const&>) {\n\t\t\tauto const nSize = tc::size(rng);\n\t\t\treturn no_adl::SRestrictSize<Rng>(\n\t\t\t\trng,\n\t\t\t\tnDecrementMax < nSize ? nSize - nDecrementMax : tc::explicit_cast<typename boost::range_size<Rng>::type>(0),\n\t\t\t\tnDecrementMin < nSize ? nSize - nDecrementMin : tc::explicit_cast<typename boost::range_size<Rng>::type>(0)\n\t\t\t);\n\t\t} else\n#endif\n\t\t{\n\t\t\treturn no_adl::SRestrictSizeDummy{};\n\t\t}\n\t}\n\n\ttemplate< typename Rng >\n\tconstexpr auto restrict_size_decrement(Rng const& rng) {\n\t\treturn restrict_size_decrement(rng, 1, 1);\n\t}\n\n}\n"
  },
  {
    "path": "tc/algorithm/round.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/explicit_cast.h\"\n#include \"../base/return_decltype.h\"\n#include \"../base/inplace.h\"\n#include \"../base/type_traits.h\"\n#include \"../base/integer.h\"\n#include \"compare.h\"\n#include <type_traits>\n#include <chrono>\n\nnamespace tc {\n\tnamespace floor_detail {\n\t\ttemplate<typename T>\n\t\tconstexpr T constexpr_abs(T t) noexcept { // TODO: replace by std::abs(...) when it becomes constexpr\n\t\t\tif( 0 <= t ) {\n\t\t\t\treturn t;\n\t\t\t} else {\n\t\t\t\treturn -t;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<std::floating_point TFloat> requires (std::numeric_limits<TFloat>::digits/*MANT_DIG*/ <= std::numeric_limits<std::intmax_t>::digits)\n\t\tconstexpr TFloat constexpr_floor(TFloat f) noexcept { // TODO: replace by std::floor(...) when it becomes constexpr\n\t\t\tusing mantint_t = typename tc::int_least_t<std::numeric_limits<TFloat>::digits/*MANT_DIG*/>;\n\t\t\tstatic_assert(std::numeric_limits<mantint_t>::lowest() < -std::numeric_limits<mantint_t>::max());\n\t\t\treturn f != f || static_cast<TFloat>(std::numeric_limits<mantint_t>::max()) <= constexpr_abs(f)\n\t\t\t\t? f\n\t\t\t\t: static_cast<mantint_t>(f) <= f\n\t\t\t\t\t? static_cast<TFloat>(static_cast<mantint_t>(f))\n\t\t\t\t\t: static_cast<TFloat>(static_cast<mantint_t>(f) - 1);\n\t\t}\n\n\t\ttemplate<std::floating_point TFloat> requires (std::numeric_limits<std::intmax_t>::digits < std::numeric_limits<TFloat>::digits)\n\t\tconstexpr TFloat constexpr_floor(TFloat f) noexcept { // TODO: replace by std::floor(...) when it becomes constexpr\n\t\t\tstatic_assert(std::numeric_limits<std::intmax_t>::lowest() < -std::numeric_limits<std::intmax_t>::max());\n\t\t\tif(f != f) {\n\t\t\t\treturn f;\n\t\t\t} else {\n\t\t\t\t_ASSERT(constexpr_abs(f)<=static_cast<TFloat>(std::numeric_limits<std::intmax_t>::max())); // depends on non-standard large integer types otherwise\n\t\t\t\treturn static_cast<std::intmax_t>(f) <= f\n\t\t\t\t\t? static_cast<TFloat>(static_cast<std::intmax_t>(f))\n\t\t\t\t\t: static_cast<TFloat>(static_cast<std::intmax_t>(f) - 1);\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<std::floating_point TFloat>\n\tconstexpr TFloat floor(TFloat f) noexcept { // TODO: replace by std::floor(...) when it becomes constexpr\n\t\tif(std::is_constant_evaluated()) {\n\t\t\treturn tc::floor_detail::constexpr_floor(f);\n\t\t} else {\n\t\t\treturn std::floor(f);\n\t\t}\n\t}\n\n\t//////////////////////////////\n\t// round\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T round( T t ) noexcept {\n\t\tstatic_assert( std::floating_point<T> );\n\t\treturn tc::floor(t+static_cast<T>(.5));\n\t}\n\n\t//////////////////////////////\n\t// type-safe multiplication and division\n\tnamespace no_adl {\n\t\ttemplate<tc::actual_integer auto val>\n\t\tstruct integer_value_prefer_unsigned {\n\t\t\tusing type = tc::int_value_least_t<val>;\n\t\t};\n\n\t\ttemplate<tc::actual_integer auto val> requires (0<=val)\n\t\tstruct integer_value_prefer_unsigned<val> {\n\t\t\tusing type = tc::uint_value_least_t<val>;\n\t\t};\n\n\t\ttemplate< typename T1, typename T2 >\n\t\tstruct TMultiply {};\n\n\t\ttemplate< tc::actual_integer_like T1, tc::actual_integer_like T2 > requires\n\t\t\tstd::numeric_limits<T1>::is_signed || std::numeric_limits<T2>::is_signed\n\t\tstruct TMultiply<T1, T2> {\n\t\t\t// For 2s complement representation,\n\t\t\t// in case of both operands signed, -(2^31) * -(2^31) = -2^62, which needs 62 bits (not including sign bit) to be represented.\n\t\t\t// In case of one unsigned and one signed, (2^32-1) * -2^31 = -2^63 + 2^31, which needs 63 bits (not including sign bit) to be represented.\n\t\t\tusing type=tc::int_least_t<std::numeric_limits<T1>::digits+std::numeric_limits<T2>::digits>;\n\t\t};\n\n\t\ttemplate< tc::actual_integer_like T1, tc::actual_integer_like T2 > requires\n\t\t\t(!std::numeric_limits<T1>::is_signed) && (!std::numeric_limits<T2>::is_signed)\n\t\tstruct TMultiply<T1, T2> {\n\t\t\tusing type=tc::uint_least_t<std::numeric_limits<T1>::digits+std::numeric_limits<T2>::digits>;\n\t\t};\n\n\t\ttemplate< typename T1, typename T2 > requires std::floating_point< T1 > || std::floating_point< T2 >\n\t\tstruct TMultiply<T1, T2> final {\n\t\t\tusing type = decltype(std::declval<T1>()*std::declval<T2>());\n\t\t};\n\n\t\ttemplate<tc::actual_integer_like T1, tc::actual_integer auto val2> requires (1==val2)\n\t\tstruct TMultiply<T1, tc::constant<val2>> {\n\t\t\tusing type = T1;\n\t\t};\n\n\t\ttemplate<tc::actual_integer_like T1, tc::actual_integer auto val2> requires (1!=val2)\n\t\tstruct TMultiply<T1, tc::constant<val2>>: TMultiply<T1, typename integer_value_prefer_unsigned<val2>::type> {\n\t\t};\n\n\t\ttemplate<tc::actual_integer auto val1, tc::actual_integer_like T2>\n\t\tstruct TMultiply<tc::constant<val1>, T2> final: TMultiply<T2, tc::constant<val1>> {};\n\t}\n\n\ttemplate< typename Lhs, typename Rhs >\n\t[[nodiscard]]\n\ttypename no_adl::TMultiply<Lhs,Rhs>::type\n\tconstexpr mul( Lhs lhs, Rhs rhs ) noexcept {\n\t\treturn tc::explicit_cast<typename no_adl::TMultiply<Lhs,Rhs>::type>(lhs)*tc::explicit_cast<typename no_adl::TMultiply<Lhs,Rhs>::type>(rhs);\n\t}\n\n\ttemplate<tc::actual_integer auto val>\n\tusing least_integer_constant_prefer_unsigned = tc::constant<tc::explicit_cast<typename no_adl::integer_value_prefer_unsigned<val>::type>(val)>;\n\n\ttemplate<tc::actual_integer auto valLhs, tc::actual_integer auto valRhs>\n\t[[nodiscard]] consteval auto mul(tc::constant<valLhs> lhs, tc::constant<valRhs> rhs) noexcept {\n\t\treturn tc::least_integer_constant_prefer_unsigned<tc::mul(\n\t\t\ttc::least_integer_constant_prefer_unsigned<valLhs>::value,\n\t\t\ttc::least_integer_constant_prefer_unsigned<valRhs>::value\n\t\t)>::value;\n\t}\n\n\ttemplate<tc::actual_integer_like Lhs, tc::actual_integer auto valRhs> requires (0==valRhs)\n\t[[nodiscard]] constexpr auto mul(Lhs lhs, tc::constant<valRhs> rhs) noexcept {\n\t\treturn tc::least_integer_constant_prefer_unsigned<0>::value;\n\t}\n\n\ttemplate<tc::actual_integer auto valLhs, tc::actual_integer_like Rhs> requires (0==valLhs)\n\t[[nodiscard]] constexpr auto mul(tc::constant<valLhs> lhs, Rhs rhs) noexcept {\n\t\treturn mul(rhs, lhs);\n\t}\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto sqr(T const& x)\n\t\treturn_decltype_noexcept( mul(x,x) )\n\n#ifdef _MSC_VER\n\t#pragma float_control(precise, on, push) // RT#17630: Disable compiler optimization num/den ---> num*(1/den) resulting in tc::fdiv(1287,100)==12.870000000000001\n#endif\n\t[[nodiscard]] inline constexpr \n#ifdef __clang__\n\t\t__attribute__((optnone)) // Disable compiler optimization num/den ---> num*(1/den) resulting in tc::fdiv(49,49)==0.99999999999999989\n#endif\n\tdouble fdiv(double const num, double const den) noexcept {\n\t\treturn num/den;\n\t}\n#ifdef _MSC_VER\n\t#pragma float_control(pop)\n#endif\n\t\n\ttemplate< typename Num, typename Den >\n\t[[nodiscard]] constexpr double fdiv(Num num, Den den) noexcept {\n\t\treturn tc::fdiv(static_cast<double>(num), static_cast<double>(den));\n\t}\n\n\tstruct SRoundFloor final {\n\t\tusing is_rounding = void;\n\n\t\ttemplate< std::integral T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn t;\n\t\t}\n\t\ttemplate< std::floating_point T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn tc::floor(t);\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T PositiveOffset( T t ) noexcept {\n\t\t\treturn 0;\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T NegativeOffset( T t ) noexcept {\n\t\t\treturn t-1;\n\t\t}\n\t} inline constexpr roundFLOOR{};\n\n\tstruct SRoundNearest final {\n\t\tusing is_rounding = void;\n\n\t\ttemplate< std::integral T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn t;\n\t\t}\n\t\ttemplate< std::floating_point T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn tc::round(t);\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T PositiveOffset( T t ) noexcept {\n\t\t\treturn t/2;\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T NegativeOffset( T t ) noexcept {\n\t\t\treturn (t-1)/2;\n\t\t}\n\t} inline constexpr roundNEAREST{};\n\n\tstruct SRoundAwayFromZero final {\n\t\tusing is_rounding = void;\n\n\t\ttemplate< std::integral T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn t;\n\t\t}\n\t\ttemplate< std::floating_point T >\n\t\tT operator()( T t ) const& noexcept {\n\t\t\treturn std::round(t);\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T PositiveOffset( T t ) noexcept {\n\t\t\treturn t/2;\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T NegativeOffset( T t ) noexcept {\n\t\t\treturn t/2;\n\t\t}\n\t} inline constexpr roundAWAYFROMZERO{};\n\n\tstruct SRoundCeil final {\n\t\tusing is_rounding = void;\n\n\t\ttemplate< std::integral T >\n\t\tconstexpr T operator()( T t ) const& noexcept {\n\t\t\treturn t;\n\t\t}\n\t\ttemplate< std::floating_point T >\n\t\tT operator()( T t ) const& noexcept {\n\t\t\treturn std::ceil(t);\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T PositiveOffset( T t ) noexcept {\n\t\t\treturn t-1;\n\t\t}\n\t\ttemplate< typename T >\n\t\tstatic constexpr T NegativeOffset( T t ) noexcept {\n\t\t\treturn 0;\n\t\t}\n\t} inline constexpr roundCEIL{};\n\n\tstruct SRoundBanker final {\n\t\tusing is_rounding = void;\n\t} inline constexpr roundBANKER{};\n\n\tstruct SNoRounding final {\n\t\tusing is_rounding = void;\n\t} inline constexpr norounding{};\n\n\ttemplate<typename Round>\n\tconcept rounding = requires { typename Round::is_rounding; };\n\n\tnamespace idiv_impl {\n\t\t// The standard guarantees that integer division rounds to zero.\n\t\t// [expr.mul]/4 (oder 5.6/4) \n\t\ttemplate< typename Num, typename Denom, tc::rounding Round >\n\t\tconstexpr Num idiv( Num num, Denom denom, Round round ) noexcept {\n\t\t\tstatic_assert( tc::actual_integer_like<Num> );\n\t\t\tstatic_assert( tc::actual_integer_like< Denom > );\n\t\t\tSTATICASSERTEQUAL( std::numeric_limits<Num>::is_signed, std::numeric_limits<Denom>::is_signed );\n\t\t\t_ASSERTE( 0<denom );\n\t\t\tif constexpr(std::same_as<Round, SRoundBanker>) {\n\t\t\t\tauto result = num / denom;\n\t\t\t\tauto remainder = num - result * denom;\n\t\t\t\tif(remainder<0) -tc::inplace(remainder);\n\t\t\t\tif(tc_auto_cref(order, tc::compare(denom,remainder * 2)); std::is_lt(order) || tc::is_eq(order) && 0 != result % 2) {\n\t\t\t\t\tresult += num < 0 ? -1 : 1;\n\t\t\t\t}\n\t\t\t\ttc_return_cast(tc_move(result));\n\t\t\t} else if constexpr(std::same_as<Round, SNoRounding>) {\n\t\t\t\t_ASSERTEQUAL(num%denom, 0);\n\t\t\t\ttc_return_cast(num/denom);\n\t\t\t} else {\n\t\t\t\ttc_return_cast( ( num<0 ? num-Round::NegativeOffset(denom) : num+Round::PositiveOffset(denom) )/denom );\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename Num, typename Denom, tc::rounding Round >\n\t[[nodiscard]] constexpr Num idiv(Num num, Denom denom, Round round) noexcept {\n\t\tstatic_assert( tc::actual_integer_like<Num> );\n\t\tif constexpr( tc::actual_integer_like<Denom> ) {\n\t\t\tif constexpr( std::numeric_limits<Num>::is_signed ) {\n\t\t\t\tif constexpr( std::numeric_limits<Denom>::is_signed ) {\n\t\t\t\t\tif (denom < 0) {\n\t\t\t\t\t\t-tc::inplace(num);\n\t\t\t\t\t\t-tc::inplace(denom);\n\t\t\t\t\t}\n\t\t\t\t\treturn idiv_impl::idiv(num, denom, round);\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::idiv/*not idiv_impl::idiv*/( num, tc::as_signed(denom), round );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn idiv_impl::idiv( num, tc::as_unsigned(denom), round );\n\t\t\t}\n\t\t} else {\n\t\t\tstatic_assert( std::floating_point< Denom > );\n\t\t\ttc_return_cast(round(num/denom));\n\t\t}\n\t}\n\n\ttemplate< typename Num, typename Denom, tc::rounding Round >\n\t[[nodiscard]] std::pair<Num,Denom> idivmod( Num num, Denom denom, Round round ) noexcept {\n\t\tNum div=tc::idiv(num,denom,round);\n\t\tDenom mod=num-div*denom;\n\t\treturn std::make_pair(div,mod);\n\t}\n\n\t/////////////////////////////////\n\t// scale_div\n\n\ttemplate< tc::actual_integer Num, typename Denom, tc::rounding Round>\n\t[[nodiscard]] constexpr Num scale_div( Num num, Denom denom, Round round ) noexcept {\n\t\treturn tc::idiv(num,denom,round);\n\t}\n\n\ttemplate< std::floating_point Num, typename Denom>\n\t[[nodiscard]] constexpr Num scale_div( Num num, Denom denom, SRoundNearest ) noexcept {\n\t\ttc_return_cast(num/denom);\n\t}\n\n\ttemplate< typename Num, typename Denom >\n\t[[nodiscard]] constexpr Num scale_div( Num num, Denom denom ) noexcept {\n\t\treturn tc::scale_div(num,denom,tc::roundNEAREST);\n\t}\n\n\ttemplate< bool bGeneralized, tc::actual_integer T>\n\t[[nodiscard]] constexpr T internal_lower_half(T t) noexcept {\n\t\treturn tc::scale_div(t, 2, tc::roundFLOOR);\n\t}\n\n\ttemplate< bool bGeneralized, std::floating_point T>\n\t[[nodiscard]] constexpr T internal_lower_half(T t) noexcept {\n\t\treturn t / 2;\n\t}\n\n\ttemplate< bool bGeneralized, typename Rep, typename Period> requires bGeneralized\n\t[[nodiscard]] constexpr std::chrono::duration<Rep, Period> internal_lower_half(std::chrono::duration<Rep, Period> const& dur) noexcept {\n\t\treturn std::chrono::duration<Rep, Period>(tc::idiv(dur.count(), 2, tc::roundFLOOR));\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto lower_half(T&& t) return_decltype_noexcept( tc::internal_lower_half</*bGeneralized*/ false>(tc_move_if_owned(t)) )\n\n\ttemplate< bool bGeneralized, typename T >\n\t[[nodiscard]] constexpr auto internal_midpoint(T const& begin, T const& end) noexcept {\n\t\treturn begin + tc::internal_lower_half<bGeneralized>(end - begin);\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto midpoint(T const& begin, T const& end) return_decltype_noexcept( tc::internal_midpoint</*bGeneralized*/false>(begin, end) )\n\n\t/////////////////////////////////\n\t// scale_mul\n\n\ttemplate<tc::actual_integer T, std::integral Factor>\n\t[[nodiscard]] constexpr T scale_mul(T t, Factor factor, SRoundNearest ) noexcept {\n\t\ttc_return_cast(tc::prepare_argument<T,Factor>(t)*tc::prepare_argument<T,Factor>(factor));\n\t}\n\n\ttemplate<tc::actual_integer T, std::floating_point Factor, tc::rounding TRound>\n\t[[nodiscard]] constexpr T scale_mul(T t, Factor factor, TRound round) noexcept {\n\t\ttc_return_cast(round(t*factor));\n\t}\n\n\ttemplate<std::floating_point T, typename Factor>\n\t[[nodiscard]] constexpr T scale_mul(T t, Factor factor, SRoundNearest ) noexcept {\n\t\ttc_return_cast(t*factor);\n\t}\n\n\ttemplate<typename T, typename Factor>\n\t[[nodiscard]] constexpr T scale_mul(T t, Factor factor) noexcept {\n\t\treturn scale_mul(t,factor,tc::roundNEAREST);\n\t}\n\n\t/////////////////////////////////\n\t// scale_muldiv\n\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct is_actual_integer_like_or_constant_impl final: tc::constant<false> {};\n\n\t\ttemplate<tc::actual_integer_like T>\n\t\tstruct is_actual_integer_like_or_constant_impl<T> final: tc::constant<true> {\n\t\t\tusing int_t = T;\n\t\t};\n\n\t\ttemplate<tc::actual_integer auto val>\n\t\tstruct is_actual_integer_like_or_constant_impl<tc::constant<val>> final: tc::constant<true> {\n\t\t\tusing int_t = typename tc::constant<val>::value_type;\n\t\t};\n\t}\n\ttemplate<typename T>\n\tusing is_actual_integer_like_or_constant = no_adl::is_actual_integer_like_or_constant_impl<std::remove_cv_t<T>>;\n\n\ttemplate<typename T>\n\tconcept actual_integer_like_or_constant = tc::is_actual_integer_like_or_constant<T>::value;\n\n\ttemplate<tc::actual_integer_like_or_constant T, tc::actual_integer_like_or_constant Num, tc::actual_integer Den, tc::rounding TRound>\n\t[[nodiscard]] constexpr typename tc::is_actual_integer_like_or_constant<T>::int_t scale_muldiv(T t, Num num, Den den, TRound round) noexcept {\n\t\ttc_return_cast(idiv(mul(t, num), den, round));\n\t}\n\n\ttemplate<tc::actual_integer_like_or_constant T, tc::actual_integer_like_or_constant Num, tc::floating_point_like Den, tc::rounding TRound>\n\t[[nodiscard]] constexpr typename tc::is_actual_integer_like_or_constant<T>::int_t scale_muldiv(T t, Num num, Den den, TRound round) noexcept {\n\t\ttc_return_cast(round(mul(t, num) / den));\n\t}\n\n\ttemplate<tc::actual_integer_like_or_constant T, tc::floating_point_like Num, typename Den, tc::rounding TRound>\n\t[[nodiscard]] constexpr typename tc::is_actual_integer_like_or_constant<T>::int_t scale_muldiv(T t, Num num, Den den, TRound round) noexcept {\n\t\ttc_return_cast(round(t * tc::fdiv(num, den)));\n\t}\n\n\ttemplate<tc::floating_point_like T, typename Num, typename Den>\n\t[[nodiscard]] constexpr auto scale_muldiv(T t, Num num, Den den, SRoundNearest) noexcept {\n\t\treturn tc::reluctant_explicit_cast<T>(t * tc::fdiv(num, den));\n\t}\n\n\ttemplate<typename T, typename Num, typename Den>\n\t[[nodiscard]] constexpr auto scale_muldiv(T const& x, Num const& num, Den const& den) noexcept {\n\t\treturn scale_muldiv(x, num, den, tc::roundNEAREST);\n\t}\n\n\tstruct fraction {\n\t\tint m_nNum;\n\t\tint m_nDen;\n\t};\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto scale_muldiv(T const& x, tc::fraction const& fracn) noexcept {\n\t\treturn scale_muldiv(x, fracn.m_nNum, fracn.m_nDen);\n\t}\n\n\t/////////////////////////////////\n\t// rounding_cast\n\ttemplate<typename Dst, typename Src, tc::rounding TRound>\n\t\trequires\n\t\t\t(tc::actual_integer<tc::decay_t<Src>> && (tc::actual_integer<Dst> || tc::floating_point_like<Dst>))\n\t\t\t|| (tc::floating_point_like<tc::decay_t<Src>> && tc::floating_point_like<Dst>)\n\t[[nodiscard]] constexpr decltype(auto) rounding_cast(Src&& x, TRound) noexcept {\n\t\treturn tc::reluctant_explicit_cast<Dst>(tc_move_if_owned(x));\n\t}\n\n\ttemplate<tc::actual_integer Dst, typename Src, tc::rounding TRound>\n\t\t requires tc::floating_point_like<tc::decay_t<Src>>\n\t[[nodiscard]] constexpr decltype(auto) rounding_cast(Src&& x, TRound round) noexcept {\n\t\treturn tc::reluctant_explicit_cast<Dst>(round(tc_move_if_owned(x)));\n\t}\n\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] constexpr decltype(auto) rounding_cast(Src&& x) noexcept {\n\t\treturn rounding_cast<Dst>(tc_move_if_owned(x), roundNEAREST);\n\t}\n\n\ttemplate<typename Lhs, typename Rhs, tc::rounding TRound>\n\tconstexpr void assign_rounding_cast(Lhs& lhs, Rhs&& rhs, TRound round) noexcept {\n\t\tlhs=tc::rounding_cast<Lhs>(tc_move_if_owned(rhs), round);\n\t}\n\n\ttemplate<typename Lhs, typename Rhs>\n\tconstexpr void assign_rounding_cast(Lhs& lhs, Rhs&& rhs) noexcept {\n\t\tlhs=tc::rounding_cast<Lhs>(tc_move_if_owned(rhs));\n\t}\n\n\tnamespace no_adl {\n\t\tstruct fn_div {\n\t\t\ttemplate<typename Num, typename Denom, typename Quot = decltype(std::declval<Num>() / std::declval<Denom>())>\n\t\t\t[[nodiscard]] constexpr Quot operator()(Num&& num, Denom&& denom) const& noexcept {\n\t\t\t\tif constexpr( tc::actual_integer_like<tc::decay_t<Num>> && tc::actual_integer_like<tc::decay_t<Denom>> ) {\n\t\t\t\t\tstatic_assert( dependent_false<Num, Denom>::value, \"Do not rely on language int/int-behavior, use tc::scale_div \" );\n\t\t\t\t\treturn tc::idiv(tc::explicit_cast<Quot>(tc_move_if_owned(num)), tc_move_if_owned(denom), tc::roundNEAREST);\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert( std::floating_point<tc::decay_t<Num>> || std::floating_point<tc::decay_t<Denom>> || std::is_class<tc::decay_t<Num>>::value || std::is_class<tc::decay_t<Denom>>::value );\n\t\t\t\t\tstatic_assert( !tc::instance<tc::decay_t<Num>, tc::size_proxy> );\n\t\t\t\t\tstatic_assert( !tc::instance<tc::decay_t<Denom>, tc::size_proxy> );\n\t\t\t\t\treturn tc_move_if_owned(num) / tc_move_if_owned(denom);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tstruct fn_assign_div {\n\t\t\ttemplate<typename Num, typename Denom>\n\t\t\t[[nodiscard]] constexpr Num& operator()(Num& num, Denom&& denom) const& noexcept {\n\t\t\t\tif constexpr( tc::actual_integer_like<tc::decay_t<Num>> ) {\n\t\t\t\t\tstatic_assert( dependent_false<Num, Denom>::value, \"Do not rely on language int/int-behavior, use tc::scale_div \" );\n\t\t\t\t\tnum = tc::idiv(num, tc_move_if_owned(denom), tc::roundNEAREST);\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert( std::floating_point<tc::decay_t<Num>> || std::is_class<tc::decay_t<Num>>::value );\n\t\t\t\t\tstatic_assert( !tc::instance<tc::decay_t<Num>, tc::size_proxy> );\n\t\t\t\t\tnum /= tc_move_if_owned(denom);\n\t\t\t\t}\n\t\t\t\treturn num;\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::fn_div;\n\tusing no_adl::fn_assign_div;\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<tc::actual_integer Target, tc::actual_arithmetic Source, tc::rounding Round>\n\t\t[[nodiscard]] constexpr Target explicit_convert_impl(adl_tag_t, std::type_identity<Target>, Source src, Round round) noexcept {\n\t\t\ttc_return_cast(round(src));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/round.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"round.h\"\n\nUNITTESTDEF( rounding_cast ) {\n\tSTATICASSERTSAME(decltype(tc::rounding_cast<int>(1, tc::roundFLOOR)), int&&, \"tc::rounding_cast<T> doesn't return T\");\n\tSTATICASSERTSAME(decltype(tc::rounding_cast<int>(1.0, tc::roundFLOOR)), int, \"tc::rounding_cast<T> doesn't return T\");\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.0, tc::roundFLOOR), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.0, tc::roundCEIL), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.0, tc::roundNEAREST), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.5, tc::roundFLOOR), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.5, tc::roundCEIL), 2);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.5, tc::roundNEAREST), 2);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1, tc::roundFLOOR), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1, tc::roundCEIL), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1, tc::roundNEAREST), 1);\n\t_ASSERTEQUAL(tc::rounding_cast<int>(1.5), 2);\n}\n\nSTATICASSERTSAME(tc::int_value_least_t<0>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::uint_value_least_t<0>, tc::uint_least_t<8>);\nSTATICASSERTSAME(tc::int_value_least_t<0ull>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::uint_value_least_t<0ll>, tc::uint_least_t<8>);\nSTATICASSERTSAME(tc::int_value_least_t<127>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::int_value_least_t<-128>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::int_value_least_t<127ull>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::int_value_least_t<-128ll>, tc::int_least_t<7>);\nSTATICASSERTSAME(tc::uint_value_least_t<255>, tc::uint_least_t<8>);\nSTATICASSERTSAME(tc::uint_value_least_t<255ll>, tc::uint_least_t<8>);\nSTATICASSERTSAME(tc::int_value_least_t<128>, tc::int_least_t<15>);\nSTATICASSERTSAME(tc::int_value_least_t<-129>, tc::int_least_t<15>);\nSTATICASSERTSAME(tc::int_value_least_t<128ull>, tc::int_least_t<15>);\nSTATICASSERTSAME(tc::int_value_least_t<-129ll>, tc::int_least_t<15>);\nSTATICASSERTSAME(tc::uint_value_least_t<256>, tc::uint_least_t<16>);\nSTATICASSERTSAME(tc::uint_value_least_t<256ll>, tc::uint_least_t<16>);\nSTATICASSERTSAME(tc::int_value_least_t<std::numeric_limits<std::int64_t>::max()>, tc::int_least_t<63>);\nSTATICASSERTSAME(tc::int_value_least_t<std::numeric_limits<std::int64_t>::lowest()>, tc::int_least_t<63>);\nSTATICASSERTSAME(tc::uint_value_least_t<std::numeric_limits<std::uint64_t>::max()>, tc::uint_least_t<64>);\nSTATICASSERTSAME(tc::uint_value_least_t<std::numeric_limits<std::uint64_t>::lowest()>, tc::uint_least_t<8>);\n\nnamespace {\n\ttemplate<typename TExpected>\n\tconsteval auto test_mul(auto lhs, auto rhs) noexcept {\n\t\tauto nResult=tc::mul(lhs, rhs);\n\t\tSTATICASSERTSAME(decltype(nResult), TExpected);\n\t\treturn nResult;\n\t}\n}\n\nstatic_assert(15==test_mul<tc::int_least_t<15>>(tc::explicit_cast<std::int8_t>(-3), tc::explicit_cast<std::int8_t>(-5)));\nstatic_assert(-15==test_mul<tc::int_least_t<15>>(tc::explicit_cast<std::int8_t>(-3), tc::explicit_cast<std::uint8_t>(5)));\nstatic_assert(15==test_mul<tc::uint_least_t<16>>(tc::explicit_cast<std::uint8_t>(3), tc::explicit_cast<std::uint8_t>(5)));\n\nstatic_assert(4.5==test_mul<double>(1.5, tc::constant<3>()));\nstatic_assert(4.5==test_mul<double>(tc::constant<3>(), 1.5));\nstatic_assert(5==test_mul<int>(5, tc::constant<1>()));\nstatic_assert(5==test_mul<int>(tc::constant<1>(), 5));\nstatic_assert(0==test_mul<tc::uint_least_t<8>>(1500, tc::constant<0>()));\nstatic_assert(0==test_mul<tc::uint_least_t<8>>(tc::constant<0>(), -1500));\nstatic_assert(15==test_mul<tc::uint_least_t<8>>(tc::constant<3>(), tc::constant<5>()));\nstatic_assert(15==test_mul<tc::uint_least_t<8>>(tc::constant<-3>(), tc::constant<-5>()));\nstatic_assert(-15==test_mul<tc::int_least_t<7>>(tc::constant<3>(), tc::constant<-5>()));\nstatic_assert(1500==test_mul<tc::uint_least_t<16>>(tc::constant<30>(), tc::constant<50>()));\nstatic_assert(-1500==test_mul<tc::int_least_t<15>>(tc::constant<-30>(), tc::constant<50>()));\nstatic_assert(15==test_mul<tc::int_least_t<15>>(tc::explicit_cast<std::int8_t>(5), tc::constant<3>()));\nstatic_assert(15==test_mul<tc::uint_least_t<16>>(tc::explicit_cast<std::uint8_t>(5), tc::constant<3>()));\nstatic_assert(-15==test_mul<tc::int_least_t<15>>(tc::explicit_cast<std::uint8_t>(5), tc::constant<-3>()));\nstatic_assert(15==test_mul<tc::int_least_t<15>>(tc::constant<-3>(), tc::explicit_cast<std::int8_t>(-5)));\n"
  },
  {
    "path": "tc/algorithm/size.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/explicit_cast.h\"\n#include \"../base/integer.h\"\n#include \"../base/type_traits.h\"\n#include \"../base/generic_macros.h\"\n#include \"../base/tag_type.h\"\n#include \"../base/renew.h\"\n#include \"../container/container_traits.h\"\n#include \"../range/meta.h\"\n\n#include <limits>\n\nnamespace tc {\n\t// forward definitions\n\tnamespace size_proxy_adl {\n\t\ttemplate< typename T > struct size_proxy;\n\t}\n\tusing size_proxy_adl::size_proxy;\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto make_size_proxy(T t) noexcept;\n\n\t////////////////////////////////\n\t// tc::size_proxy in ADL barrier\n\tnamespace size_proxy_adl {\n\t\ttemplate< typename T >\n\t\tstruct size_proxy final {\n\t\t\tstatic_assert(tc::actual_integer<T> && tc::decayed<T>);\n\t\tprivate:\n\t\t\tconstexpr void AssertInvariant() & noexcept {\n\t\t\t\t// npos should only be represented by a signed number. Otherwise casts to (larger) unsigned types may not preserve npos as static_cast<T>(-1)\n\t\t\t\t_ASSERTE( static_cast<T>(-1)==m_t ? std::is_signed<T>::value : 0<=m_t );\n\t\t\t}\n\t\tpublic:\n\t\t\tT m_t;\n\t\t\tconstexpr size_proxy() noexcept : m_t() {\n\t\t\t\tAssertInvariant();\n\t\t\t}\n\t\t\tconstexpr explicit size_proxy(T t) noexcept : m_t(t) {\n\t\t\t\tAssertInvariant();\n\t\t\t}\n\n\t\t\ttemplate<typename S>\n\t\t\tconstexpr explicit size_proxy(size_proxy<S> const& other) noexcept\n\t\t\t\t: tc_member_init( m_t, other.m_t )\n\t\t\t{\n\t\t\t\tAssertInvariant();\n\t\t\t}\n\n\t\t\ttemplate< typename S >\n\t\t\tsize_proxy& operator=(S&& s) & noexcept {\n\t\t\t\ttc::assign_explicit_cast(m_t,tc_move_if_owned(s));\n\t\t\t\tAssertInvariant();\n\t\t\t\treturn *this;\n\t\t\t}\n\n#pragma push_macro(\"CONVERT\")\n#define CONVERT( S ) \\\n\t\t\tconstexpr operator S() const& noexcept { \\\n\t\t\t\t_ASSERTE(  /*good idea to require signed?*/ std::is_signed<S>::value && static_cast<T>(-1)==m_t || tc::as_unsigned(m_t)<=tc::as_unsigned(std::numeric_limits<S>::max()) ); \\\n\t\t\t\treturn static_cast<S>(m_t); \\\n\t\t\t}\n\t\t\t\n\t\t\tCONVERT(signed char)\n\t\t\tCONVERT(unsigned char)\n\t\t\tCONVERT(short)\n\t\t\tCONVERT(unsigned short)\n\t\t\tCONVERT(int)\n\t\t\tCONVERT(unsigned int)\n\t\t\tCONVERT(long)\n\t\t\tCONVERT(unsigned long)\n\t\t\tCONVERT(long long)\n\t\t\tCONVERT(unsigned long long)\n#pragma pop_macro(\"CONVERT\")\n\t\t\toperator double() const& noexcept {\n\t\t\t\t_ASSERT(0 <= m_t || static_cast<T>(-1) == m_t);\n\t\t\t\ttc_return_cast(m_t);\n\t\t\t}\n\n\t\t\ttemplate< typename U >\n\t\t\toperator size_proxy<U>() const& noexcept {\n\t\t\t\treturn size_proxy<U>(tc::implicit_cast<U>(*this));\n\t\t\t}\n\n#pragma push_macro(\"COMPARISON_OPERATOR\")\n#define COMPARISON_OPERATOR( return_type, op ) \\\n\t\t\ttemplate< tc::actual_integer S > \\\n\t\t\tfriend constexpr return_type operator op( size_proxy const& lhs, S const& rhs ) noexcept { \\\n\t\t\t\treturn tc::prepare_argument< T,S >(lhs.m_t) op tc::prepare_argument< T,S >(rhs); \\\n\t\t\t} \\\n\t\t\ttemplate< typename S > \\\n\t\t\tfriend constexpr return_type operator op( size_proxy const& lhs, size_proxy<S> const& rhs ) noexcept { \\\n\t\t\t\treturn lhs op rhs.m_t; \\\n\t\t\t}\n\n\t\t\tCOMPARISON_OPERATOR(bool, ==) // Xcode13 doesn't compile with auto even though static_assert says the return type is bool\n\t\t\tCOMPARISON_OPERATOR(auto, <=>)\n#pragma pop_macro(\"COMPARISON_OPERATOR\")\n\t\t};\n\n#pragma push_macro(\"operator_size_proxy\")\n#define operator_size_proxy( op ) \\\n\t\ttemplate< \\\n\t\t\ttypename Lhs, tc::actual_integer Rhs \\\n\t\t> constexpr auto operator op( size_proxy<Lhs> const& lhs, Rhs const& rhs ) \\\n\t\treturn_decltype_MAYTHROW( \\\n\t\t\tmake_size_proxy( lhs.m_t op rhs ) \\\n\t\t) \\\n\t\ttemplate< \\\n\t\t\ttc::actual_arithmetic Lhs, typename Rhs \\\n\t\t> constexpr auto operator op( Lhs const& lhs, size_proxy<Rhs> const& rhs ) \\\n\t\treturn_decltype_MAYTHROW( \\\n\t\t\ttc::explicit_cast<Lhs>(lhs op rhs.m_t) \\\n\t\t) \\\n\t\ttemplate< \\\n\t\t\ttypename Lhs, typename Rhs, \\\n\t\t\tstd::enable_if_t<!tc::actual_arithmetic<Lhs>>* = nullptr \\\n\t\t> constexpr auto operator op( Lhs const& lhs, size_proxy<Rhs> const& rhs ) \\\n\t\treturn_decltype_MAYTHROW( \\\n\t\t\tlhs op rhs.m_t \\\n\t\t) \\\n\t\ttemplate< typename Lhs, typename Rhs > constexpr auto operator op( size_proxy<Lhs> const& lhs, size_proxy<Rhs> const& rhs ) \\\n\t\treturn_decltype_MAYTHROW( \\\n\t\t\tmake_size_proxy( lhs.m_t op rhs.m_t ) \\\n\t\t)\n\t\t\n\t\toperator_size_proxy(+)\n\t\toperator_size_proxy(-)\n\t\toperator_size_proxy(*)\n\t\toperator_size_proxy(/ )\n\t\toperator_size_proxy(%)\n#pragma pop_macro(\"operator_size_proxy\")\n\t\t\n#pragma push_macro(\"assign_operator_size_proxy\")\n#define assign_operator_size_proxy( assign_op, op ) \\\n\t\ttemplate< typename Lhs, typename Rhs> \\\n\t\tconstexpr Lhs& operator assign_op ( Lhs& lhs, size_proxy<Rhs> const& rhs ) noexcept { \\\n\t\t\tif constexpr( std::integral<Lhs> ) { \\\n\t\t\t\tlhs=tc:: op (tc::as_const(lhs),rhs.m_t); \\\n\t\t\t} else { \\\n\t\t\t\tlhs assign_op rhs.m_t; \\\n\t\t\t} \\\n\t\t\treturn lhs; \\\n\t\t}\n\n\t\tassign_operator_size_proxy(+=,add)\n\t\tassign_operator_size_proxy(-=,sub)\n#pragma pop_macro(\"assign_operator_size_proxy\")\n\n\t\ttemplate< tc::actual_integer Lhs, typename Rhs >\n\t\tLhs& operator %= ( Lhs& lhs, size_proxy<Rhs> const& rhs ) noexcept {\n\t\t\tlhs%=rhs.m_t;\n\t\t\treturn lhs;\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto make_size_proxy(T t) noexcept {\n\t\tif constexpr( tc::actual_integer<T> ) {\n\t\t\treturn size_proxy<T>(t);\n\t\t} else {\n\t\t\tstatic_assert( tc::instance<T, size_proxy> );\n\t\t\treturn t;\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto unmake_size_proxy(T t) noexcept {\n\t\tif constexpr( tc::instance<T, size_proxy> ) {\n\t\t\treturn t.m_t;\n\t\t} else {\n\t\t\tstatic_assert( tc::actual_integer<T> );\n\t\t\treturn t;\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate <typename T0, typename T1>\n\t\tusing size_proxy_common_type = tc::size_proxy<tc::common_type_t<T0, T1>>;\n\n\t\ttemplate <tc::actual_integer T0, tc::actual_integer T1>\n\t\tstruct common_type_decayed_impl<tc::size_proxy<T0>, tc::size_proxy<T1>> : boost::mp11::mp_defer<size_proxy_common_type, T0, T1> {};\n\n\t\ttemplate <tc::actual_integer T0, tc::actual_integer T1>\n\t\tstruct common_type_decayed_impl<tc::size_proxy<T0>, T1> {\n\t\t\tusing type = T1;\n\t\t};\n\n\t\ttemplate <tc::actual_integer T0, tc::actual_integer T1>\n\t\tstruct common_type_decayed_impl<T0, tc::size_proxy<T1>> {\n\t\t\tusing type = T0;\n\t\t};\n\t}\n\n\t////////////////////////////////\n\t// tc::constexpr_size\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct constexpr_size_impl;\n\n\t\t// Rng has a size function that returns an integral_constant.\n\t\ttemplate <typename Rng> requires requires { decltype(std::declval<Rng&>().size())::value; }\n\t\tstruct constexpr_size_impl<Rng> : decltype(std::declval<Rng&>().size()) {};\n\n\t\ttemplate<typename T, std::size_t N>\n\t\tstruct constexpr_size_impl<T[N]> : tc::least_uint_constant<N - (tc::char_type<T> ? 1 : 0)> {};\n\n\t\ttemplate<typename T, T... t>\n\t\tstruct constexpr_size_impl<std::integer_sequence<T, t...>> : tc::least_uint_constant<sizeof...(t)> {};\n\t}\n\n\ttemplate <typename Rng> requires has_constexpr_size<Rng>\n\tconstexpr auto constexpr_size = []() noexcept {\n\t\tusing type = no_adl::constexpr_size_impl<std::remove_cvref_t<Rng>>;\n\t\tstatic_assert(std::derived_from<type, tc::least_uint_constant<type::value>>);\n\t\treturn tc::least_uint_constant<type::value>{};\n\t}();\n\n\t////////////////////////////////\n\t// tc::size\n\tnamespace size_raw_internal {\n\t\t// tc::size() requires a range with either:\n\t\t//  - a constexpr_size_impl specialization which provide size as a compile time constant\n\t\t//  - a size member function, which is assumed to run in O(1)\n\t\t//  - random_access iterators, which are assumed to be able to calculate size in O(1)\n\t\t// TODO: inline when clang supports lambdas in unevaluated contexts\n\t\ttemplate<typename Rng> requires\n\t\t\thas_constexpr_size<Rng> || has_mem_fn_size<Rng> || (random_access_range<Rng&> && tc::common_range<Rng>)\n\t\tconstexpr auto size_raw(Rng&& rng) noexcept {\n\t\t\tif constexpr( has_constexpr_size<Rng> ) {\n\t\t\t\treturn [&]() return_decltype_noexcept(constexpr_size<Rng>());\n\t\t\t} else if constexpr( has_mem_fn_size<Rng> ) {\n\t\t\t\treturn [&]() return_MAYTHROW(tc_move_if_owned(rng).size()); // .size() may throw for files\n\t\t\t} else {\n\t\t\t\t// Do not use boost::size. It always uses std::distance, which is O(n) for\n\t\t\t\t// ranges with boost::iterators::random_access_traversal_tag but not std::random_access_iterator_tag,\n\t\t\t\t// e.g., boost::transform_iterator\n\t\t\t\treturn [&]() return_MAYTHROW(tc::as_unsigned(tc::end(rng) - tc::begin(rng)));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr auto size_raw(Rng&& rng) return_decltype_MAYTHROW(\n\t\tsize_raw_internal::size_raw(tc_move_if_owned(rng))()\n\t)\n\n\t// Note: This overload is only necessary for the assertion - the size is otherwise computed the same by constexpr_size.\n\ttemplate<tc::char_type T, std::size_t N>\n\t[[nodiscard]] constexpr auto size_raw(T const (&ach)[N]) noexcept {\n\t\t_ASSERTE(tc::strlen(ach)==N-1); // VERIFYEQUAL is not constexpr\n\t\treturn N-1;\n\t}\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto size(T&& t) return_decltype_MAYTHROW(\n\t\tmake_size_proxy(tc::size_raw(tc_move_if_owned(t)))\n\t)\n\n\tTC_HAS_EXPR(size, (T), size_raw(std::declval<T>()))\n\tDEFINE_FN2(tc::size_raw, fn_size_raw)\n\n\ttemplate <auto Fn, typename ... Rng>\n\t[[nodiscard]] constexpr auto compute_range_adaptor_size(Rng&&... rng) MAYTHROW {\n\t\tif constexpr ((tc::has_constexpr_size<Rng> && ...)) {\n\t\t\ttc::actual_unsigned_integer auto constexpr value = Fn(tc::constexpr_size<Rng>()...);\n\t\t\treturn tc::least_uint_constant<value>{};\n\t\t} else {\n\t\t\ttc::actual_unsigned_integer auto const value = Fn(tc::size_raw(tc_move_if_owned(rng))...);\n\t\t\treturn value;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "tc/algorithm/size_bounded.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../container/container_traits.h\"\n#include \"size.h\"\n#include \"break_or_continue.h\"\n#include \"for_each.h\"\n\nnamespace tc {\n\ttemplate< typename It, typename T, typename Sentinel >\n\tT advance_forward_bounded(It&& it, T n, Sentinel&& itBound) noexcept {\n\t\t_ASSERT(0 <= n);\n\t\tif constexpr( std::convertible_to<\n\t\t\ttypename boost::iterator_traversal<std::remove_reference_t<It>>::type,\n\t\t\tboost::iterators::random_access_traversal_tag\n\t\t> && requires { itBound - it; } ) {\n\t\t\tif (tc::assign_better(tc::fn_less_equal(), n, tc::make_size_proxy(itBound - it))) {\n\t\t\t\tit = tc_move_if_owned(itBound);\n\t\t\t} else {\n\t\t\t\tit += n;\n\t\t\t}\n\t\t\treturn n;\n\t\t} else {\n\t\t\t// size_proxy does not provide operator++ and the operation cannot fail here,\n\t\t\t// because nCount is always inside interval [0,n].\n\t\t\tauto nCount = tc::explicit_cast<decltype(tc::unmake_size_proxy(n))>(0);\n\t\t\twhile (nCount != n && it != itBound) {\n\t\t\t\t++nCount;\n\t\t\t\t++it;\n\t\t\t}\n\t\t\ttc_return_cast(nCount);\n\t\t}\n\t}\n\n\ttemplate< typename Rng, typename T>\n\t[[nodiscard]] constexpr auto size_bounded(Rng const& rng, T const nBound) noexcept {\n\t\tif constexpr( tc::has_size<Rng> ) {\n\t\t\treturn tc::size(rng);\n\t\t} else if constexpr( tc::range_with_iterators<Rng> ) {\n\t\t\treturn advance_forward_bounded( tc::begin(rng), nBound, tc::end(rng) );\n\t\t} else {\n\t\t\tT n = 0;\n\t\t\tif (0 < nBound) {\n\t\t\t\tauto const Enumerate = [&](tc::unused) noexcept { return tc::continue_if(nBound!=++n); };\n\t\t\t\tSTATICASSERTSAME(tc::break_or_continue, decltype(tc::for_each(rng, Enumerate)), \"size_bounded only works with interruptible generators\");\n\t\t\t\ttc::for_each(rng, Enumerate);\n\t\t\t}\n\t\t\treturn n;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "tc/algorithm/size_linear.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/has_xxx.h\"\n#include \"size.h\"\n#include \"for_each.h\"\n\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( size_linear, const&)\n\nnamespace tc {\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr auto size_linear_raw(Rng const& rng) noexcept {\n\t\tif constexpr( tc::has_size<Rng const> ) {\n\t\t\treturn tc::size_raw(rng);\n\t\t} else if constexpr( has_mem_fn_size_linear<Rng> ) {\n\t\t\treturn rng.size_linear();\n\t\t} else if constexpr( tc::range_with_iterators<Rng const> ) {\n#ifdef __cpp_lib_ranges // std::distance and boost::range::distance do not support end sentinels.\n\t\t\treturn std::ranges::distance(tc::begin(rng), tc::end(rng));\n#else\n\t\t\ttypename boost::range_difference<Rng>::type result = 0;\n\t\t\tauto first = tc::begin(rng);\n\t\t\tauto const last = tc::end(rng);\n\t\t\twhile (first != last) {\n\t\t\t\t++first;\n\t\t\t\t++result;\n\t\t\t}\n\t\t\treturn result;\n#endif\n\t\t} else {\n\t\t\tstd::size_t sz=0;\n\t\t\ttc::for_each(rng, [&sz](auto&&...) noexcept {++sz;});\n\t\t\treturn sz;\n\t\t}\n\t}\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto size_linear(T&& t) return_decltype_MAYTHROW(\n\t\tmake_size_proxy(tc::size_linear_raw(tc_move_if_owned(t)))\n\t)\n}\n"
  },
  {
    "path": "tc/algorithm/sort_streaming.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"append.h\"\n#include \"element.h\"\n#include \"../range/reverse_adaptor.h\"\n\n#include <boost/range/algorithm/heap_algorithm.hpp>\n\nnamespace tc {\n\ttemplate<typename Cont, typename T, typename Less = tc::fn_less>\n\tvoid replace_heap(Cont& cont, T&& t, Less less = Less()) noexcept {\n\t\t// Replace largest item in max-heap with t.\n\t\t// Equivalent to\n\t\t// std::ranges::pop_heap(cont, less);\n\t\t// tc::back(cont) = tc_move_if_owned(t);\n\t\t// std::ranges::push_heap(cont, less);\n\t\tauto const n = tc::size_raw(cont);\n\t\tauto const IndexAndIterator = [&](decltype(n) i) noexcept {\n\t\t\treturn tc::make_tuple(i, tc::at<tc::return_element>(cont, i));\n\t\t};\n\t\tauto nitHole = IndexAndIterator(0);\n\t\tauto const nWithRightChildEnd = (n - 1) / 2;\n\t\tfor( ;; ) {\n\t\t\tauto const nHole = tc::get<0>(nitHole);\n\t\t\tdecltype(nitHole) nitGreaterChild;\n\t\t\tif( nHole < nWithRightChildEnd ) { // hole has right child\n\t\t\t\tnitGreaterChild = tc::best(\n\t\t\t\t\ttc::projected(tc::reverse_binary_rel(less), tc_fn(*tc::get<1>)),\n\t\t\t\t\tIndexAndIterator(nHole * 2 + 1),\n\t\t\t\t\tIndexAndIterator(nHole * 2 + 2)\n\t\t\t\t);\n\t\t\t} else if( nHole == nWithRightChildEnd && 0 == n % 2 ) { // hole has very last left child\n\t\t\t\tnitGreaterChild = IndexAndIterator(nHole * 2 + 1);\n\t\t\t} else { // hole has no children\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif( less(t, *tc::get<1>(nitGreaterChild)) ) {\n\t\t\t\t*tc::get<1>(nitHole) = tc_move_always(*tc::get<1>(nitGreaterChild));\n\t\t\t\tnitHole = nitGreaterChild;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t*tc::get<1>(nitHole) = tc_move_if_owned(t);\n\t}\n\n\ttemplate<typename Rng, typename Less = tc::fn_less, typename PredKeep = tc::constexpr_function<false>>\n\tauto sort_streaming(Rng&& rng, Less&& less = Less(), PredKeep&& predKeep = PredKeep()) noexcept {\n\t\t// Notes:\n\t\t//  * not a stable sort algorithm \n\t\t//  * not an inplace sort algorithm\n\t\t//  * first element is generated in O(n)\n\t\treturn tc::generator_range_output<tc::range_value_t<Rng const&>&>([\n\t\t\trng = tc::make_reference_or_value(tc_move_if_owned(rng)),\n\t\t\t// std heap algorithm using less create max heap, we need min heap. Hence, we use greater.\n\t\t\tgreater = tc::reverse_binary_rel(less),\n\t\t\tpredKeep = tc::decay_copy(tc_move_if_owned(predKeep))\n\t\t](auto&& sink) MAYTHROW -> tc::common_type_t<decltype(tc::continue_if_not_break(sink, std::declval<tc::range_value_t<Rng const&>&>())), tc::constant<tc::continue_>> {\n\t\t\tauto vec = tc::make_vector(*rng);\n\t\t\tboost::range::make_heap(vec, greater);\n\t\t\twhile( auto const it = tc::front<tc::return_element_or_null>(vec) ) {\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, *it)) // MAYTHROW\n\t\t\t\tif( tc_invoke(predKeep, *it) ) {\n\t\t\t\t\ttc::replace_heap(vec, tc::range_value_t<decltype(vec)>(tc_move_always(*it)), greater);\n\t\t\t\t} else {\n\t\t\t\t\tboost::range::pop_heap(vec, greater);\n\t\t\t\t\ttc::drop_last_inplace(vec);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn tc::constant<tc::continue_>();\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "tc/algorithm/sort_streaming.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"sort_streaming.h\"\n#include \"../string/ascii.h\"\n#include \"../unittest.h\"\n\nUNITTESTDEF( sort_streaming ) {\n\t_ASSERTEQUAL( tc::make_str(tc::sort_streaming(\"5714926380\")), \"0123456789\" );\n\t_ASSERTEQUAL( tc::make_str<char>(\n\t\ttc::transform(tc::sort_streaming(\"5714926380\", tc::fn_greater(), tc_fn(tc::isasciidigit)), [](char& ch) noexcept {\n\t\t\tchar chOrig = ch;\n\t\t\tch -= 7;\n\t\t\treturn chOrig;\n\t\t})),\n\t\t\"9876543221100\"\n\t);\n}\n"
  },
  {
    "path": "tc/array.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"base/assert_defs.h\"\n#include \"base/reference_or_value.h\"\n#include \"base/type_traits.h\"\n#include \"base/explicit_cast_fwd.h\"\n#include \"base/tag_type.h\"\n#include \"base/construction_restrictiveness.h\"\n#include \"algorithm/compare.h\"\n#include \"algorithm/equal.h\"\n#include \"algorithm/empty.h\"\n#include \"algorithm/quantifier.h\"\n#include \"storage_for.h\"\n#include \"range/transform.h\"\n\n#include <boost/iterator/indirect_iterator.hpp>\n#include <boost/range/algorithm/copy.hpp>\n#include <cstdint>\n#include <array>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate< typename T >\n\t\tstruct empty_array_storage {\n\t\t\tconstexpr operator T*() { return nullptr; }\n\t\t\tconstexpr operator T const*() const { return nullptr; }\n\t\t};\n\n\t\ttemplate< typename T, std::size_t N >\n\t\tstruct array_storage {\n\t\t\tusing type = T[N];\n\t\t};\n\n\t\ttemplate< typename T >\n\t\tstruct array_storage<T, 0> {\n\t\t\tusing type = empty_array_storage<T>;\n\t\t};\n\t}\n\n\tnamespace array_adl {\n\t\ttemplate< typename T, std::size_t N >\n\t\tstruct array;\n\n\t\ttemplate< typename T, std::size_t N >\n\t\tstruct array<T&, N> {\n\t\t\tstatic_assert( !std::is_reference<T>::value );\n\t\tprivate:\n\t\t\ttypename no_adl::array_storage<T*, N>::type m_a;\n\n\t\tpublic:\n\t\t\tusing iterator = boost::indirect_iterator<T* const*, tc::decay_t<T>, /*CategoryOrTraversal*/boost::use_default, T&>;\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<N>{};\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<typename Func, std::size_t ...IndexPack>\n\t\t\tconstexpr array(func_tag_t, Func func, std::index_sequence<IndexPack...>) MAYTHROW \n\t\t\t\t: m_a{std::addressof(func(IndexPack))...} \n\t\t\t{\n\t\t\t\tstatic_assert(tc::safely_constructible_from<T&, decltype(func(0))>);\n\t\t\t}\n\t\tpublic:\n\t\t\ttemplate<typename Func>\n\t\t\tarray(func_tag_t, Func func) MAYTHROW\n\t\t\t\t: array(tc::func_tag, func, std::make_index_sequence<N>())\n\t\t\t{}\n\n\t\t\t// make sure forwarding ctor has at least two parameters, so no ambiguity with copy/move ctors\n\t\t\ttemplate <typename... Args> requires (tc::econstructionIMPLICIT==tc::elementwise_construction_restrictiveness<T&, Args&...>::value)\n\t\t\tconstexpr array(tc::aggregate_tag_t, Args& ... args) MAYTHROW\n\t\t\t\t: m_a{std::addressof(args)...}\n\t\t\t{\n\t\t\t\tSTATICASSERTEQUAL(sizeof...(Args), N, \"array initializer list does not match number of elements\");\n\t\t\t}\n\n\t\tprivate:\n\t\t\tDEFINE_NESTED_TAG_TYPE(range_tag)\n\n\t\t\ttemplate<typename Iterator, std::size_t ...IndexPack>\n\t\t\tconstexpr array(range_tag_t, Iterator it, Iterator itEnd, std::index_sequence<IndexPack...>) MAYTHROW\n\t\t\t\t: m_a{(_ASSERTE(itEnd!=it), std::addressof(*it)), (static_cast<void>(IndexPack), ++it, _ASSERTE(itEnd!=it), std::addressof(*it))...}\n\t\t\t{\n\t\t\t\tstatic_assert(tc::safely_constructible_from<T&, decltype(*it)>);\n\t\t\t\tSTATICASSERTEQUAL(N, sizeof...(IndexPack)+1);\n\t\t\t\t_ASSERTE(itEnd==++it);\n\t\t\t}\n\t\tpublic:\n\t\t\ttemplate<typename Rng> requires (0 != N) && (tc::econstructionIMPLICIT==tc::construction_restrictiveness<T&, decltype(*tc::as_lvalue(tc::begin(std::declval<Rng&>())))>::value)\n\t\t\tconstexpr explicit array(Rng&& rng) MAYTHROW\n\t\t\t\t: array(range_tag, tc::begin(rng), tc::end(rng), std::make_index_sequence<N-1>())\n\t\t\t{}\n\n#if 0\n\t\t\ttemplate<typename T2> requires tc::safely_assignable_from<T&, T2 const&>\n\t\t\tarray const& operator=(array<T2, N> const& rhs) const& noexcept(std::is_nothrow_assignable<T&, T2 const&>::value) {\n\t\t\t\tVERIFY(boost::copy(VERIFYINITIALIZED(rhs), begin())==end());\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate<typename T2> requires tc::safely_assignable_from<T&, T2&&>\n\t\t\tarray const& operator=(array<T2, N>&& rhs) const& noexcept(std::is_nothrow_assignable<T&, T2&&>::value) {\n\t\t\t\tauto it=tc::begin(rhs);\n\t\t\t\tauto const itEnd=tc::end(rhs);\n\t\t\t\tfor(auto itOut=begin(); itEnd!=it; ++it, ++itOut) {\n\t\t\t\t\t*itOut=tc_move_if_owned(VERIFYINITIALIZED(*it)); // T2 may be lvalue-reference\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n#endif\n\n\t\t\t// iterators\n\t\t\t// reference semantics == no deep constness\n\t\t\titerator begin() const& noexcept {\n\t\t\t\treturn std::addressof(m_a[0]);\n\t\t\t}\n\t\t\titerator end() const& noexcept {\n\t\t\t\treturn std::addressof(m_a[0])+N;\n\t\t\t\t\t// std::addressof(m_a[N]); triggers warning in clang\n\t\t\t}\n\n\t\t\t// access (no rvalue-qualified overloads, must not move data out of a reference)\n\t\t\t// reference semantics == no deep constness\n\t\t\t[[nodiscard]] constexpr T& operator[](std::size_t const i) const& noexcept {\n\t\t\t\t_ASSERTDEBUG(i<N);\n\t\t\t\treturn *m_a[i];\n\t\t\t}\n\n#if defined(TC_PRIVATE) && defined(_DEBUG) && !defined(__clang__)\n\t\t\tfriend constexpr bool check_initialized_impl(array const& a) noexcept {\n\t\t\t\treturn tc::all_of(a, tc::check_initialized);\n\t\t\t}\n#endif\n\t\t};\n\n\t\ttemplate<typename Lhs, typename Rhs, std::size_t N>\n\t\t[[nodiscard]] constexpr bool operator==(array<Lhs, N> const& lhs, array<Rhs, N> const& rhs) noexcept {\n\t\t\treturn tc::equal(VERIFYINITIALIZED(lhs), VERIFYINITIALIZED(rhs));\n\t\t}\n\n\t\ttemplate<typename Lhs, std::size_t N, typename Rhs>\n\t\t[[nodiscard]] constexpr auto operator<=>(array<Lhs, N> const& lhs, array<Rhs, N> const& rhs) noexcept {\n\t\t\treturn tc::lexicographical_compare_3way(VERIFYINITIALIZED(lhs), VERIFYINITIALIZED(rhs));\n\t\t}\n\t} // namespace array_adl\n\tusing array_adl::array;\n\n\t/////////////////////////////////////////////////////\n\t// std::array\n\n\tnamespace no_adl {\n\t\ttemplate<typename T, std::size_t N>\n\t\tstruct constexpr_size_impl<std::array<T, N>> : tc::least_uint_constant<N> {};\n\t}\n\n\tnamespace explicit_convert_std_array_detail {\n\t\ttemplate<typename T, std::size_t N, typename Func, std::size_t... IndexPack>\n\t\tconstexpr std::array<T, N> with_func_tag_impl(std::type_identity<std::array<T, N>>, Func func, std::index_sequence<IndexPack...>) noexcept(noexcept(T(func(std::declval<std::size_t>()))))\n\t\t\trequires tc::safely_convertible_to<decltype(func(std::declval<std::size_t>())), T>\n\t\t{\n\t\t\treturn {func(IndexPack)...};\n\t\t}\n\n\t\ttemplate<typename T, std::size_t N, std::size_t ...IndexPack>\n\t\tconstexpr std::array<T, N> with_fill_tag_impl(std::type_identity<std::array<T, N>>, std::index_sequence<IndexPack...>, auto&&... args) noexcept(\n\t\t\tnoexcept(tc::explicit_cast<T>(tc_const_forward(args)...)) &&\n\t\t\tnoexcept(tc::explicit_cast<T>(tc_move_if_owned(args)...))\n\t\t) requires\n\t\t\trequires { tc::explicit_cast<T>(tc_const_forward(args)...); } &&\n\t\t\trequires { tc::explicit_cast<T>(tc_move_if_owned(args)...); }\n\t\t{\n\t\t\tSTATICASSERTEQUAL(N, sizeof...(IndexPack)+1);\n\t\t\treturn {\n\t\t\t\t(tc::discard(IndexPack), tc::explicit_cast<T>(tc_const_forward(args)...))...,\n\t\t\t\ttc::explicit_cast<T>(tc_move_if_owned(args)...)\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename T, typename Iterator, typename Dummy>\n\t\tconstexpr std::array<T, 1> with_range_tag_impl(std::type_identity<std::array<T, 1>>, Iterator it, Iterator itEnd, Dummy&&) noexcept(noexcept(T(*it)))\n\t\t\trequires tc::safely_convertible_to<decltype(*it), T>\n\t\t{\n\t\t\treturn {(_ASSERTE(itEnd != it), _ASSERTE(itEnd == tc_modified(it, ++_)), *it)};\n\t\t}\n\n\t\ttemplate<typename T, std::size_t N, typename Iterator, std::size_t... IndexPack> requires (1<N)\n\t\tconstexpr std::array<T, N> with_range_tag_impl(std::type_identity<std::array<T, N>>, Iterator it, Iterator itEnd, std::index_sequence<IndexPack...>) noexcept(noexcept(T(*it)) && noexcept(++it))\n\t\t\trequires tc::safely_convertible_to<decltype(*it), T>\n\t\t{\n\t\t\tSTATICASSERTEQUAL(N, sizeof...(IndexPack)+2);\n\t\t\treturn {\n\t\t\t\t(_ASSERTE(itEnd != it), *it),\n\t\t\t\t(static_cast<void>(IndexPack), ++it, _ASSERTE(itEnd != it), *it)...,\n\t\t\t\t(++it, _ASSERTE(itEnd != it), _ASSERTE(itEnd == tc_modified(it, ++_)), *it)\n\t\t\t};\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename It>\n\t\t\tstruct fn_construct_element_and_increment { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\t\tIt& m_itOut;\n\t\t\t\tconstexpr auto operator()(auto&& t) const& noexcept(noexcept(tc::renew(*m_itOut, tc_move_if_owned(t)))) {\n\t\t\t\t\ttc::renew(*m_itOut, tc_move_if_owned(t)); // MAYTHROW\n\t\t\t\t\t++m_itOut;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename T, std::size_t N, typename Func>\n\t\tconstexpr std::array<T, N> explicit_convert_impl(adl_tag_t, std::type_identity<std::array<T, N>> id, tc::func_tag_t, Func func) noexcept(noexcept(tc::explicit_convert_std_array_detail::with_func_tag_impl(id, tc_move(func), std::make_index_sequence<N>()))) {\n\t\t\tstatic_assert(tc::safely_constructible_from<T, decltype(func(N-1))>);\n\t\t\treturn tc::explicit_convert_std_array_detail::with_func_tag_impl(id, tc_move(func), std::make_index_sequence<N>());\n\t\t}\n\n\t\ttemplate<typename T, std::size_t N, typename... Args> requires (0!=N) && tc::explicit_castable_from<T, Args&&...>\n\t\tconstexpr std::array<T, N> explicit_convert_impl(adl_tag_t, std::type_identity<std::array<T, N>> id, tc::fill_tag_t, Args&& ... args) return_MAYTHROW(\n\t\t\ttc::explicit_convert_std_array_detail::with_fill_tag_impl(id, std::make_index_sequence<N-1>(), tc_move_if_owned(args)...)\n\t\t)\n\n\t\ttemplate<typename T, std::size_t N, typename... Args> requires (tc::explicit_castable_from<T, Args&&> && ...)\n\t\tconstexpr std::array<T, N> explicit_convert_impl(adl_tag_t, std::type_identity<std::array<T, N>>, tc::aggregate_tag_t, Args&& ... args) noexcept((... && noexcept(tc::explicit_cast<T>(tc_move_if_owned(args))))) {\n\t\t\tSTATICASSERTEQUAL(sizeof...(Args), N, \"array initializer list does not match number of elements\");\n\t\t\treturn {tc::explicit_cast<T>(tc_move_if_owned(args))...};\n\t\t}\n\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tconcept noexcept_explicit_castable = std::same_as<TTarget, TSource> /*optimistically assume guaranteed copy elision*/ || noexcept(tc::explicit_cast<TTarget>(std::declval<TSource>()));\n\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tusing noexcept_explicit_castable_t=tc::constant<noexcept_explicit_castable<TTarget, TSource>>;\n\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr std::array<T, N> explicit_convert_impl(adl_tag_t, std::type_identity<std::array<T, N>> id, auto&& rng) noexcept(\n\t\t\t0==N ||\n\t\t\tboost::mp11::mp_apply<boost::mp11::mp_all, tc::mp_transform<boost::mp11::mp_bind_front<noexcept_explicit_castable_t, T>::template fn, tc::range_output_t<decltype(rng)>>>::value\n\t\t)\n\t\t\trequires (0 == N)\n\t\t\t\t|| (econstructionEXPLICIT <= boost::mp11::mp_apply<tc::elementwise_construction_restrictiveness, boost::mp11::mp_append<boost::mp11::mp_list<T>, tc::range_output_t<decltype(rng)>>>::value)\n\t\t{\n\t\t\tif constexpr( 0 == N ) {\n\t\t\t\t_ASSERTE(tc::empty(rng));\n\t\t\t\treturn {};\n\t\t\t} else if constexpr( std::is_trivially_default_constructible<T>::value && std::is_trivially_destructible<T>::value ) {\n\t\t\t\tstd::array<T, N> at;\n\t\t\t\tauto itOut = tc::begin(at);\n\t\t\t\t// cont_assign(at, transform(tc_move_if_owned(rng), tc_fn(tc::explicit_cast<T>))); without moving rng and avoiding dependency\n\t\t\t\ttc::for_each(tc_move_if_owned(rng), explicit_convert_std_array_detail::no_adl::fn_construct_element_and_increment<decltype(itOut)>{itOut}); // MAYTHROW\n\t\t\t\t_ASSERTE(tc::end(at)==itOut);\n\t\t\t\treturn at;\n\t\t\t} else if constexpr(\n\t\t\t\t// The initialization of the C array inside std::array when writing std::array<T,1>{...} is\n\t\t\t\t// copy list initialization, not direct list initialization, so explicit constructors are not allowed.\n\t\t\t\t// int to double is considered narrowing, forbidden in list initialization (but double is already handled above)\n\t\t\t\ttc::safely_convertible_to<decltype(*tc::as_lvalue(tc::begin(rng))), T>\n\t\t\t) {\n\t\t\t\treturn tc::explicit_convert_std_array_detail::with_range_tag_impl(id, tc::begin(rng), tc::end(rng), std::make_index_sequence<1==N ? 0 : N-2>());\n\t\t\t} else {\n\t\t\t\ttc_return_cast(tc::transform(tc_move_if_owned(rng), tc::fn_explicit_cast<T>()));\n\t\t\t}\n\t\t}\n\t}\n\n\t//////////////////////////////////////////////////////////////\n\n\tnamespace no_adl {\n\t\ttemplate <typename T, typename...>\n\t\tstruct delayed_deduce final {\n\t\t\tusing type = T;\n\t\t};\n\n\t\ttemplate <typename... Ts>\n\t\tstruct delayed_deduce<tc::deduce_tag, Ts...> final {\n\t\t\tusing type = tc::common_type_t<Ts...>;\n\t\t};\n\t}\n\n\ttemplate<typename TTarget, std::size_t N, typename Rng>\n\t[[nodiscard]] constexpr auto make_array(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::explicit_cast<std::array<TTarget, N>>(tc_move_if_owned(rng))\n\t)\n\n\ttemplate<std::size_t N, typename Rng>\n\t[[nodiscard]] constexpr auto make_array(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::make_array<tc::range_value_t<Rng>, N>(tc_move_if_owned(rng))\n\t)\n\n\ttemplate<typename TTarget, typename Rng>\n\t[[nodiscard]] constexpr auto make_array(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::make_array<TTarget, tc::constexpr_size<Rng>()>(tc_move_if_owned(rng))\n\t)\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr auto make_array(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::make_array<tc::constexpr_size<Rng>()>(tc_move_if_owned(rng))\n\t)\n\n\ttemplate <typename T = tc::deduce_tag, typename... Ts> requires (!std::is_reference<T>::value)\n\t[[nodiscard]] constexpr auto make_array(tc::aggregate_tag_t, Ts&&... ts) noexcept {\n\t\tstatic_assert(!std::is_reference<typename no_adl::delayed_deduce<T, Ts...>::type>::value);\n\t\treturn tc::explicit_cast<std::array<typename no_adl::delayed_deduce<T, Ts...>::type, sizeof...(Ts)>>(tc::aggregate_tag, tc_move_if_owned(ts)...);\n\t}\n\n\t// If T is a reference, force argument type T for all given arguments. That way, conversions\n\t// take place in the calling expression, and cases such as\n\t//\n\t//\t\ttc::find_unique<tc::return_bool>(tc::make_array<Foo const&>(convertible_to_Foo), foo);\n\t//\n\t// will work as expected. With the usual variadic template + std::forward pattern, conversions\n\t// would take place inside the array constructor, resulting in a dangling reference.\n\n\t// Unfortunately, there seems to be no way to make this work in C++ without using macros\n#define TC_MAKE_ARRAY_LVALUE_REF(z, n, d) \\\n\ttemplate <typename T> requires std::is_lvalue_reference<T>::value \\\n\t[[nodiscard]] constexpr auto make_array(tc::aggregate_tag_t, BOOST_PP_ENUM_PARAMS(n, T t)) noexcept { \\\n\t\treturn tc::explicit_cast<tc::array<T, n>>(tc::aggregate_tag, BOOST_PP_ENUM_PARAMS(n, t)); \\\n\t}\n\n\tBOOST_PP_REPEAT_FROM_TO(1, 20, TC_MAKE_ARRAY_LVALUE_REF, _)\n#undef TC_MAKE_ARRAY_LVALUE_REF\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto single(T&& t) noexcept {\n\t\tif constexpr( std::is_reference<T>::value ) {\n\t\t\treturn tc::counted(std::addressof(t),1);\n\t\t} else {\n\t\t\t// not tc::decay_t, we want to keep reference-like proxy objects as proxy objects\n\t\t\t// just like we preserve lvalue references.\n\t\t\treturn tc::make_array<std::remove_cv_t<T> >(tc::aggregate_tag,tc_move_if_owned(t));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/base/accessors.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"generic_macros.h\"\n#include \"type_traits_fwd.h\"\n\n#include <boost/preprocessor/comparison/greater.hpp>\n\nnamespace tc {\n\t// customization point accessor_return_type\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct accessor_return_type final { \n\t\t\tstatic_assert(tc::decayed<T>);\n\t\t\tusing const_ref_type = T;\n\t\t\tusing ref_ref_type = T;\n\t\t\tusing const_ref_ref_type = T;\n\t\t};\n\n\t\ttemplate<typename T> requires\n\t\t\tstd::is_union<std::remove_reference_t<T>>::value ||\n\t\t\tstd::is_class<std::remove_reference_t<T>>::value ||\n\t\t\tstd::is_array<std::remove_reference_t<T>>::value\n\t\tstruct accessor_return_type<T> final {\n\t\t\tstatic_assert(std::is_array<T>::value || tc::decayed<T>);\n\t\t\tusing const_ref_type = T const&;\n\t\t\tusing ref_ref_type = T&&;\n\t\t\tusing const_ref_ref_type = T const&&;\n\t\t};\n\t}\n}\n\n#define DEFINE_MEMBER_WITHOUT_INIT(type, name) \\\n\t\ttype name;\n#define DEFINE_MEMBER_WITH_INIT(type, name, ...) \\\n\t\ttype name{__VA_ARGS__};\n\n#define DEFINE_MEMBER_BASE(type, ...) \\\n\tTC_EXPAND(TC_EXPAND(BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1), DEFINE_MEMBER_WITH_INIT, DEFINE_MEMBER_WITHOUT_INIT))(TC_FWD(type), __VA_ARGS__))\n\n#define DEFINE_ACCESSORS_BASE(type, funcname, invariant, name) \\\n\t[[nodiscard]] constexpr typename tc::no_adl::accessor_return_type<type>::const_ref_type funcname() const& noexcept { invariant(name); return name; } \\\n\t\\\n\ttemplate<ENABLE_SFINAE> requires /*dummy constraint making this function preferred in overload resolution over the deleted function below*/true \\\n\t[[nodiscard]] constexpr typename tc::no_adl::accessor_return_type<SFINAE_TYPE(type)>::ref_ref_type funcname() && noexcept { invariant(name); return tc_move(name); } \\\n\t\\\n\ttemplate<ENABLE_SFINAE> /* needed to stay behind non-deleted function in overload resolution */ \\\n\t[[nodiscard]] constexpr type&& funcname() && noexcept = delete; /* Visual Studio gives improper error message if it returns a dummy type */ \\\n\t\\\n\ttemplate<ENABLE_SFINAE> requires true \\\n\t[[nodiscard]] constexpr typename tc::no_adl::accessor_return_type<SFINAE_TYPE(type)>::const_ref_ref_type funcname() const&& noexcept { invariant(name); return tc_move_always_even_const(name); } \\\n\t\\\n\ttemplate<ENABLE_SFINAE> \\\n\t[[nodiscard]] constexpr type const&& funcname() const&& noexcept = delete; /* Visual Studio gives improper error message if it returns a dummy type */\n\n#define DEFINE_MEMBER_INVARIANT(...) ([&](auto const& _) constexpr noexcept { \\\n\t_ASSERTINITIALIZED(_); \\\n\t__VA_ARGS__; \\\n})\n\n#define INTERNAL_MEMBER_AND_NAMED_ACCESSOR_INVARIANT(accessspecifierMember, type, accessspecifierAccessor, funcname, invariant, ...) /* type, funcname, invariant, name(, value) */ \\\n\taccessspecifierMember: \\\n\tDEFINE_MEMBER_BASE(TC_FWD(type), __VA_ARGS__) \\\n\taccessspecifierAccessor: \\\n\tDEFINE_ACCESSORS_BASE(TC_FWD(type), TC_FWD(funcname), DEFINE_MEMBER_INVARIANT(invariant), BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)) \\\n\taccessspecifierMember:\n\n/********* private member, public accessor ******************************************************************/\n\n#define PRIVATE_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(type, funcname, invariant, ...) /* type, funcname, invariant, name(, value) */ \\\n\tINTERNAL_MEMBER_AND_NAMED_ACCESSOR_INVARIANT(private, TC_FWD(type), public, TC_FWD(funcname), TC_FWD(invariant), __VA_ARGS__)\n\n#define PRIVATE_MEMBER_PUBLIC_NAMED_ACCESSOR(type, funcname, ...) /* type, funcname, name(, value) */ \\\n\tPRIVATE_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), TC_FWD(funcname), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n#define PRIVATE_MEMBER_PUBLIC_ACCESSOR_INVARIANT(type, invariant, ...) /* type, invariant, name(, value) */ \\\n\tPRIVATE_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__), _), TC_FWD(invariant), __VA_ARGS__)\n\n#define PRIVATE_MEMBER_PUBLIC_ACCESSOR(type, ...) /* type, name(, value) */ \\\n\tPRIVATE_MEMBER_PUBLIC_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n/********* protected member, public accessor ******************************************************************/\n\n#define PROTECTED_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(type, funcname, invariant, ...) /* type, funcname, invariant, name(, value) */ \\\n\tINTERNAL_MEMBER_AND_NAMED_ACCESSOR_INVARIANT(protected, TC_FWD(type), public, TC_FWD(funcname), TC_FWD(invariant), __VA_ARGS__)\n\n#define PROTECTED_MEMBER_PUBLIC_NAMED_ACCESSOR(type, funcname, ...) /* type, funcname, name(, value) */ \\\n\tPROTECTED_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), TC_FWD(funcname), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n#define PROTECTED_MEMBER_PUBLIC_ACCESSOR_INVARIANT(type, invariant, ...) /* type, invariant, name(, value) */ \\\n\tPROTECTED_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__), _), TC_FWD(invariant), __VA_ARGS__)\n\n#define PROTECTED_MEMBER_PUBLIC_ACCESSOR(type, ...) /* type, name(, value) */ \\\n\tPROTECTED_MEMBER_PUBLIC_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n/********* public member, public accessor ******************************************************************/\n\n#define PUBLIC_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(type, funcname, invariant, ...) /* type, funcname, invariant, name(, value) */ \\\n\tINTERNAL_MEMBER_AND_NAMED_ACCESSOR_INVARIANT(public, TC_FWD(type), public, TC_FWD(funcname), TC_FWD(invariant), __VA_ARGS__)\n\n#define PUBLIC_MEMBER_PUBLIC_NAMED_ACCESSOR(type, funcname, ...) /* type, funcname, name(, value) */ \\\n\tPUBLIC_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), TC_FWD(funcname), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n#define PUBLIC_MEMBER_PUBLIC_ACCESSOR_INVARIANT(type, invariant, ...) /* type, invariant, name(, value) */ \\\n\tPUBLIC_MEMBER_PUBLIC_NAMED_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__), _), TC_FWD(invariant), __VA_ARGS__)\n\n#define PUBLIC_MEMBER_PUBLIC_ACCESSOR(type, ...) /* type, name(, value) */ \\\n\tPUBLIC_MEMBER_PUBLIC_ACCESSOR_INVARIANT(TC_FWD(type), BOOST_PP_EMPTY(), __VA_ARGS__)\n\n/********* private member, private accessor ******************************************************************/\n\n#define PRIVATE_MEMBER_PRIVATE_ACCESSOR_INVARIANT(type, invariant, ...) /* type, invariant, name(, value) */ \\\n\tINTERNAL_MEMBER_AND_NAMED_ACCESSOR_INVARIANT(private, TC_FWD(type), private, BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__), _), TC_FWD(invariant), __VA_ARGS__)\n"
  },
  {
    "path": "tc/base/as_lvalue.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\nnamespace tc {\n\ttemplate <typename T>\n\t[[nodiscard]] constexpr T& as_lvalue(T&& t) noexcept {\n\t\treturn static_cast<T&>(t); // required as soon as \"P2266R3: Simpler implicit move\" is implemented\n\t}\n}\n"
  },
  {
    "path": "tc/base/assert_defs.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#ifdef TC_PRIVATE\n\t#include \"Library/ErrorReporting/assert_fwd.h\"\n#else\n\t#include \"fundamental.h\"\n\t#include \"move.h\"\n\t#include <type_traits>\n\t#include <cstdlib>\n\n\t#ifndef _CHECKS\n\t\t#define _CHECKS\n\t#endif\n\n\t#ifndef IF_TC_CHECKS\n\t\t#ifdef _CHECKS\n\t\t\t#define IF_TC_CHECKS(...) __VA_ARGS__\n\t\t#else\n\t\t\t#define IF_TC_CHECKS(...)\n\t\t#endif\n\t#endif\n\t#ifndef IF_TC_DEBUG\n\t\t#ifdef _DEBUG\n\t\t\t#define IF_TC_DEBUG(...) __VA_ARGS__\n\t\t#else\n\t\t\t#define IF_TC_DEBUG(...)\n\t\t#endif\n\t#endif\n\n\t#ifndef _ASSERT\n\t\t#ifdef NDEBUG\n\t\t\t#define _ASSERT(...) IF_TC_CHECKS((TC_FWD(__VA_ARGS__) ? (void)0 : std::abort()))\n\t\t#else\n\t\t\t#include <cassert>\n\t\t\t#define _ASSERT(...) IF_TC_CHECKS(assert(TC_FWD(__VA_ARGS__)))\n\t\t#endif\n\t#endif\n\t#ifndef TRYASSERT\n\t\t#define TRYASSERT _ASSERT\n\t#endif\n\t#ifndef _ASSERTE\n\t\t#define _ASSERTE(...) (static_cast<void>(0))\n\t#endif\n\t#ifndef _ASSERTDEBUG\n\t\t#define _ASSERTDEBUG(...) IF_TC_DEBUG(_ASSERT((__VA_ARGS__)))\n\t#endif\n\t#ifndef _ASSERTFALSE\n\t\t#define _ASSERTFALSE _ASSERT(false)\n\t#endif\n\t#ifndef _ASSERTNORETURN\n\t\t#define _ASSERTNORETURN _ASSERT\n\t#endif\n\t#ifndef _ASSERTNORETURNFALSE\n\t\t#define _ASSERTNORETURNFALSE _ASSERTFALSE\n\t#endif\n\t#ifndef _ASSERTNOTIFY\n\t\t#define _ASSERTNOTIFY _ASSERT\n\t#endif\n\t#ifndef _ASSERTNOTIFYFALSE\n\t\t#define _ASSERTNOTIFYFALSE _ASSERTFALSE\n\t#endif\n\t#ifndef _ASSERTENOTIFY\n\t\t#define _ASSERTENOTIFY _ASSERTE\n\t#endif\n\t#ifndef _ASSERTEQUAL\n\t\t#define _ASSERTEQUAL(a, b) _ASSERT((a)==(b))\n\t#endif\n\t#ifndef _ASSERTDEBUGEQUAL\n\t\t#define _ASSERTDEBUGEQUAL(a, b) IF_TC_DEBUG(_ASSERTEQUAL(a, b))\n\t#endif\n\t#ifndef _ASSERTANYOF\n\t\t#include <boost/preprocessor/seq/enum.hpp>\n\t\t#define _ASSERTANYOF(expr, values) [](auto const& e, auto const&... val) noexcept { _ASSERT( ((e == val) || ...) ); }(expr, BOOST_PP_SEQ_ENUM(values))\n\t#endif\n\t#ifndef _ASSERTDEBUGANYOF\n\t\t#define _ASSERTDEBUGANYOF(expr, values) IF_TC_DEBUG(_ASSERTANYOF(expr, values))\n\t#endif\n\t#ifndef _ASSERTINITIALIZED\n\t\t#define _ASSERTINITIALIZED( expr ) tc::discard(expr)\n\t#endif\n\t#ifndef _ASSERTPRINT\n\t\t#define _ASSERTPRINT( cond, ... ) _ASSERT( cond )\n\t#endif\n\t#ifndef VERIFYEQUAL\n\t\tnamespace ErrorHandling {\n\t\t\ttemplate <typename Expr, typename Const>\n\t\t\tconstexpr Expr&& VerifyEqual(Expr&& expr, Const const& c) {\n\t\t\t\t_ASSERTEQUAL(expr, c);\n\t\t\t\treturn tc_move_if_owned(expr);\n\t\t\t}\n\t\t}\n\t\t#define VERIFYEQUAL( expr, constant ) ErrorHandling::VerifyEqual(expr, constant)\n\t#endif\n\t#ifndef VERIFYEQUALNOPRINT\n\t\t#define VERIFYEQUALNOPRINT VERIFYEQUAL\n\t#endif\n\t#ifndef VERIFY\n\t\tnamespace ErrorHandling {\n\t\t\ttemplate <typename Expr>\n\t\t\tconstexpr Expr&& Verify(Expr&& expr) {\n\t\t\t\t_ASSERT(expr);\n\t\t\t\treturn tc_move_if_owned(expr);\n\t\t\t}\n\t\t}\n\t\t#define VERIFY ErrorHandling::Verify\n\t#endif\n\t#ifndef VERIFYPRED\n\t\tnamespace ErrorHandling {\n\t\t\ttemplate <typename Expr, typename Pred>\n\t\t\tconstexpr Expr&& VerifyPred(Expr&& expr, Pred pred) {\n\t\t\t\t_ASSERT(pred(expr));\n\t\t\t\treturn tc_move_if_owned(expr);\n\t\t\t}\n\t\t}\n\t\t#define VERIFYPRED( expr, ... ) ErrorHandling::VerifyPred(expr, [&](auto const& _) { return (__VA_ARGS__); })\n\t#endif\n\t#ifndef VERIFYINITIALIZED\n\t\t#define VERIFYINITIALIZED( expr ) (expr)\n\t#endif\n\t#ifndef VERIFYNOTIFYEQUAL\n\t\t#define VERIFYNOTIFYEQUAL VERIFYEQUAL\n\t#endif\n\t#ifndef VERIFYNOTIFY\n\t\t#define VERIFYNOTIFY VERIFY\n\t#endif\n\t#ifndef VERIFYNORETURN\n\t\t#define VERIFYNORETURN VERIFY\n\t#endif\n\t#ifndef VERIFYCRITICALPRED\n\t\t#define VERIFYCRITICALPRED VERIFYPRED\n\t#endif\n\t#ifndef VERIFYNOTIFYPRED\n\t\t#define VERIFYNOTIFYPRED VERIFYPRED\n\t#endif\n\t#ifndef NOBADALLOC\n\t\t#define NOBADALLOC( expr ) (expr)\n\t#endif\n\t#ifndef NOEXCEPT\n\t\t#define NOEXCEPT( ... ) \\\n\t\t\t[&]() noexcept -> decltype(auto) { \\\n\t\t\t\treturn (__VA_ARGS__); \\\n\t\t\t}()\n\t#endif\n\t#ifndef NOEXCEPT_NO_LAMBDA\n\t\t#define NOEXCEPT_NO_LAMBDA( ... ) (__VA_ARGS__)\n\t#endif\n\n\t#define switch_no_default(...) \\\n\tswitch( auto const& /*lifetime extended until end of switch block*/ __switch=(__VA_ARGS__) ) \\\n\tdefault: \\\n\t\tif ( _ASSERTFALSE, false ) {std::abort(); /*never executed, but the compiler might complain about this code path not returning a value*/} \\\n\t\telse\n\n\tnamespace tc {\n\t\ttemplate<typename T>\n\t\tT construct_default_or_terminate() noexcept {\n\t\t\tif constexpr( !std::is_void<T>::value ) {\n\t\t\t\tif constexpr( std::is_default_constructible<T>::value ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn T();\n\t\t\t\t\t} catch ( ... ) {}\n\t\t\t\t}\n\t\t\t\tstd::abort(); // same behavior as violated noexcept\n\t\t\t}\n\t\t}\n\t}\n#endif\n"
  },
  {
    "path": "tc/base/bit_cast.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"casts.h\"\n#include \"../range/subrange.h\"\n#include \"../array.h\"\n#include <boost/range/algorithm/copy.hpp>\n\n//-----------------------------------------------------------------------------------------------------------------------------\n\nnamespace tc {\n\n\t//--------------------------------------------------------------------------------------------------------------------------\n\t// as_blob\n\t// reinterprets a range of items as a range of bytes\n\n\t// We use unsigned char for uninterpreted memory.\n\t// - The type used must support aliasing, so the only candidates are char, signed char and unsigned char.\n\t// - char is bad because we interpret char as UTF-8 and char* as zero-terminated range.\n\t// - unsigned char is better than signed char because the binary representation of signs may vary between platforms.\n\t// - char is bad because it is either signed or unsigned, so it has the same problem.\n\t// - unsigned char is better than std::uint8_t because the latter must be 8 bit, but we mean the smallest addressable unit, which is char and may be larger (or smaller?) on other platforms.\n\n\tstatic_assert(!tc::range_with_iterators< void const* >);\n\n\tnamespace range_as_blob_detail {\n\t\t// not static local lambda to workaround MSVC bugs: 1. static local instantiation. 2. reference to constexpr\n\t\tauto as_blob_ptr(auto ptr) noexcept {\n\t\t\treturn reinterpret_cast<same_cvref_t<unsigned char, std::remove_pointer_t<decltype(ptr)>>*>(ptr);\n\t\t};\n\t}\n\n\ttemplate<tc::contiguous_range Rng>\n\t[[nodiscard]] auto range_as_blob(Rng&& rng) noexcept {\n\t\tusing cv_value_type = std::remove_pointer_t<decltype(tc::ptr_begin(rng))>;\n\t\tstatic_assert( std::is_trivially_copyable< cv_value_type >::value, \"as_blob only works on std::is_trivially_copyable types\" );\n\t\tif constexpr(tc::safely_constructible_from<tc::span<cv_value_type>, Rng>) {\n\t\t\treturn tc::make_iterator_range(\n\t\t\t\treinterpret_cast<same_cvref_t<unsigned char, cv_value_type>*>(tc::ptr_begin(rng)),\n\t\t\t\treinterpret_cast<same_cvref_t<unsigned char, cv_value_type>*>(tc::ptr_end(rng))\n\t\t\t);\n\t\t} else {\n\t\t\tstruct blob_range_t final {\n\t\t\t\texplicit blob_range_t(Rng&& rng) noexcept : m_rng(tc_move(rng)) {}\n\t\t\t\tauto begin() & noexcept { return range_as_blob_detail::as_blob_ptr(tc::ptr_begin(m_rng)); }\n\t\t\t\tauto begin() const& noexcept { return range_as_blob_detail::as_blob_ptr(tc::ptr_begin(m_rng)); }\n\t\t\t\tauto end() & noexcept { return range_as_blob_detail::as_blob_ptr(tc::ptr_end(m_rng)); }\n\t\t\t\tauto end() const& noexcept { return range_as_blob_detail::as_blob_ptr(tc::ptr_end(m_rng)); }\n\t\t\tprivate:\n\t\t\t\tstatic_assert(!std::is_reference<Rng>::value);\n\t\t\t\tstd::remove_cv_t<Rng> m_rng;\n\t\t\t};\n\t\t\treturn blob_range_t(tc_move(rng));\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Sink>\n\t\tstruct range_as_blob_sink { // no final: verify_sink_result_impl derives\n\t\tprivate:\n\t\t\t// range_as_blob_sink is only used inline in range_as_blob below, and m_sink is only passed to tc::for_each, so holding by lvalue reference ok\n\t\t\tSink& m_sink;\n\n\t\tpublic:\n\t\t\texplicit range_as_blob_sink(Sink& sink) noexcept: m_sink(sink) {}\n\n\t\t\t// chunk must be defined before operator() - otherwise MSVC will not allow it to occur in the return type of operator()\n\t\t\ttemplate<tc::contiguous_range Rng>\n\t\t\tauto chunk(Rng&& rng) const& return_decltype_MAYTHROW (\n\t\t\t\ttc::for_each(tc::range_as_blob(tc_move_if_owned(rng)), m_sink)\n\t\t\t)\n\n\t\t\ttemplate<typename T>\n\t\t\tauto operator()(T&& t) const& return_decltype_MAYTHROW (\n\t\t\t\tchunk(tc::single(/* no tc_move_if_owned */ t))\n\t\t\t)\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] auto range_as_blob(Rng&& rng) noexcept {\n\t\treturn [rng=tc::make_reference_or_value(tc_move_if_owned(rng))](auto&& sink) MAYTHROW {\n\t\t\treturn tc::for_each(*rng, no_adl::range_as_blob_sink<std::remove_reference_t<decltype(sink)>>(sink));\n\t\t};\n\t}\n\n\ttemplate<typename T> requires std::is_trivially_copyable<std::remove_reference_t<T>>::value\n\t[[nodiscard]] auto as_blob(T&& t) noexcept {\n\t\treturn tc::range_as_blob( tc::single( tc_move_if_owned(t) ) );\n\t}\n\n\tnamespace assert_no_overlap_impl {\n\t\tvoid assert_no_overlap(auto const& lhs, auto const& rhs) noexcept {\n\t\t\t_ASSERT(\n\t\t\t\treinterpret_cast<std::size_t>(tc::ptr_end(lhs)) <= reinterpret_cast<std::size_t>(tc::ptr_begin(rhs)) ||\n\t\t\t\treinterpret_cast<std::size_t>(tc::ptr_end(rhs)) <= reinterpret_cast<std::size_t>(tc::ptr_begin(lhs))\n\t\t\t);\n\t\t}\n\t}\n\ttemplate< typename Lhs, typename Rhs>\n\tvoid assert_no_overlap(Lhs const& lhs, Rhs const& rhs) noexcept {\n\t\tassert_no_overlap_impl::assert_no_overlap(tc::single(lhs), tc::single(rhs));\n\t\tif constexpr( tc::contiguous_range<Lhs> && tc::contiguous_range<Rhs> ) {\n\t\t\tassert_no_overlap_impl::assert_no_overlap(lhs, rhs);\n\t\t}\n\t}\n\n\t/////////////////////////////////////////////\n\t// bit_cast\n\n\tnamespace no_adl {\n\t\tstruct any_ptr_ref final: tc::nonmovable {\n\t\tprivate:\n\t\t\tvoid* m_pv;\n\t\tpublic:\n\t\t\texplicit any_ptr_ref(void* pv) noexcept: m_pv(pv) {}\n\n\t\t\ttemplate<typename T> requires std::same_as<std::remove_cvref_t<T>, T> && std::is_trivially_copyable<T>::value\n\t\t\toperator T() && noexcept {\n\t\t\t\tT t;\n\t\t\t\tstd::memcpy(std::addressof(t), m_pv, sizeof(t));\n\t\t\t\treturn t;\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace any_ptr_adl {\n\t\tstruct any_ptr final {\n\t\tprivate:\n\t\t\tvoid* m_pv;\n\t\tpublic:\n\t\t\tany_ptr( void* pv ) noexcept\n\t\t\t:\tm_pv(pv)\n\t\t\t{}\n\n\t\t\texplicit operator bool() const& noexcept {\n\t\t\t\treturn m_pv;\n\t\t\t}\n\n\t\t\tauto operator*() const& noexcept {\n\t\t\t\treturn tc::no_adl::any_ptr_ref(m_pv);\n\t\t\t}\n\n\t\t\ttemplate<typename T> requires std::is_pointer<T>::value || std::is_member_pointer<T>::value\n\t\t\toperator T() const& noexcept {\n\t\t\t\tSTATICASSERTEQUAL(sizeof(T), sizeof(void*));\n\t\t\t\tT t;\n\t\t\t\tstd::memcpy( std::addressof(t), std::addressof(m_pv), sizeof(t) ); // bit_cast to allow cast to member function pointers\n\t\t\t\treturn t;\n\t\t\t}\n\t\t};\n\t}\n\tusing any_ptr_adl::any_ptr;\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct type {\n\t\tprivate:\n\t\t\tsame_cvref_t<unsigned char,T>* m_pb;\n\t\tpublic:\n\t\t\texplicit type(same_cvref_t<unsigned char,T>* pb) noexcept\n\t\t\t: m_pb(pb)\n\t\t\t{}\n\t\t\texplicit type(tc::any_ptr p) noexcept\n\t\t\t: m_pb(p)\n\t\t\t{}\n\t\t\toperator std::remove_cv_t<T>() const& noexcept {\n\t\t\t\tstd::remove_cv_t<T> t;\n\t\t\t\tstd::memcpy( std::addressof(t), m_pb, sizeof(t) );\n\t\t\t\treturn t;\n\t\t\t}\n\t\t\ttype const& operator=( std::remove_cv_t<T> const& rhs ) const& noexcept {\n\t\t\t\tboost::copy( tc::as_blob(rhs), m_pb );\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename T, bool bPreventSlicing>\n\t\tstruct decay<no_adl::type<T>, bPreventSlicing> {\n\t\t\tusing type=typename tc::decay<T, bPreventSlicing>::type; // recursive\n\t\t};\n\t}\n\n\ttemplate<typename T>\n\tstruct aliasing_ref final {\n\t\tstatic_assert( !std::is_reference<T>::value );\n\t\tstatic_assert( std::is_trivially_copyable<T>::value );\n\t\tusing type=no_adl::type<T>;\n\t\tstatic type construct(same_cvref_t<unsigned char,T>* pb) noexcept {\n\t\t\treturn type(pb);\n\t\t}\n\t};\n\n\ttemplate<typename T>\n\tstruct aliasing_ref<T const> final {\n\t\tstatic_assert( !std::is_reference<T>::value );\n\t\tstatic_assert( std::is_trivially_copyable<T>::value );\n\t\tusing type = std::remove_cv_t<T>;\n\t\tstatic type construct(same_cvref_t<unsigned char,T const>* pb) noexcept {\n\t\t\ttype t;\n\t\t\tstd::memcpy( std::addressof(t), pb, sizeof(t) );\n\t\t\treturn t;\n\t\t}\n\t};\n\n\ttemplate< typename T>\n\tstruct aliasing_ptr final {\n\t\tstatic_assert( !std::is_reference<T>::value );\n\t\tstatic_assert( std::is_trivially_copyable<T>::value );\n\t\tstruct type {\n\t\tprivate:\n\t\t\tsame_cvref_t<unsigned char,T>* m_pb;\n\t\tpublic:\n\t\t\ttype() noexcept {}\n\t\t\texplicit type(T* pt) noexcept\n\t\t\t: m_pb(reinterpret_cast<same_cvref_t<unsigned char,T>*>(pt))\n\t\t\t{}\n\t\t\texplicit operator bool() const& noexcept {\n\t\t\t\treturn m_pb;\n\t\t\t}\n\t\t\ttype& operator=(std::nullptr_t) & noexcept {\n\t\t\t\tm_pb=nullptr;\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttypename aliasing_ref<T>::type operator*() const& noexcept {\n\t\t\t\treturn aliasing_ref<T>::construct(m_pb);\n\t\t\t}\n\t\t\ttype& operator+=( std::ptrdiff_t n ) & noexcept {\n\t\t\t\tm_pb+=n*static_cast<std::ptrdiff_t>(sizeof(T)); // cast to signed ptrdiff_t to silence UB sanitizer\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttype& operator-=( std::ptrdiff_t n ) & noexcept {\n\t\t\t\treturn *this+=-n;\n\t\t\t}\n\t\t\ttemplate< typename Offset > friend type operator+( type ptr, Offset n ) noexcept {\n\t\t\t\treturn ptr+=n;\n\t\t\t}\n\t\t\ttemplate< typename Offset > friend type operator-( type ptr, Offset n ) noexcept {\n\t\t\t\treturn ptr-=n;\n\t\t\t}\n\t\t\ttypename aliasing_ref<T>::type operator[]( std::ptrdiff_t n ) const& noexcept {\n\t\t\t\treturn *(*this+n);\n\t\t\t}\n\t\t};\n\t};\n\n\ttemplate< typename T > requires std::is_function<T>::value\n\tstruct aliasing_ptr<T> final {\n\t\tusing type = T*;\n\t};\n\n\ttemplate<>\n\tstruct aliasing_ptr<char> final {\n\t\tusing type = char*;\n\t};\n\n\ttemplate<>\n\tstruct aliasing_ptr<char const> final {\n\t\tusing type = char const*;\n\t};\n\n\ttemplate<>\n\tstruct aliasing_ptr<unsigned char> final {\n\t\tusing type = unsigned char*;\n\t};\n\n\ttemplate<>\n\tstruct aliasing_ptr<unsigned char const> final {\n\t\tusing type = unsigned char const*;\n\t};\n\n\ttemplate<typename Dst, tc::contiguous_range Src>\n\t[[nodiscard]] Dst bit_cast_range(Src const& src) noexcept {\n\t\ttc_auto_cref(rng, tc::range_as_blob(src));\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst);\n\t\t_ASSERTEQUAL(tc::size(rng), sizeof(Dst));\n\t\tstatic_assert(std::is_trivially_copyable< Dst >::value);\n\t\tDst dst;\n\t\tstd::memcpy(std::addressof(dst), tc::ptr_begin(rng), sizeof(dst));\n\t\treturn dst;\n\t}\n\n\t// no danger of aliasing\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] constexpr Dst bit_cast(Src const& src) noexcept {\n\t\tstatic_assert( !std::is_pointer<Src>::value || !std::is_pointer<Dst>::value );\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst );\n\t\tSTATICASSERTEQUAL(sizeof(Dst), sizeof(Src), \"bit_cast source and destination must be same size\");\n\t\tstatic_assert(std::is_trivially_copyable<Dst>::value && std::is_trivially_copyable<Src>::value);\n\t\t// Visual Studio use __builtin_bit_cast to implement std::bit_cast.\n\t\t// clang has __builtin_bit_cast but does not support std::bit_cast (Xcode 13).\n\t\treturn __builtin_bit_cast(Dst, src);\n\t}\n\n\t// danger of aliasing\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] typename aliasing_ptr<std::remove_pointer_t<Dst>>::type aliasing_cast(Src const& src) noexcept {\n\t\tstatic_assert( std::is_pointer<Src>::value );\n\t\tstatic_assert( std::is_pointer<Dst>::value );\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst);\n\t\treturn typename aliasing_ptr<std::remove_pointer_t<Dst>>::type(reinterpret_cast<Dst>(src));\n\t}\n}\n"
  },
  {
    "path": "tc/base/bitfield.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n\n#include <bit>\n#include <limits>\n\n#if defined(_MSC_VER) && defined(_M_ARM64EC)\n#include <intrin.h>\n#endif\n\nnamespace tc {\n\ttemplate<typename Uint>\n\t[[nodiscard]] constexpr int index_of_least_significant_bit(Uint u) noexcept {\n\t\treturn std::countr_zero(VERIFYPRED(u, 0 != _));\n\t}\n\n\ttemplate<typename Uint>\n\t[[nodiscard]] constexpr Uint least_significant_bit(Uint u) noexcept {\n\t\tstatic_assert( std::is_unsigned<Uint>::value );\nMODIFY_WARNINGS_BEGIN(((disable)(4146))) // unary minus operator applied to unsigned type, result still unsigned\n\t\treturn u & -u;\nMODIFY_WARNINGS_END\n\t}\n\n\ttemplate<typename Uint>\n\t[[nodiscard]] constexpr int index_of_most_significant_bit(Uint u) noexcept {\n\t\t// return std::bit_width() - 1;\n\t\treturn std::numeric_limits<Uint>::digits - 1 - std::countl_zero(VERIFYPRED(u, 0 != _));\n\t}\n\n\ttemplate<typename Uint>\n\t[[nodiscard]] constexpr Uint most_significant_bit(Uint u) noexcept {\n\t\t// return std::bit_floor(u);\n\t\tif( 0 == u ) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn Uint{1} << tc::index_of_most_significant_bit(u);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/base/bitfield.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n\n#include \"assert_defs.h\"\n#include \"bitfield.h\"\n#include \"../unittest.h\"\n\nnamespace {\n\tauto constexpr nAllBitsSet = static_cast<unsigned int>(-1);\n}\n\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(nAllBitsSet), 0 );\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(0x00000001u), 0 );\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(0x00018000u), 15 );\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(0x000ff000u), 12 );\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(0x80000000u), 31 );\nSTATICASSERTEQUAL( tc::index_of_least_significant_bit(0x80000001u), 0 );\n\nSTATICASSERTEQUAL( tc::least_significant_bit(0u), 0u );\nSTATICASSERTEQUAL( tc::least_significant_bit(nAllBitsSet), 1u );\nSTATICASSERTEQUAL( tc::least_significant_bit(0x00000001u), 0x00000001u );\nSTATICASSERTEQUAL( tc::least_significant_bit(0x00018000u), 0x00008000u );\nSTATICASSERTEQUAL( tc::least_significant_bit(0x000ff000u), 0x00001000u );\nSTATICASSERTEQUAL( tc::least_significant_bit(0x80000000u), 0x80000000u );\nSTATICASSERTEQUAL( tc::least_significant_bit(0x80000001u), 0x00000001u );\n\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(nAllBitsSet), std::numeric_limits<unsigned int>::digits - 1 );\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(0x00000001u), 0 );\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(0x00018000u), 16 );\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(0x000ff000u), 19 );\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(0x80000000u), 31 );\nSTATICASSERTEQUAL( tc::index_of_most_significant_bit(0x80000001u), 31 );\n\nSTATICASSERTEQUAL( tc::most_significant_bit(0u), 0u );\nSTATICASSERTEQUAL( tc::most_significant_bit(nAllBitsSet), 1u << ( sizeof(nAllBitsSet)*CHAR_BIT-1 ) );\nSTATICASSERTEQUAL( tc::most_significant_bit(0x00000001u), 0x00000001u );\nSTATICASSERTEQUAL( tc::most_significant_bit(0x00018000u), 0x00010000u );\nSTATICASSERTEQUAL( tc::most_significant_bit(0x000ff000u), 0x00080000u );\nSTATICASSERTEQUAL( tc::most_significant_bit(0x80000000u), 0x80000000u );\nSTATICASSERTEQUAL( tc::most_significant_bit(0x80000001u), 0x80000000u );\n"
  },
  {
    "path": "tc/base/casts.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"functors.h\"\n#include \"explicit_cast_fwd.h\"\n\n#include <boost/integer.hpp>\n#ifndef __EMSCRIPTEN__\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\" // sprintf is deprecated in Xcode14.1 RC\n#endif\n#include <boost/filesystem/path.hpp>\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n#endif\n\n#include <type_traits>\n\n//-----------------------------------------------------------------------------------------------------------------------------\n\nnamespace tc {\n\t//-------------------------------------------------------------------------------------------------------------------------\n\n\t/////////////////////////////////////////////\n\t// base_cast\n\t// (cannot be implemented like derived_cast because when deriving protected, derived to base cast is often publicly inaccessible)\n\n\t#pragma push_macro(\"BASE_CAST_IMPL\")\n\t#define BASE_CAST_IMPL(cvref) \\\n\ttemplate<typename Dst> requires std::is_class<Dst>::value \\\n\t[[nodiscard]] constexpr Dst cvref base_cast(typename std::type_identity<Dst>::type cvref t) noexcept { \\\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst); \\\n\t\treturn static_cast<Dst cvref>(t); \\\n\t}\n\tBASE_CAST_IMPL(&)\n\tBASE_CAST_IMPL(&&)\n\tBASE_CAST_IMPL(*)\n\tBASE_CAST_IMPL(const&)\n\tBASE_CAST_IMPL(const&&)\n\tBASE_CAST_IMPL(const*)\n\tBASE_CAST_IMPL(volatile&)\n\tBASE_CAST_IMPL(volatile&&)\n\tBASE_CAST_IMPL(volatile*)\n\tBASE_CAST_IMPL(volatile const&)\n\tBASE_CAST_IMPL(volatile const&&)\n\tBASE_CAST_IMPL(volatile const*)\n\t#pragma pop_macro(\"BASE_CAST_IMPL\")\n\n\t/////////////////////////////////////////////\n\t// derived_cast\n\t\n\tnamespace derived_cast_detail {\n\t\ttemplate<typename To, typename From>\n\t\tconstexpr void check_derived_cast(From const& obj) noexcept {\n\t\t\tif constexpr (!std::is_same<To, From>::value && std::is_polymorphic<From>::value) {\n\t\t\t\t_ASSERT(dynamic_cast<To const*>(std::addressof(obj)));\n\t\t\t}\n\t\t}\n\n\t\tnamespace derived_cast_internal_default {\n\t\t\ttemplate<typename To, typename From, bool bChecked>\n\t\t\t[[nodiscard]] constexpr same_cvref_t< To, From&&> derived_cast_internal_impl(std::type_identity<To>, From&& t, std::bool_constant<bChecked>) noexcept {\n\t\t\t\tstatic_assert( tc::derived_from<To, std::remove_reference_t<From>>, \"derived_cast is for downcasts only.\");\n\t\t\t\tif constexpr (bChecked) {\n\t\t\t\t\tcheck_derived_cast<To>(t);\n\t\t\t\t}\n\t\t\t\treturn static_cast< apply_cvref_t< To, From&&> >(t);\n\t\t\t}\n\n\t\t\ttemplate<typename To, typename From, bool bChecked>\n\t\t\t[[nodiscard]] constexpr same_cvref_t< To, From>* derived_cast_internal_impl(std::type_identity<To>, From* pt, std::bool_constant<bChecked>) noexcept {\n\t\t\t\tstatic_assert( tc::derived_from<To, std::remove_pointer_t<From>>, \"derived_cast is for downcasts only.\");\n\t\t\t\tif constexpr (bChecked) {\n\t\t\t\t\tif (nullptr != pt) check_derived_cast<To>(*pt);\n\t\t\t\t}\n\t\t\t\treturn static_cast< apply_cvref_t< To, From>* >(pt);\n\t\t\t}\n\t\t}\n\n\t\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(derived_cast_internal)\n\t}\n\n\ttemplate<typename To, typename From>\n\t[[nodiscard]] constexpr decltype(auto) derived_cast(From&& t) noexcept {\n\t\tSTATICASSERTSAME(std::remove_reference_t<To>, To);\n\t\treturn tc::derived_cast_detail::derived_cast_internal(std::type_identity<To>(), tc_move_if_owned(t), /*bChecked*/tc::constant<true>());\n\t}\n\n\ttemplate<typename To, typename From>\n\t[[nodiscard]] constexpr decltype(auto) unchecked_derived_cast(From&& t) noexcept {\n\t\tSTATICASSERTSAME(std::remove_reference_t<To>, To);\n\t\treturn tc::derived_cast_detail::derived_cast_internal(std::type_identity<To>(), tc_move_if_owned(t), /*bChecked*/tc::constant<false>());\n\t}\n\n\t/////////////////////////////////////////////\n\t// to_underlying\n\n\tnamespace to_underlying_default {\n\t\ttemplate< tc::char_type T >\n\t\t[[nodiscard]] constexpr auto to_underlying_impl(T t)\n\t\t\treturn_decltype_noexcept( static_cast<typename boost::uint_t<sizeof(T)*8>::exact>(t) )\n\n\t\ttemplate< tc::enum_type T >\n\t\t[[nodiscard]] constexpr auto to_underlying_impl( T e ) noexcept {\n\t\t\treturn static_cast<std::underlying_type_t<T>>(e);\n\t\t}\n\n\t\t// No implicit conversions to bool\n\t\ttemplate< std::same_as<bool> T >\n\t\t[[nodiscard]] constexpr auto to_underlying_impl(T b) noexcept {\n\t\t\tSTATICASSERTEQUAL(sizeof(bool), sizeof(unsigned char));\n\t\t\treturn static_cast<unsigned char>(b);\n\t\t}\n\t}\n\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(to_underlying)\n\n\ttemplate<typename T>\n\tusing underlying_type_t = decltype(tc::to_underlying(std::declval<T>()));\n\n\tnamespace from_underlying_detail {\n\t\tnamespace from_underlying_default {\n\t\t\ttemplate< tc::char_type T >\n\t\t\t[[nodiscard]] constexpr auto from_underlying_impl(std::type_identity<T>, underlying_type_t<T> t) noexcept {\n\t\t\t\t// We don't need to do any checks, the underlying type has the same size.\n\t\t\t\treturn static_cast<T>(t);\n\t\t\t}\n\n\t\t\ttemplate< tc::enum_type T >\n\t\t\t[[nodiscard]] constexpr auto from_underlying_impl(std::type_identity<T>, underlying_type_t<T> e) noexcept {\n\t\t\t\t// We cannot do checks on arbitrary enums; there's a specialization for contiguous enums.\n\t\t\t\treturn static_cast<T>(e);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr auto from_underlying_impl(std::type_identity<bool>, underlying_type_t<bool> b) noexcept {\n\t\t\t\t_ASSERTANYOF(b, (0)(1));\n\t\t\t\treturn static_cast<bool>(b);\n\t\t\t}\n\t\t}\n\n\t\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(from_underlying)\n\t}\n\n\ttemplate<typename T, typename U>\n\t\trequires tc::explicit_castable_from<tc::underlying_type_t<T>, U>\n\t[[nodiscard]] constexpr T from_underlying(const U& value) return_MAYTHROW(\n\t\tfrom_underlying_detail::from_underlying(std::type_identity<T>{}, tc::explicit_cast<tc::underlying_type_t<T>>(value))\n\t)\n\n\t/////////////////////////////////////////////\n\t// as_unsigned/signed\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr auto as_unsigned(T t) noexcept code_return_decltype(\n\t\tstatic_assert( tc::actual_integer<T> );\n\t\t_ASSERTE( 0<=t );,\n\t\tstatic_cast<std::make_unsigned_t<T>>(t)\n\t)\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr std::make_signed_t<T> as_signed(T t) noexcept {\n\t\tstatic_assert( tc::actual_integer<T> );\n\t\tif constexpr (!std::is_signed<T>::value) {\n\t\t\t_ASSERTE(t <= tc::as_unsigned(std::numeric_limits<std::make_signed_t<T>>::max()));\n\t\t}\n\t\treturn static_cast<std::make_signed_t<T>>(t);\n\t}\n\n#define tc_decay_bitfield(...) \\\n\t([&](auto char_const_volatile) noexcept { \\\n\t\tusing BitfieldBaseType = std::remove_reference_t<decltype((__VA_ARGS__))>; \\\n\t\tstatic_assert( \\\n\t\t\t(tc::actual_integer<BitfieldBaseType> || tc::enum_type<BitfieldBaseType>) && \\\n\t\t\t/* Taking the address of a bit-field is disallowed and a non-const reference cannot bind to a bit-field. */ \\\n\t\t\t!requires { reinterpret_cast<typename decltype(char_const_volatile)::type&>(__VA_ARGS__); }, \\\n\t\t\t\"\\\"\" #__VA_ARGS__ \"\\\" is not a bit field\" \\\n\t\t); \\\n\t\treturn __VA_ARGS__; \\\n\t})(std::type_identity<char const volatile>{})\n\n\t/////////////////////////////////////////////\n\t// const casts\n\n\tMODIFY_WARNINGS_BEGIN(((disable)(4180))) // qualifier applied to function type has no meaning; ignored\n\n\t\ttemplate <typename T>\n\t\t[[nodiscard]] constexpr T const& as_const(T& t) noexcept { // intention is to avoid side-effects\n\t\t\treturn static_cast<T const&>(t);\n\t\t}\n\t\ttemplate <typename T, unsigned Lifetime>\n\t\t[[nodiscard]] constexpr T const& as_const(tc::temporary<T, Lifetime>& tmp) noexcept {\n\t\t\treturn static_cast<T const&>(tmp);\n\t\t}\n\n\t\ttemplate <typename T> requires std::is_rvalue_reference<T&&>::value\n\t\t[[nodiscard]] constexpr T&& as_const(T&& t) noexcept { // needed in generic code when both values and references can occur\n\t\t\tstatic_assert(!std::is_lvalue_reference<T&&>::value);\n\t\t\treturn static_cast<T&&>(t);\n\t\t}\n\n\t\ttemplate< typename T >\n\t\t[[nodiscard]] constexpr std::remove_const_t<T>& as_mutable(T& t) noexcept {\n\t\t\treturn const_cast<std::remove_const_t<T>&>(t);\n\t\t}\n\n\tMODIFY_WARNINGS_END\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T const* as_const_ptr( T const* pt ) noexcept {\n\t\treturn pt;\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T* as_mutable_ptr( T const* pt ) noexcept {\n\t\treturn const_cast<T*>(pt);\n\t}\n\n\t/////////////////////////////////////////////\n\t// void_cast\n\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] Dst* void_cast(Src* p) noexcept{\n\t\tstatic_assert(std::is_void<Src>::value,\"Src must be possibly qualified void*\");\n\t\tstatic_assert(!std::is_reference<Dst>::value);\n\t\t// static_assert(!std::is_void<Dst>::value); // practical for generic code to allow it\n\t\treturn static_cast<Dst*>(p);\n\t}\n\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] Dst const* void_cast(Src const* p) noexcept{\n\t\tstatic_assert(std::is_void<Src>::value,\"Src must be possibly qualified void*\");\n\t\tstatic_assert(!std::is_reference<Dst>::value);\n\t\t// static_assert(!std::is_void<Dst>::value); // practical for generic code to allow it\n\t\treturn static_cast<Dst const*>(p);\n\t}\n\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] Dst volatile* void_cast(Src volatile* p) noexcept{\n\t\tstatic_assert(std::is_void<Src>::value,\"Src must be possibly qualified void*\");\n\t\tstatic_assert(!std::is_reference<Dst>::value);\n\t\t// static_assert(!std::is_void<Dst>::value); // practical for generic code to allow it\n\t\treturn static_cast<Dst volatile*>(p);\n\t}\n\n\ttemplate<typename Dst, typename Src>\n\t[[nodiscard]] Dst volatile const* void_cast(Src volatile const* p) noexcept{\n\t\tstatic_assert(std::is_void<Src>::value,\"Src must be possibly qualified void*\");\n\t\tstatic_assert(!std::is_reference<Dst>::value);\n\t\t// static_assert(!std::is_void<Dst>::value); // practical for generic code to allow it\n\t\treturn static_cast<Dst volatile const*>(p);\n\t}\n\n\t/////////////////////////////////////////////\n\t// implicit_cast\n\n\ttemplate<typename TTarget, typename TSource> requires (!tc::actual_integer<std::remove_reference_t<TSource>>) && tc::safely_convertible_to<TSource&&, TTarget>\n\t[[nodiscard]] constexpr TTarget implicit_cast(TSource&& src) noexcept {\n\t\treturn tc_move_if_owned(src);\n\t}\n\n\t// bit filed cannot bind to universal reference\nMODIFY_WARNINGS_BEGIN(((disable)(4244))) // disable warning C4244: conversion from 'int' to 'float', possible loss of data\n\ttemplate<typename TTarget, typename TSource> requires tc::actual_integer<TSource> && tc::safely_convertible_to<TSource&&, TTarget>\n\t[[nodiscard]] constexpr TTarget implicit_cast(TSource src) noexcept {\n\t\treturn src;\n\t}\nMODIFY_WARNINGS_END\n\n\t/////////////////////////////////////////////\n\t// reluctant_implicit_cast\n\t// Returns a reference to its argument whenever possible, otherwise performs an implicit conversion.\n\n\ttemplate<typename TTarget, typename TSource>\n\t[[nodiscard]] std::conditional_t<\n\t\ttc::decayed_derived_from<TSource, TTarget>,\n\t\tTSource&&,\n\t\tTTarget\n\t> reluctant_implicit_cast(TSource&& src) noexcept {\n\t\tSTATICASSERTSAME(std::remove_cvref_t<TTarget>, TTarget);\n\t\treturn tc_move_if_owned(src);\n\t}\n\n\t/////////////////////////////////////////////\n\t// as_c_str\n\tnamespace as_c_str_default {\n\t\ttemplate< typename Char, typename Traits, typename Alloc >\n\t\t[[nodiscard]] Char const* as_c_str_impl(std::basic_string< Char, Traits, Alloc > const& str) noexcept\n\t\t{\n\t\t\treturn str.data(); // since C++ 11, performs same function as c_str(). cannot use tc::ptr_begin to avoid circular dependency\n\t\t}\n\n\t\ttemplate< typename Char, typename Traits, typename Alloc >\n\t\t[[nodiscard]] Char* as_c_str_impl(std::basic_string< Char, Traits, Alloc >& str) noexcept\n\t\t{\n\t\t\treturn str.data(); // since C++ 11, performs same function as c_str(). cannot use tc::ptr_begin to avoid circular dependency\n\t\t}\n\n\t\ttemplate< typename Char, typename Traits, typename Alloc >\n\t\t[[nodiscard]] Char* as_c_str_impl(std::basic_string< Char, Traits, Alloc >&& str) noexcept\n\t\t{\n\t\t\treturn str.data(); // since C++ 11, performs same function as c_str(). cannot use tc::ptr_begin to avoid circular dependency\n\t\t}\n\n\t\ttemplate<tc::char_type Char>\n\t\t[[nodiscard]] constexpr Char const* as_c_str_impl(Char const* psz) noexcept {\n\t\t\treturn psz;\n\t\t}\n\n\t\ttemplate<tc::char_type Char>\n\t\t[[nodiscard]] constexpr Char* as_c_str_impl(Char* psz) noexcept {\n\t\t\treturn psz;\n\t\t}\n\n\t#ifdef TC_PRIVATE\n\t\t// Prevents implicit conversion from std::vector<wchar_t> to boost::filesystem::path on Windows, which causes a dangling pointer to be returned\n\t\ttemplate<typename T> requires std::is_same<T, boost::filesystem::path>::value\n\t\t[[nodiscard]] inline boost::filesystem::path::value_type const* as_c_str_impl(T const& fspath) noexcept {\n\t\t\treturn fspath.c_str();\n\t\t}\n\t#endif\n\t}\n\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(as_c_str)\n}\n\n"
  },
  {
    "path": "tc/base/casts.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"casts.h\"\n#include \"../unittest.h\"\n\n#include <utility>\n\nnamespace {\n\t[[maybe_unused]] void static_tests_as_const() {\n\t\tint value;\n\t\ttc::temporary<int, 0> tmp(value);\n\n\t\tSTATICASSERTSAME(decltype(tc::as_const(value)), int const&);\n\t\tSTATICASSERTSAME(decltype(tc::as_const(tmp)), int const&);\n\t\tSTATICASSERTSAME(decltype(tc::as_const(0)), int&&);\n\t\tSTATICASSERTSAME(decltype(tc::as_const(tc::temporary<int, 0>(0))), TC_FWD(tc::temporary<int, 0>&&));\n\t}\n}\n\nnamespace {\n\tstruct base{};\n\tstruct derived final : base{};\n}\n\nUNITTESTDEF(DerivedCastTests) {\n\tbase b;\n\tderived& d = tc::derived_cast<derived>(b);\n\t_ASSERTEQUAL(std::addressof(b), std::addressof(d));\n\n\tderived&& drref = tc::derived_cast<derived>(tc_move_if_owned(b));\n\t_ASSERTEQUAL(std::addressof(b), std::addressof(drref));\n}\n"
  },
  {
    "path": "tc/base/chained.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"invoke.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\t// Function pointers have disadvantages over function objects, in particular when being aggregated in wrapper objects:\n\t\t// - Invokation through a function pointer usually results in an extra indirection (like a virtual function call),\n\t\t//   unless the compiler can figure out the address is constant over the entire lifetime of the wrapper. Note that\n\t\t//   this is hard to prove for the compiler: The type of the wrapper is independent of the function address, so they\n\t\t//   might be assigned from wrappers of the same type, storing pointers to different addresses.\n\t\t// - Many wrappers in our library support default construction (which is useful when used with STL or Boost containers).\n\t\t//   Default construction would leave a function pointer unintitialized!\n\t\ttemplate<typename T>\n\t\tstruct verify_functor final{\n\t\t\t// TODO: We would like to verify specifically that T is a class or lambda, but unfortunately\n\t\t\t// there is no trait to test for the latter. For now, just blacklist (function-)pointers here,\n\t\t\t// as other types are not callable, anyway.\n\t\t\tstatic_assert(!std::is_pointer<T>::value, \"Do not pass raw function pointer as functor. Use tc_fn instead.\");\n\t\t\tusing type=T;\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tusing verify_functor_t=typename verify_functor<T>::type;\n\t}\n\tusing no_adl::verify_functor_t;\n\n\tnamespace no_adl {\n\t\ttemplate <typename FuncSecond, typename FuncFirst>\n\t\tstruct [[nodiscard]] chained_impl /*not final*/ {\n\t\t\ttc::verify_functor_t<tc::decay_t<FuncSecond>> m_funcSecond;\n\t\t\ttc::verify_functor_t<tc::decay_t<FuncFirst>> m_funcFirst;\n\n\t\t\ttemplate <typename... Args>\n\t\t\tconstexpr auto operator()(Args&&... args) const& return_decltype_allow_xvalue_slow_MAYTHROW(\n\t\t\t\ttc_invoke(m_funcSecond, tc_invoke_pack(m_funcFirst, tc_move_if_owned(args)))\n\t\t\t)\n\n\t\t\tconstexpr auto inverted() const& MAYTHROW {\n\t\t\t\treturn chained_impl<decltype(m_funcFirst.inverted()), decltype(m_funcSecond.inverted())>{\n\t\t\t\t\tm_funcFirst.inverted(),\n\t\t\t\t\tm_funcSecond.inverted()\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tusing is_transparent = void;\n\t\t};\n\t}\n\n\ttemplate <typename FuncSecond, typename FuncFirst>\n\tconstexpr auto chained(FuncSecond&& funcSecond, FuncFirst&& funcFirst) noexcept {\n\t\treturn no_adl::chained_impl<FuncSecond, FuncFirst>{tc_move_if_owned(funcSecond), tc_move_if_owned(funcFirst)};\n\t}\n}\n"
  },
  {
    "path": "tc/base/change.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"casts.h\"\n#ifndef __EMSCRIPTEN__\n#include <atomic>\n#endif\n\n/////////////////////////////////////////////////////////////////////\n// comparison functors, required for assign_min/assign_max\n\n\nnamespace tc {\n\nnamespace unbounded_adl {\n\tstruct greatest {};\n\n\t[[nodiscard]] constexpr auto operator<(tc::unused, greatest) return_ctor_noexcept(tc::constant<true>, ())\n\t[[nodiscard]] constexpr auto operator<=(tc::unused, greatest) return_ctor_noexcept(tc::constant<true>, ())\n\t[[nodiscard]] constexpr auto operator<(greatest, tc::unused) return_ctor_noexcept(tc::constant<false>, ())\n\t[[nodiscard]] constexpr auto operator<=(greatest, tc::unused) return_ctor_noexcept(tc::constant<false>, ())\n\n\tstruct least {};\n\n\t[[nodiscard]] constexpr auto operator<(tc::unused, least) return_ctor_noexcept(tc::constant<false>, ())\n\t[[nodiscard]] constexpr auto operator<=(tc::unused, least) return_ctor_noexcept(tc::constant<false>, ())\n\t[[nodiscard]] constexpr auto operator<(least, tc::unused) return_ctor_noexcept(tc::constant<true>, ())\n\t[[nodiscard]] constexpr auto operator<=(least, tc::unused) return_ctor_noexcept(tc::constant<true>, ())\n\n\t[[nodiscard]] constexpr auto operator<(least, greatest) return_ctor_noexcept(tc::constant<true>, ())\n\t[[nodiscard]] constexpr auto operator<=(least, greatest) return_ctor_noexcept(tc::constant<true>, ())\n\t[[nodiscard]] constexpr auto operator<(greatest, least) return_ctor_noexcept(tc::constant<false>, ())\n\t[[nodiscard]] constexpr auto operator<=(greatest, least) return_ctor_noexcept(tc::constant<false>, ())\n}\nusing unbounded_adl::least;\nusing unbounded_adl::greatest;\n\n////////////////////////////\n// comparison functors\n// Unlike std::less<> et. al., they are special-made for comparisons, so they only use operator== and operator< with constant arguments and expect noexcept and a bool return\n// This avoids types having to support operator> and operator>=, which we do not want to use in our code.\n\nnamespace equal_to_default {\n\ttemplate<typename Lhs, typename Rhs> requires\n\t\tstd::is_class<Lhs>::value ||\n\t\tstd::is_class<Rhs>::value ||\n\t\tstd::is_pointer<Lhs>::value ||\n\t\tstd::is_pointer<Rhs>::value ||\n\t\tstd::is_same<std::remove_volatile_t<Lhs>, std::remove_volatile_t<Rhs>>::value\n\t[[nodiscard]] constexpr auto equal_to_impl(Lhs const& lhs, Rhs const& rhs) return_decltype_MAYTHROW(\n\t\ttc::implicit_cast<bool>(lhs==rhs)\n\t)\n\t\n\ttemplate<tc::actual_arithmetic Lhs, tc::actual_arithmetic Rhs> requires\n\t\t(!std::is_same<std::remove_volatile_t<Lhs>, std::remove_volatile_t<Rhs>>::value)\n\t[[nodiscard]] constexpr bool equal_to_impl(Lhs const& lhs, Rhs const& rhs) noexcept {\n\t\treturn tc::explicit_cast<decltype(lhs+rhs)>(lhs)==tc::explicit_cast<decltype(lhs+rhs)>(rhs);\n\t}\n}\n\nDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(equal_to)\n\n// 1. at least one of the operands is a pointer,\n// 2. array-to-pointer conversions, derived-to-base pointer conversions, function pointer conversions, and qualification conversions are applied as necessary to convert both operands to the same pointer type, and the resulting pointer type is an object pointer type\n// 3. std::nullptr_t is not ordered comparable to pointers\ntemplate<typename Lhs, typename Rhs>\nconcept comparable_pointers =\n\t(\n\t\t(std::is_pointer<Lhs>::value && (std::is_pointer<Rhs>::value || std::is_array<Rhs>::value))\n\t\t||\n\t\t((std::is_pointer<Lhs>::value || std::is_array<Lhs>::value) && std::is_pointer<Rhs>::value)\n\t) &&\n\tstd::is_pointer<tc::common_type_t<Lhs, Rhs>>::value;\n\ntemplate<typename Lhs, typename Rhs>\n[[nodiscard]] constexpr auto less(Lhs const& lhs, Rhs const& rhs) noexcept requires requires { lhs<rhs; } {\n\tif constexpr (tc::actual_arithmetic<Lhs> && tc::actual_arithmetic<Rhs>) {\n\t\tauto result = tc::explicit_cast<decltype(lhs+rhs)>(lhs)<tc::explicit_cast<decltype(lhs+rhs)>(rhs);\n\t\tstatic_assert(std::is_same<decltype(result), bool>::value || std::is_same<decltype(result), tc::constant<true>>::value || std::is_same<decltype(result), tc::constant<false>>::value);\n\t\treturn result;\n\t} else if constexpr (tc::comparable_pointers<Lhs, Rhs>) {\n\t\t// A specialization of std::less for any pointer type yields the implementation-defined strict total order, even if the built-in < operator does not.\n\t\treturn std::less<tc::common_type_t<Lhs, Rhs>>()(lhs, rhs);\n\t} else {\n\t\tstatic_assert(\n\t\t\t!(std::is_pointer<Lhs>::value && std::is_class<Rhs>::value && std::convertible_to<Rhs const&, Lhs>) &&\n\t\t\t!(std::is_class<Lhs>::value && std::is_pointer<Rhs>::value && std::convertible_to<Lhs const&, Rhs>), // use std::convertible_to instead of tc::safely_convertible_to avoid any pointer comparison with operator<\n\t\t\t\"if a class type is implicitly convertible to a pointer type and you want to compare this class type with the pointer type,\"\n\t\t\t\" tc::implicit_cast class object to pointer when you want to make a pointer comparison between the two,\"\n\t\t\t\" otherwise use specific comparison function, e.g. tc::lexicographical_compare_3way, instead of tc::less.\"\n\t\t);\n\t\tauto result = lhs<rhs;\n\t\tstatic_assert(std::is_same<decltype(result), bool>::value || std::is_same<decltype(result), tc::constant<true>>::value  || std::is_same<decltype(result), tc::constant<false>>::value);\n\t\treturn result;\n\t}\n}\n\nnamespace no_adl\n{\n\tDEFINE_FN2(!tc::equal_to, fn_not_equal_to)\n\n\tstruct[[nodiscard]] fn_less{\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\t[[nodiscard]] constexpr auto operator()(Lhs const& lhs, Rhs const& rhs) const& return_decltype_noexcept(\n\t\t\ttc::less(lhs,rhs)\n\t\t)\n\t\tusing is_transparent = void;\n\n\t\tusing supremum = tc::greatest;\n\t\tusing infimum = tc::least;\n\t};\n\n\tDEFINE_FN2(!tc::less, fn_greater_equal)\n\n\tstruct[[nodiscard]] fn_greater{\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\t[[nodiscard]] constexpr auto operator()(Lhs const& lhs, Rhs const& rhs) const& return_decltype_noexcept(\n\t\t\ttc::less(rhs,lhs)\n\t\t)\n\t\tusing is_transparent = void;\n\n\t\tusing supremum = tc::least;\n\t\tusing infimum = tc::greatest;\n\t};\n\n\tstruct[[nodiscard]] fn_less_equal{\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\t[[nodiscard]] constexpr auto operator()(Lhs const& lhs, Rhs const& rhs) const& return_decltype_noexcept(\n\t\t\t!tc::less(rhs,lhs)\n\t\t)\n\t\tusing is_transparent = void;\n\t};\n}\n\nusing no_adl::fn_not_equal_to;\nusing no_adl::fn_less;\nusing no_adl::fn_greater_equal;\nusing no_adl::fn_greater;\nusing no_adl::fn_less_equal;\n\n/////////////////////////////////////////////////////////////////////\n// change\n\ntemplate< typename Better, typename Var, typename Val  >\nconstexpr auto assign_better( Better better, Var&& var, Val&& val ) noexcept {\n\treturn tc::make_overload(\n\t\t[&](tc::constant<true> b) noexcept {\n\t\t\tstatic_assert( tc::safely_assignable_from<Var&&, Val&&> );\n\t\t\ttc_move_if_owned(var) = tc_move_if_owned(val);\n\t\t\treturn b;\n\t\t},\n\t\t[&](tc::constant<false> b) noexcept {\n\t\t\treturn b;\n\t\t},\n\t\t[&](bool const b) noexcept {\n\t\t\tif (b) {\n\t\t\t\tstatic_assert( tc::safely_assignable_from<Var&&, Val&&> );\n\t\t\t\ttc_move_if_owned(var) = tc_move_if_owned(val);\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t)( tc_invoke(better, tc::as_const(val), tc::as_const(var)) );\n}\n\ntemplate< typename Var, typename Val >\nconstexpr bool change( Var&& var, Val&& val ) noexcept {\n\treturn tc::assign_better( [](auto const& val_, auto const& var_) noexcept { return !tc::equal_to(var_, val_); }, tc_move_if_owned(var), tc_move_if_owned(val) ); // var==val, not val==var\n}\n\n#ifndef __EMSCRIPTEN__\ntemplate< typename Better, typename Var, typename Val >\nbool assign_better( Better better, std::atomic<Var>& var, Val&& val ) noexcept {\n\tVar varOld=var;\n\t_ASSERTINITIALIZED( varOld );\n\twhile( better(tc::as_const(VERIFYINITIALIZED(val)), tc::as_const(varOld)) ) {\n\t\t if( var.compare_exchange_weak( varOld, val ) ) return true;\n\t}\n\treturn false;\n}\n\ntemplate< typename Better, typename Var, typename Val0, typename... Val >\nbool assign_better( Better better, std::atomic<Var>&& var, Val0&& val0, Val&&... val ) noexcept =delete; // make passing rvalue ref an error\n\ntemplate< typename Var, typename Val >\nbool change( std::atomic<Var> & var, Val&& val ) noexcept {\n\t_ASSERTINITIALIZED( val );\n\treturn !tc::equal_to(var.exchange(val),val);\n}\n\ntemplate< typename Var, typename Val >\nbool change( std::atomic<Var>&& var, Val&& val ) noexcept; // make passing rvalue ref a linker error\n#endif // __EMSCRIPTEN__\n\ntemplate< typename Better, typename Var, typename... Val> requires (1<sizeof...(Val))\nconstexpr bool assign_better( Better better, Var&& var, Val&&... val) noexcept {\n\tbool b=false;\n\tstatic_cast<void>(std::initializer_list<bool>{(b=(tc::assign_better(better, var, tc_move_if_owned(val)) || b))...});\n\treturn b;\n}\n\ntemplate< typename Var, typename Val0, typename... Val >\nconstexpr bool assign_max( Var&& var, Val0&& val0, Val&&... val ) noexcept {\n\treturn tc::assign_better( tc::fn_greater(), tc_move_if_owned(var), tc_move_if_owned(val0), tc_move_if_owned(val)... ); // use operator< for comparison just like tc::min/max\n}\n\ntemplate< typename Var, typename Val0, typename... Val>\nconstexpr bool assign_min( Var&& var, Val0&& val0, Val&&... val ) noexcept {\n\treturn tc::assign_better( tc::fn_less(), tc_move_if_owned(var), tc_move_if_owned(val0), tc_move_if_owned(val)... );\n}\n\ntemplate<typename Var, typename Val>\nvoid change_with_or(Var&& var, Val&& val, bool& bChanged) noexcept {\n\t// accessing an uninitialized variable is undefined behavior, so don't compare for equality if var is uninitialized!\n\tif( VERIFYINITIALIZED(bChanged) ) {\n\t\t_ASSERTINITIALIZED( val );\n\t\ttc_move_if_owned(var) = tc_move_if_owned(val);\n\t} else {\n\t\tbChanged = tc::change( tc_move_if_owned(var), tc_move_if_owned(val) );\n\t}\n}\n\ntc_define_fn( assign_max );\ntc_define_fn( assign_min );\n\n////////////////////////////////////\n// change for float/double\n\n// Treat float/double assignment as bit pattern assignment, to avoid NaN problems.\n// Assigning NaN to NaN should be !bChanged.\n// Might not work because IEEE 754 does not specify a unique bit pattern for NaNs.\n// RT#5691: Also, we must not rely on comparisons involving NaN to return false, as defined by the standard, because we are using /fp:fast:\n// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=518015&ppud=0&wa=wsignin1.0\n\ntemplate< typename Lhs, typename Rhs >\n[[nodiscard]] bool binary_equal( Lhs const& lhs, Rhs const& rhs ) noexcept {\n\tSTATICASSERTEQUAL( sizeof(lhs), sizeof(rhs) );\n\treturn 0==std::memcmp(std::addressof(lhs),std::addressof(rhs),sizeof(lhs));\n}\n\ntemplate< typename Dst, typename Src >\nbool binary_change( Dst& dst, Src const& src ) noexcept {\n\tSTATICASSERTEQUAL( sizeof(Dst), sizeof(src) );\n\tif( !binary_equal(dst,src) ) {\n\t\tstd::memcpy(std::addressof(dst),std::addressof(src),sizeof(dst));\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\ntemplate< typename Var, typename Value >\n\trequires std::floating_point<tc::decay_t<Var>>\t\nbool change( Var&& var, Value&& value ) noexcept {\n\tusing float_type = tc::decay_t<Var>;\n\tauto const nan = std::numeric_limits<float_type>::quiet_NaN();\n\t_ASSERTINITIALIZED( var );\n\t_ASSERT( !std::isnan( var ) || binary_equal(var, nan) );\n\t_ASSERTINITIALIZED( value );\n\tauto float_value = tc::implicit_cast<float_type>(tc_move_if_owned(value));\n\t_ASSERT( !std::isnan( float_value ) || binary_equal(float_value, nan) );\n\treturn binary_change( var, float_value );\n}\n} // namespace tc\n"
  },
  {
    "path": "tc/base/conditional.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits_fwd.h\"\n\n// used in an expression, prvalue is forwarded as xvalue\n\n#define tc_conditional_impl(b, type, lhs, rhs) \\\n\t(tc::explicit_cast<bool>(b) ? static_cast<type>(lhs) : static_cast<type>(rhs)) // static_cast needed for conversion from const& to const&&\n\n#define tc_conditional_typed(b, lhstype, lhs, rhstype, rhs) \\\n\ttc_conditional_impl(TC_FWD(b), TC_FWD(tc::common_reference_t<lhstype, rhstype>), TC_FWD(lhs), TC_FWD(rhs))\n\n#define tc_conditional_rvalue_as_ref(b, lhs, rhs) \\\n\ttc_conditional_typed(b, decltype((lhs))&&, TC_FWD(lhs), decltype((rhs))&&, TC_FWD(rhs))\n\n#define tc_conditional_prvalue_as_val(b, lhs, rhs) \\\n\ttc_conditional_typed(b, decltype((lhs)), TC_FWD(lhs), decltype((rhs)), TC_FWD(rhs))\n"
  },
  {
    "path": "tc/base/conditional.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"conditional.h\"\n\n#define TERNARY_TYPE(first, second) \\\n\tdecltype(std::declval<bool>() ? first : second)\n\n#define SAME_TYPE(first, second) \\\n\tstatic_assert(std::is_same<first, second>::value)\n\n#define CAST_LVALUEREF(TYPE) \\\n\tstatic_cast<TYPE>(std::declval<std::decay_t<TYPE>&>())\n\n#define TERNARY_TYPE_CAST_LVALUEREF(first, second) \\\n\tTERNARY_TYPE(CAST_LVALUEREF(first), CAST_LVALUEREF(second))\n\n#define TEST_TERNARY_STATIC_CAST_LVALUEREF(result, first, second) \\\n\tSAME_TYPE(result, TERNARY_TYPE_CAST_LVALUEREF(first, second))\n\nTEST_TERNARY_STATIC_CAST_LVALUEREF(int, int, int);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(int const&, int const&, int const&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(int&, int&, int&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(int&&, int&&, int&&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(int const&&, int const&&, int const&&);\n\nnamespace {\n\tstruct S {};\n}\n\nTEST_TERNARY_STATIC_CAST_LVALUEREF(S, S, S);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(S const&, S const&, S const&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(S&, S&, S&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(S&&, S&&, S&&);\nTEST_TERNARY_STATIC_CAST_LVALUEREF(S const&&, S const&&, S const&&);\n\nnamespace {\n\t// MSVC used to create extra temporaries and report errors regarding returning of these temporaries.\n\t// Making sure this is no longer the case.\n\t// https://developercommunity.visualstudio.com/content/problem/1178976/ternary-operator-with-xvalue-operands-for-non-clas.html\n\t[[maybe_unused]] decltype(auto) foo(bool b, S&& s1, S&& s2) {\n\t\treturn b ? static_cast<S&&>(s1) : static_cast<S&&>(s2);\n\t}\n\t\n\t[[maybe_unused]] decltype(auto) foo(bool b, int&& n1, int&& n2) {\n\t\treturn b ? static_cast<int&&>(n1) : static_cast<int&&>(n2);\n\t}\n\t\n\t[[maybe_unused]] decltype(auto) bar(bool b, S&& s1, S&& s2) {\n\t\treturn b ? static_cast<S const&&>(s1) : static_cast<S const&&>(s2);\n\t}\n\t\n\t[[maybe_unused]] decltype(auto) bar(bool b, int&& n1, int&& n2) {\n\t\treturn b ? static_cast<int const&&>(n1) : static_cast<int const&&>(n2);\n\t}\n}\n"
  },
  {
    "path": "tc/base/construction_restrictiveness.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"enum.h\"\n#include \"utility.h\"\n#include \"../algorithm/minmax.h\"\n\nnamespace tc {\n\t////////////////////////////////////////////////\n\t// initialization of TTarget member/element by TSource\n\n\tTC_DEFINE_ENUM( econstruction_t, econstruction, (FORBIDDEN)(EXPLICIT)(IMPLICIT) );\n\n\tnamespace construction_restrictiveness_detail {\n\t\t// Similar to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387.html :\n\t\t// - implicit construction == is_constructible && is_convertible,\n\t\t// - explicit construction == is_constructible && !is_convertible.\n\t\t// However, we make some unsafe conversions explicit or do not allow them at all.\n\t\t// Moreover, we always allow implicit construction if TTarget is constructed from a TTarget prvalue.\n\t\t// TODO: explicit construction, if there is a sensible definition for tc::explicit_cast<TTarget>(TSource) \n\t\ttemplate<typename TTarget, typename... Args>\n\t\tconsteval tc::econstruction_t get_construction_restrictiveness() {\n\t\t\tstatic_assert(!std::is_rvalue_reference<TTarget>::value);\n\t\t\tif constexpr( 1 == sizeof...(Args) ) {\n\t\t\t\tif constexpr( std::is_same<std::remove_cv_t<TTarget>, std::remove_cv_t<tc::mp_only<boost::mp11::mp_list<Args...>>>>::value ) {\n\t\t\t\t\treturn tc::econstructionIMPLICIT;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif constexpr( tc::explicit_castable_from<TTarget, Args...> ) {\n\t\t\t\treturn tc::implicit_constructible_from<TTarget, Args...>\n\t\t\t\t\t? tc::econstructionIMPLICIT\n\t\t\t\t\t: tc::econstructionEXPLICIT;\n\t\t\t} else {\n\t\t\t\treturn tc::econstructionFORBIDDEN;\n\t\t\t}\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\t// MSVC up to 16.9 compilation fails if this is an alias template instead of a class template.\n\t\t\ttemplate<typename TTarget, typename... Args>\n\t\t\tstruct construction_restrictiveness : tc::constant<construction_restrictiveness_detail::get_construction_restrictiveness<TTarget, Args...>()> {};\n\t\t}\n\t}\n\tusing construction_restrictiveness_detail::no_adl::construction_restrictiveness;\n\n\tnamespace no_adl {\n\t\t// initialize N elements of TTarget by forwarding one arg per element\n\t\ttemplate<typename TTarget, typename... Args>\n\t\tstruct elementwise_construction_restrictiveness;\n\n\t\ttemplate<tc::econstruction_t econstruction, typename TTarget, typename... Args>\n\t\tstruct elementwise_construction_restrictiveness_impl final {\n\t\t\tstatic constexpr auto value = tc::min(econstruction, elementwise_construction_restrictiveness<TTarget, Args...>::value);\n\t\t};\n\n\t\ttemplate<typename TTarget, typename... Args>\n\t\tstruct elementwise_construction_restrictiveness_impl<tc::econstructionFORBIDDEN, TTarget, Args...> final {\n\t\t\tstatic constexpr auto value = tc::econstructionFORBIDDEN;\n\t\t};\n\n\t\ttemplate<typename TTarget>\n\t\tstruct elementwise_construction_restrictiveness<TTarget> final {\n\t\t\tstatic constexpr auto value = tc::econstructionIMPLICIT;\n\t\t};\n\n\t\ttemplate<typename TTarget, typename Arg0, typename... Args>\n\t\tstruct elementwise_construction_restrictiveness<TTarget, Arg0, Args...> final {\n\t\t\tstatic constexpr auto value = elementwise_construction_restrictiveness_impl<tc::construction_restrictiveness<TTarget, Arg0>::value, TTarget, Args...>::value;\n\t\t};\n\t}\n\tusing no_adl::elementwise_construction_restrictiveness;\n}\n"
  },
  {
    "path": "tc/base/derivable.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"explicit_cast_fwd.h\"\n#include \"construction_restrictiveness.h\"\n\n//-----------------------------------------------------------------------------------------------------------------------------\n\nnamespace tc {\n\t/////////////////////////////////////////////\n\t// derivable_t\n\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct derivable_wrapper {\n\t\t\tSTATICASSERTSAME( std::remove_cvref_t<T>, T );\n\t\t\tstatic_assert( !std::is_class<T>::value );\n\n\t\t\tderivable_wrapper() noexcept\n\t\t\t{}\n\n\t\t\ttemplate<typename A1> requires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<T, A1&&>::value)\n\t\t\tderivable_wrapper(A1&& a1) noexcept\n\t\t\t\t: m_t(tc_move_if_owned(a1))\n\t\t\t{}\n\n\t\t\ttemplate<typename A1> requires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<T, A1&&>::value)\n\t\t\texplicit derivable_wrapper(A1&& a1) noexcept\n\t\t\t\t: tc_member_init( m_t, tc_move_if_owned(a1) )\n\t\t\t{}\n\n\t\t\toperator T const&() const& noexcept {\n\t\t\t\treturn m_t;\n\t\t\t}\n\n\t\t\toperator T&() & noexcept {\n\t\t\t\treturn m_t;\n\t\t\t}\n\n\t\t\toperator T const&&() const&& noexcept {\n\t\t\t\treturn static_cast<T const&&>(m_t);\n\t\t\t}\n\n\t\t\toperator T&&() && noexcept {\n\t\t\t\treturn static_cast<T&&>(m_t);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tT m_t;\n\t\t};\n\n\t\ttemplate<>\n\t\tstruct derivable_wrapper<void> {};\n\t}\n\ttemplate<typename T>\n\tusing derivable_t = std::conditional_t<std::is_class<T>::value, T, tc::no_adl::derivable_wrapper<T>>;\n\n\t#pragma push_macro(\"BASE_CAST_IMPL\")\n\t#define BASE_CAST_IMPL(cvref) \\\n\ttemplate<typename Dst> requires (!std::is_class<Dst>::value) \\\n\t[[nodiscard]] constexpr Dst cvref base_cast(std::type_identity_t<tc::derivable_t<Dst>> cvref t) noexcept { \\\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst); \\\n\t\treturn static_cast<Dst cvref>(t); \\\n\t}\n\tBASE_CAST_IMPL(&)\n\tBASE_CAST_IMPL(&&)\n\tBASE_CAST_IMPL(const&)\n\tBASE_CAST_IMPL(const&&)\n\tBASE_CAST_IMPL(volatile&)\n\tBASE_CAST_IMPL(volatile&&)\n\tBASE_CAST_IMPL(volatile const&)\n\tBASE_CAST_IMPL(volatile const&&)\n\t#pragma pop_macro(\"BASE_CAST_IMPL\")\t\n\n\t#pragma push_macro(\"BASE_CAST_IMPL\")\n\t#define BASE_CAST_IMPL(cvref) \\\n\ttemplate<typename Dst> requires (!std::is_class<Dst>::value) \\\n\t[[nodiscard]] constexpr Dst cvref base_cast(std::type_identity_t<tc::derivable_t<Dst>> cvref p) noexcept { \\\n\t\tSTATICASSERTSAME(std::remove_cvref_t<Dst>, Dst); \\\n\t\treturn std::addressof(tc::base_cast<Dst>(*p)); \\\n\t}\n\tBASE_CAST_IMPL(*)\n\tBASE_CAST_IMPL(const*)\n\tBASE_CAST_IMPL(volatile*)\n\tBASE_CAST_IMPL(volatile const*)\n\t#pragma pop_macro(\"BASE_CAST_IMPL\")\n}\n"
  },
  {
    "path": "tc/base/empty_chain.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"fundamental.h\"\n\nnamespace tc {\n\tnamespace empty_chain_impl {\n\t\t// consider a CRTP such as implements_compare etc.\n\t\t//\n\t\t//\t\ttemplate <typename Derived, typename Chain=empty_chain>\n\t\t//\t\tstruct SomeCRTP : Chain {};\n\t\t//\n\t\t//\t\tclass A : SomeCRTP<A> {}; // implicitly derives from empty_chain\n\t\t//\t\tclass B : SomeCRTP<B> { A myA; }; // implicitly derives from empty_chain\n\t\t//\n\t\t// then, C++ does NOT allow empty base class optimization, because the compiler has to ensure\n\t\t//\t\tstd::addressof( base_cast<empty_chain>(instance_of_B) ) != std::addressof( base_cast<empty_chain>(instance_of_B.myA) )\n\t\t//\n\t\t// therefore, force different types for each instance of empty_chain, i.e.,\n\t\t//\n\t\t//\t\ttemplate <typename Derived, typename Chain=empty_chain<Derived>>\n\t\t//\t\tstruct SomeCRTP : Chain {};\n\n\t\ttemplate <typename T>\n\t\tstruct TC_EMPTY_BASES empty_chain {};\n\t}\n\tusing empty_chain_impl::empty_chain;\n}\n"
  },
  {
    "path": "tc/base/enum.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"casts.h\"\n#include \"integer.h\"\n\n#include <boost/integer.hpp>\n#include <boost/preprocessor/seq/enum.hpp>\n#include <boost/preprocessor/seq/seq.hpp>\n#include <boost/preprocessor/seq/push_back.hpp>\n#include <boost/preprocessor/seq/for_each.hpp>\n\n#include <bitset>\n#include <cstdint>\n\nnamespace tc {\n\ttemplate<typename T>\n\tconcept contiguous_enum_type = tc::enum_type<T> && requires(T const& value) {\n\t\tcontiguous_enum_impl(value);\n\t};\n\n\tnamespace no_adl {\n\t\ttemplate <typename Enum>\n\t\tstruct contiguous_enum : tc::constant<false> {};\n\n\t\ttemplate <contiguous_enum_type Enum>\n\t\tstruct contiguous_enum<Enum> : tc::constant<true> {\n\t\t\tusing impl = decltype(contiguous_enum_impl(std::declval<Enum>()));\n\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn impl::start();\n\t\t\t}\n\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\t// Note that we cannot use from_underlying due to a recursion.\n\t\t\t\treturn static_cast<decltype(impl::last())>(tc::to_underlying(impl::last()) + 1);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::contiguous_enum;\n\n\ttemplate<typename Enum, typename Integer>\n\t[[nodiscard]] constexpr bool is_enum_value_or_end(Integer const& n) noexcept { // reference to avoid error C4701: potentially uninitialized local variable\n\t\tstatic_assert( tc::actual_integer<Integer> );\n\t\tif constexpr( tc::contiguous_enum<Enum>::value ) {\n\t\t\t// There are values that e can have without UB that are not one its enum values, in particular when e has a fixed underlying_type or the value fits\n\t\t\t// into the bits needed for representing the enum values:\n\t\t\t// http://stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class\n\t\t\t// We do not allow such values here.\n\t\t\treturn tc::explicit_cast<Integer>(tc::to_underlying(tc::contiguous_enum<Enum>::begin())) <= n\n\t\t\t\t&& n <= tc::explicit_cast<Integer>(tc::to_underlying(tc::contiguous_enum<Enum>::end()));\n\t\t} else {\n\t\t\t// TODO: Implement is_enum_value_or_end(...) for all persisted enum types.\n\t\t\treturn true;\n\t\t}\n\t}\n\n\ttemplate<typename Enum, typename Integer>\n\t[[nodiscard]] constexpr bool is_enum_value(Integer const& n) noexcept {\n\t\tstatic_assert( tc::actual_integer<Integer> );\n\t\tif constexpr( tc::contiguous_enum<Enum>::value ) { \n\t\t\treturn tc::explicit_cast<Integer>(tc::to_underlying(tc::contiguous_enum<Enum>::begin())) <= n\n\t\t\t\t&& n < tc::explicit_cast<Integer>(tc::to_underlying(tc::contiguous_enum<Enum>::end()));\n\t\t} else {\n\t\t\t// TODO: Implement is_enum_value(...) for all persisted enum types.\n\t\t\treturn true;\n\t\t}\n\t}\n\n\ttemplate<tc::contiguous_enum_type Enum>\n\t[[nodiscard]] constexpr auto from_underlying_impl(std::type_identity<Enum>, tc::underlying_type_t<Enum> n) {\n\t\t_ASSERTDEBUG(is_enum_value_or_end<Enum>(n)); // _ASSERT triggers win/ARM64EC/release ICE\n\t\treturn static_cast<Enum>(n);\n\t}\n\n\t// integral constants until we have constexpr operator-\n\ttemplate<typename Enum, Enum e1, Enum e2>\n\tusing enum_difference=tc::constant<static_cast<std::underlying_type_t<Enum>>(e1)-static_cast<std::underlying_type_t<Enum>>(e2)>;\n\n\ttemplate <typename Enum>\n\tusing enum_count=tc::constant<tc::as_unsigned(enum_difference<Enum, tc::contiguous_enum<Enum>::end(), tc::contiguous_enum<Enum>::begin()>::value)>;\n}\n\n#define TC_BITMASK_OPS(Enum) \\\n[[nodiscard]] constexpr Enum operator&(Enum _Left, Enum _Right) \\\n{\t/* return _Left & _Right */ \\\n\treturn tc::from_underlying<Enum>(tc::to_underlying(_Left) & tc::to_underlying(_Right)); \\\n} \\\n\\\n[[nodiscard]] constexpr Enum operator|(Enum _Left, Enum _Right) \\\n{\t/* return _Left | _Right */ \\\n\treturn tc::from_underlying<Enum>(tc::to_underlying(_Left) | tc::to_underlying(_Right)); \\\n} \\\n\\\n[[nodiscard]] constexpr Enum operator^(Enum _Left, Enum _Right) \\\n{\t/* return _Left ^ _Right */ \\\n\treturn tc::from_underlying<Enum>(tc::to_underlying(_Left) ^ tc::to_underlying(_Right)); \\\n} \\\n\\\n[[nodiscard]] constexpr Enum operator~(Enum _Left) \\\n{\t/* return ~_Left */ \\\n\treturn tc::from_underlying<Enum>(~tc::to_underlying(_Left)); \\\n} \\\n\\\nconstexpr Enum& operator&=(Enum& _Left, Enum _Right) \\\n{\t/* return _Left &= _Right */ \\\n\t_Left = _Left & _Right; \\\n\treturn _Left; \\\n} \\\n\\\nconstexpr Enum& operator|=(Enum& _Left, Enum _Right) \\\n{\t/* return _Left |= _Right */ \\\n\t_Left = _Left | _Right; \\\n\treturn _Left; \\\n} \\\n\\\nconstexpr Enum& operator^=(Enum& _Left, Enum _Right) \\\n{\t/* return _Left ^= _Right */ \\\n\t_Left = _Left ^ _Right; \\\n\treturn _Left; \\\n} \\\n\\\n[[nodiscard]] constexpr bool HasAllOf(Enum _Left, Enum _Right) \\\n{\t/* return _Left HasAllOf _Right */\\\n\treturn !static_cast<bool>(~_Left & _Right); \\\n}\\\n\\\nstd::weak_ordering operator<=>(Enum, Enum) = delete; \\\nbool operator<(Enum, Enum) = delete; \\\nbool operator<=(Enum, Enum) = delete; \\\nbool operator>=(Enum, Enum) = delete; \\\nbool operator>(Enum, Enum) = delete;\n\n#ifdef TC_PRIVATE\nstruct CSaveHandler;\nstruct CXmlReader;\n#endif\n\nnamespace tc {\n\ttemplate< typename Enum> requires requires { tc::contiguous_enum<Enum>::end(); }\n\tconstexpr void assert_not_end(Enum e) noexcept {\n\t\t_ASSERTDEBUG(\n\t\t\t// There are values that e can have without UB that are not one its enum values, in particular when e has\n\t\t\t//\ta fixed underlying_type or the value fits into the bits needed for representing the enum values:\n\t\t\t//\thttp://stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class \n\t\t\t//\tWe don't allow such values here\n\t\t\ttc::is_enum_value<Enum>(tc::to_underlying(e))\n\t\t);\n\t}\n\n\ttemplate< typename Enum> requires requires { tc::contiguous_enum<Enum>::end(); }\n\t[[nodiscard]] constexpr Enum verify_not_end(Enum e) noexcept {\n\t\ttc::assert_not_end(e);\n\t\treturn e;\n\t}\n\n\tnamespace enumset_adl {\n\t\ttemplate< typename Enum >\n\t\tstruct enumset;\n\t}\n\tusing enumset_adl::enumset;\n}\n\n#define TC_DEFINE_CONTIGUOUS_ENUM(Enum, enumStart, enumLast) \\\n\t[[nodiscard]] inline auto contiguous_enum_impl(Enum const&) { \\\n\t\tstruct impl { \\\n\t\t\tstatic constexpr Enum start() noexcept { return (enumStart); } \\\n\t\t\tstatic constexpr Enum last() noexcept { return (enumLast); } \\\n\t\t}; \\\n\t\treturn impl{}; \\\n\t} \\\n\t[[nodiscard]] inline bool check_initialized_impl(Enum const& e) noexcept { /*reference to avoid error C4701: potentially uninitialized local variable*/ \\\n\t\treturn tc::is_enum_value_or_end<Enum>(tc::to_underlying(e)); \\\n\t} \\\n\t[[nodiscard]] constexpr tc::int_value_least_t< tc::enum_count<Enum>::value > operator-(Enum const e1, Enum const e2) noexcept { \\\n\t\treturn static_cast<tc::int_value_least_t< tc::enum_count<Enum>::value >>(tc::to_underlying(e1)-tc::to_underlying(e2)); \\\n\t} \\\n\ttemplate<ENABLE_SFINAE> \\\n\t[[nodiscard]] constexpr tc::enumset<SFINAE_TYPE(Enum)> operator|(Enum lhs, Enum rhs) noexcept { \\\n\t\ttc::enumset<SFINAE_TYPE(Enum)> sete(lhs); \\\n\t\treturn sete|=rhs; \\\n\t} \\\n\ttemplate<ENABLE_SFINAE> \\\n\t[[nodiscard]] constexpr tc::enumset<SFINAE_TYPE(Enum)> operator&(Enum lhs, Enum rhs) noexcept { \\\n\t\ttc::enumset<SFINAE_TYPE(Enum)> sete(lhs); \\\n\t\treturn sete&=rhs; \\\n\t} \\\n\tconstexpr Enum& operator++(Enum& e) noexcept { \\\n\t\t_ASSERTDEBUG( e!=tc::contiguous_enum<Enum>::end() ); \\\n\t\te = tc::from_underlying<Enum>( tc::to_underlying(e)+1); \\\n\t\treturn e; \\\n\t} \\\n\tconstexpr Enum& operator--(Enum& e) noexcept { \\\n\t\t_ASSERTDEBUG( e!=tc::contiguous_enum<Enum>::begin() ); \\\n\t\te = tc::from_underlying<Enum>( tc::to_underlying(e)-1); \\\n\t\treturn e; \\\n\t} \\\n\ttemplate<tc::actual_integer N> \\\n\tconstexpr Enum& operator+=(Enum& e, N const& n) noexcept { \\\n\t\te = tc::from_underlying<Enum>( tc::add( tc::to_underlying(e), n ) ); \\\n\t\treturn e; \\\n\t} \\\n\ttemplate<tc::actual_integer N> \\\n\tconstexpr Enum& operator-=(Enum& e, N const& n) noexcept { \\\n\t\te = tc::from_underlying<Enum>( tc::sub( tc::to_underlying(e), n ) ); \\\n\t\treturn e; \\\n\t} \\\n\ttemplate<tc::actual_integer N> \\\n\t[[nodiscard]] constexpr Enum operator+(Enum e, N const& n) noexcept { \\\n\t\te+=n; \\\n\t\treturn e; \\\n\t} \\\n\ttemplate<tc::actual_integer N> \\\n\t[[nodiscard]] constexpr Enum operator-(Enum e, N const& n) noexcept { \\\n\t\te-=n; \\\n\t\treturn e; \\\n\t} \\\n\ttemplate<ENABLE_SFINAE> \\\n\t[[nodiscard]] constexpr auto operator~(Enum e) noexcept { \\\n\t\ttc::assert_not_end(e); \\\n\t\tif constexpr( 2 == tc::enum_count<Enum>::value ) { \\\n\t\t\treturn tc::contiguous_enum<Enum>::end() - (e - tc::contiguous_enum<Enum>::begin() + 1); \\\n\t\t} else { \\\n\t\t\treturn ~tc::enumset<SFINAE_TYPE(Enum)>(e); \\\n\t\t} \\\n\t}\n\n#ifdef _DEBUG\n#define TC_PREFIX_CONSTANT_STRING( _, prefix, constant ) #prefix #constant\n\n#define TC_DEFINE_ENUM_REPORTSTREAM_PIPE( Enum, prefix, constants ) \\\n\t\tnamespace Enum ## _detail { \\\n\t\t\t/* TODO: move c_map back as static local after MSVC compiler bug is solved: https://developercommunity.visualstudio.com/t/code-generation-bug-on-static-variable-i/10541326 */ \\\n\t\t\tinline constexpr char const* c_map[]={ \\\n\t\t\t\tBOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(TC_PREFIX_CONSTANT_STRING, prefix, constants)), \\\n\t\t\t\t\"tc::contiguous_enum<\" #Enum \">::end()\" \\\n\t\t\t}; \\\n\t\t} \\\n\t\t[[nodiscard]] inline char const* enum_literal(Enum e) noexcept { \\\n\t\t\treturn Enum ## _detail::c_map[e-tc::contiguous_enum<Enum>::begin()]; \\\n\t\t}\n#else\n#define TC_DEFINE_ENUM_REPORTSTREAM_PIPE( Enum, prefix, constants )\n#endif\n\n// pair == ( Enum, prefix )\n// need to forward BOOST_PP_TUPLE_ELEM result two times, otherwise concatenation does not work\n#define TC_DEFINE_ENUM_CONSTANT_INTERN_INTERN( Enum, prefix, constant ) inline constexpr Enum prefix##constant = Enum :: constant;\n#define TC_DEFINE_ENUM_CONSTANT_INTERN(a,b,c) TC_DEFINE_ENUM_CONSTANT_INTERN_INTERN(a,b,c)\n#define TC_DEFINE_ENUM_CONSTANT( state, pair, constant ) TC_DEFINE_ENUM_CONSTANT_INTERN( BOOST_PP_TUPLE_ELEM(2, 0, pair),  BOOST_PP_TUPLE_ELEM(2, 1, pair), constant)\n\nnamespace tc::enum_detail {\n\ttemplate<typename IntOffset>\n\tconstexpr auto max_value_for_underlying_type(IntOffset nOffset, int const nConstants) noexcept {\n\t\tstatic_assert( std::is_signed<IntOffset>::value, \"unsigned underlying type not supported\" );\n\t\t// Assume two's complement.\n\t\t// -1 - nOffset, like ~nOffset never overflows.\n\t\tauto const nAbsBeginValue = nOffset < 0 ? ~nOffset : nOffset; // Can store an additional negative value\n\t\tauto const nEndValue = nOffset + nConstants;\n\t\treturn nAbsBeginValue < nEndValue ? nEndValue : nAbsBeginValue; // Avoids dependency on tc::max.\n\t}\n}\n\n#define TC_DEFINE_SCOPED_ENUM_WITH_OFFSET( Enum, prefix, offset, constants ) \\\n\tnamespace Enum ## _adl { \\\n\t\tenum class Enum : tc::int_value_least_t<tc::enum_detail::max_value_for_underlying_type((offset), BOOST_PP_SEQ_SIZE(constants))> { \\\n\t\t\tBOOST_PP_SEQ_HEAD(constants) = offset, \\\n\t\t\tBOOST_PP_SEQ_ENUM( BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_PUSH_BACK(constants, _END) ) ) \\\n\t\t}; \\\n\t\tTC_DEFINE_CONTIGUOUS_ENUM(Enum, Enum::BOOST_PP_SEQ_HEAD(constants), static_cast<Enum>(tc::to_underlying(Enum::_END) - 1)) \\\n\t\tTC_DEFINE_ENUM_REPORTSTREAM_PIPE( Enum, prefix, constants ) \\\n\t} \\\n\tusing Enum ## _adl::Enum;\n\n#define TC_DEFINE_SCOPED_ENUM( Enum, prefix, constants ) \\\n\tTC_DEFINE_SCOPED_ENUM_WITH_OFFSET( Enum, prefix, 0, constants )\n\n#define TC_DEFINE_ENUM_WITH_OFFSET( Enum, prefix, offset, constants ) \\\n\tTC_DEFINE_SCOPED_ENUM_WITH_OFFSET( Enum, prefix, offset, constants ) \\\n\tBOOST_PP_SEQ_FOR_EACH(TC_DEFINE_ENUM_CONSTANT, (Enum, prefix), constants)\n\n#define TC_DEFINE_ENUM( Enum, prefix, constants ) \\\n\tTC_DEFINE_ENUM_WITH_OFFSET( Enum, prefix, 0, constants )\n\n#define TC_DEFINE_UNPREFIXED_ENUM( Enum, constants ) \\\n\tTC_DEFINE_ENUM(Enum, , constants)\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename EnumSub>\n\t\tstruct sub_enum_trait;\n\n\t\ttemplate<typename EnumSub, typename EnumSuper>\n\t\tstruct is_sub_enum_of /* not final */: tc::constant<false> {};\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires\n\t\t\tstd::is_same<typename sub_enum_trait<std::remove_cvref_t<EnumSub>>::super, std::remove_cvref_t<EnumSuper>>::value\n\t\tstruct is_sub_enum_of<EnumSub, EnumSuper> /* not final */\n\t\t\t: tc::constant<true> {};\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires\n\t\t\t(!std::is_same<typename sub_enum_trait<std::remove_cvref_t<EnumSub>>::super, std::remove_cvref_t<EnumSuper>>::value)\n\t\tstruct is_sub_enum_of<EnumSub, EnumSuper> /* not final */\n\t\t\t: is_sub_enum_of<typename sub_enum_trait<std::remove_cvref_t<EnumSub>>::super, std::remove_cvref_t<EnumSuper>> {};\n\t}\n\tusing no_adl::is_sub_enum_of;\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename EnumSuper, typename EnumSub> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr EnumSuper explicit_convert_impl(adl_tag_t, std::type_identity<EnumSuper>, EnumSub const esub) noexcept {\n\t\t\treturn static_cast<EnumSuper>(esub); // cast from sub to super is always safe\n\t\t}\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr EnumSub explicit_convert_impl(adl_tag_t, std::type_identity<EnumSub>, EnumSuper const esuper) noexcept {\n\t\t\treturn tc::from_underlying<EnumSub>(tc::to_underlying(esuper));\n\t\t}\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr std::optional<EnumSub> explicit_convert_impl(adl_tag_t, std::type_identity<std::optional<EnumSub>>, EnumSuper const esuper) noexcept {\n\t\t\tif (auto const n = tc::to_underlying(esuper); tc::is_enum_value<EnumSub>(n)) {\n\t\t\t\treturn static_cast<EnumSub>(n);\n\t\t\t} else {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t}\n\t}\n}\n\n#define TC_VERIFY_EQUALITY_BETWEEN_ENUMSUPER_AND_ENUMSUB(state, pair, constant) \\\n\tstatic_assert(tc::to_underlying(BOOST_PP_TUPLE_ELEM(2, 0, pair)::constant) == tc::to_underlying(BOOST_PP_TUPLE_ELEM(2, 1, pair)::constant));\n\n#define TC_DEFINE_SUB_ENUM(EnumSuper, EnumSub, prefixsub, constants) \\\n\tTC_DEFINE_ENUM_WITH_OFFSET(EnumSub, prefixsub, tc::to_underlying(EnumSuper::BOOST_PP_SEQ_HEAD(constants)), constants) \\\n\tBOOST_PP_SEQ_FOR_EACH(TC_VERIFY_EQUALITY_BETWEEN_ENUMSUPER_AND_ENUMSUB, (EnumSuper, EnumSub), constants) \\\n\tnamespace tc::no_adl { \\\n\t\ttemplate<> \\\n\t\tstruct sub_enum_trait<EnumSub> final { \\\n\t\t\tusing super = EnumSuper; \\\n\t\t}; \\\n\t}\n"
  },
  {
    "path": "tc/base/enum.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"enum.h\"\n#include \"../enumset.h\"\n#include \"../unittest.h\"\n\n#define TEST_ENUM(offset, constants, underlying) \\\n\tnamespace { namespace BOOST_PP_CAT(enum_test_, __COUNTER__) { \\\n\t\tTC_DEFINE_ENUM_WITH_OFFSET(Enum, en, offset, constants); \\\n\t\tstatic_assert( std::is_signed<std::underlying_type_t<Enum>>::value ); \\\n\t\tSTATICASSERTEQUAL( sizeof(std::underlying_type_t<Enum>), sizeof(underlying) ); \\\n\t\tSTATICASSERTEQUAL( tc::to_underlying(tc::contiguous_enum<Enum>::begin()), offset ); \\\n\t\tSTATICASSERTEQUAL( tc::to_underlying(tc::contiguous_enum<Enum>::end()), offset + BOOST_PP_SEQ_SIZE(constants) ); \\\n\t} }\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunused\" // unused functions/variables defined in unnamed namespace\n#endif\n\nTEST_ENUM(0, (a), std::int8_t);\nTEST_ENUM(126, (a), std::int8_t);\nTEST_ENUM(-128, (a), std::int8_t);\nTEST_ENUM(127, (a), std::int16_t);\nTEST_ENUM(-129, (a), std::int16_t);\nTEST_ENUM(-0x8000, (a), std::int16_t);\nTEST_ENUM(-0x10000, (a), std::int32_t);\nTEST_ENUM(0x10000, (a), std::int32_t);\nTEST_ENUM(-0x100000000, (a), std::int64_t);\nTEST_ENUM(0x100000000, (a), std::int64_t);\n\n#define CONSTANTS4(pre) (pre ## 0)(pre ## 1)(pre ## 2)(pre ## 3)\n#define CONSTANTS16(pre) CONSTANTS4(pre ## 0)CONSTANTS4(pre ## 1)CONSTANTS4(pre ## 2)CONSTANTS4(pre ## 3)\n#define CONSTANTS64(pre) CONSTANTS16(pre ## 0)CONSTANTS16(pre ## 1)CONSTANTS16(pre ## 2)CONSTANTS16(pre ## 3)\n#define CONSTANTS192 CONSTANTS64(a ## 0)CONSTANTS64(a ## 1)CONSTANTS64(a ## 2)\n\nTEST_ENUM(-128, CONSTANTS192, std::int8_t);\nTEST_ENUM(-129, CONSTANTS192, std::int16_t);\nTEST_ENUM(0, CONSTANTS192, std::int16_t);\n\nnamespace {\nTC_DEFINE_ENUM_WITH_OFFSET(ETest, etest, 1234, (A)(B)(C)(D)(E)(F));\nconstexpr auto etestEND = tc::contiguous_enum<ETest>::end();\n\nUNITTESTDEF(enumset_index_inc_dec) {\n\ttc::enumset<ETest> setetest;\n\tsetetest |= etestB;\n\tsetetest |= etestC;\n\tsetetest |= etestE;\n\n\tauto itetest = tc::begin(setetest);\n\t_ASSERTEQUAL(*itetest++, etestB);\n\t_ASSERTEQUAL(*itetest++, etestC);\n\t_ASSERTEQUAL(*itetest++, etestE);\n\t_ASSERTEQUAL(itetest, tc::end(setetest));\n\t_ASSERTEQUAL(*--itetest, etestE);\n\t_ASSERTEQUAL(*--itetest, etestC);\n\t_ASSERTEQUAL(*--itetest, etestB);\n\t_ASSERTEQUAL(itetest, tc::begin(setetest));\n}\n\n}\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n"
  },
  {
    "path": "tc/base/explicit_cast.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"explicit_cast_fwd.h\"\n#include \"casts.h\"\n#include \"noncopyable.h\"\n#include \"trivial_functors.h\"\n#include \"../tuple.h\"\n#include <type_traits>\n#include <optional>\n\nnamespace tc {\n\tDEFINE_FN2_TMPL( explicit_cast, (typename) )\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<tc::char_type TTarget, tc::char_type TSource>\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, TSource src) noexcept {\n\t\t\tstatic_assert(tc::decayed<TTarget>);\n\t\t\t_ASSERTE(tc::char_in_range<TSource>(tc::to_underlying(src)));\n\t\t\t_ASSERTE(tc::char_in_range<TTarget>(tc::to_underlying(src)));\n\t\t\treturn static_cast<TTarget>(src);\n\t\t}\n\n\t\ttemplate<tc::actual_integer TTarget, std::floating_point TSource>\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, TSource src) noexcept {\n\t\t\tTTarget target=static_cast<TTarget>(src);\n\t\t\t_ASSERTDEBUG(target==src); // default round-to-zero from floating point to integer is wrong most of the time, so we force rounding first\n\t\t\treturn target;\n\t\t}\n\n\t\ttemplate<std::floating_point TTarget, tc::actual_integer TSource>\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, TSource src) noexcept {\n\t\t\treturn static_cast<TTarget>(src); // silence warning for int to float conversion\n\t\t}\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wsign-compare\"\n#else\nMODIFY_WARNINGS_BEGIN(\n\t((disable)(4018)) // signed/unsigned mismatch\n\t((disable)(4388)) // signed/unsigned mismatch\n)\n#endif\n\t\ttemplate<tc::actual_integer TTarget, tc::actual_integer TSource>\n\t\tconstexpr TTarget explicit_convert_impl(adl_tag_t, std::type_identity<TTarget>, TSource src) noexcept {\n\t\t\t_ASSERTE(\n\t\t\t\t(\n\t\t\t\t\t!std::is_signed<TSource>::value ||\n\t\t\t\t\t( std::is_signed<TTarget>::value \n\t\t\t\t\t\t? std::numeric_limits<TTarget>::lowest() <= src\n\t\t\t\t\t\t: /*must be signed 0 to avoid conversion of src to unsigned*/0 <= src\n\t\t\t\t\t)\n\t\t\t\t) &&\n\t\t\t\t// conversion to unsigned (Warning 4018 and 4388) is ok here:\n\t\t\t\tsrc <= std::numeric_limits<TTarget>::max()\n\t\t\t);\n\t\t\treturn static_cast<TTarget>(src);\n\t\t}\n#ifdef __clang__\n#pragma clang diagnostic pop\n#else\nMODIFY_WARNINGS_END\n#endif\n\n\t\ttemplate<typename T>\n\t\tstd::streamoff explicit_convert_impl(adl_tag_t, std::type_identity<std::streamoff>, std::fpos<T> const& pos) noexcept {\n\t\t\treturn pos;\n\t\t}\n\n\t\t// tc::constant\n\n\t\ttemplate<typename T, T t, typename TSource> requires tc::explicit_castable_from<T, TSource&&>\n\t\tconstexpr tc::constant<t> explicit_convert_impl(adl_tag_t, std::type_identity<std::integral_constant<T, t>>, TSource&& source) noexcept {\n\t\t\t_ASSERTE(t == tc::explicit_cast<T>(tc_move_if_owned(source)));\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tnamespace return_cast_detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename... Args>\n\t\t\tstruct [[nodiscard]] return_cast_impl final : tc::nonmovable {\n\t\t\t\ttc::tuple<Args&&...> m_tuple;\n\t\t\t\ttemplate<tc::explicit_castable_from<Args...> TTarget> \n\t\t\t\tconstexpr operator TTarget() && return_MAYTHROW(\n\t\t\t\t\ttc_apply(tc::fn_explicit_cast<std::remove_cv_t<TTarget>>(), tc_move(m_tuple))\n\t\t\t\t)\n\n\t\t\t\tconstexpr return_cast_impl&& operator+() && noexcept {\n\t\t\t\t\treturn static_cast<return_cast_impl&&>(*this);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename... Args>\n\t\tconstexpr no_adl::return_cast_impl<Args...> return_cast(Args&&... args) noexcept {\n\t\t\treturn { {}, tc::tie(tc_move_if_owned(args)...) };\n\t\t}\n\t}\n\n\t// operator+ casts to xvalue to disallow tc_return_cast in function with auto return type.\n\t#define tc_return_cast/*(...)*/ \\\n\t\treturn +tc::return_cast_detail::return_cast /*(__VA_ARGS__)*/\n\n\tDEFINE_FN2_TMPL( reluctant_explicit_cast, (typename) )\n\t\n\tnamespace no_adl {\n\t\ttemplate<typename TTarget, typename... Args>\n\t\tstruct [[nodiscard]] lazy_explicit_cast final : tc::nonmovable {\n\t\t\ttc::tuple<Args&&...> m_tuple;\n\t\t\t// std::remove_cv affects only values and leaves const/volatile references untouched, which is what we want.\n\t\t\tconstexpr operator TTarget() && return_MAYTHROW(\n\t\t\t\ttc_apply(tc::fn_explicit_cast<std::remove_cv_t<TTarget>>(), tc_move(m_tuple))\n\t\t\t)\n\t\t};\n\n\t\ttemplate <typename TTarget, typename... Args>\n\t\tstruct is_value_safely_constructible<TTarget, lazy_explicit_cast<TTarget, Args...>&&> : tc::constant<true> {};\n\t}\n\n\ttemplate<typename T, typename... Args> requires tc::explicit_castable_from<T, Args&&...>\n\tconstexpr tc::no_adl::lazy_explicit_cast<T, Args...> lazy_explicit_cast(Args&&... args) noexcept {\n\t\treturn { {}, tc::tie(tc_move_if_owned(args)...) };\n\t}\n\n\ttemplate<typename T, typename Arg> requires tc::explicit_castable_from<T, Arg&&>\n\tconstexpr decltype(auto) reluctant_lazy_explicit_cast(Arg&& arg) noexcept {\n\t\tif constexpr(tc::safely_constructible_from<T, Arg&&>) {\n\t\t\treturn tc_move_if_owned(arg);\n\t\t} else {\n\t\t\treturn tc::lazy_explicit_cast<T>(tc_move_if_owned(arg));\n\t\t}\n\t}\n\n\tnamespace detail {\n\t\ttemplate<typename T, typename Func, typename... Args, std::enable_if_t<static_cast<bool>(tc::safely_constructible_from<T, Args&&...>)>* = nullptr> // TODO CWG2369: https://cplusplus.github.io/CWG/issues/2369.html; static_cast to workaround gcc bug\n\t\tconstexpr auto with_lazy_explicit_cast_impl(Func func, Args&&... args) return_decltype_MAYTHROW(\n\t\t\tfunc(tc_move_if_owned(args)...)\n\t\t)\n\n\t\ttemplate<typename T, typename Func, typename... Args, std::enable_if_t<!static_cast<bool>(tc::safely_constructible_from<T, Args&&...>)>* = nullptr> // TODO CWG2369: https://cplusplus.github.io/CWG/issues/2369.html; static_cast to workaround gcc bug\n\t\tconstexpr auto with_lazy_explicit_cast_impl(Func func, Args&&... args) return_decltype_MAYTHROW(\n\t\t\tfunc(tc::lazy_explicit_cast<T>(tc_move_if_owned(args)...))\n\t\t)\n\t}\n\n\ttemplate<typename T, typename Func, typename... Args>\n\tconstexpr auto with_lazy_explicit_cast(Func&& func, Args&&... args) return_decltype_MAYTHROW(\n\t\ttc::detail::with_lazy_explicit_cast_impl<T>(tc_move_if_owned(func), tc_move_if_owned(args)...)\n\t)\n\n\tnamespace explicit_convert_adl {\n\t\t// std::pair\n\n\t\ttemplate<typename TTargetFirst, typename TTargetSecond, typename TSourceFirst, typename TSourceSecond>\n\t\t\t requires tc::explicit_castable_from<TTargetFirst, TSourceFirst&&>\n\t\t\t\t&& tc::explicit_castable_from<TTargetSecond, TSourceSecond&&>\n\t\tconstexpr auto explicit_convert_impl(adl_tag_t, std::type_identity<std::pair<TTargetFirst, TTargetSecond>>, TSourceFirst&& first, TSourceSecond&& second)\n\t\t\tnoexcept(\n\t\t\t\tnoexcept(tc::explicit_cast<TTargetFirst>(tc_move_if_owned(first))) &&\n\t\t\t\tnoexcept(tc::explicit_cast<TTargetSecond>(tc_move_if_owned(second)))\n\t\t\t)\n\t\t{\n\t\t\treturn std::pair<TTargetFirst, TTargetSecond>(\n\t\t\t\ttc::reluctant_lazy_explicit_cast<TTargetFirst>(tc_move_if_owned(first)),\n\t\t\t\ttc::reluctant_lazy_explicit_cast<TTargetSecond>(tc_move_if_owned(second))\n\t\t\t);\n\t\t}\n\n\t\t// std::optional\n\n\t\ttemplate<typename T, typename... TSource> requires tc::explicit_castable_from<T, TSource&&...>\n\t\tconstexpr std::optional<T> explicit_convert_impl(adl_tag_t, std::type_identity<std::optional<T>>, std::in_place_t, TSource&&... src) MAYTHROW {\n\t\t\treturn tc::with_lazy_explicit_cast<T> (\n\t\t\t\t[](auto&&... args) return_ctor_MAYTHROW(std::optional<T>, (std::in_place, tc_move_if_owned(args)...)),\n\t\t\t\ttc_move_if_owned(src)...\n\t\t\t);\n\t\t}\n\n\t\ttemplate<typename T, typename TSource>\n\t\tconstexpr auto explicit_convert_impl(adl_tag_t, std::type_identity<std::optional<T>>, TSource&& source) return_decltype_MAYTHROW(\n\t\t\tsource ? tc::explicit_cast<std::optional<T>>(std::in_place, *tc_move_if_owned(source)) : std::nullopt\n\t\t)\n\t}\n\n\ttemplate<typename T, typename... Args>\n\tconstexpr void optional_emplace(std::optional<T>& o, Args&& ... args) noexcept(noexcept(tc::explicit_cast<T>(tc_move_if_owned(args)...))) {\n\t\ttc::with_lazy_explicit_cast<T>(\n\t\t\t[&](auto&&... args2) MAYTHROW {\n\t\t\t\to.emplace(tc_move_if_owned(args2)...);\n\t\t\t},\n\t\t\ttc_move_if_owned(args)...\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "tc/base/explicit_cast_fwd.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits_fwd.h\"\n#include \"template_func.h\"\n#include \"invoke.h\"\n#include <array>\n\n//////////////////////////////////////////////////////////////////\n// generic initialization and assignment between different types\n//\n// Copy/move/assignment cannot be overloaded for third party types\n// or builtins.\n//\n// If tc::explicit_cast<T, S> is used to convert a builtin numeric type S into\n// another builtin numeric type T, rounding and range checks are\n// applied.\n//\n// For other types, the default behavior of explicit_cast is\n//   A a(tc::explicit_cast<A>(b))                       is equivalent to   A(a) ,\n//   a=tc::explicit_cast<remove_reference<A>::type>(b)  is equivalent to   a=b ,\n// i.e., the argument b is forwarded to the copy/move/assignment operators\n// of A.\n//\n// Specialize explicit_convert if additional conversions for specific target\n// types are required.\n\nnamespace tc {\n\tDEFINE_TAG_TYPE(fill_tag)\n\tDEFINE_TAG_TYPE(range_tag)\n\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct char_limits;\n\n\t\ttemplate<>\n\t\tstruct char_limits<char> {\n\t\t\tstatic constexpr std::size_t c_nMaxCodeUnitsPerCodePoint = 4;\n\n\t\t\t[[nodiscard]] static constexpr bool interval_in_range(unsigned int nFirst, unsigned int nLast) noexcept {\n\t\t\t\treturn nLast <= 0x7f;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<>\n\t\tstruct char_limits<char16_t> {\n\t\t\tstatic constexpr std::size_t c_nMaxCodeUnitsPerCodePoint = 2;\n\n\t\t\t[[nodiscard]] static constexpr bool interval_in_range(unsigned int nFirst, unsigned int nLast) noexcept {\n\t\t\t\treturn nLast <= 0xd7ff || (0xe000 <= nFirst && nLast <= 0xffff);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<>\n\t\tstruct char_limits<char32_t> {\n\t\t\tstatic constexpr std::size_t c_nMaxCodeUnitsPerCodePoint = 1;\n\n\t\t\t[[nodiscard]] static constexpr bool interval_in_range(unsigned int nFirst, unsigned int nLast) noexcept {\n\t\t\t\treturn nLast <= 0xd7ff || (0xe000 <= nFirst && nLast <= 0x10ffff);\n\t\t\t}\n\t\t};\n\n\t\tstruct char_limits_undefined_dummy {};\n\n\t\ttemplate<>\n\t\tstruct char_limits<wchar_t> :\n\t\t\tstd::conditional_t<\n\t\t\t\t2 == sizeof(wchar_t),\n\t\t\t\tchar_limits<char16_t>,\n\t\t\t\tstd::conditional_t<\n\t\t\t\t\t4 == sizeof(wchar_t),\n\t\t\t\t\tchar_limits<char32_t>,\n\t\t\t\t\tchar_limits_undefined_dummy\n\t\t\t\t>\n\t\t\t>\n\t\t{};\n\n\t}\n\tusing no_adl::char_limits;\n\n\ttemplate <typename T>\n\t[[nodiscard]] constexpr bool char_in_range(unsigned int const n) noexcept {\n\t\treturn char_limits<T>::interval_in_range(n, n);\n\t}\n\n\tnamespace explicit_convert_default {\n\t\t// This is the default explicit_convert, not a specialization, because aggregate initialization must have lower priority than other specializations which could also be aggregate types\n\t\t// Aggregate types are tc::safely_constructible_from same type (copy/move). This is handled in the default explicit_cast below.\n\t\ttemplate<typename TTarget, typename... Args> requires std::is_class<TTarget>::value && std::is_aggregate<TTarget>::value\n\t\tconstexpr auto explicit_convert_impl(std::type_identity<TTarget>, Args&&... args)\n\t\t\treturn_decltype_MAYTHROW( TTarget{tc_move_if_owned(args)...} )\n\n\t\ttemplate<typename T, std::size_t N, typename... Args>\n\t\tstd::array<T, N> explicit_convert_impl(std::type_identity<std::array<T, N>>, Args&&... args) = delete; // explicitly delete direct list construction of std::array\n\t}\n\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(explicit_convert)\n\n\tnamespace no_adl {\n\t\ttemplate<typename TTarget>\n\t\tstruct fn_internal_explicit_cast final {\n\t\t\ttemplate<typename... Args, std::enable_if_t<!tc::safely_constructible_from<std::remove_cv_t<TTarget>, Args&&...>>* = nullptr>\n\t\t\tconstexpr auto operator()(Args&&... args) const&\n\t\t\t\treturn_decltype_MAYTHROW(tc::explicit_convert(std::type_identity<std::remove_cv_t<TTarget>>(), tc_move_if_owned(args)...))\n\n\t\t\ttemplate<typename... Args> requires tc::safely_constructible_from<std::remove_cv_t<TTarget>, Args&&...>\n\t\t\tconstexpr auto operator()(Args&&... args) const&\n\t\t\t\treturn_ctor_MAYTHROW(std::remove_cv_t<TTarget>, (tc_move_if_owned(args)...))\n\t\t};\n\t}\n\n\ttemplate<typename TTarget>\n\t[[nodiscard]] constexpr auto explicit_cast(auto&&... args) return_decltype_MAYTHROW(\n\t\ttc_invoke_pack(no_adl::fn_internal_explicit_cast<TTarget>(), tc_move_if_owned(args))\n\t)\n\n\ttemplate<typename TTarget, typename... Args>\n\tconcept explicit_castable_from = requires { tc::explicit_cast<TTarget>(std::declval<Args>()...); };\n\n\t// Using decltype(this->member) ensures casting to the correct type even if member is shadowed (but disallows base classes).\n\t#define tc_member_init(member, ...) member(tc::explicit_cast<decltype(this->member)>(__VA_ARGS__))\n\n\tnamespace no_adl {\n\t\tstruct bool_context final {\n\t\t\ttemplate< typename T >\n\t\t\tconstexpr bool_context(T const& t) noexcept\n\t\t\t\t: tc_member_init(m_b, t)\n\t\t\t{}\n\t\t\tconstexpr operator bool() const& noexcept { return m_b; }\n\t\tprivate:\n\t\t\tbool m_b;\n\t\t};\n\t}\n\tusing no_adl::bool_context;\n\n\ttemplate<typename TTarget, typename TSource>\n\t[[nodiscard]] constexpr decltype(auto) reluctant_explicit_cast(TSource&& src) noexcept {\n\t\tSTATICASSERTSAME(std::remove_cvref_t<TTarget>, TTarget);\n\t\tif constexpr( tc::decayed_derived_from<TSource, TTarget> ) {\n\t\t\treturn tc_move_if_owned(src);\n\t\t} else {\n\t\t\treturn tc::explicit_cast<TTarget>(tc_move_if_owned(src));\n\t\t}\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// concepts\n\n\ttemplate <typename Func, typename T>\n\tconcept predicate = tc::invocable<Func const&, std::remove_cvref_t<T> const&>\n\t\t&& requires(Func const& f, std::remove_cvref_t<T> const& t) { tc::explicit_cast<bool>(tc_invoke(f, t)); };\n\ttemplate <typename Func, typename T>\n\tconcept nothrow_predicate = tc::predicate<Func, T> && tc::nothrow_invocable<Func const&, std::remove_cvref_t<T> const&>;\n\n\ttemplate <typename Func, typename T>\n\tconcept constant_predicate = tc::predicate<Func, T>\n\t\t&& requires(Func const& f, std::remove_cvref_t<T> const& t) { tc::explicit_cast<bool>(decltype(tc_invoke(f, t))::value); };\n\n\ttemplate <typename Func, typename T>\n\tconcept constant_predicate_true = tc::constant_predicate<Func, T>\n\t\t&& tc::explicit_cast<bool>(decltype(tc_invoke(std::declval<Func const&>(), std::declval<std::remove_cvref_t<T> const&>()))::value);\n\ttemplate <typename Func, typename T>\n\tconcept constant_predicate_false = tc::constant_predicate<Func, T>\n\t\t&& !tc::explicit_cast<bool>(decltype(tc_invoke(std::declval<Func const&>(), std::declval<std::remove_cvref_t<T> const&>()))::value);\n\n\ttemplate <typename Func, typename T>\n\tconcept runtime_predicate = tc::predicate<Func, T> && (!tc::constant_predicate<Func, T>);\n}\n"
  },
  {
    "path": "tc/base/functors.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"invoke.h\"\n\n#include <boost/preprocessor/seq/for_each_i.hpp>\n#include <boost/preprocessor/control/if.hpp>\n\n#include <cmath>\n#include <cstdlib>\n#include <algorithm>\n\n////////////////////////////////\n// functor equivalents for operators, free functions and member functions\n\n#define DEFINE_FN2( func, name ) \\\n\tstruct [[nodiscard]] name { \\\n\t\ttemplate< typename... Args > \\\n\t\tconstexpr auto operator()( Args&& ... args) /*no &*/ const \\\n\t\t\treturn_decltype_allow_xvalue_MAYTHROW( func(tc_move_if_owned(args)...) ) \\\n\t\tusing is_transparent=void; \\\n\t};\n\n#define DEFINE_MEM_FN_BODY_( ... ) \\\n\ttemplate< typename O, typename... __A > \\\n\tconstexpr auto operator()( O&& o, __A&& ... __a ) const \\\n\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_move_if_owned(o) __VA_ARGS__ ( tc_move_if_owned(__a)... ) )\n\n// std::mem_fn (C++11 standard 20.8.2) knows the type it can apply its member function pointer to and\n// dereferences via operator* until it reaches that something of that type. We cannot do that because\n// we have no type. Merely checking for the presence of the member function name is dangerous because\n// changes in otherwise unrelated types (the iterator and its pointee) would influence the lookup. \n// Instead we distinguish between shallow member access, implemented in dot_mem_fn, and deep \n// member access via operator->, with the small addition that if operator-> does not exist, we use the\n// the dot operator, in the spirit of dereferencing as much as possible.\n\n#define DEFINE_MEM_FN_AUTO_BODY_( ... ) \\\n\ttemplate< typename O, typename... __A, std::enable_if_t<tc::has_operator_arrow<O>::value>* = nullptr > \\\n\tconstexpr auto operator()( O&& o, __A&& ... __a ) const \\\n\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_move_if_owned(o)-> __VA_ARGS__ ( tc_move_if_owned(__a)... ) ) \\\n\ttemplate< typename O, typename... __A, std::enable_if_t<!tc::has_operator_arrow<O>::value>* = nullptr > \\\n\tconstexpr auto operator()( O&& o, __A&& ... __a ) const \\\n\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_move_if_owned(o). __VA_ARGS__ ( tc_move_if_owned(__a)... ) )\n\n// When a functor must be declared in class-scope, e.g., to access a protected member function,\n// you should use DEFINE_MEM_FN instead of tc_define_fn. \n// tc_define_fn always has to define a function named \"void func(define_fn_dummy_t)\" which may\n// shadow inherited members named func.\n#define DEFINE_MEM_FN( func ) \\\n\tstruct [[nodiscard]] dot_mem_fn_ ## func { \\\n\t\tDEFINE_MEM_FN_BODY_( .func ) \\\n\t}; \\\n\tstruct [[nodiscard]] mem_fn_ ## func { \\\n\t\tDEFINE_MEM_FN_AUTO_BODY_( func ) \\\n\t};\n\n#define tc_define_fn( func ) \\\n\tstatic void func(tc::define_fn_dummy_t) noexcept = delete; \\\n\tDEFINE_FN2( func, fn_ ## func ) \\\n\tDEFINE_MEM_FN( func )\n\n#define MEM_FN_TEMPLATE_DECLARATION(r, data, i, elem) BOOST_PP_COMMA_IF(i) elem T##i\n#define MEM_FN_TEMPLATE_INVOCATION(r, data, i, elem) BOOST_PP_COMMA_IF(i) T##i\n\n#define DEFINE_FN2_TMPL( func, tmpl ) \\\n    template< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_DECLARATION, _, tmpl ) > \\\n    DEFINE_FN2( func< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_INVOCATION, _, tmpl ) >, fn_ ## func )\n\n// See comments above for DEFINE_MEM_FN\n#define DEFINE_MEM_FN_TMPL( func, tmpl ) \\\n\ttemplate< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_DECLARATION, _, tmpl ) > \\\n\tstruct [[nodiscard]] dot_mem_fn_ ## func { \\\n\t\tDEFINE_MEM_FN_BODY_( .template func< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_INVOCATION, _, tmpl ) > ) \\\n\t}; \\\n\ttemplate< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_DECLARATION, _, tmpl ) > \\\n\tstruct [[nodiscard]] mem_fn_ ## func { \\\n\t\tDEFINE_MEM_FN_AUTO_BODY_( template func< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_INVOCATION, _, tmpl ) > ) \\\n\t};\n\n#define DEFINE_FN_TMPL( func, tmpl ) \\\n\ttemplate< BOOST_PP_SEQ_FOR_EACH_I( MEM_FN_TEMPLATE_DECLARATION, _, tmpl ) > \\\n\tstatic void func(tc::define_fn_dummy_t) noexcept = delete; \\\n\tDEFINE_FN2_TMPL( func, tmpl ) \\\n\tDEFINE_MEM_FN_TMPL( func, tmpl )\n\n\n#define tc_fn(...) ([](auto&&... args) return_decltype_allow_xvalue_MAYTHROW(__VA_ARGS__(tc_move_if_owned(args)...)))\n\nnamespace tc {\n\tconstexpr bool is_chained_member_access_expression(char const* const strExpr) noexcept {\n\t\t// This is a heuristic with false positives (e.g. complex template parameters).\n\t\tauto nArrowCount = 0;\n\t\tfor (auto it = strExpr; *it; ++it) {\n\t\t\tif ((')' == it[0] || ']' == it[0]) && ('.' == it[1] || ('-' == it[1] && '>' == it[2]) || '[' == it[1] || '(' == it[1])) {\n\t\t\t\t// We access the result of a function call, which might be a prvalue.\n\t\t\t\treturn true;\n\t\t\t} else if ('-' == it[0] && '>' == it[1]) {\n\t\t\t\t++nArrowCount;\n\t\t\t\tif (1 < nArrowCount) {\n\t\t\t\t\t// Chaining arrows is problematic, as an overloaded operator-> might create a temporary.\n\t\t\t\t\t// (Chaining dot is fine as it's not overloadable).\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate <typename Return, bool bIsChainedMemberAccessExpression, typename Obj>\n\t\tstruct mem_fn_return_type {\n\t\t\tusing type = Return;\n\t\t};\n\t\ttemplate <typename Return, bool bIsChainedMemberAccessExpression, typename Obj>\n\t\tstruct mem_fn_return_type<Return&&, bIsChainedMemberAccessExpression, Obj> {\n\t\t\tstatic_assert(!bIsChainedMemberAccessExpression, \"tc_mem_fn/tc_member cannot contain chained member function calls that ultimately return an xvalue\");\n\t\t\tusing type = tc::rewrap_temporary_t<Return&&, Obj>;\n\t\t};\n\t}\n\ttemplate <typename Return, bool bIsChainedMemberAccessExpression, typename Obj>\n\tusing mem_fn_return_type_t = typename no_adl::mem_fn_return_type<Return, bIsChainedMemberAccessExpression, Obj>::type;\n\n#define tc_mem_fn_impl(bIsChained, Obj, ...) noexcept(noexcept(__VA_ARGS__)) -> tc::mem_fn_return_type_t<decltype((__VA_ARGS__)), bIsChained, Obj> { \\\n\treturn __VA_ARGS__; \\\n}\n}\n\n#define tc_mem_fn(...) ([](auto&& _, auto&&... args) tc_mem_fn_impl(tc::is_chained_member_access_expression(#__VA_ARGS__), decltype(_), \\\n\ttc_unwrap_temporary(tc_move_if_owned(_))__VA_ARGS__(tc_move_if_owned(args)...) \\\n))\n\n#define tc_member(...) ([](auto&& _) tc_mem_fn_impl(tc::is_chained_member_access_expression(#__VA_ARGS__), decltype(_), \\\n\ttc_unwrap_temporary(tc_move_if_owned(_))__VA_ARGS__ \\\n))\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <typename... F>\n\t\tstruct [[nodiscard]] TC_EMPTY_BASES overload : std::remove_cvref_t<F>... {\n\t\t\tusing std::remove_cvref_t<F>::operator()...;\n\t\t\tconstexpr overload(F&&... f) noexcept : std::remove_cvref_t<F>(tc_move_if_owned(f))... {}\n\t\t};\n\t}\n\tusing no_adl::overload;\n\n\ttemplate <typename... F>\n\t[[nodiscard]] constexpr auto make_overload(F&&... f) noexcept {\n\t\treturn overload<F...>(tc_move_if_owned(f)...);\n\t}\n}\n\nDEFINE_FN2( operator delete, fn_operator_delete )\n\n// Cannot use DEFINE_FN2_TMPL here, since casts are build in and the compiler\n//(both clang and MSVC) does not accept passing a parameter pack to *_cast\n#pragma push_macro(\"DEFINE_CAST_\")\n#define DEFINE_CAST_(name, constexpr_) \\\n\tnamespace no_adl { \\\n\t\ttemplate <typename To> \\\n\t\tstruct [[nodiscard]] fn_ ## name final { \\\n\t\t\ttemplate<typename From> \\\n\t\t\tconstexpr_ auto operator()(From&& from) const return_decltype_allow_xvalue_MAYTHROW( tc_rewrap_temporary(From, name<To>(tc_unwrap_temporary(tc_move_if_owned(from)))) )  \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_ ## name;\n\nnamespace tc {\n\tDEFINE_CAST_(static_cast, constexpr)\n\tDEFINE_CAST_(reinterpret_cast, /*constexpr*/)\n\tDEFINE_CAST_(const_cast, constexpr)\n}\n\n#pragma pop_macro(\"DEFINE_CAST_\")\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct [[nodiscard]] fn_subscript final {\n\t\t\ttemplate <typename Lhs, typename Rhs>\n\t\t\tconstexpr auto operator()( Lhs&& lhs, Rhs&& rhs ) const&\n\t\t\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_rewrap_temporary(Lhs, tc_unwrap_temporary(tc_move_if_owned(lhs))[tc_unwrap_temporary(tc_move_if_owned(rhs))]) )\n\t\t};\n\t}\n\tusing no_adl::fn_subscript;\n\n#pragma push_macro(\"PREFIX_FN_\")\n#define PREFIX_FN_( name, op ) \\\n\tnamespace no_adl { \\\n\t\tstruct [[nodiscard]] fn_ ## name final { \\\n\t\t\ttemplate <typename T> \\\n\t\t\tconstexpr auto operator()(T&& t ) const \\\n\t\t\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_rewrap_temporary(T, op tc_unwrap_temporary(tc_move_if_owned(t))) ) \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_ ## name;\n\n\tPREFIX_FN_( logical_not, ! )\n\tPREFIX_FN_( indirection, * )\n\tPREFIX_FN_( increment, ++ )\n\tPREFIX_FN_( decrement, -- )\n\n#pragma pop_macro(\"PREFIX_FN_\")\n\n#pragma push_macro(\"INFIX_FN_\")\n#define INFIX_FN_( name, op ) \\\n\tnamespace no_adl { \\\n\t\tstruct [[nodiscard]] fn_ ## name final { \\\n\t\t\ttemplate <typename Lhs, typename Rhs> \\\n\t\t\tconstexpr auto operator()(Lhs&& lhs, Rhs&& rhs ) const& \\\n\t\t\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_rewrap_temporary(TC_FWD(Lhs, Rhs), tc_unwrap_temporary(tc_move_if_owned(lhs)) op tc_unwrap_temporary(tc_move_if_owned(rhs))) ) \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_ ## name;\n\n\tINFIX_FN_( bit_or, | )\n\tINFIX_FN_( bit_and, & )\n\tINFIX_FN_( bit_xor, ^ )\n\tINFIX_FN_( plus, + )\n\tINFIX_FN_( minus, - )\n\tINFIX_FN_( mul, * )\n\tINFIX_FN_( logical_or, || )\n\tINFIX_FN_( logical_and, && )\n\t// tc::fn_div defined in round.h\n\n#pragma pop_macro(\"INFIX_FN_\")\n\n#pragma push_macro(\"ASSIGN_FN_\")\n#define ASSIGN_FN_( name, op ) \\\n\tnamespace no_adl { \\\n\t\tstruct [[nodiscard]] fn_ ## name final { \\\n\t\t\ttemplate <typename Lhs, typename Rhs> \\\n\t\t\tconstexpr auto operator()(Lhs&& lhs, Rhs&& rhs ) const& \\\n\t\t\t\treturn_decltype_allow_xvalue_MAYTHROW( tc_rewrap_temporary(Lhs, tc_unwrap_temporary(tc_move_if_owned(lhs)) op tc_unwrap_temporary(tc_move_if_owned(rhs))) ) \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_ ## name;\n\n\tASSIGN_FN_( assign_bit_or, |= )\n\tASSIGN_FN_( assign_bit_and, &= )\n\tASSIGN_FN_( assign_bit_xor, ^= )\n\tASSIGN_FN_( assign_plus, += )\n\tASSIGN_FN_( assign_minus, -= )\n\tASSIGN_FN_( assign_mul, *= )\n\t// tc::fn_assign_div defined in round.h\n\tASSIGN_FN_( assign, = )\n\n#pragma pop_macro(\"ASSIGN_FN_\")\n\n#pragma push_macro(\"FN_LOGICAL_\")\n#define FN_LOGICAL_(name, op) \\\n\tnamespace no_adl { \\\n\t\tstruct [[nodiscard]] fn_assign_logical_ ## name { \\\n\t\t\ttemplate <typename Lhs, typename Rhs> \\\n\t\t\tconstexpr decltype(auto) operator()(Lhs&& lhs, Rhs&& rhs) const& noexcept(noexcept(tc_unwrap_temporary(lhs) = tc_unwrap_temporary(tc_move_if_owned(lhs)) op tc_unwrap_temporary(tc_move_if_owned(rhs)))) { \\\n\t\t\t\ttc_unwrap_temporary(lhs) = tc_unwrap_temporary(tc_move_if_owned(lhs)) op tc_unwrap_temporary(tc_move_if_owned(rhs)); \\\n\t\t\t\treturn tc_move_if_owned(lhs); \\\n\t\t\t} \\\n\t\t}; \\\n\t} \\\n\tusing no_adl::fn_assign_logical_ ## name;\n\n\tFN_LOGICAL_(or, ||)\n\tFN_LOGICAL_(and, &&)\n\n#pragma pop_macro(\"FN_LOGICAL_\")\n}\n"
  },
  {
    "path": "tc/base/fundamental.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include <boost/preprocessor/seq/elem.hpp>\n#include <boost/preprocessor/seq/for_each.hpp>\n\n#include <cstdint>\n#include <limits>\n\n#ifdef _MSC_VER\n\t#define MODIFY_WARNING_HELPER(r, data, subseq) __pragma( warning( BOOST_PP_SEQ_ELEM(0, subseq): BOOST_PP_SEQ_ELEM(1, subseq) ) )\n\t#define MODIFY_WARNINGS(seq) BOOST_PP_SEQ_FOR_EACH(MODIFY_WARNING_HELPER, _, seq)\n\t#define MODIFY_WARNINGS_BEGIN(seq) \\\n\t\t__pragma( warning( push ) ) \\\n\t\tMODIFY_WARNINGS(seq)\n\t#define MODIFY_WARNINGS_END __pragma( warning( pop ) )\n#else\n\t#define MODIFY_WARNINGS(seq)\n\t#define MODIFY_WARNINGS_BEGIN(seq)\n\t#define MODIFY_WARNINGS_END\n#endif\n\n#ifdef _MSC_VER\n\t// https://devblogs.microsoft.com/cppblog/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/\n\t#define TC_EMPTY_BASES __declspec(empty_bases)\n#else\n\t#define TC_EMPTY_BASES\n#endif\n\n#if 201803L <= __has_cpp_attribute(unlikely)\n\t// There is also the [[likely]] attribute, but we prefer to only annotate unlikely code paths to avoid redundancy.\n\t#define TC_UNLIKELY [[unlikely]]\n#else\n\t#define TC_UNLIKELY\n#endif\n\n#ifdef _MSC_VER\n\t#define TC_FORCEINLINE [[msvc::forceinline]]\n#else\n\t#define TC_FORCEINLINE [[gnu::always_inline, gnu::nodebug]]\n#endif\n\n\n#define THROW(...) noexcept(false)\n\n// MAYTHROW is introduced for those very generic functions which may throw only with a few types, but we cannot\n// handle the exceptions in those functions. The exceptions should be handled where the function is called.\n#define MAYTHROW noexcept(false)\n\n// #define FOO(x) FOO_(TC_FWD(x))\n// Always use TC_FWD instead of parentheses to forward an argument to another macro. If the expansion of x has\n// unshielded comma(s), TC_FWD(x) will still be recognized as a single argument by FOO_ and then forward x\n// to FOO_ with its comma(s), but without putting extra parentheses around x as FOO_((x)) would do.\n#define TC_FWD(...) __VA_ARGS__\n\nnamespace tc {\n\t// Used for explicitly discarding return value from function decorated with [[nodiscard]] attribute.\n\t// Also used to suppress 'unused variable' warnings, if no better option available.\n\ttemplate <typename T>\n\tconstexpr void discard(T&&) noexcept{}\n}\n\n#ifdef _MSC_VER\n\t// MSVC generates null checks when upcasting this (https://godbolt.org/z/o6zhWaKGo).\n\t#define MSVC_WORKAROUND_THIS (__assume(nullptr != this), this)\n#else\n\t#define MSVC_WORKAROUND_THIS this\n#endif\n\n#ifdef _MSC_VER\n\t// MSVC seems to mistake the .template memfn<...>(...) syntax for the beginning of a template class.\n\t// Supposedly, this has been fixed in VS2019, but we still see it happening in a few places.\n\t#define MSVC_TEMPLATE_WORKAROUND\n#else\n\t#define MSVC_TEMPLATE_WORKAROUND template\n#endif\n\n#ifdef _MSC_VER\n#define MSVC_WORKAROUND // comment out this line for Microsoft internal compiler unit test\n#endif\n\n#ifdef MSVC_WORKAROUND\n#define IF_MSVC_WORKAROUND(...) __VA_ARGS__\n#define IF_NO_MSVC_WORKAROUND(...)\n#define IF_MSVC_WORKAROUND_ELSE(argMsvc, argNoMsvc) argMsvc\n#else\n#define IF_MSVC_WORKAROUND(...)\n#define IF_NO_MSVC_WORKAROUND(...) __VA_ARGS__\n#define IF_MSVC_WORKAROUND_ELSE(argMsvc, argNoMsvc) argNoMsvc\n#endif\n\n#ifndef __clang__ \n#define TC_REQUIRES_CWG2369_WORKAROUND(cond) > requires (cond)\n#else\n#define TC_REQUIRES_CWG2369_WORKAROUND(cond) , /*not requires because of CWG issue 2369*/ std::enable_if_t<(cond)>* = nullptr>\n#endif\n\n#if defined(TC_PRIVATE) && defined(_MSC_VER)\n// Please update *.natvis on modification\n#define no_adl NQ\n#define cont_emplace_back_detail NQ0\n#define transform_adaptor_adl NQ1\n#define concat_adaptor_adl NQ2\n#define RefT_adl NQ3\n#define generator_range_output_adaptor_adl NQ4\n#define interval_adl NQ5\n#define empty_range_adl NQ6\n#define select_range_adaptor_adl NQ7\n#define tuple_adl NQ8\n#define _precT_adl NQ9\n#define point_adl NQA\n#define counting_iterator_adl NQB\n#define cartesian_product_adaptor_adl NQC\n#define union_adaptor_adl NQD\n#define dense_map_adl NQE\n#define append_no_adl NQF\n#define explicit_convert_adl NQG\n#define for_each_adl NQH\n#define size_proxy_adl NQI\n#define expanding_invoke_adl NQJ\n#define literal_range_adl NQK\n#define as_constexpr_no_adl NQL\n#define less_key_adl NQM\n#define lohi_adl NQN\n#define sign_adl NQO\n#define adjacent_adaptor_adl NQP\n#define cartesian_product_adaptor_detail NQQ\n#define reverse_adaptor_adl NQR\n#define tuple_detail NQS\n#define debug_output_impl_ns NQT\n#define debug_output_adl NQU\n#define hash_append_detail NQV\n#define hash_append_adl NQW\n#define enumset_adl NQX\n#define make_lazy_adl NQY\n#define static_auto_constexpr_no_adl NQZ\n#define invoke_detail NQa\n#define SNamedPropT_adl NQb\n#define _fill_adl NQc\n#define integral_as_padded_dec_adl NQd\n#define section_entry_detail NQe\n#define restricted_enum_adl NQf\n#define _linestyle_adl NQg\n#define index_iterator_impl NQh\n#define SGridline_adl NQi\n#define void_generator_type_check_no_adl NQj\n#define EnterReportSection_detail NQk\n//NQl\n#define static_vector_adl NQm\n#define com_ptr_adl NQn\n#define EDateFormatType_adl NQo\n#define value_epsilon_adl NQp\n#define generator_range_adl NQq\n#define find_first_if_detail NQr\n#define convert_enc_impl NQs\n#define iterator_facade_adl NQt\n#define unique_adaptor_adl NQu\n#define strong_typedef_adl NQv\n#define explicit_convert_std_array_detail NQw\n#endif\n"
  },
  {
    "path": "tc/base/generic_macros.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include <boost/preprocessor/arithmetic/dec.hpp>\n#include <boost/preprocessor/comparison/equal.hpp>\n#include <boost/preprocessor/comparison/less.hpp>\n#include <boost/preprocessor/control/if.hpp>\n#include <boost/preprocessor/seq/cat.hpp>\n#include <boost/preprocessor/seq/elem.hpp>\n#include <boost/preprocessor/seq/enum.hpp>\n#include <boost/preprocessor/seq/for_each.hpp>\n#include <boost/preprocessor/seq/for_each_i.hpp>\n#include <boost/preprocessor/seq/push_back.hpp>\n#include <boost/preprocessor/seq/push_front.hpp>\n#include <boost/preprocessor/seq/pop_back.hpp>\n#include <boost/preprocessor/seq/seq.hpp>\n#include <boost/preprocessor/seq/size.hpp>\n#include <boost/preprocessor/seq/transform.hpp>\n#include <boost/preprocessor/seq/reverse.hpp>\n#include <boost/preprocessor/tuple/eat.hpp>\n\n#define TC_EXPAND(...) __VA_ARGS__\n\n#define TC_PP_APPLY_MACRO(state, macro, elem) macro(elem)\n\n// According to boost reference https://www.boost.org/doc/libs/1_73_0/libs/preprocessor/doc/ref/seq_nil.html,\n// BOOST_PP_SEQ_NIL is only a placeholder for BOOST_PP_SEQ_PUSH_BACK.\n// We should not use BOOST_PP_SEQ_NIL as an empty sequence when calling BOOST_PP_SEQ_xxx macros (except BOOST_PP_SEQ_PUSH_BACK).\n// However, TC_PP_SEQ_xxx macros support BOOST_PP_SEQ_NIL as an empty sequence. We should use TC_PP_SEQ_xxx if the sequence can be NIL. \n\n#define TC_PP_SEQ_SIZE(seq) BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_PUSH_BACK(seq,~)))\n#define TC_PP_SEQ_IS_NIL(seq) BOOST_PP_EQUAL(TC_PP_SEQ_SIZE(seq),0 )\n\n#define TC_PP_IF(cond, t, f) BOOST_PP_EXPAND(TC_FWD BOOST_PP_IF(cond, (t), (f)))\n#define TC_PP_IF_SEQ_NOT_NIL(seq, ...) TC_PP_IF(TC_PP_SEQ_IS_NIL(seq), , TC_FWD(__VA_ARGS__))\n\n#define TC_PP_SEQ_HELPER_PUSH_FRONT_TO_NIL(seq, elem) (elem)\n#define TC_PP_SEQ_PUSH_FRONT(seq, elem) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), TC_PP_SEQ_HELPER_PUSH_FRONT_TO_NIL, BOOST_PP_SEQ_PUSH_FRONT)(seq, elem)\n\n#define TC_PP_SEQ_HELPER_TO_NIL(seq) BOOST_PP_SEQ_NIL\n#define TC_PP_SEQ_POP_BACK(seq) \\\n\tBOOST_PP_IF(BOOST_PP_DEC(TC_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_POP_BACK, TC_PP_SEQ_HELPER_TO_NIL)(seq)\n\n#define TC_PP_SEQ_CAT(seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, BOOST_PP_SEQ_CAT)(seq)\n\n#define TC_PP_SEQ_FOR_EACH(macro, data, seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, BOOST_PP_SEQ_FOR_EACH)(macro, data, seq)\n\n#define TC_PP_SEQ_ENUM(seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, BOOST_PP_SEQ_ENUM)(seq)\n\n#define TC_PP_SEQ_TRANSFORM(op, data, seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, BOOST_PP_SEQ_TRANSFORM)(op, data, seq)\n\n// expands to \"macro(elem1)macro(elem2)...macro(elemN)\"\n#define TC_PP_CAT_TRANSFORMED_SEQ(macro, seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, TC_PP_SEQ_CAT)(TC_PP_SEQ_TRANSFORM(TC_PP_APPLY_MACRO, macro, seq))\n\n// expands to \"op(elem1), op(elem2), ...., op(elemN)\"\n#define TC_PP_ENUM_TRANSFORMED_SEQ(op, data, seq) \\\n\tBOOST_PP_IF(TC_PP_SEQ_IS_NIL(seq), BOOST_PP_EAT, BOOST_PP_SEQ_ENUM)(TC_PP_SEQ_TRANSFORM(op, data, seq))\n\n// expands to \"macro(elem1) macro(elem2) macro(elemN)\"\n#define TC_PP_UNPACK_TRANSFORMED_SEQ(macro, seq) \\\n\tTC_PP_SEQ_FOR_EACH(TC_PP_APPLY_MACRO, macro, seq)\n\n// expands to \"(macro(elem))(delimiter)\"\n#define TC_PP_HELPER_DELIMIT_TRANSFORMED_SEQ(state, pair, elem) \\\n\t(BOOST_PP_SEQ_ELEM(0, pair)(elem))(BOOST_PP_SEQ_ELEM(1, pair))\n\n// expands to \"macro(elem1) delimiter macro(elem2) delimiter ... delimiter macro(elemN)\"\n#define TC_PP_DELIMIT_TRANSFORMED_SEQ(macro, delimiter, seq) \\\n\tTC_PP_UNPACK_TRANSFORMED_SEQ( \\\n\t\tTC_EXPAND, \\\n\t\tTC_PP_SEQ_POP_BACK(BOOST_PP_IF( \\\n\t\t\tTC_PP_SEQ_SIZE(seq), \\\n\t\t\tTC_PP_SEQ_FOR_EACH(TC_PP_HELPER_DELIMIT_TRANSFORMED_SEQ, (macro)(delimiter), seq), /*(macro(elem1))(delimiter)...(delimiter)(macro(elemN))(delimiter)*/ \\\n\t\t\tBOOST_PP_SEQ_NIL \\\n\t\t)) /*(macro(elem1))(delimiter)...(delimiter)(macro(elemN))*/ \\\n\t)\n\n// expands a parameter seq into its pack:\n// ((type)(...)(name)) --> ...\n// ((type)(name)) -->\n#define TC_PP_PARAM_PACK(seq) \\\n\tBOOST_PP_IF(BOOST_PP_EQUAL(TC_PP_SEQ_SIZE(seq),3), BOOST_PP_SEQ_ELEM, BOOST_PP_EAT)(1, seq)\n\n// expands a parameter seq into its type:\n// ((type)(...)(name)) --> type\n// ((type)(name)) --> type\n#define TC_PP_PARAM_TYPE(seq) \\\n\tBOOST_PP_SEQ_ELEM(0, seq)\n\n// expands a parameter seq into its type pack:\n// ((type)(...)(name)) --> type ...\n// ((type)(name)) --> type\n#define TC_PP_PARAM_TYPE_PACK(seq) \\\n\tTC_PP_PARAM_TYPE(seq) TC_PP_PARAM_PACK(seq)\n\n// expands a parameter seq into its name:\n// ((type)(...)(name)) --> name\n// ((type)(name)) --> name\n#define TC_PP_PARAM_NAME(seq) \\\n\tBOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(seq))\n\n// expands a parameter seq into its name pack:\n// ((type)(...)(name)) --> name ...\n// ((type)(name)) --> name\n#define TC_PP_PARAM_NAME_PACK(seq) \\\n\tTC_PP_PARAM_NAME(seq) TC_PP_PARAM_PACK(seq)\n\n// expands a parameter seq:\n// ((type)(...)(name)) --> type ... name\n// ((type)(name)) --> type name\n#define TC_PP_PARAM(seq) \\\n\tTC_PP_PARAM_TYPE_PACK(seq) TC_PP_PARAM_NAME(seq)\n\n// expands a variable pair into its type:\n// ((type)(name)) --> type\n#define TC_PP_PAIR_VAR_TYPE(pairTypeName) \\\n\tBOOST_PP_SEQ_ELEM(0, pairTypeName)\n\n// expands a variable pair into its name:\n// ((type)(name)) --> name\n#define TC_PP_PAIR_VAR_NAME(pairTypeName) \\\n\tBOOST_PP_SEQ_ELEM(1, pairTypeName)\n\n// expands a variable pair:\n// ((type)(name)) --> type name\n#define TC_PP_PAIR_VAR(pairTypeName) \\\n\tTC_PP_PAIR_VAR_TYPE(pairTypeName) TC_PP_PAIR_VAR_NAME(pairTypeName)\n\n// expands a variable pair into its definition (with semicolon, useful for defining members from a list of pairs)\n// ((type)(name)) --> type name;\n#define TC_PP_PAIR_VAR_DEFINE(pairTypeName) \\\n\tTC_PP_PAIR_VAR(pairTypeName);\n\n// expands parameter seq to enum. e.g. (template|function definition) parameter list supporting optional parameter pack:\n// \"type1 (...)? name1, type2 (...)? name2, ... , typeN (...)? nameN\"\n#define TC_PP_PARAMS_ENUM(seqArgs) \\\n\tTC_PP_ENUM_TRANSFORMED_SEQ(TC_PP_APPLY_MACRO, TC_PP_PARAM, seqArgs)\n\n// expands parameter seq to argument enum (losing the types). e.g. (template|function call) argument list supporting optional parameter pack:\n// \"name1 (...)?, name2 (...)?, ... , nameN (...)?\"\n#define TC_PP_PARAMS_ARG_ENUM(seqArgs) \\\n\tTC_PP_ENUM_TRANSFORMED_SEQ(TC_PP_APPLY_MACRO, TC_PP_PARAM_NAME_PACK, seqArgs)\n\n// expands parameter seq to type enum (losing the names). e.g. (template template|function decl) parameter list supporting optional parameter pack:\n// \"type1 (...)?, type2 (...)?, ... , typeN (...)?\n#define TC_PP_PARAMS_TYPE_ENUM(seqArgs) \\\n\tTC_PP_ENUM_TRANSFORMED_SEQ(TC_PP_APPLY_MACRO, TC_PP_PARAM_TYPE_PACK, seqArgs)\n\n#define TC_OP_PAIR_TO_SPACE_SEPARATED_PAIR(state, data, pair) \\\n\tBOOST_PP_SEQ_ELEM(0, pair) BOOST_PP_SEQ_ELEM(1, pair)\n\n#define TC_OP_PAIR_TO_1ST_ELEMENT(state, data, pair) \\\n\tBOOST_PP_SEQ_ELEM(0, pair)\n\n#define TC_OP_PAIR_TO_2ND_ELEMENT(state, data, pair) \\\n\tBOOST_PP_SEQ_ELEM(1, pair)\n\n// Macro for accessing nameless union members within MS structs, which we can't control (can't name the union).\n// In Mac nameless union is not allowed, so the union has a name.\n#ifdef __clang__\n#define WIN32_UNION_MEMBER(_obj_ptr, _member) \\\n    (_obj_ptr)->DUMMYUNIONNAME._member\n#else\n#define WIN32_UNION_MEMBER(_obj_ptr, _member) \\\n    (_obj_ptr)->_member\n#endif\n\n// Use if you have to check if an expression compiles, e.g., to check if an operator is defined, a cast is valid etc\n#define TC_HAS_EXPR_TEMPLATE_PARAMETER(Type) typename Type\n#define TC_HAS_EXPR(name, seqArgs, ...) \\\ntemplate< BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(TC_PP_APPLY_MACRO, TC_HAS_EXPR_TEMPLATE_PARAMETER, seqArgs)) > \\\nconcept has_ ## name = requires { __VA_ARGS__; };\n"
  },
  {
    "path": "tc/base/has_xxx.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n\n#include <type_traits>\n#include <utility>\n\n#define TC_HAS_MEM_FN_XXX_CONCEPT_DEF( name, decoration, ... ) \\\n\ttemplate<typename T> \\\n\tconcept has_mem_fn_ ## name = requires { std::declval<T decoration >().name( __VA_ARGS__ ); };\n\n#define TC_HAS_STATIC_FN_XXX_CONCEPT_DEF( name, ... ) \\\n\ttemplate<typename T> \\\n\tconcept has_static_fn_ ## name = requires { T::name(__VA_ARGS__); };\n"
  },
  {
    "path": "tc/base/inplace.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"noncopyable.h\"\n#include \"has_xxx.h\"\n#include \"move.h\"\n#include \"type_traits_fwd.h\"\n#include <atomic>\n\n// Defined as a macro, to preserve the short-circuiting semantics of && and ||\n// Example:\n//\tbool b = ...;\n//\ttc_inplace(b) && bool_convertible_condition()\n//\ttc_inplace(b) || bool_convertible_condition()\n#define tc_inplace(expr) \\\n\t(expr)=VERIFYINITIALIZED(expr)\n\n\nnamespace tc {\n\tnamespace inplace_adl {\n\t\ttemplate< typename T >\n\t\tstruct [[nodiscard]] inplace final : tc::noncopyable {\n\t\t\tconstexpr explicit inplace(T& t) noexcept:m_t(VERIFYINITIALIZED(t)){}\n\t\t\tT& m_t;\n\t\t};\n\t}\n\tusing inplace_adl::inplace;\n\n#pragma push_macro(\"DEFINE_INPLACE_OPERATOR\")\n#define DEFINE_INPLACE_OPERATOR(op, name) \\\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF( name, & ) \\\n\t\\\n\tnamespace inplace_adl { \\\n\t\ttemplate< typename T > \\\n\t\tconstexpr void operator op(inplace<T> t) noexcept { \\\n\t\t\tt.m_t=op tc_move_always(t.m_t); \\\n\t\t} \\\n\t\t\\\n\t\ttemplate< has_mem_fn_ ## name T > \\\n\t\tconstexpr void operator op(inplace<T> t) noexcept { \\\n\t\t\tt.m_t.name(); \\\n\t\t} \\\n\t\t\\\n\t\ttemplate< typename T > \\\n\t\tvoid operator op(inplace<std::atomic<T>> t) noexcept { \\\n\t\t\tstatic_assert( !has_mem_fn_ ## name<T> ); \\\n\t\t\tT tCurrent = t.m_t.load(std::memory_order_relaxed); \\\n\t\t\twhile (!t.m_t.compare_exchange_weak(tCurrent, op tCurrent)) \\\n\t\t\t\t{} \\\n\t\t} \\\n\t} \\\n\t\\\n\ttemplate<typename T> \\\n\tconstexpr T name(T t) noexcept { \\\n\t\top tc::inplace(t); \\\n\t\treturn t; \\\n\t}\n\n\tDEFINE_INPLACE_OPERATOR(-, negate)\n\tDEFINE_INPLACE_OPERATOR(~, bitwise_not)\n\tDEFINE_INPLACE_OPERATOR(!, logical_not)\n#pragma pop_macro(\"DEFINE_INPLACE_OPERATOR\")\n}\n"
  },
  {
    "path": "tc/base/inside_unwinding.h",
    "content": "#pragma once\n\n#include \"assert_defs.h\"\n#include <exception>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct inside_unwinding {\n\t\t\tinside_unwinding() noexcept\n\t\t\t: m_nUncaughtExceptions(std::uncaught_exceptions())\n\t\t\t{}\n\t\t\tinside_unwinding(inside_unwinding const&) noexcept\n\t\t\t: inside_unwinding()\n\t\t\t{}\n\t\t\tinside_unwinding& operator=(inside_unwinding const&) & noexcept {\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tbool inside_stack_unwinding() const& noexcept {\n\t\t\t\tint const nUncaughtExceptions = std::uncaught_exceptions();\n\t\t\t\t_ASSERT(m_nUncaughtExceptions<=nUncaughtExceptions);\n\t\t\t\treturn m_nUncaughtExceptions<nUncaughtExceptions;\n\t\t\t}\n\t\tprivate:\n\t\t\tint const m_nUncaughtExceptions;\n\t\t};\n\t}\n\tusing no_adl::inside_unwinding;\n}\n"
  },
  {
    "path": "tc/base/integer.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits_fwd.h\"\n#include \"explicit_cast.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<int nBits>\n\t\tstruct int_least;\n\n\t\ttemplate<int nBits> requires (nBits<=std::numeric_limits<std::intmax_t>::digits)\n\t\tstruct int_least<nBits> {\n\t\t\tusing type=typename boost::int_t<nBits+1>::least; // boost::int_t<Bits>::least uses bit-width including sign bit\n\t\t};\n\n\t\ttemplate<int nBits>\n\t\tstruct uint_least;\n\n\t\ttemplate<int nBits> requires (nBits<=std::numeric_limits<std::uintmax_t>::digits)\n\t\tstruct uint_least<nBits> {\n\t\t\tusing type=typename boost::uint_t<nBits>::least;\n\t\t};\n\t}\n\n\t// nBits is the number of radix-2 digits the type can represent without change. It does not include sign bit. nBits<=std::numeric_limits<tc::int_least_t<nBits>>::digits.\n\ttemplate<int nBits>\n\tusing int_least_t = typename no_adl::int_least<nBits>::type;\n\n\ttemplate<int nBits>\n\tusing uint_least_t = typename no_adl::uint_least<nBits>::type;\n\t\n\tnamespace actual_integer_like_detail {\n\t\ttemplate<typename T>\n\t\tinline constexpr bool actual_integer_like_impl = tc::actual_integer<T>;\n\t}\n\ttemplate<typename T>\n\tconcept actual_integer_like = actual_integer_like_detail::actual_integer_like_impl<T>;\n\n\tnamespace floating_point_like_detail {\n\t\ttemplate<typename T>\n\t\tinline constexpr bool floating_point_like_impl = std::floating_point<T>;\n\t}\n\ttemplate<typename T>\n\tconcept floating_point_like = floating_point_like_detail::floating_point_like_impl<T>;\n\n\t// checks whether arithmetic operations Lhs op Rhs preserve values of Lhs and Rhs (vs. silently converting one to unsigned)\n\ttemplate< typename Lhs, typename Rhs >\n\tstruct arithmetic_operation_preserves_sign : tc::constant<\n\t\t// std::is_signed is false for non-arithmetic (e.g., user-defined) types. In this case, we check that the result of addition is signed. This presumably ensures that there is no silent conversion to unsigned.\n\t\t(!std::is_signed<Lhs>::value && !std::is_signed<Rhs>::value) || std::is_signed<decltype(std::declval<Lhs>()+std::declval<Rhs>())>::value\n\t> {\n\t\tstatic_assert(tc::actual_integer<Lhs>);\n\t\tstatic_assert(tc::actual_integer<Rhs>);\n\t};\n\n\tstatic_assert( !tc::arithmetic_operation_preserves_sign<unsigned int, int>::value );\n\tstatic_assert( tc::arithmetic_operation_preserves_sign<unsigned char, int>::value );\n\n\ttemplate<typename Lhs, typename Rhs, typename T>\n\tconstexpr auto prepare_argument(T t) noexcept {\n\t\tif constexpr( tc::arithmetic_operation_preserves_sign<Lhs,Rhs>::value ) {\n\t\t\treturn t;\n\t\t} else {\n\t\t\treturn tc::as_unsigned(t);\n\t\t}\n\t}\n\n\ttemplate< typename Lhs, tc::actual_integer Rhs> requires tc::actual_integer<Lhs> || tc::char_type<Lhs>\n\t[[nodiscard]] constexpr Lhs add( Lhs lhs, Rhs rhs ) noexcept {\n\t\tif constexpr( std::is_signed<Lhs>::value ) {\n\t\t\t// does not rely on implementation-defined truncation of integers\n\t\t\ttc_return_cast( lhs+tc::explicit_cast< std::make_signed_t<decltype(lhs+rhs)>>(rhs) );\n\t\t} else {\n\t\t\t// modulo semantics, both arguments are zero- or sign-extended to unsigned and the result truncated\n\t\t\treturn static_cast<Lhs>(lhs+rhs);\n\t\t}\n\t}\n\n\ttemplate< typename Lhs, tc::actual_integer Rhs> requires tc::actual_integer<Lhs> || tc::char_type<Lhs>\n\t[[nodiscard]] constexpr Lhs sub( Lhs lhs, Rhs rhs ) noexcept {\n\t\tif constexpr( std::is_signed<Lhs>::value ) {\n\t\t\t// does not rely on implementation-defined truncation of integers\n\t\t\ttc_return_cast( lhs-tc::explicit_cast< std::make_signed_t<decltype(lhs-rhs)>>(rhs) );\n\t\t} else {\n\t\t\t// modulo semantics, both arguments are zero- or sign-extended to unsigned and the result truncated\n\t\t\treturn static_cast<Lhs>(lhs-rhs);\n\t\t}\n\t}\n\n\ttemplate<typename T>\n\tconstexpr T& assign_add(T& lhs, T rhs) noexcept {\n\t\tstatic_assert( tc::actual_integer<T> );\n\t\t_ASSERTE( lhs < 0\n\t\t\t? std::numeric_limits<T>::lowest() - lhs <= rhs\n\t\t\t: rhs <= std::numeric_limits<T>::max() - lhs\n\t\t);\n\t\treturn lhs += rhs;\n\t}\n\n\ttemplate<typename T>\n\tconstexpr T& assign_mul(T& lhs, T rhs) noexcept {\n\t\tstatic_assert( tc::actual_integer<T> );\n\t\t_ASSERTE(\n\t\t\tlhs <= 0\n\t\t\t\t? rhs <= 0\n\t\t\t\t\t? 0 == lhs || std::numeric_limits<T>::max() / lhs <= rhs\n\t\t\t\t\t: 0 == rhs || std::numeric_limits<T>::lowest() / rhs <= lhs\n\t\t\t\t: rhs <= 0\n\t\t\t\t\t? std::numeric_limits<T>::lowest() / lhs <= rhs\n\t\t\t\t\t: rhs <= std::numeric_limits<T>::max() / lhs\n\t\t);\n\t\treturn lhs *= rhs;\n\t}\n\n\ttemplate<typename B, typename E>\n\t[[nodiscard]] constexpr auto pow(B const base, E exp) noexcept -> decltype(base * base) {\n\t\tstatic_assert( tc::actual_integer<B> );\n\t\tstatic_assert( tc::actual_integer<E> );\n\t\tusing R = decltype(base * base);\n\t\tR result = 1;\n\t\tif( 0 != exp ) {\n\t\t\t_ASSERTE( 0 < exp );\n\t\t\tR rbase = base;\n\t\t\tfor (;;) {\n\t\t\t\tif( 1 == exp % 2 ) {\n\t\t\t\t\ttc::assign_mul(result, rbase);\n\t\t\t\t}\n\t\t\t\texp /= 2;\n\t\t\t\tif( 0 == exp ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttc::assign_mul(rbase, rbase);\n\t\t\t}\n\t\t} else {\n\t\t\t_ASSERTE( 0 != base );\n\t\t}\n\t\treturn result;\n\t}\n}\n"
  },
  {
    "path": "tc/base/invoke.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"utility.h\"\n#include \"tag_type.h\"\n\n#include <boost/preprocessor/punctuation/comma_if.hpp>\n#include <boost/preprocessor/seq/seq.hpp>\n#include <boost/preprocessor/seq/for_each_i.hpp>\n#include <boost/preprocessor/variadic/to_seq.hpp>\n\nnamespace tc {\n\t//////////////////////////////////////////////////////////////////////////\n\t// invoke\n\tnamespace invoke_detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate <typename Arg>\n\t\t\tstruct expanded final {\n\t\t\t\tusing indices = std::index_sequence<0>;\n\n\t\t\t\ttemplate <std::size_t I>\n\t\t\t\tstatic constexpr Arg&& select(Arg&& arg) noexcept {\n\t\t\t\t\tSTATICASSERTEQUAL(I, 0);\n\t\t\t\t\treturn tc_move_if_owned(arg);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate <typename Tuple> requires tc::tuple_like<tc::remove_ref_temporary_t<Tuple>>\n\t\t\tstruct expanded<Tuple> final {\n\t\t\t\tusing indices = std::make_index_sequence<std::tuple_size<tc::remove_ref_temporary_t<Tuple>>::value>;\n\n\t\t\t\ttemplate <std::size_t I>\n\t\t\t\tstatic constexpr decltype(auto) select(Tuple&& tpl) noexcept {\n\t\t\t\t\t// While tc_decrement_lifetime, tc_increment_lifetime are correct here, it increases compile time of tcaddin by 20% on Mac.\n\t\t\t\t\treturn /*tc_decrement_lifetime(*/tc::get<I>(/*tc_increment_lifetime(*/tc_move_if_owned(tpl))/*))*/;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tusing no_adl::expanded;\n\n\t\t// We use ADL to workaround cyclic dependencies.\n\t\tnamespace expanding_invoke_adl {\n\t\t\tDEFINE_ADL_TAG_TYPE(tag)\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\tstruct overload_temporary {};\n\t\t\tstruct overload_remove_temporary {};\n\t\t\tstruct overload_expanded {};\n\t\t}\n\t\tusing no_adl::overload_temporary;\n\t\tusing no_adl::overload_remove_temporary;\n\t\tusing no_adl::overload_expanded;\n\n\t\t// Simplify using requires on invoke once xcode implements CWG issue 2369.\n\t\ttemplate <bool bForceExpand, typename Func, typename ... Args>\n\t\tconstexpr auto select_overload() noexcept {\n\t\t\tif constexpr (bForceExpand) {\n\t\t\t\treturn overload_expanded{};\n\t\t\t} else if constexpr (requires(Func&& func, Args&&... args) { tc_move_if_owned(func)(tc_move_if_owned(args)...); }) {\n\t\t\t\tusing result_type = decltype(std::declval<Func>()(std::declval<Args>()...));\n\t\t\t\tstatic_assert(!tc::instance_tn<std::remove_reference_t<result_type>, tc::temporary>, \"function returns a dangling temporary\");\n\t\t\t\tif constexpr (std::is_rvalue_reference<result_type>::value) {\n\t\t\t\t\treturn overload_temporary{}; // if the return type when called with xvalues is an xvalue, function might want to react to temporaries\n\t\t\t\t} else {\n\t\t\t\t\treturn overload_remove_temporary{};\n\t\t\t\t}\n\t\t\t} else if constexpr ((tc::tuple_like<Args&&> || ...)) {\n\t\t\t\treturn overload_expanded{};\n\t\t\t}\n\t\t}\n\t\ttemplate <bool bForceExpand, typename Func, typename ... Args>\n\t\tusing selected_overload = decltype(select_overload<bForceExpand, Func, tc::unwrap_temporary_t<Args>...>());\n\n#pragma push_macro(\"return_invoke\")\n// We do want to return a tc::temporary<T, 0>, so can't use the return_decltype_* macros\n// (We have to use decltype(auto) + requires due to a GCC compiler bug.)\n#define return_invoke(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(auto) requires requires { __VA_ARGS__; } { return __VA_ARGS__; }\n\n\t\ttemplate <bool bForceExpand, typename Func, typename ... Args, /* not requires because of CWG issue 2369 */std::enable_if_t<std::same_as<selected_overload<bForceExpand, Func, Args...>, overload_temporary>>* = nullptr>\n\t\tconstexpr auto invoke(Func&& func, Args&&... args) return_invoke(\n\t\t\ttc_decrement_lifetime(tc_move_if_owned(func)(tc_increment_lifetime(tc_move_if_owned(args))...))\n\t\t)\n\n\t\ttemplate <bool bForceExpand, typename Func, typename ... Args, /* not requires because of CWG issue 2369 */std::enable_if_t<std::same_as<selected_overload<bForceExpand, Func, Args...>, overload_remove_temporary>>* = nullptr>\n\t\tconstexpr auto invoke(Func&& func, Args&&... args) return_decltype_MAYTHROW(\n\t\t\ttc_move_if_owned(func)(tc_unwrap_temporary(tc_move_if_owned(args))...)\n\t\t)\n\n\t\ttemplate <bool bForceExpand, typename Func, typename ... Args, /* not requires because of CWG issue 2369 */std::enable_if_t<std::same_as<selected_overload<bForceExpand, Func, Args...>, overload_expanded>>* = nullptr>\n\t\tconstexpr auto invoke(Func&& func, Args&&... args) return_invoke(\n\t\t\t/* ADL to resolve cyclic dependency */expanding_invoke_impl(expanding_invoke_adl::tag,\n\t\t\t\ttc::repeat_integer_sequence<std::index_sequence<expanded<Args&&>::indices::size()...>, std::index_sequence_for<Args&&...>>{},\n\t\t\t\ttc::concat_index_sequence<typename expanded<Args&&>::indices...>{},\n\t\t\t\ttc_move_if_owned(func), tc_move_if_owned(args)...\n\t\t\t)\n\t\t)\n\n\t\tnamespace expanding_invoke_adl {\n\t\t\ttemplate <std::size_t ... ArgIdxs, std::size_t ... InnerIdxs, typename Func, typename ... Args>\n\t\t\tconstexpr auto expanding_invoke_impl(tag_t, std::index_sequence<ArgIdxs...>, std::index_sequence<InnerIdxs...>, Func&& func, Args&&... args) return_invoke(\n\t\t\t\ttc::invoke_detail::invoke</* bForceExpand */false>(tc_move_if_owned(func),\n\t\t\t\t\ttc_prvalue_as_temporary(expanded<boost::mp11::mp_at_c<boost::mp11::mp_list<Args&&...>, ArgIdxs>>::template select<InnerIdxs>(tc::select_nth<ArgIdxs>(tc_move_if_owned(args)...)))...\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\n#pragma pop_macro(\"return_invoke\")\n\t}\n\n\t#define tc_invoke_argument(r, data, i, expr) BOOST_PP_COMMA_IF(i) tc_prvalue_as_temporary(expr)\n\t#define tc_invoke_argument_list(...) BOOST_PP_SEQ_FOR_EACH_I(tc_invoke_argument, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))\n\n\t// Calls a function, expanding tuple arguments into components (even recursively), if necessary.\n\t#define tc_invoke(func, ...) (tc::invoke_detail::invoke</* bForceExpand */false>(func, tc_invoke_argument_list(__VA_ARGS__)))\n\t#define tc_invoke_pack(func, ...) (tc::invoke_detail::invoke</* bForceExpand */false>(func, tc_invoke_argument_list(__VA_ARGS__) ... ))\n\n\t// Like tc_invoke, but expands all arguments at least once.\n\t#define tc_apply(func, ...) (tc::invoke_detail::invoke</* bForceExpand */true>(func, tc_invoke_argument_list(__VA_ARGS__)))\n\t#define tc_apply_pack(func, ...) (tc::invoke_detail::invoke</* bForceExpand */true>(func, tc_invoke_argument_list(__VA_ARGS__) ... ))\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// concepts\n\ttemplate <typename Func, typename... Args>\n\tusing invoke_result_t = decltype(tc_invoke_pack(std::declval<Func>(), std::declval<tc::prvalue_as_temporary_t<Args>>()));\n\n\ttemplate <typename Func, typename... Args>\n\tconcept invocable = requires { typename invoke_result_t<Func, Args...>; };\n\ttemplate <typename Func, typename... Args>\n\tconcept nothrow_invocable = tc::invocable<Func, Args...> && noexcept(tc_invoke_pack(std::declval<Func>(), std::declval<tc::prvalue_as_temporary_t<Args>>()));\n}\n"
  },
  {
    "path": "tc/base/invoke.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"invoke.h\"\n#include \"casts.h\"\n#include \"../tuple.h\"\n\nnamespace {\n\ttemplate <typename ... ExpectedArgs>\n\tstruct test_arguments {\n\t\tmutable int foo;\n\n\t\ttemplate <typename ... Args>\n\t\tint&& /* we return an rvalue reference, otherwise invoke would not give us temporaries */ operator()(Args&&...) const noexcept {\n\t\t\t([]{ STATICASSERTSAME(ExpectedArgs&&, Args&&); }(), ...);\n\t\t\treturn tc_move(foo);\n\t\t}\n\t};\n\n\t[[maybe_unused]] void static_tests_invoke_arguments() noexcept {\n\t\tint i;\n\t\ttc::tuple<int> tpl;\n\n\t\ttc_invoke(\n\t\t\t(test_arguments<tc::temporary<int, 1>, tc::temporary<bool, 1>, char const(&)[4], int&&, int const&>{}),\n\t\t\t1, true, \"abc\", tc_move(i), tc::as_const(i)\n\t\t);\n\n\t\ttc_invoke(\n\t\t\t(test_arguments<tc::temporary<tc::tuple<>, 1>, tc::temporary<tc::tuple<int>, 1>, tc::tuple<int>&, tc::temporary<tc::tuple<int&>, 1>>{}), \n\t\t\ttc::make_tuple(), tc::make_tuple(0), tpl, tc::tie(i)\n\t\t);\n\n\t\ttc_apply(\n\t\t\t(test_arguments<tc::temporary<int, 1>, int&, int&>{}),\n\t\t\ttc::make_tuple(), tc::make_tuple(0), tpl, tc::tie(i)\n\t\t);\n\n\t\ttc_apply(\n\t\t\t(test_arguments<tc::temporary<int, 2>, int&>{}),\n\t\t\t(tc::temporary<tc::tuple<int>, 1>(tc::make_tuple(0))), (tc::temporary<tc::tuple<int&>, 1>(tc::tie(i)))\n\t\t);\n\t}\n\n\t[[maybe_unused]] void static_tests_invoke() noexcept {\n\t\ttc_static_auto_constexpr_lambda(rvalue_sink) = [](int, double&&, char const&) noexcept {};\n\t\tstatic_assert(!tc::invocable<decltype(rvalue_sink), int, double&, char>);\n\t\tstatic_assert(!tc::invocable<decltype(rvalue_sink), tc::tuple<int, double&, char>>);\n\n\t\ttc_invoke(rvalue_sink, 0, 0., 'a');\n\t\ttc_invoke(rvalue_sink, tc::make_tuple(0, 0., 'a'));\n\t\ttc_invoke(rvalue_sink, tc::make_tuple(0, 0.), 'a');\n\t\ttc_invoke(rvalue_sink, tc::make_tuple(0, tc::make_tuple(tc::make_tuple(0.), 'a')));\n\n\t\ttc_static_auto_constexpr_lambda(lvalue_sink) = [](int, double&, char const&) noexcept {};\n\t\tstatic_assert(!tc::invocable<decltype(lvalue_sink), int, double, char>);\n\t\tstatic_assert(!tc::invocable<decltype(lvalue_sink), tc::tuple<int, double, char>>);\n\t\tstatic_assert(!tc::invocable<decltype(lvalue_sink), tc::tuple<int&&, double&&, char&&>>);\n\n\t\tint a0 = 0;\n\t\tdouble a1 = 0.;\n\t\tchar a2 = 'a';\n\t\ttc_invoke(lvalue_sink, a0, a1, a2);\n\t\ttc_invoke(lvalue_sink, tc::tie(a0, a1, a2));\n\t\ttc_invoke(lvalue_sink, tc::tie(a0, a1), a2);\n\t\ttc_invoke(lvalue_sink, tc::tie(a0, tc::tie(tc::tie(a1), a2)));\n\t}\n\n\t[[maybe_unused]] void static_tests_apply() noexcept {\n\t\t// We need the lambda to test tc_apply without any arguments - the macro requires at least one.\n\t\ttc_static_auto_constexpr_lambda(apply) = [](auto fn, auto&& ... args) noexcept {\n\t\t\ttc_apply_pack(fn, tc_move_if_owned(args));\n\t\t};\n\n\t\tapply([](auto const& ... args) noexcept { STATICASSERTEQUAL(sizeof...(args), 4); }, tc::make_tuple(0, tc::make_tuple(1, 2), 3), 4);\n\t\tapply([]{});\n\t\tapply([]{}, tc::make_tuple(), tc::make_tuple());\n\t}\n}\n"
  },
  {
    "path": "tc/base/invoke_with_constant.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once \n\n#include \"type_traits_fwd.h\"\n#include \"utility.h\"\n#include \"../algorithm/size.h\"\n#include \"../range/iota_range.h\"\n\nnamespace tc {\n\tnamespace invoke_with_constant_impl {\n\t\ttemplate<typename TResult, typename TIndex, TIndex I, typename Func, typename... Args>\n\t\tTResult invoke_impl(Func func, Args&&... args) MAYTHROW {\n\t\t\treturn func(tc::constant<I>(), tc_move_if_owned(args)...);\n\t\t}\n\n\t\ttemplate<typename TIndex, TIndex I, TIndex... Is>\n\t\tinline constexpr TIndex IdxFirst = I;\n\n\t\ttemplate<typename T>\n\t\tstruct invoke_with_constant_impl {};\n\n\t\ttemplate<typename TIndex, TIndex... Is>\n\t\tstruct invoke_with_constant_impl<std::integer_sequence<TIndex, Is...>> {\n\t\t\ttemplate<typename Func, typename... Args>\n\t\t\tstruct inner {\n\t\t\t\tusing result_type = tc::common_reference_t<\n\t\t\t\t\tdecltype(std::declval<std::decay_t<Func>&>()(tc::constant<Is>(), std::declval<Args>()...))...\n\t\t\t\t>;\n\n\t\t\t\ttemplate<TIndex I, TIndex... IsRemaining>\n\t\t\t\tstatic result_type constexpr invoke_constexpr(Func&& func, TIndex nIndex, Args&&... args) MAYTHROW {\n\t\t\t\t\tif (I == nIndex) {\n\t\t\t\t\t\treturn func(tc::constant<I>(), tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t\t} else if constexpr (0 < sizeof...(IsRemaining)) {\n\t\t\t\t\t\treturn invoke_constexpr<IsRemaining...>(tc_move_if_owned(func), nIndex, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERTFALSE;\n\t\t\t\t\t\treturn func(tc::constant<I>(), tc_move_if_owned(args)...);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstatic result_type constexpr invoke_constexpr_outer(Func&& func, TIndex nIndex, Args&&... args) MAYTHROW {\n\t\t\t\t\treturn invoke_constexpr<Is...>(tc_move_if_owned(func), nIndex, tc_move_if_owned(args)...); // MAYTHROW (but won't because constexpr)\n\t\t\t\t}\n\n\t\t\tprivate:\n\t\t\t\t// TODO: move back as static local after MSVC compiler bug is fixed: https://developercommunity.visualstudio.com/t/code-generation-bug-on-static-variable-i/10541326\n\t\t\t\t// tc_static_auto_constexpr with std::array triggers pdb problem.\n\t\t\t\tstatic constexpr std::add_pointer_t<result_type(std::remove_reference_t<Func>, Args&&...)> c_apfn[] = {\n\t\t\t\t\tinvoke_impl<result_type, TIndex, Is, std::decay_t<Func>, Args...>\n\t\t\t\t\t...\n\t\t\t\t};\n\t\t\tpublic:\n\t\t\t\tstatic result_type invoke_non_constexpr(Func&& func, TIndex nIndex, Args&&... args) MAYTHROW {\n\t\t\t\t\tauto const nTableIndex = nIndex - IdxFirst<TIndex, Is...>;\n\t\t\t\t\t_ASSERTNORETURN(0 <= nTableIndex && nTableIndex < tc::size(c_apfn));\n\n\t\t\t\t\treturn c_apfn[nTableIndex](tc_move_if_owned(func), tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\t}\n\n\ttemplate<typename ContiguousIntegerSequence, typename Func, typename... Args>\n\tdecltype(auto) constexpr invoke_with_constant(Func&& func, typename ContiguousIntegerSequence::value_type nIndex, Args&&... args) MAYTHROW {\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<ContiguousIntegerSequence>::value);\n\n\t\tif constexpr (0 < ContiguousIntegerSequence::size()) {\n\t\t\tusing impl_type = typename invoke_with_constant_impl::invoke_with_constant_impl<ContiguousIntegerSequence>::template inner<Func, Args...>;\n\t\t\tif (std::is_constant_evaluated()) {\n\t\t\t\treturn impl_type::invoke_constexpr_outer(tc_move_if_owned(func), nIndex, tc_move_if_owned(args)...);\n\t\t\t} else {\n\t\t\t\treturn impl_type::invoke_non_constexpr(tc_move_if_owned(func), nIndex, tc_move_if_owned(args)...);\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Enum, typename Func, typename... Args>\n\tdecltype(auto) invoke_with_constant(Func func, Enum e, Args&&... args) MAYTHROW {\n\t\treturn tc::invoke_with_constant<std::make_index_sequence<tc::size(tc::all_values<Enum>())>>(\n\t\t\t[&](auto constn) MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc_invoke_pack(func, tc::constant<tc_at_nodebug(tc::all_values<Enum>(), decltype(constn)::value)>(), tc_move_if_owned(args));\n\t\t\t},\n\t\t\ttc::all_values<Enum>().index_of(e)\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "tc/base/large_integer.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"integer.h\"\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wsign-conversion\"\n#pragma clang diagnostic ignored \"-Wconversion\"\n#pragma clang diagnostic ignored \"-Wcomma\"\n#else\nMODIFY_WARNINGS_BEGIN(((disable)(4459))) // declaration hides global declaration\n#endif\n#include <boost/multiprecision/cpp_int.hpp>\n#ifdef __clang__\n#pragma clang diagnostic pop\n#else\nMODIFY_WARNINGS_END\n#endif\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<int nBits> requires (std::numeric_limits<std::intmax_t>::digits<nBits)\n\t\tstruct int_least<nBits> {\n\t\t\tusing type=boost::multiprecision::number<boost::multiprecision::cpp_int_backend<nBits/*not -1 due to signed magnitude representation*/, nBits/*not -1 due to signed magnitude representation*/, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;\n\t\t};\n\n\t\ttemplate<int nBits> requires (std::numeric_limits<std::uintmax_t>::digits<nBits)\n\t\tstruct uint_least<nBits> {\n\t\t\tusing type=boost::multiprecision::number<boost::multiprecision::cpp_int_backend<nBits, nBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\n\t\t};\n\t}\n\n\tnamespace actual_integer_like_detail {\n\t\ttemplate<unsigned MinBits,unsigned MaxBits,boost::multiprecision::cpp_integer_type SignType,boost::multiprecision::cpp_int_check_type Checked,typename Alloc>\n\t\tinline constexpr bool actual_integer_like_impl<boost::multiprecision::number<\n\t\t\tboost::multiprecision::cpp_int_backend<\n\t\t\t\tMinBits,\n\t\t\t\tMaxBits,\n\t\t\t\tSignType,\n\t\t\t\tChecked,\n\t\t\t\tAlloc\n\t\t\t>\n\t\t>> = true;\n\t}\n}\n"
  },
  {
    "path": "tc/base/modified.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"type_traits_fwd.h\"\n#include \"temporary.h\"\n\nnamespace tc {\n\ttemplate <typename T>\n\tconcept inplace_modifiable = !std::is_lvalue_reference<tc::unwrap_temporary_t<T>>::value && !std::is_const<std::remove_reference_t<tc::unwrap_temporary_t<T>>>::value;\n\n\ttemplate<typename T, typename Fn>\n\t[[nodiscard]] constexpr decltype(auto) modified_impl(T&& t, Fn fn) MAYTHROW {\n\t\tif constexpr (inplace_modifiable<T&&>) {\n\t\t\tfn(tc_unwrap_temporary(t));\n\t\t\treturn tc_move(t);\n\t\t} else {\n\t\t\tauto tCopy = tc::decay_copy(tc_unwrap_temporary(t));\n\t\t\tfn(tCopy);\n\t\t\treturn tCopy;\n\t\t}\n\t}\n}\n\n#define tc_modified(obj, ...) tc::modified_impl(obj, [&](auto& _) MAYTHROW -> void { __VA_ARGS__; })\n"
  },
  {
    "path": "tc/base/modified.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) 2016-2023 think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"modified.h\"\n#include \"../unittest.h\"\n\nUNITTESTDEF(tc_modified) {\n\tint lvalue = 0;\n\tstatic_assert(!tc::inplace_modifiable<int&>);\n\t_ASSERTEQUAL(tc_modified(lvalue, _ = 11), 11);\n\t_ASSERTEQUAL(lvalue, 0);\n\n\tint const clvalue = 0;\n\tstatic_assert(!tc::inplace_modifiable<int const&>);\n\t_ASSERTEQUAL(tc_modified(clvalue, _ = 11), 11);\n\t_ASSERTEQUAL(clvalue, 0);\n\n\tint rvalue = 0;\n\tstatic_assert(tc::inplace_modifiable<int&&>);\n\t_ASSERTEQUAL(tc_modified(tc_move(rvalue), _ = 11), 11);\n\t_ASSERTEQUAL(rvalue, 11);\n\n\tint const crvalue = 0;\n\tstatic_assert(!tc::inplace_modifiable<int const&&>);\n\t_ASSERTEQUAL(tc_modified(tc_move_always_even_const(crvalue), _ = 11), 11);\n\t_ASSERTEQUAL(crvalue, 0);\n\n\tint tmp_rvalue = 0;\n\tstatic_assert(tc::inplace_modifiable<tc::temporary<int, 0>&&>);\n\t_ASSERTEQUAL(static_cast<int&&>(tc_modified((tc::temporary<int, 0>(tmp_rvalue)), _ = 11)), 11);\n\t_ASSERTEQUAL(tmp_rvalue, 11);\n\n\tint tmp_crvalue = 0;\n\tstatic_assert(!tc::inplace_modifiable<tc::temporary<int const, 0>&&>);\n\t_ASSERTEQUAL(tc_modified((tc::temporary<int const, 0>(tmp_crvalue)), _ = 11), 11);\n\t_ASSERTEQUAL(tmp_crvalue, 0);\n\n\tint tmp_lvalue_i = 0;\n\ttc::temporary<int, 0> tmp_lvalue(tmp_lvalue_i);\n\tstatic_assert(!tc::inplace_modifiable<tc::temporary<int, 0>&>);\n\t_ASSERTEQUAL(tc_modified(tmp_lvalue, _ = 11), 11);\n\t_ASSERTEQUAL(tmp_lvalue_i, 0);\n\n\tint tmp_clvalue_i = 0;\n\tstatic_assert(!tc::inplace_modifiable<tc::temporary<int const, 0>&>);\n\ttc::temporary<int const, 0> tmp_clvalue(tmp_clvalue_i);\n\t_ASSERTEQUAL(tc_modified(tmp_clvalue, _ = 11), 11);\n\t_ASSERTEQUAL(tmp_clvalue_i, 0);\n}\n"
  },
  {
    "path": "tc/base/move.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"fundamental.h\"\n#include <type_traits>\n\nMODIFY_WARNINGS(((disable)(4521))) // '...' : multiple copy constructors specified (happens when two ctors, one with T const&, the other with T & parameter, are defined)\n\nnamespace tc {\n\t/////////////////////////////\n\t// remove_rvalue_reference\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct remove_rvalue_reference {\n\t\t\tusing type=T;\n\t\t};\n\t\ttemplate <typename T>\n\t\tstruct remove_rvalue_reference<T&&> {\n\t\t\tusing type=T;\n\t\t};\n\t}\n\n\tusing no_adl::remove_rvalue_reference;\n\n\ttemplate<typename T>\n\tusing remove_rvalue_reference_t=typename tc::remove_rvalue_reference<T>::type;\n\n\tconstexpr bool is_id_expression(char const* const strExpr) noexcept {\n\t\tfor(auto it = strExpr; *it; ++it)\n\t\t\tif(!('A' <= *it && *it <= 'Z') && !('a' <= *it && *it <= 'z') && !('0' <= *it && *it <= '9') && *it != '_' && *it != ':')\n\t\t\t\treturn false;\n\t\treturn true;\n\t}\n}\n\n#define tc_is_id_expression(...) tc::is_id_expression(#__VA_ARGS__)\n\n/////////////////////////////////////////////\n// safer variants of std::move\n\nnamespace tc::move_detail {\n\ttemplate <typename Decltype, bool bIsIdExpression>\n\tconstexpr decltype(auto) move(auto&& obj) noexcept {\n\t\tstatic_assert(!std::is_const<std::remove_reference_t<decltype(obj)>>::value, \"Cannot move out of const.\");\n\t\tstatic_assert(!std::is_rvalue_reference<decltype(obj)>::value, \"Unnecessary move; already an rvalue.\");\n\n\t\tstatic_assert(!std::is_lvalue_reference<Decltype>::value, \"Are you sure you want to move out of an lvalue reference? Then use tc_move_always.\");\n\t\tstatic_assert(bIsIdExpression, \"Instead of `tc_move(obj.member)`, use `tc_move(obj).member`. Instead of `tc_move(ptr->member)`, use `tc_move_always(ptr->member)`.\");\n\n\t\treturn static_cast<std::remove_reference_t<Decltype>&&>(obj);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate <typename Decltype, bool bIsIdExpression>\n\t\tstruct move_if_owned final {\n\t\t\tstatic_assert(std::is_reference<Decltype>::value || bIsIdExpression, \"Instead of `tc_move_if_owned(obj.member)`, use `tc_move_if_owned(obj).member`.\");\n\n\t\t\tusing type = Decltype&&;\n\t\t};\n\n\t\ttemplate <typename Decltype, bool bIsIdExpression>\n\t\tstruct const_forward final {\n\t\t\tstatic_assert(std::is_reference<Decltype>::value || bIsIdExpression, \"Instead of `tc_const_forward(obj.member)`, use `tc_const_forward(obj).member`.\");\n\n\t\t\tusing type = std::conditional_t<std::is_lvalue_reference<Decltype>::value, Decltype, tc::remove_rvalue_reference_t<Decltype> const&&>;\n\t\t};\n\t}\n}\n\n// T -> T&& (e.g. local variable)\n// T& -> error (e.g. lvalue reference argument)\n// T&& -> T&& (e.g. rvalue reference argument)\n#define tc_move(...) (static_cast<decltype(tc::move_detail::move<decltype(__VA_ARGS__), tc_is_id_expression(__VA_ARGS__)>(__VA_ARGS__))>(__VA_ARGS__))\n\n// T -> T&& (e.g. local variable)\n// T& -> T& (e.g. lvalue reference argument)\n// T&& -> T&& (e.g. rvalue reference argument)\n#define tc_move_if_owned(...) (static_cast<typename tc::move_detail::no_adl::move_if_owned<decltype(__VA_ARGS__), tc_is_id_expression(__VA_ARGS__)>::type>(__VA_ARGS__))\n\n// MSVC sometimes forgets a const when decltyping.\n#define tc_move_if_owned_msvc_workaround(Type, ...) (static_cast<typename tc::move_detail::no_adl::move_if_owned<Type, tc_is_id_expression(__VA_ARGS__)>::type>(__VA_ARGS__))\n\n// Implementing tc_move_always and tc_move_always_even_const as functions avoids workaround for MSVC.\ntemplate<typename T>\n[[nodiscard]] constexpr std::remove_reference_t<T>&& tc_move_always(T&& t) noexcept { // same as std::move, but asserts on non-constness of argument\n\tstatic_assert(!std::is_const<std::remove_reference_t<T>>::value, \"Cannot move out of const.\");\n\treturn static_cast<std::remove_reference_t<T>&&>(t);\n}\n\ntemplate<typename T>\n[[nodiscard]] constexpr std::remove_reference_t<T>&& tc_move_always_even_const(T&& t) noexcept {\n\treturn static_cast<std::remove_reference_t<T>&&>(t);\n}\n\n// T -> T const&&, T& -> T&, T&& -> T const&&\n#define tc_const_forward(...) (static_cast<typename tc::move_detail::no_adl::const_forward<decltype(__VA_ARGS__), tc_is_id_expression(__VA_ARGS__)>::type>(__VA_ARGS__))\n"
  },
  {
    "path": "tc/base/noncopyable.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"fundamental.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\t// Derived classes can be moved and copied.\n\t\tstruct TC_EMPTY_BASES copyable {};\n\n\t\t// Derived classes can be moved, but not copied.\n\t\tstruct TC_EMPTY_BASES noncopyable {\n\t\tprotected:\n\t\t\tconstexpr noncopyable() noexcept = default;\n\t\t\tnoncopyable(noncopyable&&) noexcept = default;\n\t\t\tnoncopyable& operator=(noncopyable&&) noexcept = default;\n\t\t};\n\n\t\t// Derived classes cannot be moved or copied.\n\t\tstruct TC_EMPTY_BASES nonmovable {\n\t\t\tnonmovable& operator=(nonmovable&&) noexcept = delete;\n\t\t};\n\t}\n\tusing no_adl::copyable;\n\tusing no_adl::noncopyable;\n\tusing no_adl::nonmovable;\n}\n"
  },
  {
    "path": "tc/base/ref.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"as_lvalue.h\"\n#include \"../algorithm/for_each.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\t///////////////////////////////////////////////////\n\t\t// tc::function_ref\n\n\t\tunion any_ref {\n\t\t\t// Any pointer to function can be converted to a pointer to a different function type. Calling the\n\t\t\t// function through a pointer to a different function type is undefined, but converting such pointer\n\t\t\t// back to pointer to the original function type yields the pointer to the original function.\n\t\t\t// https://en.cppreference.com/w/cpp/language/reinterpret_cast\n\n\t\t\ttemplate <typename RefT>\n\t\t\texplicit any_ref(RefT& ref) noexcept\n\t\t\t\t: m_pvRef(std::addressof(ref))\n\t\t\t{}\n\n\t\t\ttemplate <typename RefT> requires std::is_function<RefT>::value\n\t\t\texplicit any_ref(RefT& ref) noexcept\n\t\t\t\t: m_fpvRef(reinterpret_cast<void(*)()>(std::addressof(ref)))\n\t\t\t{}\n\n\t\t\ttemplate <typename RefT> // may be const and/or volatile\n\t\t\tRefT& get_ref() const& noexcept {\n\t\t\t\tstatic_assert(!std::is_reference<RefT>::value); \n\t\t\t\tif constexpr (std::is_function<RefT>::value) {\n\t\t\t\t\treturn *reinterpret_cast<RefT*>(m_fpvRef);\n\t\t\t\t} else {\n\t\t\t\t\treturn *static_cast<RefT*>(tc::as_mutable_ptr(m_pvRef));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid const* m_pvRef;\n\t\t\tvoid (*m_fpvRef)();\n\t\t};\n\n\t\ttemplate <bool bNoExcept, typename Ret, typename... Args>\n\t\tusing type_erased_function_ptr = Ret(*)(tc::no_adl::any_ref, Args...) noexcept(bNoExcept);\n\n\t\ttemplate <bool bNoExcept, typename Func, typename Ret, typename... Args>\n\t\tstruct make_type_erased_function_ptr final {\n\t\t\ttc::no_adl::type_erased_function_ptr<bNoExcept, Ret, Args...> operator()() const& noexcept {\n\t\t\t\treturn [](tc::no_adl::any_ref anyref, Args... args) noexcept(bNoExcept) -> Ret { // implicit cast of stateless lambda to function pointer\n\t\t\t\t\treturn tc_invoke_pack(anyref.get_ref<Func>(), tc_move_if_owned(args)); // MAYTHROW unless bNoExcept\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\ttemplate <bool bNoExcept, typename Func, typename... Args>\n\t\tstruct make_type_erased_function_ptr<bNoExcept, Func, void, Args...> final {\n\t\t\ttc::no_adl::type_erased_function_ptr<bNoExcept, void, Args...> operator()() const& noexcept {\n\t\t\t\treturn [](tc::no_adl::any_ref anyref, Args... args) noexcept(bNoExcept) { // implicit cast of stateless lambda to function pointer\n\t\t\t\t\ttc_invoke_pack(anyref.get_ref<Func>(), tc_move_if_owned(args)); // MAYTHROW unless bNoExcept\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\ttemplate <bool bNoExcept, typename Func, typename... Args>\n\t\tstruct make_type_erased_function_ptr<bNoExcept, Func, tc::break_or_continue, Args...> final {\n\t\t\ttc::no_adl::type_erased_function_ptr<bNoExcept, tc::break_or_continue, Args...> operator()() const& noexcept {\n\t\t\t\treturn [](tc::no_adl::any_ref anyref, Args... args) noexcept(bNoExcept) -> tc::break_or_continue { // implicit cast of stateless lambda to function pointer\n\t\t\t\t\t// Not tc::continue_if_not_break because it casts sink to const&.\n\t\t\t\t\treturn tc_internal_continue_if_not_break(tc_invoke_pack(anyref.get_ref<Func>(), tc_move_if_owned(args))); // MAYTHROW unless bNoExcept\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\ttemplate <bool bNoExcept, typename Ret, typename... Args>\n\t\tstruct function_ref_base {\n\t\t\tfunction_ref_base(function_ref_base const&) noexcept = default;\n\n\t\t\tRet operator()(Args... args) const& noexcept(bNoExcept) {\n\t\t\t\treturn m_pfuncTypeErased(m_anyref, tc_move_if_owned(args)...); // MAYTHROW unless bNoExcept\n\t\t\t}\n\t\t\t\t\n\t\t\ttemplate <typename Func> requires\n\t\t\t\t(!tc::decayed_derived_from<Func, function_ref_base>)\n\t\t\t\t&& tc::invocable<std::remove_reference_t<Func>&, Args...>\n\t\t\t\t&& (\n\t\t\t\t\tstd::convertible_to<decltype(tc_invoke_pack(std::declval<std::remove_reference_t<Func>&>(), std::declval<Args>())), Ret>\n\t\t\t\t\t|| std::is_same<Ret, tc::break_or_continue>::value\n\t\t\t\t\t|| std::is_void<Ret>::value\n\t\t\t\t)\n\t\t\tfunction_ref_base(Func&& func) noexcept\n\t\t\t\t: m_pfuncTypeErased(tc::no_adl::make_type_erased_function_ptr<bNoExcept, std::remove_reference_t<Func>, Ret, Args...>{}())\n\t\t\t\t, m_anyref(tc::as_lvalue(func))\n\t\t\t{\n\t\t\t\tstatic_assert(!std::is_member_function_pointer<Func>::value, \"Raw member functions are not supported (how would you call them?).  Pass in a lambda or use std::mem_fn/tc_mem_fn instead.\");\n\t\t\t\tstatic_assert(!std::is_pointer<Func>::value, \"Pass in functions rather than function pointers.\");\n\t\t\t\t// Checking the noexcept value of the function call is commented out because MAYTHROW is widely used in generic code such as for_each, range_adaptor...\n\t\t\t\t// static_assert(!bNoExcept || noexcept(std::declval<tc::decay_t<Func>&>()(std::declval<Args>()...)));\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttc::no_adl::type_erased_function_ptr<bNoExcept, Ret, Args...> m_pfuncTypeErased;\n\t\t\ttc::no_adl::any_ref m_anyref;\n\t\t};\n\n\t\ttemplate <typename Sig>\n\t\tstruct function_ref;\n\n\t\ttemplate <typename Ret, typename... Args>\n\t\tstruct function_ref<Ret(Args...)> : tc::no_adl::function_ref_base</*bNoExcept*/false, Ret, Args...> {\n\t\t\tusing base_ = typename function_ref::function_ref_base;\n\t\t\tusing base_::base_;\n\t\t};\n\n\t\ttemplate <typename Ret, typename... Args>\n\t\tstruct function_ref<Ret(Args...) noexcept> : tc::no_adl::function_ref_base</*bNoExcept*/true, Ret, Args...> {\n\t\t\tusing base_ = typename function_ref::function_ref_base;\n\t\t\tusing base_::base_;\n\t\t};\n\n\t\ttemplate <typename T>\n\t\tstruct any_range_ref {\n\t\t\tfriend auto range_output_t_impl(any_range_ref const&) -> boost::mp11::mp_list<T>; // declaration only\n\n\t\t\ttemplate <typename Rng>\n\t\t\tany_range_ref(Rng&& rng) noexcept\n\t\t\t\t: m_pfuncTypeErased(\n\t\t\t\t\t[](tc::no_adl::any_ref anyrefRng, tc::no_adl::function_ref<tc::break_or_continue (T) noexcept> fn) noexcept -> tc::break_or_continue { // implicit cast of stateless lambda to function pointer\n\t\t\t\t\t\treturn tc::for_each(anyrefRng.get_ref<std::remove_reference_t<Rng>>(), fn);\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\t, m_anyrefRng(tc::as_lvalue(rng))\n\t\t\t{}\n\t\t\n\t\t\ttc::break_or_continue operator()(tc::no_adl::function_ref<tc::break_or_continue (T) noexcept> fn) const& noexcept {\n\t\t\t\treturn m_pfuncTypeErased(m_anyrefRng, fn);\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttc::no_adl::type_erased_function_ptr</*bNoExcept*/true, tc::break_or_continue, tc::no_adl::function_ref<tc::break_or_continue (T) noexcept>> m_pfuncTypeErased;\n\t\t\ttc::no_adl::any_ref m_anyrefRng;\n\t\t};\n\t}\n\tusing no_adl::function_ref;\n\tusing no_adl::any_range_ref;\n\tusing no_adl::any_ref;\n}\n"
  },
  {
    "path": "tc/base/reference_or_value.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"renew.h\"\n#include \"tag_type.h\"\n#include \"casts.h\"\n\n#include <type_traits>\n#include <memory>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate< typename T, bool bBestAccess >\n\t\tstruct value_holder_impl {\n\t\t\tT m_t;\n\t\t};\n\n\t\ttemplate< typename T>\n\t\tstruct value_holder_impl<T, /*bBestAccess*/true> {\n\t\t\t// Store mutable T to return mutable reference from best_access().\n\t\t\t// best_access() is used to create an index object from an iterator\n\t\t\t// to m_t. add_index_interface<T>::index needs a mutable iterator.\n\t\t\t// This is because of a deficiency in the STL: If there was a way to\n\t\t\t// get a mutable reference from a const_iterator *and* a mutable T,\n\t\t\t// the index type could always take the const_iterator instead.\n\t\t\tT mutable m_t;\n\t\t};\n\n\t\ttemplate< typename T, bool bBestAccess >\n\t\tstruct reference_or_value: private value_holder_impl<T, bBestAccess> {\n\t\t\tstatic_assert( !std::is_void<T>::value );\n\t\t\tstatic_assert( !std::is_reference<T>::value );\n\t\t\tstatic_assert( !std::is_const<T>::value );\n\t\t\tstatic_assert( !std::is_volatile<T>::value );\n\n\t\t\tconstexpr reference_or_value() = default; // m_t may be default-constructible\n\t\t\tconstexpr reference_or_value(reference_or_value const&) = default;\n\t\t\tconstexpr reference_or_value(reference_or_value&&) = default;\n\t\t\t\n\t\t\ttemplate< typename Rhs> requires tc::safely_constructible_from<T, Rhs&&>\n\t\t\tconstexpr reference_or_value( aggregate_tag_t, Rhs&& rhs ) noexcept\n\t\t\t\t: value_holder_impl<T, bBestAccess>{tc_move_if_owned(rhs)}\n\t\t\t{}\n\n\t\t\t// reference_or_value<T> is trivially copy assignable if T is trivially copy assignable.\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value const& other) & requires std::is_trivially_copy_assignable<T>::value = default;\n\t\t\t// T may be a proxy with reference behavior (e.g. pair<X&,X&>): operator= must be non trivial and may not be equivalent to copy ctor.\n\t\t\t// operator=() with tc::renew for pointer semantics.\n#ifdef __clang__ // workaround clang bug on trivially copyable: https://github.com/llvm/llvm-project/issues/63352\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value<SFINAE_TYPE(T), bBestAccess> const& other) & noexcept requires\n#else\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value const& other) & noexcept requires\n#endif\n\t\t\t\t(!std::is_trivially_copy_assignable<T>::value) &&\n\t\t\t\tstd::is_copy_constructible<T>::value\n\t\t\t{\n\t\t\t\t_ASSERTE(this != std::addressof(other));\n\t\t\t\ttc::renew(this->m_t, other.m_t);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value&& other) & requires std::is_trivially_move_assignable<T>::value = default;\n#ifdef __clang__ // workaround clang bug on trivially copyable: https://github.com/llvm/llvm-project/issues/63352\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value<SFINAE_TYPE(T), bBestAccess>&& other) & noexcept requires\n#else\n\t\t\tconstexpr reference_or_value& operator=(reference_or_value&& other) & noexcept requires\n#endif\n\t\t\t\t(!std::is_trivially_move_assignable<T>::value) &&\n\t\t\t\tstd::is_move_constructible<T>::value\n\t\t\t{\n\t\t\t\t_ASSERTE(this != std::addressof(other));\n\t\t\t\ttc::renew(this->m_t, tc_move(other).m_t);\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\t\n\t\t\tconstexpr T& best_access() const& noexcept requires bBestAccess {\n\t\t\t\t// When declaring m_t non-mutable and using const_cast here be undefined behavior in code like:\n\t\t\t\t//\treference_or_value<T> _const_ foo;\n\t\t\t\t//\tfoo.best_access();\n\t\t\t\t// ?\n\t\t\t\treturn this->m_t;\n\t\t\t}\n\t\t\tconstexpr T* operator->() & noexcept {\n\t\t\t\treturn std::addressof(this->m_t);\n\t\t\t}\n\t\t\tconstexpr T const* operator->() const& noexcept {\n\t\t\t\treturn std::addressof(this->m_t);\n\t\t\t}\n\t\t\tconstexpr T& operator*() & noexcept {\n\t\t\t\treturn this->m_t;\n\t\t\t}\n\t\t\tconstexpr T const& operator*() const& noexcept {\n\t\t\t\treturn this->m_t;\n\t\t\t}\n\t\t\tconstexpr T&& operator*() && noexcept {\n\t\t\t\treturn tc_move_always(*this).m_t;\n\t\t\t}\n\t\t\tconstexpr T const&& operator*() const&& noexcept {\n\t\t\t\treturn tc_move_always_even_const(tc::as_const(*this)).m_t;\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename T, bool bBestAccess >\n\t\tstruct reference_or_value<T&, bBestAccess> {\n\t\tprivate:\n\t\t\tT* m_pt;\n\n\t\tpublic:\n\t\t\tconstexpr reference_or_value(aggregate_tag_t, T& t) noexcept\n\t\t\t:\tm_pt(std::addressof(t))\n\t\t\t{}\n\t\t\tconstexpr T& best_access() const& noexcept requires bBestAccess {\n\t\t\t\treturn *m_pt;\n\t\t\t}\n\t\t\tconstexpr T* operator->() const& noexcept {\n\t\t\t\treturn m_pt;\n\t\t\t}\n\t\t\tconstexpr T& operator*() const& noexcept {\n\t\t\t\treturn *m_pt;\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename T, bool bBestAccess >\n\t\tstruct reference_or_value<T&&, bBestAccess> {\n\t\tprivate:\n\t\t\tT* m_pt;\n\n\t\tpublic:\n\t\t\tconstexpr reference_or_value(aggregate_tag_t, T&& t) noexcept\n\t\t\t\t: m_pt(std::addressof(t))\n\t\t\t{}\n\t\t\tconstexpr T&& best_access() const& noexcept requires bBestAccess {\n\t\t\t\treturn tc_move_always(*m_pt);\n\t\t\t}\n\t\t\tconstexpr T* operator->() const& noexcept { // no such thing as \"pointer-to-rvalue\"\n\t\t\t\treturn m_pt;\n\t\t\t}\n\t\t\tconstexpr T& operator*() const& noexcept {\n\t\t\t\treturn *m_pt;\n\t\t\t}\n\t\t\tconstexpr T&& operator*() const&& noexcept {\n\t\t\t\treturn tc_move_always(*m_pt);\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename T >\n\t\tstruct TC_EMPTY_BASES empty_value {\n\t\t\tstatic_assert( tc::empty_type<T> );\n\n\t\t\tconstexpr empty_value() = default;\n\t\t\tconstexpr empty_value(aggregate_tag_t, T) noexcept {}\n\n\t\t\tstatic constexpr T best_access() noexcept { return T(); }\n\t\t\tconstexpr auto operator->() const& noexcept {\n\t\t\t\tstruct pointer final {\n\t\t\t\t\tT m_t;\n\t\t\t\t\tconstexpr T* operator->() && noexcept { return std::addressof(m_t); }\n\t\t\t\t};\n\t\t\t\treturn pointer();\n\t\t\t}\n\t\t\tconstexpr T operator*() const& noexcept { return T(); }\n\t\t};\n\t}\n\ttemplate<typename T, bool bBestAccess=false>\n\tusing reference_or_value = std::conditional_t<\n\t\ttc::empty_type<std::remove_cvref_t<tc::store_temporary_t<T>>>,\n\t\tno_adl::empty_value<std::remove_cvref_t<tc::store_temporary_t<T>>>,\n\t\tno_adl::reference_or_value<std::remove_cv_t<tc::store_temporary_t<T>>, bBestAccess>\n\t>;\n\t\n\ttemplate< bool bBestAccess=false, typename T >\n\t[[nodiscard]] constexpr auto make_reference_or_value(T&& t) return_ctor_noexcept(\n\t\tTC_FWD(tc::reference_or_value<T, bBestAccess>),\n\t\t(tc::aggregate_tag, tc_move_if_owned(t))\n\t)\n\n\tnamespace no_adl {\n\t\ttemplate< typename Func, typename... Args >\n\t\tstruct stores_result_of final {\n\t\tprivate:\n\t\t\ttc::reference_or_value< decltype(std::declval<Func>()(std::declval<Args>()...)) > m_t;\n\n\t\tpublic:\n\t\t\tconstexpr stores_result_of( Func&& func, Args&&... args ) MAYTHROW\n\t\t\t\t: m_t(aggregate_tag, tc_move_if_owned(func)(tc_move_if_owned(args)...))\n\t\t\t{}\n\n\t\t\tconstexpr auto get() const& noexcept ->decltype(auto) {\n\t\t\t\treturn *m_t;\n\t\t\t}\n\t\t\tconstexpr auto get() & noexcept ->decltype(auto) {\n\t\t\t\treturn *m_t;\n\t\t\t}\n\t\t\tconstexpr auto get() && noexcept ->decltype(auto) {\n\t\t\t\treturn *tc_move(m_t);\n\t\t\t}\n\t\t\ttemplate<typename FuncTo, typename... ArgsTo>\n\t\t\tconstexpr auto pass_to(FuncTo&& functo, ArgsTo&& ...args) const& noexcept ->decltype(auto) {\n\t\t\t\treturn tc_move_if_owned(functo)(*m_t, tc_move_if_owned(args)...);\n\t\t\t}\n\t\t\ttemplate<typename FuncTo, typename... ArgsTo>\n\t\t\tconstexpr auto pass_to(FuncTo&& functo, ArgsTo&& ...args) & noexcept ->decltype(auto) {\n\t\t\t\treturn tc_move_if_owned(functo)(*m_t, tc_move_if_owned(args)...);\n\t\t\t}\n\t\t\ttemplate<typename FuncTo, typename... ArgsTo>\n\t\t\tconstexpr auto pass_to(FuncTo&& functo, ArgsTo&& ...args) && noexcept ->decltype(auto) {\n\t\t\t\treturn tc_move_if_owned(functo)(*tc_move(m_t), tc_move_if_owned(args)...);\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Func, typename... Args > requires std::is_void< decltype(std::declval<Func>()(std::declval<Args>()...)) >::value\n\t\tstruct stores_result_of<Func, Args... > final {\n\t\t\tconstexpr stores_result_of( Func&& func, Args... args ) MAYTHROW {\n\t\t\t\ttc_move_if_owned(func)(static_cast<Args>(args)...);\n\t\t\t}\n\n\t\t\tstatic constexpr void get() noexcept {}\n\t\t\ttemplate<typename FuncTo, typename... ArgsTo>\n\t\t\tstatic constexpr auto pass_to(FuncTo&& functo, ArgsTo&& ...args) noexcept ->decltype(auto) {\n\t\t\t\treturn tc_move_if_owned(functo)(tc_move_if_owned(args)...);\n\t\t\t}\n\t\t};\n\t}\n\ttemplate< typename Func, typename... Args >\n\tusing stores_result_of=no_adl::stores_result_of<Func, Args...>;\n}\n"
  },
  {
    "path": "tc/base/reference_or_value.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"reference_or_value.h\"\n#include \"../tuple.h\"\n#include <utility>\n\nstatic_assert(std::is_trivially_copyable<tc::reference_or_value<int>>::value);\nstatic_assert(std::is_trivially_copy_assignable<tc::reference_or_value<int>>::value);\nstatic_assert(std::is_trivially_move_assignable<tc::reference_or_value<int>>::value);\n\nstatic_assert(!std::is_trivially_copy_assignable<std::pair<int&, int&>>::value);\nstatic_assert(!std::is_trivially_move_assignable<std::pair<int&, int&>>::value);\nstatic_assert(!std::is_trivially_copyable<tc::reference_or_value<std::pair<int&, int&>>>::value);\nstatic_assert(!std::is_trivially_copy_assignable<tc::reference_or_value<std::pair<int&, int&>>>::value);\nstatic_assert(!std::is_trivially_move_assignable<tc::reference_or_value<std::pair<int&, int&>>>::value);\n\nstatic_assert(std::is_trivially_copyable<tc::reference_or_value<int&>>::value);\nstatic_assert(std::is_trivially_copy_assignable<tc::reference_or_value<int&>>::value);\nstatic_assert(std::is_trivially_move_assignable<tc::reference_or_value<int&>>::value);\n\nstatic_assert(std::is_trivially_copyable<tc::reference_or_value<tc::tuple<int, double>>>::value);\nstatic_assert(std::is_trivially_copy_assignable<tc::reference_or_value<tc::tuple<int, double>>>::value);\nstatic_assert(std::is_trivially_move_assignable<tc::reference_or_value<tc::tuple<int, double>>>::value);\n"
  },
  {
    "path": "tc/base/renew.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"explicit_cast_fwd.h\"\n\n#include <algorithm>\n#include <typeinfo>\n\nnamespace tc {\n\ttemplate<typename T >\n\tconstexpr void assert_most_derived(T const& t) noexcept {\n\t\tif constexpr( !std::is_final<T>::value && std::is_polymorphic<T>::value ) { // The runtime check is not necessary if T is final, and not available if T is not polymorphic.\n\t\t\tif( !std::is_constant_evaluated() ) { // type_info::operator== is not constexpr\n\t\t\t\t_ASSERTEQUAL(typeid(t), typeid(T));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\tconstexpr void dtor_static( T & t ) noexcept { // can call dtor on const&, but does not seem sensible\n#ifdef _MSC_VER // Cannot call destructor on uninitialized int during constant evaluation in MSVC.\n\t\tif constexpr( !std::is_trivially_destructible<T>::value )\n#endif\n\t\t{\n\t\t\tt.T::~T(); // Intentionally ignore dynamic type of T.\n\t\t}\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\tif( !std::is_constant_evaluated() ) {\n\t\t\ttc::fill_with_dead_pattern(t);\n\t\t}\n#endif\n\t}\n\n\ttemplate <typename T, typename... Args> requires (0==sizeof...(Args) && std::is_trivially_default_constructible<T>::value/*value initialization*/) || tc::safely_constructible_from<T, Args&&...>\n\tconstexpr void ctor(T& t, Args&&... args) noexcept(std::is_nothrow_constructible<T, Args&&...>::value) {\nMODIFY_WARNINGS_BEGIN(((disable)(4244))) // double to float is tc::safely_constructible_from but triggers warning/error 4244 with std::construct_at.\n\t\tstd::construct_at(std::addressof(t), tc_move_if_owned(args)...);\nMODIFY_WARNINGS_END\n\t}\n\n\ttemplate <typename T, typename... Args> requires (!((0==sizeof...(Args) && std::is_trivially_default_constructible<T>::value/*value initialization*/) || tc::safely_constructible_from<T, Args&&...>)) && tc::explicit_castable_from<T, Args&&...>\n\tconstexpr void ctor(T& t, Args&&... args) noexcept(noexcept(tc::explicit_cast<T>(std::declval<Args>()...))) {\n\t\tif constexpr( std::is_move_constructible<T>::value ) {\n\t\t\tif( std::is_constant_evaluated() ) {\n\t\t\t\ttc::ctor(t, tc::explicit_cast<T>(tc_move_if_owned(args)...));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// :: ensures that non-class scope operator new is used.\n\t\t// cast to void* ensures that built-in placement new is used  (18.6.1.3).\n\t\t// not using std::construct_at to guarantee copy elision.\n\t\t::new (static_cast<void*>(std::addressof(t))) T(tc::explicit_cast<T>(tc_move_if_owned(args)...)); \n\t}\n\n\tnamespace renew_detail {\n\t\ttemplate <typename T, typename... Args>\n\t\tconstexpr void renew(T& t, Args&&... args) noexcept(\n\t\t\t// If t is not guaranteed default constructed in case tc::ctor throws, call std::terminate.\n\t\t\tnoexcept(tc::ctor(t, std::declval<Args>()...)) || !std::is_trivially_default_constructible<T>::value\n\t\t) {\n\t\t\ttc::assert_most_derived(t);\n\t\t\ttc::dtor_static(t);\n\t\t\ttc::ctor(t, tc_move_if_owned(args)...);\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\tvoid renew_default(T& t) noexcept {\n\t\tstatic_assert( std::is_nothrow_default_constructible<T>::value );\n\t\ttc::assert_most_derived(t);\n\t\ttc::dtor_static(t);\n\t\t::new (static_cast<void*>(std::addressof(t))) T; // :: ensures that non-class scope operator new is used, cast to void* ensures that built-in placement new is used  (18.6.1.3)\n\t}\n\n\ttemplate< typename T > // renew_value with non-empty argument list is useful in generic code\n\tconstexpr void renew_value(T& t) return_MAYTHROW(\n\t\trenew_detail::renew(t)\n\t)\n\n\ttemplate< typename T, typename... Args >\n\tconstexpr void renew(T& t, Args&&... args) noexcept(noexcept(renew_detail::renew(t, tc_move_if_owned(args)...)))\t{\n\t\tstatic_assert(!std::is_trivially_default_constructible<T>::value || 0 < sizeof...(Args), \"You must decide between renew_default and renew_value!\");\n\t\trenew_detail::renew(t, tc_move_if_owned(args)...);\n\t}\n\n\ttemplate<typename Lhs, typename... Rhs>\n\tconstexpr void assign_explicit_cast(Lhs& lhs, Rhs&&... rhs) MAYTHROW {\n\t\tlhs=tc::explicit_cast<Lhs>(tc_move_if_owned(rhs)...);\n\t}\n}\n\n#define ASSIGN_BY_RENEW_IMPL(Lhs, Rhs, /*SelfAssignCheck*/...) \\\n\tLhs& operator=(Rhs rhs) & noexcept { \\\n\t\t/*static_assert( std::convertible_to< S, T >, \"assignment must correspond to implicit construction\" ); */ \\\n\t\t__VA_ARGS__ { \\\n\t\t\ttc::renew(*this, tc_move_if_owned(rhs)); \\\n\t\t} \\\n\t\treturn *this; \\\n\t}\n\n#define COPY_SELF_ASSIGN_CHECK(Lhs, Rhs) \\\n\tstatic_assert(std::same_as<Lhs, std::remove_cvref_t<Rhs>> && std::is_lvalue_reference<Rhs>::value); \\\n\tif(std::addressof(rhs)!=this)\n\n// Self assignment check only need to be applied if std::remove_cvref_t<Rhs> and Lhs are the same type and Rhs is an lvalue reference, because\n//   1. for rvalue references passed to the C++ library, the caller must ensure that they can be treated as temporaries, e.g., that they don't alias.\n//      - https://eel.is/c++draft/res.on.arguments#note-2\n//      - https://eel.is/c++draft/lib.types.movedfrom#2\n//   2. values cannot alias.\n//   3. for same type copy assignment, rhs must be unchanged. https://en.cppreference.com/w/cpp/named_req/CopyAssignable\n\n// ASSIGN_BY_RENEW:  assignment which has no danger of overlapping/self assignment. We must look case by case if Lhs and Rhs are different types and may overlap.\n#define ASSIGN_BY_RENEW(Lhs, Rhs) ASSIGN_BY_RENEW_IMPL(TC_FWD(Lhs), TC_FWD(Rhs), static_assert(!std::same_as<Lhs, std::remove_cvref_t<Rhs>> || !std::is_lvalue_reference<Rhs>::value);)\n// COPY_ASSIGN_BY_RENEW: same type copy assignment. check against self assignment is always needed because of dtor->ctor.\n#define COPY_ASSIGN_BY_RENEW(Lhs, Rhs) ASSIGN_BY_RENEW_IMPL(TC_FWD(Lhs), TC_FWD(Rhs), COPY_SELF_ASSIGN_CHECK(TC_FWD(Lhs), TC_FWD(Rhs)))\n\n#define ASSIGN_BY_SWAP(T) \\\n\tT& operator=( T other ) & noexcept { \\\n\t\tswap( *this, other ); /*not tc::swap, which may be implemented in terms of move, which would be circular*/ \\\n\t\treturn *this; \\\n\t}\n"
  },
  {
    "path": "tc/base/return_decltype.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"temporary.h\"\n\nnamespace tc {\n\t#define return_MAYTHROW(...) noexcept(noexcept((__VA_ARGS__))) { \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\ttemplate<typename T>\n\tusing xvalue_decay_t = typename std::conditional_t<std::is_rvalue_reference<T>::value || tc::instance_tn<T, tc::temporary>,\n\t\ttc::decay<T>,\n\t\tstd::type_identity<T>\n\t>::type;\n\n\t// helper function to decay rvalues when decltype cannot be used because of lambdas in the expression\n\ttemplate<typename T>\n\tconstexpr xvalue_decay_t<T&&> lvalue_or_decay(T&& t) noexcept {\n\t\treturn tc_move_if_owned(t);\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// return_decltype: does not allow returning xvalues, safely handles tc::temporary\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct return_decltype final {\n\t\t\tstatic_assert(!std::is_rvalue_reference<T>::value, \"use return_decltype_allow_xvalue if you really want to return xvalue references, but be prepared to handle tc::temporary arguments\");\n\t\t\tusing type = tc::return_temporary_t<T>;\n\t\t};\n\t}\n\ttemplate<typename T>\n\tusing return_decltype_t = typename no_adl::return_decltype<T>::type;\n\n\t#define return_decltype_MAYTHROW(...) noexcept(noexcept((__VA_ARGS__))) -> tc::return_decltype_t<decltype((__VA_ARGS__))> { \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t#define return_decltype_noexcept(...) noexcept -> tc::return_decltype_t<decltype((__VA_ARGS__))> { \\\n\t\tstatic_assert(noexcept((__VA_ARGS__)), \"expression is not noexcept\"); \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t// TODO C++20: When lambdas are allowed in unevaluated contexts, they will be allowed inside noexcept() expressions, and\n\t// any usage of return_decltype_NOEXCEPT(XYZ) should be replaced with return_decltype_noexcept(NOEXCEPT(XYZ)), and\n\t// we can remove NOEXCEPT_NO_LAMBDA\n\t#define return_decltype_NOEXCEPT(...) noexcept -> tc::return_decltype_t<decltype((__VA_ARGS__))> { \\\n\t\treturn NOEXCEPT_NO_LAMBDA(__VA_ARGS__); \\\n\t}\n\n\t#define code_return_decltype(code, ...) -> tc::return_decltype_t<decltype((__VA_ARGS__))> { \\\n\t\tcode \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// return_decltype_allow_xvalue: allows returning xvalues but does not allow dangling temporaries\n\t#define return_decltype_allow_xvalue_MAYTHROW(...) noexcept(noexcept((__VA_ARGS__))) -> decltype((__VA_ARGS__)) { \\\n\t\tstatic_assert(!tc::dangling_temporary<decltype((__VA_ARGS__))>, \"you need to use return_decltype_allow_xvalue_slow_MAYTHROW\"); \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t#define return_decltype_allow_xvalue_noexcept(...) noexcept -> decltype((__VA_ARGS__)) { \\\n\t\tstatic_assert(!tc::dangling_temporary<decltype((__VA_ARGS__))>, \"you need to use return_decltype_allow_xvalue_slow_noexcept\"); \\\n\t\tstatic_assert(noexcept((__VA_ARGS__)), \"expression is not noexcept\"); \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t// We cannot have return_decltype_allow_xvalue_NOEXCEPT since xvalues cannot be passed through NOEXCEPT.\n\n\t#define code_return_decltype_allow_xvalue(code, ...) -> decltype((__VA_ARGS__)) { \\\n\t\tstatic_assert(!tc::dangling_temporary<decltype((__VA_ARGS__))>, \"you need to use code_return_decltype_allow_xvalue_slow\"); \\\n\t\tcode \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// return_decltype_allow_xvalue_slow: allows returning xvalues and safely handles dangling temporaries.\n\t// Only use it, when the static_assert tells you to.\n\t// (This cannot be folded into return_decltype_allow_xvalue due to a drastic compile-time increase.)\n\t#define return_decltype_allow_xvalue_slow_MAYTHROW(...) noexcept(noexcept((__VA_ARGS__))) -> tc::return_temporary_t<decltype((__VA_ARGS__))> { \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t#define return_decltype_allow_xvalue_slow_noexcept(...) noexcept -> tc::return_temporary_t<decltype((__VA_ARGS__))> { \\\n\t\tstatic_assert(noexcept((__VA_ARGS__)), \"expression is not noexcept\"); \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t// We cannot have return_decltype_allow_xvalue_slow_NOEXCEPT since xvalues cannot be passed through NOEXCEPT.\n\n\t#define code_return_decltype_allow_xvalue_slow(code, ...) -> tc::return_temporary_t<decltype((__VA_ARGS__))> { \\\n\t\tcode \\\n\t\treturn (__VA_ARGS__); \\\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// return_ctor: always returns T as prvalue\n\t#define return_ctor_MAYTHROW(T, ...) noexcept(noexcept(T __VA_ARGS__)) -> T { \\\n\t\treturn T __VA_ARGS__ ; \\\n\t}\n\n\t#define return_ctor_noexcept(T, ...) noexcept -> T { \\\n\t\tstatic_assert((noexcept(T __VA_ARGS__)), \"expression is not noexcept\"); \\\n\t\treturn T __VA_ARGS__ ; \\\n\t}\n\n\t#define return_ctor_NOEXCEPT(T, ...) noexcept -> T { \\\n\t\treturn NOEXCEPT_NO_LAMBDA(T __VA_ARGS__) ; \\\n\t}\n\n\t#define code_return_ctor(code, T, ...) -> T { \\\n\t\tcode \\\n\t\treturn T __VA_ARGS__ ; \\\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_auto_cref\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct auto_cref_impl final {\n\t\t\tSTATICASSERTSAME(std::remove_cv_t<T>, tc::decay_t<T>);\n\t\t\tusing type = std::remove_cv_t<T> const;\n\t\t};\n\n\t\ttemplate <typename T>\n\t\tstruct auto_cref_impl<T&&> final {\n\t\t\tSTATICASSERTSAME(std::remove_cv_t<T>, tc::decay_t<T>);\n\t\t\tusing type = std::remove_cv_t<T> const;\n\t\t};\n\n\t\ttemplate <typename T, unsigned Lifetime>\n\t\tstruct auto_cref_impl<tc::temporary<T, Lifetime>> final {\n\t\t\tSTATICASSERTSAME(std::remove_cv_t<T>, tc::decay_t<T>);\n\t\t\tusing type = std::conditional_t<0 == Lifetime, std::remove_cv_t<T> const, tc::temporary<T const, Lifetime> const>; // if 0 < Lifetime, the underlying temporary object lives longer than the current function\n\t\t};\n\n\t\ttemplate <typename T>\n\t\tstruct auto_cref_impl<T&> final {\n\t\t\tusing type = T const&;\n\t\t};\n\t}\n\ttemplate <typename T>\n\tusing auto_cref_t = typename no_adl::auto_cref_impl<tc::canonicalize_temporary_t<T>>::type;\n\ttemplate <typename T>\n\tusing auto_cref_return_t = std::remove_const_t<auto_cref_t<T>>;\n\n\t#define tc_auto_cref( var, ... ) \\\n\t\ttc::auto_cref_t<decltype((__VA_ARGS__))> var = __VA_ARGS__\n\t#define tc_auto_cref_return( var, ... ) \\\n\t\ttc::auto_cref_return_t<decltype((__VA_ARGS__))> var = __VA_ARGS__\n}\n"
  },
  {
    "path": "tc/base/rvalue_property.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"return_decltype.h\"\n#include \"move.h\"\n\n#define RVALUE_THIS_NAMED_OVERLOAD_CONST(METHOD, FUNC) \\\n\ttemplate<typename... Args> constexpr auto METHOD(Args&& ...args) const& return_decltype_allow_xvalue_MAYTHROW(FUNC(*this, tc_move_if_owned(args)...)) \\\n\ttemplate<typename... Args> constexpr auto METHOD(Args&& ...args) const&& return_decltype_allow_xvalue_MAYTHROW(FUNC(tc_move_always_even_const(*this), tc_move_if_owned(args)...))\n\n// An underscore is appended to the static member function name because otherwise Visual Studio (as of version 19.15.26726) would trigger error C1202:\n// \"recursive type or function dependency context too complex\", while using the return_decltype_* macros for sfinae\n\n#define RVALUE_THIS_OVERLOAD_CONST(METHOD) \\\n\tRVALUE_THIS_NAMED_OVERLOAD_CONST(METHOD, BOOST_JOIN(METHOD,_))\n\n#define RVALUE_THIS_NAMED_OVERLOAD_MOVABLE(METHOD, FUNC) \\\n\tRVALUE_THIS_NAMED_OVERLOAD_CONST(METHOD, FUNC) \\\n\ttemplate<typename... Args> constexpr auto METHOD(Args&& ...args) && return_decltype_allow_xvalue_MAYTHROW(FUNC(tc_move_always(*this), tc_move_if_owned(args)...))\n\n#define RVALUE_THIS_OVERLOAD_MOVABLE(METHOD) \\\n\tRVALUE_THIS_NAMED_OVERLOAD_MOVABLE(METHOD, BOOST_JOIN(METHOD,_))\n\n#define RVALUE_THIS_NAMED_OVERLOAD_MOVABLE_MUTABLE_REF(METHOD, FUNC) \\\n\tRVALUE_THIS_NAMED_OVERLOAD_MOVABLE(METHOD, FUNC) \\\n\ttemplate<typename... Args> constexpr auto METHOD(Args&& ...args) & return_decltype_allow_xvalue_MAYTHROW(FUNC(*this, tc_move_if_owned(args)...))\n\n#define RVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(METHOD) \\\n\tRVALUE_THIS_NAMED_OVERLOAD_MOVABLE_MUTABLE_REF(METHOD, BOOST_JOIN(METHOD,_))\n"
  },
  {
    "path": "tc/base/rvalue_property.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"rvalue_property.h\"\n#include \"type_traits.h\"\n#include \"../unittest.h\"\n\nnamespace {\n\tstruct A final {\n\t\ttemplate<typename Self>\n\t\tstatic decltype(auto) test_(Self&& self) noexcept {\n\t\t\treturn (tc_move_if_owned(self).i);\n\t\t}\n\t\tint i;\n\t\t\n\t\tRVALUE_THIS_OVERLOAD_CONST(test);\n\t};\n\n\tSTATICASSERTSAME(decltype(std::declval<A>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<A const>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<A&&>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<A const&&>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<A&>().test()), int const&);\n\tSTATICASSERTSAME(decltype(std::declval<A const&>().test()), int const&);\n\n\t\n\tstruct B final {\n\t\ttemplate<typename Self>\n\t\tstatic decltype(auto) test_(Self&& self) noexcept {\n\t\t\treturn (tc_move_if_owned(self).i);\n\t\t}\n\t\tint i;\n\t\t\n\t\tRVALUE_THIS_OVERLOAD_MOVABLE(test);\n\t};\n\t\n\tSTATICASSERTSAME(decltype(std::declval<B>().test()), int&&);\n\tSTATICASSERTSAME(decltype(std::declval<B const>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<B&&>().test()), int&&);\n\tSTATICASSERTSAME(decltype(std::declval<B const&&>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<B&>().test()), int const&);\n\tSTATICASSERTSAME(decltype(std::declval<B const&>().test()), int const&);\n\t\n\tstruct C final {\n\t\ttemplate<typename Self>\n\t\tstatic decltype(auto) test_(Self&& self) noexcept {\n\t\t\treturn (tc_move_if_owned(self).i);\n\t\t}\n\t\tint i;\n\t\t\n\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(test);\n\t};\n\t\n\tSTATICASSERTSAME(decltype(std::declval<C>().test()), int&&);\n\tSTATICASSERTSAME(decltype(std::declval<C const>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<C&&>().test()), int&&);\n\tSTATICASSERTSAME(decltype(std::declval<C const&&>().test()), int const&&);\n\tSTATICASSERTSAME(decltype(std::declval<C&>().test()), int&);\n\tSTATICASSERTSAME(decltype(std::declval<C const&>().test()), int const&);\n}\n"
  },
  {
    "path": "tc/base/safe_comparison.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits.h\"\n#include \"casts.h\"\n#include <concepts>\n\nnamespace tc {\n\t// By default, a comparison is safe; specialize to mark as unsafe.\n\t// (We can't delegate to safely_convertible_to, as we can't tell whether `T == U` is valid because of implicit conversions,\n\t// or because of an overloaded operator== that takes those types and handles them safely.)\n\ttemplate <typename T, typename U>\n\tconstexpr bool safe_comparison = true;\n\n\t// Comparison between mixed integral types is only safe as long as neither is a char type and they have the same signedness.\n\ttemplate <std::integral T, std::integral U>\n\t\trequires (!std::same_as<T, U>)\n\tconstexpr bool safe_comparison<T, U>\n\t\t= !tc::char_type<T> && !tc::char_type<U>\n\t\t&& std::is_signed<T>::value == std::is_signed<U>::value;\n\n\ttemplate <typename T, typename U>\n\tconcept safely_equality_comparable_with = std::equality_comparable_with<T, U> && safe_comparison<tc::decay_t<T>, tc::decay_t<U>>;\n\n\ttemplate <typename T, typename U>\n\tconcept safely_totally_ordered_with = std::totally_ordered_with<T, U> && safe_comparison<tc::decay_t<T>, tc::decay_t<U>>;\n}\n"
  },
  {
    "path": "tc/base/safe_comparison.t.cpp",
    "content": "// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"safe_comparison.h\"\n#include \"../unittest.h\"\n#include \"../string/char.h\"\n\n// Same type is safe.\nstatic_assert(tc::safe_comparison<int, int>);\nstatic_assert(tc::safe_comparison<unsigned, unsigned>);\nstatic_assert(tc::safe_comparison<tc::char16, tc::char16>);\n// Mixed signedness is unsafe.\nstatic_assert(!tc::safe_comparison<int, unsigned>);\nstatic_assert(!tc::safe_comparison<unsigned, int>);\n// Mixed chars are unsafe.\nstatic_assert(!tc::safe_comparison<char, char16_t>);\nstatic_assert(!tc::safe_comparison<char8_t, char32_t>);\n// chars and ints are unsafe.\nstatic_assert(!tc::safe_comparison<char, short>);\nstatic_assert(!tc::safe_comparison<char32_t, int>);\n"
  },
  {
    "path": "tc/base/scope.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once \n\n#include \"type_traits.h\"\n#include \"noncopyable.h\"\n#include \"tag_type.h\"\n#include \"change.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct scope_exit_impl final : private tc::nonmovable {\n\t\t\tconstexpr explicit scope_exit_impl(T const& exitscope) noexcept\n\t\t\t:\tm_exitscope(exitscope)\n\t\t\t{}\n\t\t\tconstexpr ~scope_exit_impl(){\n\t\t\t\tm_exitscope();\n\t\t\t}\n\t\tprivate:\n\t\t\tT const m_exitscope;\n\t\t};\n\n\t\tstruct make_scope_exit_impl {\n\t\t\ttemplate <typename T>\n\t\t\t[[nodiscard]] constexpr scope_exit_impl<T> operator->*(T const& exitscope) && noexcept {\n\t\t\t\treturn scope_exit_impl<T>(exitscope);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::scope_exit_impl;\n\tusing no_adl::make_scope_exit_impl;\n\n\tDEFINE_TAG_TYPE(scoped_assign_tag)\n\n\tnamespace no_adl {\n\t\ttemplate< typename T >\n\t\tstruct scoped_restorer : private tc::nonmovable {\n\t\t\tstatic_assert(!std::is_array<std::remove_reference_t<T>>::value);\n\t\t\tstatic_assert(\n\t\t\t\tstd::is_lvalue_reference<T>::value,\n\t\t\t\t\"There may be use cases for non-lvalue types here. \"\n\t\t\t\t\"But this assert has to stay at least until https://connect.microsoft.com/VisualStudio/Feedback/Details/2117239 is fixed\"\n\t\t\t);\n\t\tprotected:\n\t\t\tstd::conditional_t< std::is_lvalue_reference<T>::value,\n\t\t\t\tT, // regular reference\n\t\t\t\tstd::remove_reference_t<T> // proxy, store by value (and not as rvalue reference)\n\t\t\t> m_var;\n\t\t\ttc::decay_t<T> m_valSaved;\n\t\tpublic:\n\t\t\tconstexpr scoped_restorer( T&& var ) noexcept\n\t\t\t:\tm_var(tc_move_if_owned(var)),\n\t\t\t\tm_valSaved(VERIFYINITIALIZED(var)) {}\n\t\t\tconstexpr scoped_restorer( T&& var, scoped_assign_tag_t ) noexcept\n\t\t\t:\tm_var(tc_move_if_owned(var)),\n\t\t\t\tm_valSaved(tc_move_always(VERIFYINITIALIZED(var))) {}\n\t\t\tconstexpr ~scoped_restorer() {\n\t\t\t\tm_var=tc_move(m_valSaved);\n\t\t\t}\n\t\t\t// can be used to access/change saved value\n\t\t\ttemplate<typename T2>\n\t\t\tconstexpr scoped_restorer& operator=( T2&& t ) & noexcept {\n\t\t\t\tm_valSaved=tc_move_if_owned(t);\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr operator tc::decay_t<T> const& () const& noexcept {\n\t\t\t\treturn m_valSaved;\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename T>\n\t\tscoped_restorer(T&&) -> scoped_restorer<T&&>;\n\t}\n\tusing no_adl::scoped_restorer;\n\n\tDEFINE_TAG_TYPE(scoped_change_tag)\n\n\tnamespace no_adl {\n\t\ttemplate< typename T >\n\t\tstruct scoped_assigner\n\t\t:\tscoped_restorer<T> {\n\t\t\ttemplate<typename T2>\n\t\t\tconstexpr explicit scoped_assigner( T&& var, T2&& val ) noexcept\n\t\t\t:\tscoped_restorer<T>( tc_move_if_owned(var), scoped_assign_tag )\n\t\t\t{\n\t\t\t\tthis->m_var=tc_move_if_owned(val);\n\t\t\t}\n\t\t\ttemplate<typename T2>\n\t\t\tconstexpr explicit scoped_assigner( scoped_change_tag_t, T&& var, T2&& val ) noexcept\n\t\t\t:\tscoped_assigner( tc_move_if_owned(var), tc_move_if_owned(val) )\n\t\t\t{\n\t\t\t\t_ASSERT(!(this->m_var == this->m_valSaved));\n\t\t\t}\n\t\t\tusing scoped_restorer<T>::operator=;\n\t\t};\n\n\t\ttemplate <typename T, typename T2>\n\t\tscoped_assigner(T&&, T2&&) -> scoped_assigner<T>;\n\t\ttemplate <typename T, typename T2>\n\t\tscoped_assigner(scoped_change_tag_t, T&&, T2&&) -> scoped_assigner<T>;\n\t}\n\tusing no_adl::scoped_assigner;\n\n\tnamespace no_adl {\n\t\ttemplate< typename T >\n\t\tstruct scoped_assigner_better\n\t\t:\tscoped_restorer<T> {\n\t\t\ttemplate<typename Val, typename Better>\n\t\t\tconstexpr explicit scoped_assigner_better( T& var, Val&& val, Better better ) noexcept\n\t\t\t:\tscoped_restorer<T>( var )\n\t\t\t{\n\t\t\t\ttc::assign_better(tc_move(better), var, tc_move_if_owned(val));\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename T, typename Val, typename Better>\n\t\tscoped_assigner_better(T&, Val&&, Better) -> scoped_assigner_better<T&>;\n\t}\n\tusing no_adl::scoped_assigner_better;\n}\n\n// Note about brackets:\n// * in the decltype, var is parenthesized to add a reference.\n// * in the constructor, var and __VA_ARGS__ is not parenthesized to disallow use of the comma operator.\n// * we use braces to create the object to prevent a function declaration.\n//\n// We do not have a semicolon in the declaration to force the caller to add one.\n#define tc_restore_after_scope(var)    tc::scoped_restorer< decltype((var)) > UNIQUE_IDENTIFIER{var}\n#define tc_scoped_assign(var, ...)     tc::scoped_assigner< decltype((var)) > UNIQUE_IDENTIFIER{var, __VA_ARGS__}\n#define tc_scoped_change(var, ...)\t   tc::scoped_assigner< decltype((var)) > UNIQUE_IDENTIFIER{tc::scoped_change_tag, var, __VA_ARGS__}\n#define tc_scoped_assign_max(var, ...) tc::scoped_assigner_better< decltype((var)) > UNIQUE_IDENTIFIER{var, __VA_ARGS__,tc::fn_greater()}\n\n#if _MSC_VER_FULL <= 190023026\n\t#define tc_scoped_assign_for_baseclass_member(var, ...)  tc::scoped_assigner< decltype(var)& > UNIQUE_IDENTIFIER{var, __VA_ARGS__}\n\t#define tc_restore_after_scope_for_baseclass_member(var) tc::scoped_restorer< decltype(var)& > UNIQUE_IDENTIFIER{var}\n#else\n\t#error \"should be fixed: https://connect.microsoft.com/VisualStudio/Feedback/Details/2117239\"\n#endif\n\n// tc_scope_exit must not throw in order to avoid double throws. If exceptions are needed, implement scope_success/scope_failure.\n#define tc_scope_exit auto UNIQUE_IDENTIFIER = tc::make_scope_exit_impl{} ->* [&]() noexcept -> void\n\n// the empty namespace ensures the macro is only used at file scope\n#define tc_file_scope_exit \\\n\tnamespace {} \\\n\tstatic constinit auto UNIQUE_IDENTIFIER = tc::make_scope_exit_impl{} ->* []() noexcept -> void\n"
  },
  {
    "path": "tc/base/static_polymorphism.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include <type_traits>\n#include \"tag_type.h\"\n\nnamespace tc {\n\tDEFINE_TAG_TYPE(unchecked_derived_cast_tag)\n}\n\n#define STATIC_VIRTUAL_METHOD_NAME( Name ) \\\n\tName ## _ImplDoNotCallDirectly\n\n#define STATIC_VIRTUAL_DISPATCH_IMPL_NAME( Name ) \\\n\tName ## _DispatchDoNotCallDirectly\n\n#define STATIC_VIRTUAL_FALLBACK_NAME( Name ) \\\n\tName ## _FallbackDoNotCallDirectly\n\n#define STATIC_VIRTUAL_FORWARD_IMPL( Name, Decoration, ExpandCall, DerivedCast, MaybeUncheckedDerivedCastTagWithComma ) \\\n\ttemplate<typename Derived_=Derived, typename... Args> \\\n\tconstexpr auto Name(Args&&... args) Decoration return_decltype_allow_xvalue_MAYTHROW( \\\n\t\tExpandCall( \\\n\t\t\tName, \\\n\t\t\tTC_FWD(DerivedCast<Derived_>(static_cast<this_type Decoration>(*MSVC_WORKAROUND_THIS))), \\\n\t\t\tMaybeUncheckedDerivedCastTagWithComma tc_move_if_owned(args)... \\\n\t\t) \\\n\t)\n\n#define STATIC_VIRTUAL_FORWARD_ALL_IMPL( Name, ExpandCall, DerivedCast, MaybeUncheckedDerivedCastTagWithComma ) \\\n\tSTATIC_VIRTUAL_FORWARD_IMPL( Name, &, ExpandCall, DerivedCast, TC_FWD(MaybeUncheckedDerivedCastTagWithComma) ) \\\n\tSTATIC_VIRTUAL_FORWARD_IMPL( Name, const&, ExpandCall, DerivedCast, TC_FWD(MaybeUncheckedDerivedCastTagWithComma) ) \\\n\tSTATIC_VIRTUAL_FORWARD_IMPL( Name, &&, ExpandCall, DerivedCast, TC_FWD(MaybeUncheckedDerivedCastTagWithComma) ) \\\n\tSTATIC_VIRTUAL_FORWARD_IMPL( Name, const&&, ExpandCall, DerivedCast, TC_FWD(MaybeUncheckedDerivedCastTagWithComma) )\n\n#define STATIC_VIRTUAL_COMMON( Name ) \\\n\tusing Name ## _derived_type = Derived; \\\n\tusing Name ## _declaring_type = this_type;\n\n#define TC_STATIC_VIRTUAL_METHOD_CALL(Name, self, ...) \\\n\tself.STATIC_VIRTUAL_METHOD_NAME(Name)(__VA_ARGS__)\n\n#define STATIC_VIRTUAL( Name ) \\\n\tSTATIC_VIRTUAL_COMMON( Name ) \\\n\tSTATIC_VIRTUAL_FORWARD_ALL_IMPL( Name, TC_STATIC_VIRTUAL_METHOD_CALL, tc::derived_cast, /*MaybeUncheckedDerivedCastTagWithComma*/ )\n\n#define UNCHECKED_STATIC_VIRTUAL( Name ) \\\n\tSTATIC_VIRTUAL( Name ) \\\n\tSTATIC_VIRTUAL_FORWARD_ALL_IMPL( Name, TC_STATIC_VIRTUAL_METHOD_CALL, tc::unchecked_derived_cast, TC_FWD(tc::unchecked_derived_cast_tag,) )\n\n// force implementation as static method, using STATIC_FINAL_MOD(static, Name) \n#define STATIC_STATIC_VIRTUAL( Name ) \\\n\tusing Name ## _derived_type = Derived; \\\n\tusing Name ## _declaring_type = this_type; \\\n\ttemplate<typename Derived_=Derived, typename... Args_> \\\n\tstatic constexpr auto Name(Args_&& ...args) return_decltype_allow_xvalue_MAYTHROW( \\\n\t\tDerived_:: STATIC_VIRTUAL_METHOD_NAME(Name) (tc_move_if_owned(args)...) \\\n\t)\n\n#define STATIC_VIRTUAL_WITH_DEFAULT_IMPL_MOD( Mod, Name ) \\\n\tSTATIC_VIRTUAL( Name ) \\\n\tMod \\\n\tauto STATIC_VIRTUAL_METHOD_NAME( Name )\n\n#define STATIC_VIRTUAL_WITH_DEFAULT_IMPL( Name ) \\\n\tSTATIC_VIRTUAL_WITH_DEFAULT_IMPL_MOD( BOOST_PP_EMPTY(), Name )\n\n#define STATIC_FINAL_MOD_DECLARING(Mod, Declaring, Name) \\\n\tfriend typename Declaring; \\\n\tstatic_assert( \\\n\t\tstd::is_same< typename Declaring::Name ## _derived_type, this_type >::value, \\\n\t\t\"The class implementing the final static virtual method must be the Derived type of the class declaring the method.\" \\\n\t); \\\n\tMod \\\n\tauto STATIC_VIRTUAL_METHOD_NAME( Name )\n\n#define STATIC_FINAL_DECLARING(Declaring, Name) \\\n\tSTATIC_FINAL_MOD_DECLARING(BOOST_PP_EMPTY(), TC_FWD(Declaring), Name)\n\n#define STATIC_FINAL_MOD(Mod, Name) \\\n\tSTATIC_FINAL_MOD_DECLARING(TC_FWD(Mod), this_type::Name ## _declaring_type, Name)\n\n#define STATIC_FINAL(Name) \\\n\tSTATIC_FINAL_MOD(BOOST_PP_EMPTY(), Name)\n\n#define STATIC_OVERRIDE_MOD_DECLARING_BASE(Declaring, Name, ...) \\\n\tfriend typename Declaring; \\\n\t__VA_ARGS__ \\\n\tauto STATIC_VIRTUAL_METHOD_NAME( Name )\n\n#define STATIC_OVERRIDE_MOD_DECLARING(Mod, Declaring, Name) \\\n\tSTATIC_OVERRIDE_MOD_DECLARING_BASE(TC_FWD(Declaring), Name, \\\n\t\tstatic_assert( \\\n\t\t\tstd::is_same<typename Declaring::Name ## _derived_type, Derived>::value, \\\n\t\t\t\"The Derived type of the class implementing a non-final static virtual method must be the same as the one of the class declaring the method.\" \\\n\t\t); \\\n\t\tMod \\\n\t)\n\n#define STATIC_OVERRIDE_DECLARING(Declaring, Name) \\\n\tSTATIC_OVERRIDE_MOD_DECLARING(BOOST_PP_EMPTY(), TC_FWD(Declaring), Name)\n\n#define STATIC_OVERRIDE_MOD(Mod, Name) \\\n\tSTATIC_OVERRIDE_MOD_DECLARING(TC_FWD(Mod), this_type::Name ## _declaring_type, Name)\n\n#define STATIC_OVERRIDE( Name ) \\\n\tSTATIC_OVERRIDE_MOD( BOOST_PP_EMPTY(), Name )\n\n#define TC_STATIC_VIRTUAL_DISPATCH_CALL(Name, self, ...) \\\n\tSTATIC_VIRTUAL_DISPATCH_IMPL_NAME(Name)(self, __VA_ARGS__)\n\n#define STATIC_VIRTUAL_WITH_FALLBACK_MOD(Mod, Name) \\\n\tSTATIC_VIRTUAL_COMMON( Name ) \\\n\ttemplate<typename Derived_, typename... Args> \\\n\tstatic constexpr auto STATIC_VIRTUAL_DISPATCH_IMPL_NAME(Name)(Derived_&& derived, Args&&... args) return_decltype_allow_xvalue_MAYTHROW( \\\n\t\ttc_move_if_owned(derived).STATIC_VIRTUAL_METHOD_NAME(Name)(tc_move_if_owned(args)...) \\\n\t) \\\n\ttemplate<typename Derived_, typename... Args TC_REQUIRES_CWG2369_WORKAROUND( !requires { std::declval<Derived_>().STATIC_VIRTUAL_METHOD_NAME(Name)( std::declval<Args>()... ); } ) \\\n\tstatic constexpr auto STATIC_VIRTUAL_DISPATCH_IMPL_NAME(Name)(Derived_&& derived, Args&&... args) return_decltype_allow_xvalue_MAYTHROW( \\\n\t\ttc_move_if_owned(derived).STATIC_VIRTUAL_FALLBACK_NAME(Name)(tc_move_if_owned(args)...) \\\n\t) \\\n\tSTATIC_VIRTUAL_FORWARD_ALL_IMPL( Name, TC_STATIC_VIRTUAL_DISPATCH_CALL, tc::derived_cast, /*MaybeUncheckedDerivedCastTagWithComma*/ ) \\\n\tMod \\\n\tauto STATIC_VIRTUAL_FALLBACK_NAME(Name)\n\n#define STATIC_VIRTUAL_WITH_FALLBACK(Name) \\\n\tSTATIC_VIRTUAL_WITH_FALLBACK_MOD( BOOST_PP_EMPTY(), Name )\n"
  },
  {
    "path": "tc/base/string_template_param.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits_fwd.h\"\n\nnamespace tc {\n\tnamespace literal_range_adl {\n\t\ttemplate <typename T, auto... Ts>\n\t\tstruct literal_range;\n\t}\n\tusing literal_range_adl::literal_range;\n\n\tnamespace no_adl {\n\t\ttemplate <typename Char, std::size_t N> requires tc::char_like<Char> && (!std::is_volatile<Char>::value)\n\t\tstruct string_template_param final {\n\t\t\tconsteval string_template_param(Char const (&str)[N]) noexcept {\n\t\t\t\tfor(int i=0; i<N; ++i) m_str[i]=str[i]; // avoid using library functions to prevent circular dependency on _ASSERT\n\t\t\t}\n\t\t\ttemplate <auto ... Cs>\n\t\t\tconsteval string_template_param(literal_range<Char, Cs...>) noexcept {\n\t\t\t\tstatic_assert(sizeof...(Cs) + 1 == N);\n\t\t\t\tstd::size_t idx = 0;\n\t\t\t\t((m_str[idx++] = Cs), ...); // avoid using library functions to prevent circular dependency on _ASSERT\n\t\t\t\tm_str[idx] = Char();\n\t\t\t}\n\n\t\t\tconstexpr auto begin() const& noexcept {\n\t\t\t\treturn &m_str[0];\n\t\t\t}\n\n\t\t\tconstexpr auto end() const& noexcept {\n\t\t\t\treturn &m_str[N-1];\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<N-1>{};\n\t\t\t}\n\n\t\t\tconstexpr operator auto const&() const& noexcept {\n\t\t\t\treturn m_str;\n\t\t\t}\n\n\t\t\tconstexpr Char operator[](std::size_t idx) const& noexcept {\n\t\t\t\treturn m_str[idx];\n\t\t\t}\n\n\t\t\tChar m_str[N];\n\t\t};\n\n\t\ttemplate <typename Char, auto ... Cs>\n\t\tstring_template_param(literal_range<Char, Cs...>) -> string_template_param<Char, sizeof...(Cs) + 1>;\n\t}\n\tusing no_adl::string_template_param;\n}\n"
  },
  {
    "path": "tc/base/tag_type.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include <boost/preprocessor/control/expr_if.hpp>\n#include <boost/preprocessor/facilities/is_empty.hpp>\n#include <boost/preprocessor/logical/not.hpp>\n\n#include <type_traits>\n\n#define DERIVE_FROM_BASE_TAG(...) : __VA_ARGS__##_t\n\n#define DEFINE_TAG_TYPE_STRUCT(tag_name, base_tag_name, derivable) \\\n\tstruct tag_name##_t derivable BOOST_PP_EXPR_IF(BOOST_PP_NOT(BOOST_PP_IS_EMPTY(base_tag_name)), DERIVE_FROM_BASE_TAG(base_tag_name)) { \\\n\t\tconstexpr explicit tag_name##_t() noexcept = default; /* to avoid implicit initialization from {} */ \\\n\t\tusing is_tag = void; \\\n\t};\n\n#define DEFINE_TAG_TYPE_VAR(tag_name, specifier) \\\n\tspecifier constexpr auto tag_name = tag_name##_t();\n\n#define DEFINE_TAG_TYPE_BASE(tag_name, base_tag_name, derivable) \\\n\tnamespace no_adl { \\\n\t\tDEFINE_TAG_TYPE_STRUCT(tag_name, base_tag_name, derivable) \\\n\t} \\\n\tusing no_adl::tag_name##_t; \\\n\tDEFINE_TAG_TYPE_VAR(tag_name, inline)\n\n#define DEFINE_TAG_TYPE(tag_name) \\\n\tDEFINE_TAG_TYPE_BASE(tag_name, , final)\n\n#define DEFINE_NESTED_TAG_TYPE(tag_name) \\\n\tDEFINE_TAG_TYPE_STRUCT(tag_name, , final) \\\n\tDEFINE_TAG_TYPE_VAR(tag_name, static)\n\n#define DEFINE_ADL_TAG_TYPE(tag_name) \\\n\tDEFINE_TAG_TYPE_STRUCT(tag_name, , final) \\\n\tDEFINE_TAG_TYPE_VAR(tag_name, inline)\n\n#define DEFINE_TEMPLATE_TAG_TYPE(tag_name) \\\n\tnamespace no_adl { \\\n\t\ttemplate<typename T> \\\n\t\tDEFINE_TAG_TYPE_STRUCT(tag_name, , final) \\\n\t} \\\n\tusing no_adl::tag_name##_t; \\\n\ttemplate<typename T> \\\n\tinline constexpr auto tag_name = tag_name##_t<T>();\n\nnamespace tc {\n\tDEFINE_TAG_TYPE(aggregate_tag) // tag to distinguish constructors that aggregate their single argument from templated copy constructors\n\tDEFINE_TAG_TYPE(func_tag)\n\tDEFINE_TEMPLATE_TAG_TYPE(type_tag)\n\n\t// tc_define_fn(func) always defines a function void func(define_fn_dummy_t)\n\t// If that function did not exist, -> decltype( func(...) ) would not be\n\t// a valid statement and clang complains about that.\n\tDEFINE_TAG_TYPE(define_fn_dummy)\n\n\ttemplate<typename T>\n\tconcept tag = requires { typename std::remove_cv_t<T>::is_tag; };\n}\n"
  },
  {
    "path": "tc/base/template_func.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"tag_type.h\"\n#include \"type_list.h\"\n\n#define DECLARE_TMPL_FUNC_WITH_CUSTOMIZATIONS(name) \\\n\tnamespace name ## _adl { \\\n\t\tstruct adl_tag_t; \\\n\t} \\\n\tnamespace no_adl { \\\n\t\tstruct fn_ ## name; \\\n\t} \\\n\textern inline no_adl::fn_ ## name const name;\n\n// define a template function with possible customization overloads\n// 1. overloads for external types: highest priority; customization name_impl(adl_tag_prio_t, ...) is defined in name_adl namespace with adl_tag_prio_t as 1st parameter\n// 2. overloads for our classes: second highest priority; customization name_impl(...) is defined in ADL namespace (prefer friend function)\n// 3. overloads for external types: third highest priority; customization name_impl(adl_tag_t, ...) is defined in name_adl namespace with adl_tag_t as 1st parameter\n// 4. default implementation(s): lowest priority; name_impl(...) is implemented in name_default namespace before this macro\n#define DEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(name) \\\n\tnamespace name ## _default { \\\n\t\tvoid name ## _impl(tc::define_fn_dummy_t) noexcept; \\\n\t} \\\n\tnamespace name ## _adl { \\\n\t\tDEFINE_ADL_TAG_TYPE(adl_tag) \\\n\t\tDEFINE_ADL_TAG_TYPE(adl_tag_prio) \\\n\t} \\\n\tnamespace name ## _detail { \\\n\t\ttemplate<typename... Args> \\\n\t\tconcept has_adl_tag_prio_ ## name ## _impl = requires { name ## _impl(name ## _adl::adl_tag_prio, std::declval<Args>()...); }; \\\n\t\ttemplate<typename... Args> \\\n\t\tconcept has_adl_ ## name ## _impl = requires { name ## _impl(std::declval<Args>()...); }; \\\n\t\ttemplate<typename... Args> \\\n\t\tconcept has_adl_tag_ ## name ## _impl = requires { name ## _impl(name ## _adl::adl_tag, std::declval<Args>()...); }; \\\n\t\ttemplate<typename... Args> \\\n\t\tconcept has_default_ ## name ## _impl = requires { name ## _default:: name ## _impl(std::declval<Args>()...); }; \\\n\t} \\\n\t\\\n\tnamespace no_adl { \\\n\t\tstruct [[nodiscard]] TC_EMPTY_BASES fn_ ## name { \\\n\t\tprivate: \\\n\t\t\ttemplate<typename... Args> \\\n\t\t\tstatic constexpr bool NoExcept() noexcept { \\\n\t\t\t\tif constexpr(name ## _detail::has_adl_tag_prio_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn noexcept(name ## _impl(name ## _adl::adl_tag_prio, std::declval<Args>()...)); \\\n\t\t\t\t} else if constexpr (name ## _detail::has_adl_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn noexcept(name ## _impl(std::declval<Args>()...)); \\\n\t\t\t\t} else if constexpr(name ## _detail::has_adl_tag_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn noexcept(name ## _impl(name ## _adl::adl_tag, std::declval<Args>()...)); \\\n\t\t\t\t} else { static_assert(name ## _detail::has_default_ ## name ## _impl<Args...>); \\\n\t\t\t\t\treturn noexcept(name ## _default:: name ## _impl(std::declval<Args>()...)); \\\n\t\t\t\t} \\\n\t\t\t} \\\n\t\tpublic: \\\n\t\t\tusing is_transparent=void; \\\n\t\t\ttemplate<typename... Args> requires \\\n\t\t\t\tname ## _detail::has_adl_tag_prio_ ## name ## _impl<Args...> || \\\n\t\t\t\tname ## _detail::has_adl_ ## name ## _impl<Args...> || \\\n\t\t\t\tname ## _detail::has_adl_tag_ ## name ## _impl<Args...> || \\\n\t\t\t\tname ## _detail::has_default_ ## name ## _impl<Args...> \\\n\t\t\tconstexpr decltype(auto) operator()(Args&& ... args) const& noexcept( NoExcept<Args...>() ) { \\\n\t\t\t\tif constexpr(name ## _detail::has_adl_tag_prio_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn name ## _impl(name ## _adl::adl_tag_prio, tc_move_if_owned(args)...); \\\n\t\t\t\t} else if constexpr (name ## _detail::has_adl_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn name ## _impl(tc_move_if_owned(args)...); \\\n\t\t\t\t} else if constexpr(name ## _detail::has_adl_tag_ ## name ## _impl<Args...>) { \\\n\t\t\t\t\treturn name ## _impl(name ## _adl::adl_tag, tc_move_if_owned(args)...); \\\n\t\t\t\t} else { static_assert(name ## _detail::has_default_ ## name ## _impl<Args...>); \\\n\t\t\t\t\treturn name ## _default:: name ## _impl(tc_move_if_owned(args)...); \\\n\t\t\t\t} \\\n\t\t\t} \\\n\t\t}; \\\n\t} \\\n\tinline no_adl::fn_ ## name constexpr name;\n\n"
  },
  {
    "path": "tc/base/temporary.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"as_lvalue.h\"\n#include \"move.h\"\n#include \"type_traits_fwd.h\"\n\nnamespace tc {\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// `tc::temporary<T cv, Lifetime>` wraps a temporary object that was created Lifetime functions above in the callstack from a prvalue.\n\t// Like a reference, `tc::temporary<T cv, Lifetime> const` is equivalent to `tc::temporary<T cv, Lifetime>`.\n\t// Like an rvalue reference, `tc::temporary<T cv, Lifetime> cv2&` is equivalent to `T cv&` and `tc::temporary<T cv, Lifetime> cv2&&` is equivalent to `tc::temporay<T cv, Lifetime>`.\n\tnamespace temporary_adl {\n\t\ttemplate <typename T, unsigned Lifetime>\n\t\tstruct temporary {\n\t\t\tstatic_assert(std::is_object<T>::value);\n\t\t\tstatic_assert(!tc::instance_tn<T, temporary>);\n\n\t\tprivate:\n\t\t\tT&& m_ref;\n\n\t\t\ttemplate <typename, unsigned>\n\t\t\tfriend struct temporary;\n\n\t\tpublic:\n\t\t\ttemplate <typename U> requires std::same_as<std::remove_cvref_t<U>, std::remove_cv_t<T>> && std::is_convertible<std::remove_reference_t<U>*, T*>::value\n\t\t\tconstexpr explicit(std::is_lvalue_reference<U>::value && !std::is_const<T>::value) temporary(U&& ref) noexcept : m_ref(tc_move_always_even_const(ref)) {}\n \n\t\t\ttemplate <typename U, unsigned OtherLifetime> requires std::same_as<std::remove_cvref_t<U>, std::remove_cv_t<T>> && std::is_convertible<std::remove_reference_t<U>*, T*>::value\n\t\t\tconstexpr explicit(OtherLifetime < Lifetime) temporary(temporary<U, OtherLifetime> const& other) noexcept : m_ref(tc_move_always_even_const(other.m_ref)) {}\n\n\t\t\tconstexpr operator T&() const& noexcept {\n\t\t\t\treturn m_ref;\n\t\t\t}\n\t\t\tconstexpr operator T&&() && noexcept { // overload needed for clang: https://godbolt.org/z/9sv9YsMsc\n\t\t\t\treturn tc_move_always_even_const(m_ref);\n\t\t\t}\n\t\t\tconstexpr operator T&&() const&& noexcept {\n\t\t\t\treturn tc_move_always_even_const(m_ref);\n\t\t\t}\n\t\t};\n\t}\n\tusing temporary_adl::temporary;\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct remove_temporary_impl {\n\t\t\tusing type = T;\n\t\t};\n\t\ttemplate <typename T> requires tc::instance_tn<T, tc::temporary>\n\t\tstruct remove_temporary_impl<T> {\n\t\t\tusing type = boost::mp11::mp_first<typename tc::is_instance_tn<T, tc::temporary>::arguments>;\n\t\t};\n\t}\n\ttemplate <typename T>\n\tusing remove_ref_temporary_t = typename no_adl::remove_temporary_impl<std::remove_reference_t<T>>::type;\n\n\tnamespace no_adl { \n\t\t// We use a nested structure to have a single top-level instantiation for all traits.\n\t\t// E.g. for a non-temporary type, `tc::increment_lifetime_t<T>` and `tc::decrement_lifetime_t<T>` only cause one type instanitation.\n\t\t// (The temporary traits are instantiated for many different types and can easily cause compile times to explode.)\n\t\ttemplate <typename T> struct temporary_trait_impl { template <template <typename, unsigned> typename Fn> using apply = T; }; \n\t\t\n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime>> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> volatile> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const volatile> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\t\n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime>&> { template <template <typename, unsigned> typename Fn> using apply = T&; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const&> { template <template <typename, unsigned> typename Fn> using apply = T&; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> volatile&> { template <template <typename, unsigned> typename Fn> using apply = T&; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const volatile&> { template <template <typename, unsigned> typename Fn> using apply = T&; }; \n\t\t\n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime>&&> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const &&> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> volatile &&> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t\ttemplate <typename T, unsigned Lifetime> struct temporary_trait_impl<tc::temporary<T, Lifetime> const volatile&&> { template <template <typename, unsigned> typename Fn> using apply = Fn<T, Lifetime>; }; \n\t} \n\tusing no_adl::temporary_trait_impl;\n\n\ttemplate <typename T>\n\tusing canonicalize_temporary_t = typename temporary_trait_impl<T>::template apply<tc::temporary>;\n\n\ttemplate <typename T>\n\tconstexpr auto dangling_temporary_impl = false;\n\ttemplate <typename T>\n\tconstexpr auto dangling_temporary_impl<tc::temporary<T, 0>> = true;\n\ttemplate <typename T>\n\tconcept dangling_temporary = dangling_temporary_impl<tc::canonicalize_temporary_t<T>>;\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_prvalue_as_temporary: if the expression is a prvalue, materializes it and wraps the rvalue reference into tc::temporary.\n\ttemplate <typename T>\n\tusing prvalue_as_temporary_t = std::conditional_t<std::is_reference<T>::value || tc::instance_tn<T, tc::temporary>, T, tc::temporary<T, 0>>;\n\n\t#define tc_prvalue_as_temporary(...) static_cast<tc::prvalue_as_temporary_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_return_temporary: safely return an expression that is potentially a tc::temporary from a function by decaying it when necessary.\n\t// tc_store_temporary: safely store a temporary in a struct\n\ttemplate <typename T, unsigned Lifetime>\n\tusing return_temporary_impl = std::conditional_t<0 == Lifetime, std::remove_cv_t<T>, tc::temporary<T, Lifetime>>;\n\ttemplate <typename T>\n\tusing return_temporary_t = typename temporary_trait_impl<T>::template apply<return_temporary_impl>;\n\n\t#define tc_return_temporary(...) return static_cast<tc::return_temporary_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\n\ttemplate <typename T, unsigned Lifetime>\n\tusing store_temporary_impl = std::remove_cv_t<T>;\n\ttemplate <typename T>\n\tusing store_temporary_t = typename temporary_trait_impl<T>::template apply<store_temporary_impl>;\n\n\t#define tc_store_temporary(...) static_cast<tc::store_temporary_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_unwrap_temporary: turns an expression that is potentially a tc::temporary into a plain reference.\n\t// Use this when calling functions that cannot handle tc::temporary.\n\ttemplate <typename T, unsigned Lifetime>\n\tusing unwrap_temporary_impl = T&&;\n\ttemplate <typename T>\n\tusing unwrap_temporary_t = typename temporary_trait_impl<T>::template apply<unwrap_temporary_impl>;\n\n\t#define tc_unwrap_temporary(...) static_cast<tc::unwrap_temporary_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_rewrap_temporary: turns an expression back into a tc::temporary after a tc_unwrap_temporary.\n\t// Used as `tc_rewrap_temporary(Args..., f(tc_unwrap_temporary(tc_move_if_owned(args))...))`.\n\t// If none of `Args... args` are `tc::temporary`, equivalent to `f(tc_move_if_owned(args)...)`.\n\t// Otherwise, the `tc::temporary` arguments are unwrapped and then the result re-wrapped if `f` returns an rvalue reference.\n\t// `Args` only need to include the arguments whose lifetime influences the lifetime of a resulting rvalue reference.\n\tnamespace no_adl {\n\t\ttemplate <typename Result, typename ... Args>\n\t\tstruct rewrap_temporary_impl {\n\t\t\tusing type = Result;\n\t\t};\n\n\t\ttemplate <typename Result, typename ... Args> requires (tc::instance_tn<Args, tc::temporary> || ...)\n\t\tstruct rewrap_temporary_impl<Result&&, Args...> {\n\t\t\tstatic constexpr unsigned min_lifetime() noexcept {\n\t\t\t\t// Hand-written implementation due to header dependencies.\n\t\t\t\tauto result = static_cast<unsigned>(-1);\n\t\t\t\t([&]{\n\t\t\t\t\tif constexpr (tc::instance_tn<std::remove_reference_t<Args>, tc::temporary>) {\n\t\t\t\t\t\tauto constexpr lifetime = boost::mp11::mp_second<typename tc::is_instance_tn<std::remove_reference_t<Args>, tc::temporary>::arguments>::value;\n\t\t\t\t\t\tif (lifetime < result) result = lifetime;\n\t\t\t\t\t}\n\t\t\t\t}(), ...);\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tstatic_assert(!tc::instance_tn<Result, tc::temporary>, \"not possible since we canonicalized, which doesn't allow rvalues to temporary\");\n\t\t\tusing type = tc::temporary<Result, min_lifetime()>;\n\t\t};\n\t}\n\ttemplate <typename Result, typename ... Args>\n\tusing rewrap_temporary_t = typename no_adl::rewrap_temporary_impl<tc::canonicalize_temporary_t<Result>, tc::canonicalize_temporary_t<Args>...>::type;\n\n\t#define tc_rewrap_temporary(Args, ...) static_cast<tc::rewrap_temporary_t<decltype((__VA_ARGS__)), Args>>(__VA_ARGS__)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// tc_increment_lifetime: needs to be called before passing a tc::temporary to a function; increases the lifetime of all temporaries by one, does nothing for other types.\n\t// tc_decrement_lifetime: needs to be called on the result of a function that were passed tc::temporary objects; decreases the lifetime of all temporaries by one, asserting temporaries of lifetime zero, does nothing for other types.\n\t// If using tc_invoke, it is done for you.\n\ttemplate <typename T, unsigned Lifetime>\n\tusing increment_lifetime_impl = tc::temporary<T, Lifetime + 1>;\n\ttemplate <typename T>\n\tusing increment_lifetime_t = typename temporary_trait_impl<T>::template apply<increment_lifetime_impl>;\n\n\ttemplate <typename T, unsigned Lifetime> requires (0 < Lifetime) // dangling temporary returned from function\n\tusing decrement_lifetime_impl = tc::temporary<T, Lifetime - 1>;\n\ttemplate <typename T>\n\tusing decrement_lifetime_t = typename temporary_trait_impl<T>::template apply<decrement_lifetime_impl>;\n\n\t#define tc_increment_lifetime(...) static_cast<tc::increment_lifetime_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\t#define tc_decrement_lifetime(...) static_cast<tc::decrement_lifetime_t<decltype((__VA_ARGS__))>>(__VA_ARGS__)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// Type traits specializations.\n\tnamespace no_adl {\n\t\ttemplate <typename Temporary, typename TTarget> requires tc::instance_tn<std::remove_reference_t<Temporary>, tc::temporary>\n\t\tstruct is_safely_convertible_to_reference<Temporary, TTarget> {\n\t\t\tstatic auto constexpr value\n\t\t\t\t// temporary<T> is not safely convertible to an rvalue reference as that would throw away lifetime information\n\t\t\t\t= std::is_lvalue_reference<TTarget>::value\n\t\t\t\t// it then delegates to the safe conversion of the underlying reference to TTarget\n\t\t\t\t&& is_safely_convertible_to_reference<tc::unwrap_temporary_t<Temporary>, TTarget>::value;\n\t\t};\n\n\t\t// decay of a temporary<T> results in T - this also takes care of tc::common_type_t\n\t\ttemplate <typename T, unsigned Lifetime, bool bPreventSlicing>\n\t\tstruct decay<tc::temporary<T, Lifetime>, bPreventSlicing> : decay<T, bPreventSlicing> {};\n\n\t\t// common_reference_t of a temporary and a reference results in a temporary of the underlying common reference\n\t\ttemplate <typename T0, typename T1> requires tc::instance_tn<std::remove_reference_t<T0>, tc::temporary> || tc::instance_tn<std::remove_reference_t<T1>, tc::temporary>\n\t\tstruct common_reference_impl<T0, T1> {\n\t\t\tusing type = tc::rewrap_temporary_t<tc::common_reference_t<tc::unwrap_temporary_t<T0>, tc::unwrap_temporary_t<T1>>, T0, T1>;\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "tc/base/temporary.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"temporary.h\"\n\n#include \"return_decltype.h\"\n#include \"type_traits.h\"\n\nSTATICASSERTSAME(tc::prvalue_as_temporary_t<int>, TC_FWD(tc::temporary<int, 0>));\nSTATICASSERTSAME(tc::prvalue_as_temporary_t<int&>, int&);\nSTATICASSERTSAME(tc::prvalue_as_temporary_t<int&&>, int&&);\nSTATICASSERTSAME(TC_FWD(tc::prvalue_as_temporary_t<tc::temporary<int, 0>>), TC_FWD(tc::temporary<int, 0>));\nSTATICASSERTSAME(TC_FWD(tc::prvalue_as_temporary_t<tc::temporary<int, 1>>), TC_FWD(tc::temporary<int, 1>));\n\nSTATICASSERTSAME(tc::return_temporary_t<int>, int);\nSTATICASSERTSAME(tc::return_temporary_t<int&>, int&);\nSTATICASSERTSAME(tc::return_temporary_t<int&&>, int&&);\nSTATICASSERTSAME(TC_FWD(tc::return_temporary_t<tc::temporary<int, 0>>), int);\nSTATICASSERTSAME(TC_FWD(tc::return_temporary_t<tc::temporary<int const, 0>>), int);\nSTATICASSERTSAME(TC_FWD(tc::return_temporary_t<tc::temporary<int, 1>>), TC_FWD(tc::temporary<int, 1>));\n\nSTATICASSERTSAME(tc::store_temporary_t<int>, int);\nSTATICASSERTSAME(tc::store_temporary_t<int&>, int&);\nSTATICASSERTSAME(tc::store_temporary_t<int&&>, int&&);\nSTATICASSERTSAME(TC_FWD(tc::store_temporary_t<tc::temporary<int, 0>>), int);\nSTATICASSERTSAME(TC_FWD(tc::store_temporary_t<tc::temporary<int const, 0>>), int);\nSTATICASSERTSAME(TC_FWD(tc::store_temporary_t<tc::temporary<int, 1>>), int);\n\nSTATICASSERTSAME(tc::unwrap_temporary_t<int>, int);\nSTATICASSERTSAME(tc::unwrap_temporary_t<int&>, int&);\nSTATICASSERTSAME(tc::unwrap_temporary_t<int&&>, int&&);\nSTATICASSERTSAME(TC_FWD(tc::unwrap_temporary_t<tc::temporary<int, 0>>), int&&);\nSTATICASSERTSAME(TC_FWD(tc::unwrap_temporary_t<tc::temporary<int, 0>&&>), int&&);\nSTATICASSERTSAME(TC_FWD(tc::unwrap_temporary_t<tc::temporary<int, 0> const&&>), int&&);\nSTATICASSERTSAME(TC_FWD(tc::unwrap_temporary_t<tc::temporary<int, 0>&>), int&);\nSTATICASSERTSAME(TC_FWD(tc::unwrap_temporary_t<tc::temporary<int, 0> const&>), int&);\n\nSTATICASSERTSAME(TC_FWD(tc::rewrap_temporary_t<int, tc::temporary<int, 0>>), int);\nSTATICASSERTSAME(TC_FWD(tc::rewrap_temporary_t<int&, tc::temporary<int, 0>>), int&);\nSTATICASSERTSAME(TC_FWD(tc::rewrap_temporary_t<int&&, tc::temporary<int, 0>>), TC_FWD(tc::temporary<int, 0>));\nSTATICASSERTSAME(TC_FWD(tc::rewrap_temporary_t<int&&, tc::temporary<int, 0>, tc::temporary<int, 1>>), TC_FWD(tc::temporary<int, 0>));\n\nSTATICASSERTSAME(TC_FWD(tc::common_type_t<tc::temporary<int, 0>&&, short&, int const&&>), int);\n\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::temporary<int, 0>, int&, int&&>), TC_FWD(tc::temporary<int const, 0>));\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::temporary<int, 0>&&, int&, int&&>), TC_FWD(tc::temporary<int const, 0>));\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::temporary<int, 0>, int&&>), TC_FWD(tc::temporary<int, 0>));\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::temporary<int, 0>, int, int&&>), int);\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::temporary<int, 0>, tc::temporary<int, 1>>), TC_FWD(tc::temporary<int, 0>));\n\nSTATICASSERTSAME(tc::auto_cref_t<int>, int const);\nSTATICASSERTSAME(tc::auto_cref_t<int&>, int const&);\nSTATICASSERTSAME(tc::auto_cref_t<int&&>, int const);\nSTATICASSERTSAME(TC_FWD(tc::auto_cref_t<tc::temporary<int, 0>>), int const);\nSTATICASSERTSAME(TC_FWD(tc::auto_cref_t<tc::temporary<int const, 0>>), int const);\nSTATICASSERTSAME(TC_FWD(tc::auto_cref_t<tc::temporary<int, 1>>), TC_FWD(tc::temporary<int const, 1> const));\n"
  },
  {
    "path": "tc/base/track_instance.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"casts.h\"\n#include \"noncopyable.h\"\n#include \"../storage_for.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <typename Derived>\n\t\tstruct track_instance_base {\n\t\t\tstatic Derived* instance() noexcept {\n\t\t\t\treturn static_cast<Derived*>(c_ptib); \n\t\t\t}\n\t\t\tvoid set_instance() & noexcept {\n\t\t\t\t_ASSERT(!c_ptib);\n\t\t\t\tc_ptib=this;\n\t\t\t}\n\t\t\tvoid reset_instance() const& noexcept {\n\t\t\t\t_ASSERT(is_instance());\n\t\t\t\tc_ptib=nullptr;\n\t\t\t};\n\t\t\tbool is_instance() const& noexcept {\n\t\t\t\treturn c_ptib==this;\n\t\t\t}\n\t\tprivate:\n\t\t\tstatic track_instance_base* c_ptib;\n\t\t};\n\t\ttemplate <typename Derived>\n\t\ttrack_instance_base<Derived>* track_instance_base<Derived>::c_ptib = nullptr;\n\n\t\ttemplate <typename Derived>\n\t\tstruct track_unique_instance : private track_instance_base<Derived>, tc::nonmovable {\n\t\t\tfriend struct track_instance_base<Derived>; // for cast to Derived\n\n\t\t\ttrack_unique_instance() noexcept {\n\t\t\t\tthis->set_instance();\n\t\t\t}\n\t\t\t~track_unique_instance() {\n\t\t\t\tthis->reset_instance();\n\t\t\t}\n\t\t\tusing track_instance_base<Derived>::instance;\n\t\t};\n\n\t\ttemplate <typename Derived>\n\t\tstruct track_outermost_instance : private track_instance_base<Derived> {\n\t\t\tfriend struct track_instance_base<Derived>; // for cast to Derived\n\n\t\t\ttrack_outermost_instance() noexcept {\n\t\t\t\tif (!this->instance()) {\n\t\t\t\t\tthis->set_instance();\n\t\t\t\t}\n\t\t\t}\n\t\t\t~track_outermost_instance() {\n\t\t\t\treset_outermost_instance();\n\t\t\t}\n\t\t\tusing track_instance_base<Derived>::instance;\n\n\t\t\tbool is_outermost_instance() const& noexcept {\n\t\t\t\treturn this->is_instance();\n\t\t\t}\n\n\t\tprotected:\n\t\t\tbool reset_outermost_instance() & noexcept { // allow user to reset early in Derived dtor to embrace reentrance\n\t\t\t\tif (is_outermost_instance()) {\n\t\t\t\t\tthis->reset_instance();\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename Derived>\n\t\tstruct unique_instance {\n\t\t\tstatic int s_nRefCnt;\n\t\t\tstatic storage_for<Derived> s_ot;\n\t\t\tunique_instance() noexcept {\n\t\t\t\tif(0==s_nRefCnt++) {\n\t\t\t\t\ts_ot.ctor();\n\t\t\t\t}\n\t\t\t}\n\t\t\t~unique_instance() {\n\t\t\t\tif(1==s_nRefCnt) {\n\t\t\t\t\ts_ot.dtor();\n\t\t\t\t}\n\t\t\t\t--s_nRefCnt;\n\t\t\t}\n\t\t};\n\t\ttemplate <typename T> int unique_instance<T>::s_nRefCnt=0;\n\t\ttemplate <typename T> storage_for<T> unique_instance<T>::s_ot;\n\n\t\ttemplate <typename T>\n\t\tstruct scoped_increment {\n\t\tprivate:\n\t\t\tstatic int s_nRefCnt;\n\t\tpublic:\n\t\t\texplicit scoped_increment() noexcept { ++s_nRefCnt; }\n\t\t\t~scoped_increment() { --s_nRefCnt; }\n\t\t\tstatic bool IsActive() noexcept { return 0 < s_nRefCnt; }\n\t\t};\n\t\ttemplate <typename T> int scoped_increment<T>::s_nRefCnt=0;\n\t}\n\tusing no_adl::track_unique_instance;\n\tusing no_adl::track_outermost_instance;\n\tusing no_adl::unique_instance;\n\tusing no_adl::scoped_increment;\n}\n"
  },
  {
    "path": "tc/base/track_instance.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"track_instance.h\"\n#include \"../unittest.h\"\n\nUNITTESTDEF(track_instance) {\n\tstruct SUnique : tc::track_unique_instance<SUnique> {};\n\tstruct SOutermost : tc::track_outermost_instance<SOutermost> {};\n\n\t_ASSERT(!SUnique::instance());\n\t_ASSERT(!SOutermost::instance());\n\t{\n\t\tSUnique u;\n\t\t_ASSERT(SUnique::instance()==&u);\n\t\t_ASSERT(!SOutermost::instance());\n\n\t\tSOutermost o1;\n\t\t{\n\t\t\tSOutermost o2;\n\t\t\t_ASSERT(o1.is_outermost_instance());\n\t\t\t_ASSERT(!o2.is_outermost_instance());\n\t\t}\n\t\t_ASSERT(o1.is_outermost_instance());\n\t}\n\n\t_ASSERT(!SUnique::instance());\n\t_ASSERT(!SOutermost::instance());\n}\n"
  },
  {
    "path": "tc/base/trivial_functors.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"assert_defs.h\"\n#include \"utility.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct noop {\n\t\t\ttemplate<typename... Args> constexpr void operator()(Args const&...) const& noexcept {}\n\t\t};\n\n\t\ttemplate<typename T=void>\n\t\tstruct never_called {\n\t\t\ttemplate<typename... Args> T operator()(Args const&...) const& noexcept {_ASSERTFALSE; return tc::construct_default_or_terminate<T>(); }\n\t\t};\n\n\t\t// Use tc::constexpr_function<val> for types that are qualified for non type template parameter. Otherwise use MAKE_CONSTEXPR_FUNCTION.\n\t\ttemplate<auto val>\n\t\tstruct constexpr_function /* not final */ {\n\t\t\tstatic_assert( sizeof(val)<=sizeof(void*) );\n\t\t\ttemplate< typename... Args >\n\t\t\tconstexpr auto operator()( Args const&... ) const& noexcept { return val; }\n\t\t};\n\n\t\tstruct identity {\n\t\t\ttemplate< typename T >\n\t\t\tconstexpr T&& operator()(T&& t) const& noexcept {\n\t\t\t\treturn tc_move_if_owned(t);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::noop;\n\tusing no_adl::never_called;\n\tusing no_adl::constexpr_function;\n\tusing no_adl::identity;\n}\n\n// MAKE_CONSTEXPR_FUNCTION is guaranteed a constexpr function.\n#define MAKE_CONSTEXPR_FUNCTION(...) \\\n\t[]() constexpr noexcept { \\\n\t\t/*bool_constant is needed, because otherwise MSVC doesn't correctly evaluate the `if constexpr`*/ \\\n\t\tif constexpr (tc::constant<sizeof(decltype(__VA_ARGS__)) <= sizeof(void*)>::value) { \\\n\t\t\treturn [](auto&& ...) constexpr noexcept { \\\n\t\t\t\tconstexpr auto _ = __VA_ARGS__; \\\n\t\t\t\treturn _; \\\n\t\t\t}; \\\n\t\t} else { \\\n\t\t\treturn [](auto&& ...) constexpr noexcept -> decltype(auto) { \\\n\t\t\t\treturn tc_as_constexpr(__VA_ARGS__); \\\n\t\t\t}; \\\n\t\t} \\\n\t}()\t\n"
  },
  {
    "path": "tc/base/trivial_functors.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n\n#include \"assert_defs.h\"\n#include \"trivial_functors.h\"\n#include \"utility.h\"\n\n#include \"../unittest.h\"\n#include \"../array.h\"\n#include \"../algorithm/break_or_continue.h\"\n\n\nnamespace {\n\tusing TypeBiggerThanPointer = std::array<int,sizeof(void*)/sizeof(int) + 1>;\n\tauto constexpr c_typebiggerthanpointer = TypeBiggerThanPointer();\n\n\t[[maybe_unused]] void static_test_make_constexpr_function() noexcept {\n\t\t// Fits in a pointer\n\t\t{\n\t\t\tconstexpr auto fn = tc::constexpr_function<int{}>();\n\t\t\ttc_static_auto_constexpr_lambda(fnOracle) = []() constexpr noexcept {\n\t\t\t\tconstexpr auto _ = int();\n\t\t\t\treturn _;\n\t\t\t}; \n\t\t\tSTATICASSERTSAME(decltype(fnOracle()), int);\n\t\t\tSTATICASSERTSAME(decltype(fn()), int);\n\t\t}\n\t\t{\n\t\t\tstruct SFoo {\n\t\t\t\tint m_n;\n\t\t\t};\n\t\t\tconstexpr auto fn = MAKE_CONSTEXPR_FUNCTION(SFoo{});\n\t\t\ttc_static_auto_constexpr_lambda(fnOracle) = []() constexpr noexcept {\n\t\t\t\tconstexpr auto _ = SFoo{};\n\t\t\t\treturn _;\n\t\t\t}; \n\t\t\tSTATICASSERTSAME(decltype(fnOracle()), SFoo);\n\t\t\tSTATICASSERTSAME(decltype(fn()), SFoo);\n\t\t}\n\t\t{\n\t\t\tconstexpr auto fn = MAKE_CONSTEXPR_FUNCTION(tc::constant<10>());\n\t\t\ttc_static_auto_constexpr_lambda(fnOracle) = []() constexpr noexcept {\n\t\t\t\tconstexpr auto _ = tc::constant<10>();\n\t\t\t\treturn _;\n\t\t\t}; \n\t\t\tSTATICASSERTSAME(decltype(fnOracle()), tc::constant<10>);\n\t\t\tSTATICASSERTSAME(decltype(fn()), tc::constant<10>);\n\t\t}\n\t\t{\n\t\t\tconstexpr auto fn = MAKE_CONSTEXPR_FUNCTION(tc::constant<tc::break_>());\n\t\t\ttc_static_auto_constexpr_lambda(fnOracle) = []() constexpr noexcept {\n\t\t\t\tconstexpr auto _ = tc::constant<tc::break_>();\n\t\t\t\treturn _;\n\t\t\t}; \n\t\t\tSTATICASSERTSAME(decltype(fnOracle()), tc::constant<tc::break_>);\n\t\t\tSTATICASSERTSAME(decltype(fn()), tc::constant<tc::break_>);\n\t\t}\n\n\t\t// Doesn't fit in a pointer\n\t\t{\n\t\t\tconstexpr auto fn = MAKE_CONSTEXPR_FUNCTION(c_typebiggerthanpointer);\n\t\t\ttc_static_auto_constexpr_lambda(fnOracle) = []() constexpr noexcept ->decltype(auto) {\n\t\t\t\treturn (c_typebiggerthanpointer);\n\t\t\t}; \n\t\t\tSTATICASSERTSAME(decltype(fnOracle()), TypeBiggerThanPointer const&);\n\t\t\tSTATICASSERTSAME(decltype(fn()), TypeBiggerThanPointer const&);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/base/type_list.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include <utility>\n#include <boost/mp11/algorithm.hpp>\n#include <boost/mp11/bind.hpp>\n#include <boost/mp11/list.hpp>\n#include <boost/mp11/set.hpp>\n\nnamespace tc {\n\ttemplate <typename T>\n\tusing mp_identity = T;\n\n\tnamespace no_adl {\n\t\ttemplate <typename List>\n\t\tstruct mp_only_impl {};\n\t\ttemplate <template <typename...> typename List, typename T>\n\t\tstruct mp_only_impl<List<T>> {\n\t\t\tusing type = T;\n\t\t};\n\t}\n\ttemplate <typename List>\n\tusing mp_only = typename no_adl::mp_only_impl<List>::type;\n\n\t// F1<F2<F3<...Fn<Args>...>>>\n\ttemplate <template <typename...> typename ... F>\n\tusing mp_chained = boost::mp11::mp_reverse<boost::mp11::mp_compose_q<boost::mp11::mp_quote<F>...>>;\n\n\t// Boost.MP11's mp_transform is not SFINAE-friendly\n\tnamespace no_adl {\n\t\ttemplate <template <typename...> typename F, typename ... List>\n\t\tstruct mp_transform_impl {\n\t\t\tstatic_assert(sizeof...(List) == 1, \"TODO: implement variadic mp_transform when we need it\");\n\t\t};\n\n\t\ttemplate <template <typename...> typename F, template <typename...> typename List, typename ... T>\n\t\t\trequires requires { typename List<F<T>...>; }\n\t\tstruct mp_transform_impl<F, List<T...>> final {\n\t\t\tusing type = List<F<T>...>;\n\t\t};\n\t}\n\ttemplate <template <typename...> typename F, typename ... List>\n\tusing mp_transform = typename no_adl::mp_transform_impl<F, List...>::type; \n\n\ttemplate<typename ... List>\n\tusing mp_zip = boost::mp11::mp_transform<boost::mp11::mp_list, List...>; // our transform isn't variadic yet and we don't need SFINAE friendlieness\n\n\tnamespace no_adl {\n\t\ttemplate<typename IntSeq>\n\t\tstruct mp_integer_list_impl;\n\n\t\ttemplate<typename TIndex, TIndex... Is>\n\t\tstruct mp_integer_list_impl<std::integer_sequence<TIndex, Is...>> {\n\t\t\tusing type = boost::mp11::mp_list<std::integral_constant<TIndex, Is>...>;\n\t\t};\n\t}\n\ttemplate<typename IntSeq>\n\tusing mp_integer_list = typename no_adl::mp_integer_list_impl<IntSeq>::type;\n\n\ttemplate <typename Head, typename ... Tail>\n\tusing mp_enumerate = mp_zip<\n\t\t// We pick the size of the first list, mp_zip is only defined if all lists have the same size.\n\t\tmp_integer_list<std::make_integer_sequence<int, boost::mp11::mp_size<Head>::value>>,\n\t\tHead, Tail...\n\t>;\n\n\t// Boost.MP11's mp_fold is not SFINAE-friendly\n\tnamespace no_adl {\n\t\ttemplate <typename List, typename V, template <typename...> typename F>\n\t\tstruct mp_fold_impl {};\n\n\t\ttemplate <template <typename...> typename List, typename V, template <typename...> typename F>\n\t\tstruct mp_fold_impl<List<>, V, F> {\n\t\t\tusing type = V;\n\t\t};\n\n\t\ttemplate <template <typename...> typename List, typename T0, typename ... T, typename V, template <typename...> typename F>\n\t\t\trequires requires { typename F<V, T0>; }\n\t\tstruct mp_fold_impl<List<T0, T...>, V, F> : mp_fold_impl<List<T...>, F<V, T0>, F> {};\n\t}\n\ttemplate <typename List, typename V, template <typename...> typename F>\n\tusing mp_fold = typename no_adl::mp_fold_impl<List, V, F>::type;\n\n\ttemplate <typename List, template <typename...> typename F>\n\tusing mp_fold_with_front = mp_fold<boost::mp11::mp_pop_front<List>, boost::mp11::mp_front<List>, F>;\n\n\tnamespace no_adl {\n\t\ttemplate <typename List, typename V>\n\t\tstruct mp_find_unique : boost::mp11::mp_size<List> {\n\t\t\tstatic auto constexpr found = false;\n\t\t};\n\t\t// Note: mp_set_contains will cause a hard-error if List contains the same value multiple times, so no need to check unique match.\n\t\ttemplate <typename List, typename V> requires boost::mp11::mp_set_contains<List, V>::value\n\t\tstruct mp_find_unique<List, V> : boost::mp11::mp_find<List, V> {\n\t\t\tstatic auto constexpr found = true;\n\t\t\tstatic auto constexpr index = boost::mp11::mp_find<List, V>::value;\n\t\t};\n\n\t\ttemplate <typename List, template<typename...> typename P>\n\t\tstruct mp_find_unique_if : boost::mp11::mp_size<List> {\n\t\t\tstatic auto constexpr found = false;\n\t\t};\n\t\ttemplate <typename List, template <typename...> typename P> requires (0 < boost::mp11::mp_count_if<List, P>::value)\n\t\tstruct mp_find_unique_if<List, P> : boost::mp11::mp_find_if<List, P> {\n\t\t\tstatic_assert(1 == boost::mp11::mp_count_if<List, P>::value);\n\t\t\tstatic auto constexpr found = true;\n\t\t\tstatic auto constexpr index = boost::mp11::mp_find_if<List, P>::value;\n\t\t};\n\t}\n\tusing no_adl::mp_find_unique;\n\tusing no_adl::mp_find_unique_if;\n\n\tnamespace no_adl {\n\t\ttemplate <typename Lhs, typename Rhs>\n\t\tstruct mp_common_prefix_impl { // no prefix, different kinds of list\n\t\t\tusing type = boost::mp11::mp_list<>;\n\t\t};\n\n\t\ttemplate <template <typename...> typename List, typename ... Lhs, typename ... Rhs>\n\t\tstruct mp_common_prefix_impl<List<Lhs...>, List<Rhs...>> { // no prefix, same kind of list\n\t\t\tusing type = List<>;\n\t\t};\n\n\t\ttemplate <typename Head, template <typename...> typename LhsList, typename ... Lhs, template <typename...> typename RhsList, typename ... Rhs>\n\t\tstruct mp_common_prefix_impl<LhsList<Head, Lhs...>, RhsList<Head, Rhs...>> { // prefix, different kinds of list\n\t\t\tusing type = boost::mp11::mp_push_front<typename mp_common_prefix_impl<LhsList<Lhs...>, RhsList<Rhs...>>::type, Head>;\n\t\t};\n\n\t\ttemplate <typename Head, template <typename...> typename List, typename ... Lhs, typename ... Rhs>\n\t\tstruct mp_common_prefix_impl<List<Head, Lhs...>, List<Head, Rhs...>> { // prefix, same kind of list (to resolve ambiguity)\n\t\t\tusing type = boost::mp11::mp_push_front<typename mp_common_prefix_impl<List<Lhs...>, List<Rhs...>>::type, Head>;\n\t\t};\n\t}\n\n\ttemplate <typename ... List>\n\tusing mp_common_prefix = mp_fold_with_front<boost::mp11::mp_list<List...>, boost::mp11::mp_quote_trait<no_adl::mp_common_prefix_impl>::template fn>;\n\n\ttemplate <typename ... List>\n\tusing mp_common_suffix = boost::mp11::mp_reverse<mp_common_prefix<boost::mp11::mp_reverse<List>...>>;\n}\n"
  },
  {
    "path": "tc/base/type_list.t.cpp",
    "content": "// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"type_list.h\"\n#include \"type_traits_fwd.h\"\n\nSTATICASSERTSAME(TC_FWD(boost::mp11::mp_compose<std::add_const_t, std::add_pointer_t, std::add_volatile_t>::template fn<int>), int const* volatile);\nSTATICASSERTSAME(TC_FWD(tc::mp_chained<std::add_const_t, std::add_pointer_t, std::add_volatile_t>::template fn<int>), int volatile* const);\n\nSTATICASSERTSAME(\n\tTC_FWD(tc::mp_enumerate<boost::mp11::mp_list<int, float, char>, std::tuple<int*, float*, char*>>),\n\tTC_FWD(boost::mp11::mp_list<\n\t\tboost::mp11::mp_list<tc::constant<0>, int, int*>,\n\t\tboost::mp11::mp_list<tc::constant<1>, float, float*>,\n\t\tboost::mp11::mp_list<tc::constant<2>, char, char*>\n\t>)\n);\n\nstatic_assert(!tc::mp_find_unique<boost::mp11::mp_list<int, float, void, char>, long>::found);\nSTATICASSERTEQUAL(TC_FWD(tc::mp_find_unique<boost::mp11::mp_list<int, float, void, char>, float>::index), 1);\nstatic_assert(!tc::mp_find_unique_if<boost::mp11::mp_list<int, float, void, char>, std::is_pointer>::found);\nSTATICASSERTEQUAL(TC_FWD(tc::mp_find_unique_if<boost::mp11::mp_list<int, float, void, char>, std::is_void>::index), 2);\n\ntemplate<typename...> struct my_tuple {};\n\nSTATICASSERTSAME(TC_FWD(tc::mp_common_prefix<boost::mp11::mp_list<int, float>, boost::mp11::mp_list<float, int>>), boost::mp11::mp_list<>);\nSTATICASSERTSAME(TC_FWD(tc::mp_common_prefix<boost::mp11::mp_list<int, int, float>, boost::mp11::mp_list<int, int, double>>), TC_FWD(boost::mp11::mp_list<int, int>));\nSTATICASSERTSAME(TC_FWD(tc::mp_common_prefix<my_tuple<int, int, float>, boost::mp11::mp_list<int, int, double>>), TC_FWD(boost::mp11::mp_list<int, int>));\nSTATICASSERTSAME(TC_FWD(tc::mp_common_prefix<my_tuple<int, int, float>, my_tuple<int, int, double>>), TC_FWD(my_tuple<int, int>));\nSTATICASSERTSAME(TC_FWD(tc::mp_common_prefix<boost::mp11::mp_list<int, float, char>, boost::mp11::mp_list<int>, boost::mp11::mp_list<int, float, char, long>>), boost::mp11::mp_list<int>);\n\nSTATICASSERTSAME(TC_FWD(tc::mp_common_suffix<boost::mp11::mp_list<int, float, char>, boost::mp11::mp_list<long, float, char>>), TC_FWD(boost::mp11::mp_list<float, char>));\n"
  },
  {
    "path": "tc/base/type_traits.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"type_traits_fwd.h\"\n#include \"../container/string.h\"\n\n#include <boost/logic/tribool.hpp>\n\n#include <optional>\n#include <vector>\n#ifndef __EMSCRIPTEN__\n#include <atomic>\n#endif\n\nnamespace tc::no_adl {\n\t//////////////////////////\n\t// decay\n\n\t// std::vector<bool>::const_reference is bool (C++ standard)\n\ttemplate<bool bPreventSlicing>\n\tstruct decay<std::vector<bool>::reference, bPreventSlicing> {\n\t\tusing type = bool;\n\t};\n\n#ifndef __EMSCRIPTEN__\n\ttemplate<typename T, bool bPreventSlicing>\n\tstruct decay<std::atomic<T>, bPreventSlicing> {\n\t\tusing type = typename decay<T, bPreventSlicing>::type; // recursive\n\t};\n#endif\n\n\t//////////////////////////\n\t// is_class_safely_constructible\n\n\ttemplate <typename TTarget, typename... Args>\n\tstruct is_class_safely_constructible final : tc::constant<true> {};\n\n\t// allow only copy construction from other classes, everything else we do ourselves\n\ttemplate <typename T, typename A, typename Arg0, typename... Args>\n\tstruct is_class_safely_constructible<std::vector<T,A>, Arg0, Args...> final\n\t\t: tc::constant<\n\t\t\t0==sizeof...(Args) &&\n\t\t\tstd::is_class<std::remove_reference_t<Arg0>>::value\n\t\t>\n\t{\n\t};\n\n\t// allow only copy construction from other classes, everything else we do ourselves\n\ttemplate <typename C, typename T, typename A, typename Arg0, typename... Args>\n\tstruct is_class_safely_constructible<std::basic_string<C,T,A>, Arg0, Args...> final\n\t\t: tc::constant<\n\t\t\t0==sizeof...(Args) &&\n\t\t\t( std::is_class<std::remove_reference_t<Arg0>>::value || std::convertible_to<Arg0, C const*> )\n\t\t>\n\t{\n\t};\n\n\t// Restrict optional constructors\n\n\t// We consider the constructor optional<TTarget>::optional(TSource&&) dubious and\n\t// prefer optional<TTarget>::optional(std::in_place, TSource&&).\n\t// However, it is consistent with allowing optional<TTarget>::operator=(TSource&&),\n\t// which may be more efficient than optional::emplace and is used in constructs like\n\t// tc::change(otarget, source).\n\ttemplate <typename TTarget, typename TSource, typename TSourceNocvref = std::remove_cvref_t<TSource>>\n\tstruct is_optional_safely_constructible : tc::constant<\n\t\ttc::safely_constructible_from<TTarget, TSource> ||\n\t\t( // class type might have a convert operator to std::optional\n\t\t\tstd::is_class<TSourceNocvref>::value &&\n\t\t\t!safely_constructible_from_detail::object_constructible_from<TTarget, TSource> // in this case TTarget must not be constructible from the class type to avoid ambiguity\n\t\t)\n\t> {};\n\n\ttemplate <typename TTarget, typename Nullopt>\n\tstruct is_optional_safely_constructible<TTarget, /*TSource*/Nullopt, /*TSourceNocvref*/std::nullopt_t> : tc::constant<true> {};\n\n\ttemplate <typename TTarget, typename Optional, typename T>\n\tstruct is_optional_safely_constructible<TTarget, /*TSource*/Optional, /*TSourceNocvref*/std::optional<T>>\n\t\t: tc::constant<tc::safely_constructible_from<TTarget, tc::same_cvref_t<T, Optional>>>\n\t{};\n\n\ttemplate <typename T, typename Arg0, typename... Args>\n\tstruct is_class_safely_constructible<std::optional<T>, Arg0, Args...> final : std::conditional_t<\n\t\tstd::is_same<std::remove_cvref_t<Arg0>, std::in_place_t>::value,\n#ifdef __GNUC__ // workaround gcc12 internal compiler error\n\t\tstd::integral_constant<bool, tc::safely_constructible_from<T, Args...>>,\t\n#else\n\t\ttc::constant<tc::safely_constructible_from<T, Args...>>,\n#endif\n\t\tstd::conjunction<tc::constant<0 == sizeof...(Args)>, is_optional_safely_constructible<T, Arg0>>\n\t> {};\n\n\ttemplate<typename TFirst, typename TSecond, typename ArgFirst, typename ArgSecond>\n\tstruct is_class_safely_constructible<std::pair<TFirst, TSecond>, ArgFirst, ArgSecond> final: tc::constant<\n\t\ttc::safely_constructible_from<TFirst, ArgFirst> &&\n\t\ttc::safely_constructible_from<TSecond, ArgSecond>\n\t> {};\n\n\ttemplate<typename TFirst, typename TSecond, typename TPair> requires tc::instance<std::remove_reference_t<TPair>, std::pair>\n\tstruct is_class_safely_constructible<std::pair<TFirst, TSecond>, TPair> final: tc::constant<\n\t\ttc::safely_constructible_from<TFirst, decltype((std::declval<TPair>().first))> &&\n\t\ttc::safely_constructible_from<TSecond, decltype((std::declval<TPair>().second))>\n\t> {};\n\n\n\t//////////////////////////\n\t// common_type_decayed\n\n\ttemplate<>\n\tstruct common_type_decayed_impl<bool, tc::decay_t<decltype(boost::indeterminate)>> {\n\t\tusing type = boost::tribool;\n\t};\n\n\ttemplate<>\n\tstruct common_type_decayed_impl<tc::decay_t<decltype(boost::indeterminate)>, bool> {\n\t\tusing type = boost::tribool;\n\t};\n\n\ttemplate<typename T>\n\tstruct common_type_decayed_impl<T, std::nullopt_t> : std::conditional<tc::instance<T, std::optional>, T, std::optional<T>> {};\n\n\ttemplate<typename T>\n\tstruct common_type_decayed_impl<std::nullopt_t, T> : common_type_decayed_impl<T, std::nullopt_t> {};\n\n\ttemplate<>\n\tstruct common_type_decayed_impl<std::nullopt_t, std::nullopt_t> : std::type_identity<std::nullopt_t> {};\n} // namespace tc::no_adl\n"
  },
  {
    "path": "tc/base/type_traits.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"assert_defs.h\"\n#include \"type_traits.h\"\n#include \"noncopyable.h\"\n#include \"../container/insert.h\"\n#include \"../range/concat_adaptor.h\"\n#include \"../algorithm/algorithm.h\"\n#include \"../unittest.h\"\n\ntemplate <typename... T>\nconcept has_common_reference = requires { typename tc::common_reference_t<T...>; };\n\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int>, int);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int const>, int const);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int&>, int&);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int const&>, int const&);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int&&>, int);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<int const&&>, int const);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int>>, tc::vector<int>);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int> const>, tc::vector<int> const);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int>&>, tc::vector<int>&);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int> const&>, tc::vector<int> const&);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int>&&>, tc::vector<int>);\nSTATICASSERTSAME(tc::remove_rvalue_reference_t<tc::vector<int> const&&>, tc::vector<int> const);\n\nstatic_assert( tc::safely_convertible_to<int, double> );\n\nstatic_assert( std::convertible_to<int, float> );\nstatic_assert( sizeof(int)!=sizeof(float) || !tc::safely_convertible_to<int, float> );\n\nstatic_assert( std::convertible_to<long long, double> );\nstatic_assert( sizeof(long long)!=sizeof(double) || !tc::safely_convertible_to<long long, double> );\n\nstatic_assert( std::convertible_to<double, int> );\nstatic_assert( !tc::safely_convertible_to<double, int> );\n\nstatic_assert( std::convertible_to<float, int> );\nstatic_assert( !tc::safely_convertible_to<float, int> );\n\nstatic_assert( std::convertible_to<int, unsigned int> );\nstatic_assert( !tc::safely_convertible_to<int, unsigned int> );\n\nstatic_assert( std::convertible_to<unsigned int, int> );\nstatic_assert( !tc::safely_convertible_to<unsigned int, int> );\n\nstatic_assert(std::convertible_to<int*, bool>);\nstatic_assert(std::is_constructible<bool, int*>::value);\nstatic_assert(!std::convertible_to<std::nullptr_t, bool>);\nstatic_assert(std::is_constructible<bool, std::nullptr_t>::value);\nstatic_assert(tc::safely_constructible_from<bool, int*>);\nstatic_assert(tc::safely_constructible_from<bool, std::nullptr_t>);\nstatic_assert(!tc::safely_convertible_to<int*, bool>);\nstatic_assert(!tc::safely_convertible_to<std::nullptr_t, bool>);\nstatic_assert(tc::safely_constructible_from<bool, bool>);\nstatic_assert(tc::safely_convertible_to<bool, bool>);\n\n// scoped enum (enum class)\nenum class TEnumClass { a, b, c };\nenum TEnum { x, y, z };\nstatic_assert( !tc::safely_convertible_to<int, TEnumClass> );\nstatic_assert( !tc::safely_convertible_to<TEnumClass, int> );\nstatic_assert( !has_common_reference<TEnumClass, int>);\n\n// unscoped enum (primitive enum)\nenum TPrimitiveEnum { a, b, c };\nstatic_assert( !tc::safely_convertible_to<int, TPrimitiveEnum> );\nstatic_assert( std::convertible_to<TPrimitiveEnum, std::underlying_type_t<TPrimitiveEnum> > );\nstatic_assert( !tc::safely_convertible_to<TPrimitiveEnum, std::underlying_type_t<TPrimitiveEnum>> );\nstatic_assert( !has_common_reference<TPrimitiveEnum, int>);\n\nenum TPrimitiveEnum2 { l, m };\nstatic_assert( !tc::safely_convertible_to<TPrimitiveEnum, TPrimitiveEnum2> );\nstatic_assert( !has_common_reference<TPrimitiveEnum, TPrimitiveEnum2>);\n\nstruct SBase {};\nstruct SDerived final : SBase {};\nstatic_assert(std::convertible_to<SDerived, SBase>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase>);\n\nstatic_assert(tc::safely_convertible_to<SDerived&, SDerived>);\nstatic_assert(!tc::safely_convertible_to<SDerived&, SBase>);\nstatic_assert(tc::safely_convertible_to<SDerived&, SBase&>);\nstatic_assert(tc::safely_convertible_to<SDerived&, SBase const&>);\nstatic_assert(!tc::safely_convertible_to<SDerived&, SBase&&>);\nstatic_assert(tc::safely_convertible_to<SDerived&, SBase const&&>);\n\nstatic_assert(tc::safely_convertible_to<SDerived const&, SDerived>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&, SBase>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&, SBase&>);\nstatic_assert(tc::safely_convertible_to<SDerived const&, SBase const&>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&, SBase&&>);\nstatic_assert(tc::safely_convertible_to<SDerived const&, SBase const&&>);\n\nstatic_assert(tc::safely_convertible_to<SDerived, SDerived>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase const&>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase&>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase&&>);\nstatic_assert(!tc::safely_convertible_to<SDerived, SBase const&&>);\n\nstatic_assert(tc::safely_convertible_to<SDerived&&, SDerived>);\nstatic_assert(!tc::safely_convertible_to<SDerived&&, SBase>);\nstatic_assert(!tc::safely_convertible_to<SDerived&&, SBase const&>);\nstatic_assert(!tc::safely_convertible_to<SDerived&&, SBase&>);\nstatic_assert(tc::safely_convertible_to<SDerived&&, SBase&&>);\nstatic_assert(tc::safely_convertible_to<SDerived&&, SBase const&&>);\n\nstatic_assert(tc::safely_convertible_to<SDerived const&&, SDerived>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&&, SBase>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&&, SBase const&>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&&, SBase&>);\nstatic_assert(!tc::safely_convertible_to<SDerived const&&, SBase&&>);\nstatic_assert(tc::safely_convertible_to<SDerived const&&, SBase const&&>);\n\nstruct SToInt final {\n\toperator int() const& noexcept;\n};\n\nstatic_assert(!std::convertible_to<SBase, int>);\nstatic_assert(std::convertible_to<SToInt, int>);\nstatic_assert(tc::safely_convertible_to<SToInt, int>);\n\nstatic_assert(std::convertible_to<SToInt, int const&>);\nstatic_assert(!tc::safely_convertible_to<SToInt, int const&>);\n\nstatic_assert(!tc::safely_convertible_to<SToInt, int&&>);\nstatic_assert(!tc::safely_convertible_to<SToInt, int const&&>);\nstatic_assert(!tc::safely_convertible_to<SToInt&, int&&>);\nstatic_assert(!tc::safely_convertible_to<SToInt&, int const&&>);\nstatic_assert(!tc::safely_convertible_to<SToInt&&, int&&>);\nstatic_assert(!tc::safely_convertible_to<SToInt&&, int const&&>);\n\nstatic_assert(tc::safely_convertible_to<tc::string<char>&, tc::span<char>>);\nstatic_assert(tc::safely_convertible_to<tc::string<char>&, tc::span<char const>>);\nstatic_assert(!tc::safely_convertible_to<tc::string<char>, tc::span<char const>>);\nstatic_assert(!tc::safely_convertible_to<tc::string<char> const, tc::span<char const>>);\nstatic_assert(!tc::safely_convertible_to<tc::string<char>&&, tc::span<char const>>);\nstatic_assert(!tc::safely_convertible_to<tc::string<char> const&&, tc::span<char const>>);\nstatic_assert(tc::safely_convertible_to<tc::string<char> const&, tc::span<char const>>);\nstatic_assert(!tc::safely_convertible_to<char const*, tc::span<char>>);\nstatic_assert(tc::safely_convertible_to<char const*, tc::span<char const>>);\nstatic_assert(tc::safely_convertible_to<char const* &, tc::span<char const>>);\nstatic_assert(tc::safely_convertible_to<char const* &&, tc::span<char const>>);\nstatic_assert(tc::safely_convertible_to<int(&)[3], tc::span<int const>>);\nstatic_assert(tc::safely_convertible_to<int(&)[3], tc::span<int>>);\nstatic_assert(tc::safely_convertible_to<tc::span<int>, tc::span<int>>);\nstatic_assert(tc::safely_convertible_to<tc::span<int>, tc::span<int const>>);\nstatic_assert(tc::safely_convertible_to<tc::span<int>&&, tc::span<int const>>);\nstatic_assert(tc::safely_convertible_to<tc::span<int>&, tc::span<int const>>);\nstatic_assert(tc::safely_convertible_to<tc::span<int> const&, tc::span<int const>>);\nstatic_assert(!tc::safely_convertible_to<tc::span<char const>, decltype(tc::concat(\"abc\", \"def\"))>);\nstatic_assert(!tc::safely_convertible_to<tc::span<char const>, tc::vector<int>>);\n\nstatic_assert(!tc::safely_convertible_to<tc::string<char>&, tc::span<char>&>);\nstatic_assert(!tc::safely_convertible_to<tc::string<char>&, tc::span<char> const&>);\n\n#ifdef TC_MAC\nstatic_assert(tc::safely_constructible_from<void (^)(), void (^)()>);\nstatic_assert(!tc::safely_constructible_from<void (^)(), int (^)()>);\nstatic_assert(!tc::safely_constructible_from<void (^)(), void (^)(int)>);\nstatic_assert(tc::safely_constructible_from<void (^)(), nullptr_t>);\nstatic_assert(!tc::safely_constructible_from<void (^)(), int*>);\nstatic_assert(!tc::safely_constructible_from<void (^)(), void*>);\n\nnamespace {\n\tusing TVoidFunction = void (*)();\n}\nstatic_assert(!tc::safely_constructible_from<void (^)(), TVoidFunction>);\n\nstatic_assert(tc::no_adl::is_objc_block<void (^)()>::value);\nstatic_assert(tc::no_adl::is_objc_block<void (^)(int, char, bool)>::value);\nstatic_assert(!tc::no_adl::is_objc_block<void (*)(int, char, bool)>::value);\n#endif\n\nstruct A {};\nstruct B : A {\n\toperator int(){return 0;}\n};\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&&, A&&>,\n\t\tA&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, A&&>,\n\t\tA const&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, B&>,\n\t\tA&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&&, B&&>,\n\t\tA&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, B&&>,\n\t\tA const&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, A&, A const&>,\n\t\tA const&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&&, A&&, B&&>,\n\t\tA&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char const>&, tc::span<char const> const&>,\n\t\ttc::span<char const> const&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char>, tc::span<char const> const&>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char const>, tc::span<char const> const&>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char const>, tc::string<char>&>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char>, tc::string<char> const&>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char>, tc::span<char>>,\n\t\ttc::span<char>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char>, tc::span<char const>>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&, tc::vector<char> const&>,\n\t\ttc::vector<char> const&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int(&)[17], int(&)[17]>,\n\t\tint(&)[17]\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int const(&)[17], int(&)[17]>,\n\t\tint const(&)[17]\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int(&)[17], int(&)[18]>,\n\t\ttc::span<int>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int const(&)[17], int(&)[18]>,\n\t\ttc::span<int const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<int>, int(&)[19]>,\n\t\ttc::span<int>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<int> const, int(&)[19]>,\n\t\ttc::span<int>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int(&)[17], int(&)[18], int(&)[19]>,\n\t\ttc::span<int>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int&, short&>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&, tc::string<char>&>,\n\t\tstd::conditional_t<\n\t\t\tstd::same_as<tc::iterator_t<tc::vector<char>>, tc::iterator_t<tc::string<char>>>,\n\t\t\ttc::iterator_range<tc::iterator_t<tc::vector<char>>>,\n\t\t\ttc::span<char>\n\t\t>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&, tc::string<char> const&>,\n\t\tstd::conditional_t<\n\t\t\tstd::same_as<tc::iterator_t<tc::vector<char>>, tc::iterator_t<tc::string<char>>>,\n\t\t\ttc::iterator_range<tc::iterator_t<tc::vector<char> const>>,\n\t\t\ttc::span<char const>\n\t\t>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<const wchar_t (&)[6], tc::span<wchar_t>&&>,\n\t\ttc::span<wchar_t const>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&&, tc::vector<char>&>,\n\t\ttc::vector<char> const&&\n\t>::value\n);\n\nstatic_assert(\n\t!has_common_reference<tc::span<char>, tc::string<char>&&>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<char>&, tc::string<char>&&>\n);\n\nstatic_assert(\n\t!has_common_reference<char const*, tc::span<char>, tc::string<char> const&&>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<char>&&, tc::string<char>&>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::span<char const>, tc::string<char>>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, A>,\n\t\tA\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&&, A>,\n\t\tA\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A, A>,\n\t\tA\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&&, A&&>,\n\t\tA&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, A&>,\n\t\tA&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A&, A&&>,\n\t\tA const&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A const&&, A&&>,\n\t\tA const&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<A const&, A&>,\n\t\tA const&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<B const&, A volatile&>,\n\t\tA const volatile&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<B&, A volatile&&>,\n\t\tA const volatile&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<B const&&, A volatile&>,\n\t\tA const volatile&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<B const&&, B volatile&>,\n\t\tB const volatile &&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&, tc::vector<char> const&>,\n\t\ttc::vector<char> const&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int(&)[17], int(&)[17]>,\n\t\tint(&)[17]\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int const(&)[17], int(&)[17]>,\n\t\tint const(&)[17]\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<int&, short&>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&&, tc::vector<char>&>,\n\t\ttc::vector<char> const&&\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<char const>>,\n\t\ttc::span<char const>\n\t>::value\n);\n\nstatic_assert(\n\t!has_common_reference<A, B>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<char>&&, tc::string<char>&>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<char>&&, tc::string<char>&, tc::span<char const>>\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<char>, tc::string<char>&>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::static_vector<int, 3>&, tc::slice_t<tc::static_vector<int, 3>&>>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::static_vector<int, 3>&, tc::slice_t<tc::static_vector<int, 3>>&>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::slice_t<tc::static_vector<int, 3>&>, tc::slice_t<tc::static_vector<int, 3>>&>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<int>, tc::slice_t<tc::static_vector<int, 3>&>>,\n\t\ttc::span<int>\n\t>::value\n);\n\nSTATICASSERTSAME(\n\ttc::span_t<tc::slice_t<tc::vector<int>>&>,\n\ttc::span<int>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::span<int>, tc::slice_t<tc::vector<int>>&>,\n\t\ttc::span<int>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::static_vector<int, 3>&, tc::slice_t<tc::static_vector<int, 3>&>>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same <\n\t\ttc::common_reference_t<tc::static_vector<int, 3>&, tc::slice_t<tc::static_vector<int, 3>>&>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::slice_t<tc::static_vector<int, 3>&>, tc::slice_t<tc::static_vector<int, 3>>&>,\n\t\ttc::slice_t<tc::static_vector<int, 3>&>\n\t>::value\n);\n\nstatic_assert(\n\t!has_common_reference<tc::static_vector<int, 3>, tc::slice_t<tc::static_vector<int, 3>&>>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<char>&, tc::string<char>&>,\n\t\tstd::conditional_t<\n\t\t\tstd::same_as<tc::iterator_t<tc::vector<char>>, tc::iterator_t<tc::string<char>>>,\n\t\t\ttc::iterator_range<tc::iterator_t<tc::vector<char>>>,\n\t\t\ttc::span<char>\n\t\t>\n\t>::value\n);\n\nnamespace\n{\n\tstruct my_vector\n\t{\n\t\ttc::vector<int> impl;\n\n\t\tauto begin() & { return tc::begin(impl); }\n\t\tauto end() & { return tc::begin(impl); }\n\t};\n}\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_reference_t<tc::vector<int>&, my_vector&>,\n\t\ttc::iterator_range<tc::iterator_t<tc::vector<int>>>\n\t>::value\n);\n\nstatic_assert(\n\t!has_common_reference<tc::vector<int>&, my_vector>\n);\n\nnamespace {\nstruct S;\ntc::unordered_set<S const*> g_sets;\n\nstruct S{\n\tS() {\n\t\ttc::cont_must_emplace(g_sets, this);\n\t}\n\n\tS(S const& other) {\n\t\ttc::cont_must_emplace(g_sets, this);\n\t}\n\n\tS(S&& other) {\n\t\ttc::cont_must_emplace(g_sets, this);\n\t}\n\n\t~S() {\n\t\ttc::cont_must_erase(g_sets, this);\n\t}\n\n\tvoid foo() & {\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(this));\n\t}\n\n\tvoid foo() && {\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(this));\n\t}\n\n\tvoid foo() const& {\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(this));\n\t}\n\n\tvoid foo() const&& {\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(this));\n\t}\n\n\tfriend bool operator<(S const& lhs, S const& rhs) {\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(std::addressof(lhs)));\n\t\t_ASSERT(tc::end(g_sets) != g_sets.find(std::addressof(rhs)));\n\t\treturn true;\n\t}\n};\n\nS createS(int) {\n\treturn S{};\n}\n}\n\n#include \"../algorithm/minmax.h\"\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, short>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<tc::size_proxy<int>, short>,\n\t\tshort\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, tc::size_proxy<short>>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, tc::size_proxy<short>&>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, tc::size_proxy<short>&&>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, tc::size_proxy<short>, tc::size_proxy<long>>,\n\t\tint\n\t>::value\n);\n\n/*\n// must not compile\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<int, unsigned int>,\n\t\tunsigned int\n\t>::value\n);\n*/\n\n/*\n// must not compile\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<char, char16_t>,\n\t\tint\n\t>::value\n);\n*/\n\n/*\n\tmust not compile (slicing)\nstatic_assert(\n\tstd::is_same<\n\t\ttc::common_type_t<B,A>,\n\t\tA\n\t>::value\n);\n*/\n\nstatic_assert(\n\tstd::is_same<\n\t\tdecltype(tc::min(std::declval<tc::size_proxy<long>>(), std::declval<short>())),\n\t\tshort\n\t>::value\n);\n\nUNITTESTDEF(minTest) {\n\ttc::vector<int> vecn;\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::common_reference_t<decltype(tc::size(vecn)),short>,\n\t\t\tshort\n\t\t>::value\n\t);\n\n\tvoid(tc::implicit_cast<tc::common_reference_t<decltype(tc::size(vecn)),int>>(tc::size(vecn)));\n\n\tvoid(tc::min(tc::size(vecn),2));\n\n\tint a = 3;\n\tint b = 4;\n\t_ASSERTEQUAL(tc::min(a,b), 3);\n\ttc::min(a,b) = 7;\n\t_ASSERTEQUAL(a, 7);\n\n\t_ASSERTEQUAL(tc::min(a,2), 2);\n\t_ASSERTEQUAL(tc::min(5,b), 4);\n\n\t_ASSERTEQUAL(tc::min(1,a,b), 1);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<std::int16_t>(), std::declval<std::int32_t>()))\n\t\t\t, std::int32_t\n\t\t>::value\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<std::uint16_t>(), std::declval<std::int32_t>()))\n\t\t\t, std::int32_t\n\t\t>::value\n\t);\n\n\t{\n\t\tS s2[2];\n\n\t\ttc::for_each(\n\t\t\ttc::make_range_of_iterators(\n\t\t\t\ttc::transform(\n\t\t\t\t\ttc::transform(\n\t\t\t\t\t\ttc::iota(0,1),\n\t\t\t\t\t\t[&](int const n) noexcept -> S&& {\n\t\t\t\t\t\t\treturn tc_move_always(s2[n]);\n\t\t\t\t\t\t}\n\t\t\t\t\t),\n\t\t\t\t\ttc::fn_min()\n\t\t\t\t)\n\t\t\t),\n\t\t\t[&](auto it) noexcept {\n\t\t\t\ttc_auto_cref( elem, *it );\n\t\t\t\ttc::discard(elem);\n\t\t\t}\n\t\t);\n\t}\n\n\t{\n\t\tS s;\n\t\ttc::min(s,S{}).foo();\n\t}\n\n\n\ttc_invoke(tc::projected(tc::fn_min(), tc_fn(createS)), 0, 1).foo();\n\n\n\t{\n\t\tS s2[2];\n\t\ttc_invoke(tc::projected(\n\t\t\ttc::fn_min(),\n\t\t\t[&](int const n) noexcept -> S&& {\n\t\t\t\treturn tc_move_always(s2[n]);\n\t\t\t}\n\t\t), 0,1).foo();\n\t}\n\n\t{\n\t\ttc_invoke(tc::projected(\n\t\t\ttc::fn_min(),\n\t\t\ttc::fn_static_cast<S&&>()\n\t\t), createS(1), createS(2));\n\t}\n\n\t_ASSERT(tc::empty(g_sets));\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<int>(),std::declval<long>())),\n\t\t\ttc::common_type_t<int,long>\n\t\t>::value\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<long>(),std::declval<int>())),\n\t\t\ttc::common_type_t<long,int>\n\t\t>::value\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<unsigned long>(),std::declval<unsigned int>())),\n\t\t\tunsigned long\n\t\t>::value\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\tdecltype(tc::min(std::declval<unsigned int>(),std::declval<unsigned long>())),\n\t\t\tunsigned long\n\t\t>::value\n\t);\n}\n\nstatic_assert(!tc::safely_constructible_from<tc::string<wchar_t>, wchar_t const* const&, wchar_t const* const&>);\n\nnamespace is_instance_test {\n\ttemplate<typename, typename, typename> struct CTemplate1 : tc::nonmovable {};\n\ttemplate<typename, typename, typename> struct CTemplate2 : tc::nonmovable {};\n\n\tusing CInstantiation1 = CTemplate1<int, bool, void>;\n\tusing CInstantiation2 = CTemplate2<bool, void, int>;\n\n\tstatic_assert(tc::instance<CInstantiation1, CTemplate1>);\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<int, bool, void>), TC_FWD(typename tc::is_instance<CInstantiation1, CTemplate1>::arguments));\n\n\tstatic_assert(!tc::instance<CInstantiation2, CTemplate1>);\n\n\tstatic_assert(!tc::instance<CInstantiation1, CTemplate2>);\n\n\tstatic_assert(tc::instance<CInstantiation2, CTemplate2>);\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<bool, void, int>), TC_FWD(typename tc::is_instance<CInstantiation2, CTemplate2>::arguments));\n}\n\nnamespace is_instance_ttn_test {\n\ttemplate<typename, typename, bool> struct CTemplate1 : tc::nonmovable {};\n\ttemplate<typename, typename, bool> struct CTemplate2 : tc::nonmovable {};\n\n\tusing CInstantiation1 = CTemplate1<int, bool, true>;\n\tusing CInstantiation2 = CTemplate2<bool, void, false>;\n\n\tstatic_assert(tc::instance_ttn<CInstantiation1, CTemplate1>);\n\tSTATICASSERTSAME(TC_FWD(tc::is_instance_ttn<CInstantiation1, CTemplate1>::arguments), TC_FWD(boost::mp11::mp_list<int, bool, tc::constant<true>>));\n\n\tstatic_assert(!tc::instance_ttn<CInstantiation2, CTemplate1>);\n\n\tstatic_assert(!tc::instance_ttn<CInstantiation1, CTemplate2>);\n\n\tstatic_assert(tc::instance_ttn<CInstantiation2, CTemplate2>);\n\tSTATICASSERTSAME(TC_FWD(tc::is_instance_ttn<CInstantiation2, CTemplate2>::arguments), TC_FWD(boost::mp11::mp_list<bool, void, tc::constant<false>>));\n}\n\nnamespace is_instance_or_derived_test {\n\ttemplate<typename, typename> struct CTemplate1 : tc::nonmovable {};\n\ttemplate<typename T> struct CTemplate1Int : CTemplate1<int, T> {};\n\ttemplate<typename, typename> struct CTemplate2 : tc::nonmovable {\n\t\t// Catch-all constructor for implicit conversion, should be ignored.\n\t\ttemplate<typename T> CTemplate2(T&&);\n\t};\n\n\tstruct CInstantiation1 : CTemplate1Int<bool> {\n\t\t// Implicit conversions to unrelated type, should be ignored.\n\t\toperator CTemplate2<void, void>();\n\t\toperator CTemplate2<void, void>&();\n\t\toperator CTemplate2<void, void>*();\n\t};\n\tusing CInstantiation2 = CTemplate2<bool, void>;\n\n\tstatic_assert(tc::instance_or_derived<CInstantiation1, CTemplate1>);\n\tstatic_assert(!tc::instance_or_derived<CInstantiation1&, CTemplate1>);\n\tstatic_assert(!tc::is_instance_or_derived<CInstantiation1&, CTemplate1>::value);\n\tSTATICASSERTSAME(TC_FWD(CTemplate1<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1>::base_instance));\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1>::arguments));\n\n#if defined(_MSC_VER) && !defined(__clang__)\n\tstatic_assert(tc::instance_or_derived<CInstantiation1, CTemplate1 const volatile>);\n\tSTATICASSERTSAME(TC_FWD(CTemplate1<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1 const volatile>::base_instance));\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1 const volatile>::arguments));\n#endif\n\n\tstatic_assert(tc::instance_or_derived<CInstantiation1 const volatile, CTemplate1>);\n\tSTATICASSERTSAME(TC_FWD(CTemplate1<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1 const volatile, CTemplate1>::base_instance));\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<int, bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1 const volatile, CTemplate1>::arguments));\n\n\tstatic_assert(tc::instance_or_derived<CInstantiation1, CTemplate1Int>);\n\tSTATICASSERTSAME(TC_FWD(CTemplate1Int<bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1Int>::base_instance));\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<bool>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation1, CTemplate1Int>::arguments));\n\n\tstatic_assert(!tc::instance_or_derived<CInstantiation2, CTemplate1>);\n\n\tstatic_assert(!tc::instance_or_derived<CInstantiation1, CTemplate2>);\n\n\tstatic_assert(tc::instance_or_derived<CInstantiation2, CTemplate2>);\n\tSTATICASSERTSAME(TC_FWD(CTemplate2<bool, void>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation2, CTemplate2>::base_instance));\n\tSTATICASSERTSAME(TC_FWD(boost::mp11::mp_list<bool, void>), TC_FWD(typename tc::is_instance_or_derived<CInstantiation2, CTemplate2>::arguments));\n\n\tstruct CPrivateInstantiation1 : private CTemplate1<int, int> {\n\t\toperator CTemplate1<void, void>();\n\t\toperator CTemplate1<void, void>&();\n\t\toperator CTemplate1<void, void>*();\n\t};\n\n\t// static_assert(!tc::instance_or_derived<CPrivateInstantiation1, CTemplate1>);  // Does not compile.\n\tstatic_assert(!tc::instance_or_derived<CPrivateInstantiation1, CTemplate1Int>);\n\tstatic_assert(!tc::instance_or_derived<CPrivateInstantiation1, CTemplate2>);\n}\n\nnamespace is_instance_or_derived2_test {\n\tIS_INSTANCE_OR_DERIVED_TRAIT(2, ((typename)(T1))((typename)(T2))((bool)(b)), using first_argument = T1; using second_argument = T2; static constexpr auto third_argument = b;)\n\n\ttemplate<typename, typename, bool> struct CTemplate1 : tc::nonmovable {};\n\ttemplate<typename, typename, bool> struct CTemplate2 : tc::nonmovable {};\n\n\tusing CInstantiation1 = CTemplate1<int, bool, true>;\n\tusing CInstantiation2 = CTemplate2<bool, void, false>;\n\n\tstatic_assert(instance_or_derived2<CInstantiation1, CTemplate1>);\n\tSTATICASSERTSAME(int, TC_FWD(is_instance_or_derived2<CInstantiation1, CTemplate1>::first_argument));\n\tSTATICASSERTSAME(bool, TC_FWD(is_instance_or_derived2<CInstantiation1, CTemplate1>::second_argument));\n\tSTATICASSERTEQUAL(true, TC_FWD(is_instance_or_derived2<CInstantiation1, CTemplate1>::third_argument));\n\n\tstatic_assert(!instance_or_derived2<CInstantiation2, CTemplate1>);\n\n\tstatic_assert(!instance_or_derived2<CInstantiation1, CTemplate2>);\n\n\tstatic_assert(instance_or_derived2<CInstantiation2, CTemplate2>);\n\tSTATICASSERTSAME(bool, TC_FWD(is_instance_or_derived2<CInstantiation2, CTemplate2>::first_argument));\n\tSTATICASSERTSAME(void, TC_FWD(is_instance_or_derived2<CInstantiation2, CTemplate2>::second_argument));\n\tSTATICASSERTEQUAL(false, TC_FWD(is_instance_or_derived2<CInstantiation2, CTemplate2>::third_argument));\n\n\ttemplate<typename T, bool b> struct CTemplate1Int : CTemplate1<int, T, b> {};\n\n\tstruct CInstantiation3: CTemplate1Int<double, false> {\n\t\toperator CTemplate2<void, void, true>() const&;\n\t\toperator CTemplate2<void, void, true>&() const&;\n\t\toperator CTemplate2<void, void, true>*() const&;\n\t};\n\n\tstatic_assert(instance_or_derived2<CInstantiation3, CTemplate1>);\n\tstatic_assert(!instance_or_derived2<CInstantiation3, CTemplate2>);\n\n\tSTATICASSERTSAME(int, TC_FWD(is_instance_or_derived2<CInstantiation3, CTemplate1>::first_argument));\n\tSTATICASSERTSAME(double, TC_FWD(is_instance_or_derived2<CInstantiation3, CTemplate1>::second_argument));\n\tSTATICASSERTEQUAL(false, TC_FWD(is_instance_or_derived2<CInstantiation3, CTemplate1>::third_argument));\n}\n\nnamespace noncopyable_test {\n\tstruct NonCopyable final : tc::noncopyable {};\n\tstatic_assert(!std::is_copy_constructible<NonCopyable>::value);\n\tstatic_assert(!std::is_copy_assignable<NonCopyable>::value);\n\tstatic_assert(std::is_trivially_move_constructible<NonCopyable>::value);\n\tstatic_assert(std::is_trivially_move_assignable<NonCopyable>::value);\n\n\tstruct NonMovable final : tc::nonmovable {};\n\tstatic_assert(!std::is_copy_constructible<NonMovable>::value);\n\tstatic_assert(!std::is_copy_assignable<NonMovable>::value);\n\tstatic_assert(!std::is_move_constructible<NonMovable>::value);\n\tstatic_assert(!std::is_move_assignable<NonMovable>::value);\n}\n\nstatic_assert(std::is_same<tc::common_type_t<std::optional<int> const&, std::nullopt_t>, std::optional<int>>::value);\nstatic_assert(std::is_same<tc::common_type_t<std::nullopt_t, std::optional<int>>, std::optional<int>>::value);\nstatic_assert(std::is_same<tc::common_type_t<std::nullopt_t, std::nullopt_t>, std::nullopt_t>::value);\nstatic_assert(std::is_same<tc::common_type_t<int, std::nullopt_t>, std::optional<int>>::value);\nstatic_assert(std::is_same<tc::common_type_t<int const&, std::nullopt_t>, std::optional<int>>::value);\nstatic_assert(std::is_same<tc::common_type_t<std::nullopt_t, int const&>, std::optional<int>>::value);\n\n\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::tuple<int const&, int const&>, tc::tuple<int, int>>), TC_FWD(tc::tuple<int, int>));\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::tuple<int const&, int const&>, tc::tuple<int, int> const&>), TC_FWD(tc::tuple<int const&, int const&>));\nSTATICASSERTSAME(TC_FWD(tc::common_reference_t<tc::tuple<int const&, int const&>, tc::tuple<int, int>&&>), TC_FWD(tc::tuple<int const&&, int const&&>));\n"
  },
  {
    "path": "tc/base/type_traits_fwd.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"generic_macros.h\"\n#include \"move.h\"\n#include \"type_list.h\"\n\n#include <boost/preprocessor/facilities/empty.hpp>\n#include <boost/preprocessor/facilities/overload.hpp>\n#include <boost/preprocessor/seq/cat.hpp>\n#include <boost/integer.hpp>\n\n#include <type_traits>\n#include <limits>\n#include <concepts>\n\n//////////////////////////////////////////////////////////////////////////\n// STATICASSERTSAME\n#ifdef TC_MAC\n# define TC_CONSTEVAL_PCH_WORKAROUND constexpr // Xcode 13 still has problems with consteval when compiling our precompiled header\n#else\n# define TC_CONSTEVAL_PCH_WORKAROUND consteval\n#endif\nnamespace tc::static_assert_impl {\n\ttemplate <typename T1, T1 n1, typename T2, T2 n2>\n\tstruct NotEqual { // struct name chosen to make __FUNCSIG__ in static_assert message more meaningful\n\t\tstatic TC_CONSTEVAL_PCH_WORKAROUND void test() {\n\t\t\t// assert is inside a function so __FUNCSIG__ can be used to include template parameters in error message\n\t\t\tstatic_assert(n1 == n2,\n#ifdef _MSC_VER\n\t\t\t\t\"STATICASSERTEQUAL failed: \" __FUNCSIG__\n#else\n\t\t\t\t\"values not equal: see template parameters in error log\" // __PRETTY_FUNCTION__ is similar to __FUNCSIG__ but is not a string literal\n#endif\n\t\t\t);\n\t\t}\n\t};\n\n\ttemplate <typename T1, typename T2>\n\tstruct NotSame { // struct name chosen to make __FUNCSIG__ in static_assert message more meaningful\n\t\tstatic TC_CONSTEVAL_PCH_WORKAROUND void test() {\n\t\t\t// assert is inside a function so __FUNCSIG__ can be used to include template parameters in error message\n\t\t\tstatic_assert(std::is_same<T1, T2>::value\n#ifdef _MSC_VER\n\t\t\t\t// clang's default message in this case contains the non-matching type parameters\n\t\t\t\t, \"STATICASSERTSAME failed: \" __FUNCSIG__\n#endif\n\t\t\t);\n\t\t}\n\t};\n}\n\n// STATICASSERTEQUAL_IMPL and STATICASSERTSAME_IMPL should expand to something that is allowed wherever static_assert is allowed\n// and has no effect on the generated code, but forces NotEqual::test() or NotSame::test() to be compiled, which is why we use static_assert((test(), true)).\n#define STATICASSERTEQUAL_IMPL(n1, n2) static_assert((tc::static_assert_impl::NotEqual<decltype(n1), n1, decltype(n2), n2>::test(), true))\n#define STATICASSERTSAME_IMPL(t1, t2) static_assert((tc::static_assert_impl::NotSame<t1, t2>::test(), true))\n\n// Each macro should static_assert at the point of expansion (to point to the correct error location and show the correct message)\n// as well is inside the template (to show the erroneous parameters).\n#define STATICASSERTEQUAL(n1, n2, ...) static_assert((n1) == (n2) __VA_OPT__(,) __VA_ARGS__); STATICASSERTEQUAL_IMPL(TC_FWD(n1), TC_FWD(n2))\n#define STATICASSERTSAME(t1, t2, ...) static_assert(std::is_same<t1, t2>::value __VA_OPT__(,) __VA_ARGS__); STATICASSERTSAME_IMPL(TC_FWD(t1), TC_FWD(t2))\n\n// Use as type of constructor arguments that are required for enabling / disabling constructor through SFINAE.\n// To be replaced by template parameter default when Visual C++ supports template parameter defaults for functions.\nstruct unused_arg final {};\n\nnamespace tc {\n\t//////////////////////////\n\t// decay\n\tnamespace no_adl {\n\t\ttemplate<typename T, bool bPreventSlicing = true>\n\t\tstruct decay {\n\t\t\tusing type = std::decay_t<T>; // must still do function-to-pointer\n\t\t};\n\n\t\t// forbid decaying of C arrays, they decay to pointers, very unlike std/tc::array\n\t\ttemplate<typename T>\n\t\tstruct do_not_decay_arrays {\n\t\tprivate:\n\t\t\tchar dummy; // make non-empty, empty structs are preferred in make_subrange_result\n\t\t};\n\n#pragma push_macro(\"DECAY_ARRAY_IMPL\")\n#define DECAY_ARRAY_IMPL(cv) \\\n\t\ttemplate<typename T, bool bPreventSlicing> \\\n\t\tstruct decay<T cv[], bPreventSlicing> { \\\n\t\t\tusing type=do_not_decay_arrays<T cv[]>; \\\n\t\t}; \\\n\t\ttemplate<typename T,std::size_t N, bool bPreventSlicing> \\\n\t\tstruct decay<T cv[N], bPreventSlicing> { \\\n\t\t\tusing type = do_not_decay_arrays<T cv[N]>; \\\n\t\t};\n\n\t\tDECAY_ARRAY_IMPL(BOOST_PP_EMPTY())\n\t\tDECAY_ARRAY_IMPL(const)\n\t\tDECAY_ARRAY_IMPL(volatile)\n\t\tDECAY_ARRAY_IMPL(const volatile)\n#pragma pop_macro(\"DECAY_ARRAY_IMPL\")\n\n\t\ttemplate<typename T, bool bPreventSlicing>\n\t\tstruct decay<T volatile, bPreventSlicing> {\n\t\t\tusing type = typename decay<T, bPreventSlicing>::type; // recursive\n\t\t};\n\n\t\ttemplate<typename T, bool bPreventSlicing>\n\t\tstruct decay<T const, bPreventSlicing> {\n\t\t\tusing type = typename decay<T, bPreventSlicing>::type; // recursive\n\t\t};\n\n\t\ttemplate<typename T, bool bPreventSlicing>\n\t\tstruct decay<T const volatile, bPreventSlicing> {\n\t\t\tusing type = typename decay<T, bPreventSlicing>::type; // recursive\n\t\t};\n\n\t\ttemplate<typename T, bool bPreventSlicing, bool bIsNonLeafPolymorphic = std::is_polymorphic<T>::value && !std::is_final<T>::value>\n\t\tstruct decay_reference {\n\t\t\tusing type = typename decay<T, bPreventSlicing>::type; // recursive\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tstruct decay_reference<T, /*bPreventSlicing*/true, /*bIsNonLeafPolymorphic*/true> {};\n\n\t\ttemplate<typename T, bool bPreventSlicing>\n\t\tstruct decay<T&, bPreventSlicing> : decay_reference<T, bPreventSlicing> {}; // recursive\n\n\t\ttemplate<typename T, bool bPreventSlicing>\n\t\tstruct decay<T&&, bPreventSlicing> : decay_reference<T, bPreventSlicing> {}; // recursive\n\t}\n\tusing no_adl::decay;\n\n\ttemplate<typename T>\n\tusing decay_t = typename decay<T>::type;\n\n\t//\tauto a=b; uses std::decay\n\t// <=>\n\t//\tauto a=decay_copy(b); uses tc::decay_t\n\ttemplate<typename T>\n\tconstexpr tc::decay_t<T&&> decay_copy(T&& t) noexcept {\n\t\treturn tc_move_if_owned(t);\n\t}\n\t\n\t//////////////////////////\n\t// type classification concepts\n\n\ttemplate<typename T>\n\tconcept char_type = boost::mp11::mp_set_contains<boost::mp11::mp_list<char, wchar_t, char8_t, char16_t, char32_t>, std::remove_cv_t<T>>::value;\n\n\ttemplate< typename T >\n\tconcept char_ptr = std::is_pointer<T>::value && tc::char_type<std::remove_pointer_t<T>>;\n\n\tnamespace char_like_detail {\n\t\ttemplate<typename T>\n\t\tinline constexpr bool char_like_impl = tc::char_type<T>; // Customizable\n\t}\n\n\ttemplate<typename T>\n\tconcept char_like = char_like_detail::char_like_impl<T>;\n\n\ttemplate< typename T >\n\tconcept decayed = std::same_as< T, tc::decay_t<T> >;\n\n\ttemplate<typename T>\n\tconcept actual_integer = std::integral<T> && (!std::same_as<std::remove_cv_t<T>, bool>) && (!tc::char_type<T>);\n\ttemplate<typename T>\n\tconcept actual_unsigned_integer = tc::actual_integer<T> && std::unsigned_integral<T>;\n\ttemplate<typename T>\n\tconcept actual_signed_integer = tc::actual_integer<T> && std::signed_integral<T>;\n\n\ttemplate<typename T>\n\tconcept actual_arithmetic = tc::actual_integer<T> || std::floating_point<T>;\n\n\ttemplate<typename T>\n\tconcept empty_type = std::is_empty<T>::value && std::is_trivial<std::remove_cv_t<T>>::value;\n\n\ttemplate<typename T>\n\tconcept enum_type = std::is_enum<T>::value;\n\n\ttemplate<tc::actual_integer auto val>\n\tusing int_value_least_t = std::conditional_t<\n\t\t0<=val,\n\t\ttypename boost::int_max_value_t<val>::least,\n\t\ttypename boost::int_min_value_t<val>::least\n\t>;\n\n\ttemplate<tc::actual_integer auto val>\n\tusing uint_value_least_t = typename boost::uint_value_t<val>::least;\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// constant\n\n\ttemplate<auto t>\n\tusing constant = std::integral_constant<decltype(t), t>;\n\n\ttemplate<tc::actual_integer auto N> requires (N >= 0)\n\tusing least_uint_constant = tc::constant<static_cast<tc::uint_value_least_t<N>>(N)>;\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// TRAITFROMCONCEPT\n\n\tnamespace no_adl {\n\t\ttemplate<auto ConceptLambda>\n\t\tstruct trait_from_concept {\n\t\t\ttemplate<typename T>\n\t\t\tusing trait = tc::constant<ConceptLambda.template operator()<T>()>;\n\t\t};\n\t}\n\n\t#define TRAITFROMCONCEPT(TheConcept) \\\n\t\ttc::no_adl::trait_from_concept<[]<typename TraitFromConceptType /* prevent name shadow */> () consteval { return TheConcept<TraitFromConceptType>; }>::template trait\n\n\t//////////////////////////\n\t// derived_from\n\n\t// 1. std::derived_from<X,X> is true only if X is a class type.\n\t// 2. use std::is_base_of for private/protected inheritance\n\n\tnamespace derived_from_detail {\n\t\ttemplate<typename Derived, typename Base>\n\t\tinline constexpr bool derived_from_impl = std::same_as<Derived, Base> || std::derived_from<Derived, Base>; // Customizable\n\t}\n\n\ttemplate<typename Derived, typename Base>\n\tconcept derived_from = derived_from_detail::derived_from_impl<std::remove_cv_t<Derived>, std::remove_cv_t<Base>>;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Derived, typename Base>\n\t\tstruct decayed_derived_from_impl : tc::constant<\n\t\t\ttc::derived_from< typename tc::decay<Derived, /*bPreventSlicing*/false>::type, Base >\n\t\t> {\n\t\t\tstatic_assert(tc::decayed<Base>);\n\t\t};\n\t}\n\ttemplate<typename Derived, typename Base>\n\tconcept decayed_derived_from = no_adl::decayed_derived_from_impl<Derived, Base>::value;\n\n\tnamespace no_adl {\n\t\ttemplate<template<typename...> typename A, template<typename...> typename B>\n\t\tstruct is_same_template : tc::constant<false> {};\n\n\t\ttemplate<template<typename...> typename A>\n\t\tstruct is_same_template<A, A> : tc::constant<true> {};\n\t}\n\ttemplate<template<typename...> typename A, template<typename...> typename B>\n\tconcept same_template_as = no_adl::is_same_template<A, B>::value;\n} // tc\n\n\t/////////////////////////////////////////////\n\t// is_instance\n\n#define IS_INSTANCE_TRAIT(suffix, seq, ...) \\\nnamespace no_adl { \\\n\ttemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> struct is_instance ## suffix: tc::constant<false> {}; \\\n\ttemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> struct is_instance ## suffix<TInstance const, Template>: is_instance ## suffix<TInstance, Template> {}; \\\n\ttemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> struct is_instance ## suffix<TInstance volatile, Template>: is_instance ## suffix<TInstance, Template> {}; \\\n\ttemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> struct is_instance ## suffix<TInstance const volatile, Template>: is_instance ## suffix<TInstance, Template> {}; \\\n\ttemplate< \\\n\t\tTC_PP_PARAMS_ENUM(seq), \\\n\t\ttemplate<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template \\\n\t> struct is_instance ## suffix<Template<TC_PP_PARAMS_ARG_ENUM(seq)>, Template> : tc::constant<true> { \\\n\t\t__VA_ARGS__ \\\n\t}; \\\n} \\\nusing no_adl::is_instance ## suffix; \\\ntemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> \\\nconcept instance ## suffix = no_adl::is_instance ## suffix<TInstance, Template>::value;\n\nnamespace tc {\n\t// Each n in the suffix adds one non-type template parameter, each t a prefix type template parameter.\n\tIS_INSTANCE_TRAIT(, ((typename)(...)(T)), using arguments = boost::mp11::mp_list<T...>;)\n\tIS_INSTANCE_TRAIT(_n, ((auto)(V))((typename)(...)(T)), using arguments = boost::mp11::mp_list<tc::constant<V>, T...>; )\n\tIS_INSTANCE_TRAIT(_tn, ((typename)(T1))((auto)(V))((typename)(...)(T)), using arguments = boost::mp11::mp_list<T1, tc::constant<V>, T...>;)\n\tIS_INSTANCE_TRAIT(_ttn, ((typename)(T1))((typename)(T2))((auto)(V))((typename)(...)(T)), using arguments = boost::mp11::mp_list<T1, T2, tc::constant<V>, T...>;)\n}\n\n\t/////////////////////////////////////////////\n\t// is_instance_or_derived\n\n#define IS_INSTANCE_OR_DERIVED_TRAIT(suffix, seq, ...) \\\nnamespace no_adl { \\\n\ttemplate<template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template, TC_PP_PARAMS_ENUM(seq)> \\\n\tstruct BOOST_PP_CAT(is_instance_or_derived_found, suffix) final: tc::constant<true> { \\\n\t\t__VA_ARGS__ \\\n\t}; \\\n\ttemplate<template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> \\\n\tstruct BOOST_PP_CAT(is_instance_or_derived_detector, suffix) final { \\\n\t\ttemplate<TC_PP_PARAMS_ENUM(seq)> \\\n\t\tstatic BOOST_PP_CAT(is_instance_or_derived_found, suffix)<Template, TC_PP_PARAMS_ARG_ENUM(seq)> detector(Template<TC_PP_PARAMS_ARG_ENUM(seq)>*); \\\n\t\tstatic tc::constant<false> detector(...); \\\n\t}; \\\n} \\\ntemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> \\\nusing BOOST_PP_CAT(is_instance_or_derived, suffix) = \\\n\tdecltype( \\\n\t\tno_adl::BOOST_PP_CAT(is_instance_or_derived_detector, suffix)<Template>::detector( \\\n\t\t\tstd::declval<std::conditional_t<std::is_reference<TInstance>::value, /* anything that cannot bind to Template<...>* */ int*, std::remove_cvref_t<TInstance>*>>() \\\n\t\t) \\\n\t); \\\ntemplate<typename TInstance, template<TC_PP_PARAMS_TYPE_ENUM(seq)> typename Template> \\\nconcept instance_or_derived ## suffix = \\\n\tBOOST_PP_CAT(is_instance_or_derived, suffix)<TInstance, Template>::value;\n\nnamespace tc {\n\tIS_INSTANCE_OR_DERIVED_TRAIT(, ((typename)(...)(T)), using base_instance=Template<T...>;using arguments = boost::mp11::mp_list<T...>;)\n\n\t/////////////////////////////////////////////\n\t// apply_cvref\n\n\ttemplate<typename Dst, typename Src>\n\tstruct apply_cvref {\n\t\tstatic_assert( std::is_same< Src, std::remove_cvref_t<Src> >::value && !std::is_reference<Src>::value, \"Src must not be cv-qualified. Check if a template specialization of apply_cvref is missing.\" );\n\t\tusing type = Dst;\n\t};\n\n\t#pragma push_macro(\"APPLY_CVREF_IMPL\")\n\t#define APPLY_CVREF_IMPL(cvref) \\\n\ttemplate<typename Dst, typename Src> \\\n\tstruct apply_cvref<Dst, Src cvref> { \\\n\t\tusing type = Dst cvref; \\\n\t};\n\n\tAPPLY_CVREF_IMPL(&)\n\tAPPLY_CVREF_IMPL(&&)\n\tAPPLY_CVREF_IMPL(const&)\n\tAPPLY_CVREF_IMPL(const&&)\n\tAPPLY_CVREF_IMPL(const)\n\tAPPLY_CVREF_IMPL(volatile&)\n\tAPPLY_CVREF_IMPL(volatile&&)\n\tAPPLY_CVREF_IMPL(volatile)\n\tAPPLY_CVREF_IMPL(volatile const&)\n\tAPPLY_CVREF_IMPL(volatile const&&)\n\tAPPLY_CVREF_IMPL(volatile const)\n\n\t#pragma pop_macro(\"APPLY_CVREF_IMPL\")\n\n\ttemplate< typename Dst, typename Src >\n\tusing apply_cvref_t = typename apply_cvref<Dst, Src>::type;\n\n\t/////////////////////////////////////////////\n\t// same_cvref\n\n\ttemplate<typename Dst, typename Src>\n\tstruct same_cvref : apply_cvref<Dst, Src> {\n\t\tSTATICASSERTSAME(Dst, std::remove_cvref_t<Dst>); // use non-cv-qualified non-reference Dst type or apply_cvref\n\t};\n\n\ttemplate< typename Dst, typename Src >\n\tusing same_cvref_t = typename same_cvref<Dst, Src>::type;\n\n\t//////////////////////////\n\t// safely_convertible_to/assignable_from/constructible_from\n\n\tnamespace no_adl {\n\t\ttemplate <typename TTarget, typename... Args>\n\t\tstruct is_class_safely_constructible;\n\n\t\ttemplate <typename TTarget, typename... Args>\n\t\tstruct is_value_safely_constructible_base : tc::constant<false> {};\n\n\t\ttemplate <typename TTarget, typename Arg0, typename... Args> requires std::is_class<TTarget>::value\n\t\tstruct is_value_safely_constructible_base<TTarget, Arg0, Args...>\n\t\t\t// prevent slicing\n\t\t\t: tc::constant<\n\t\t\t\t( 0<sizeof...(Args) || std::is_same<TTarget, std::remove_cvref_t<Arg0>>::value || !tc::derived_from<std::remove_reference_t<Arg0>, TTarget> ) &&\n\t\t\t\tis_class_safely_constructible<TTarget, Arg0, Args...>::value\n\t\t\t>\n\t\t{\n\t\t\tstatic_assert(!std::is_reference<TTarget>::value);\n\t\t};\n\n\t\t// non-trivial default construction of classes is ok\n\t\ttemplate <typename TTarget> requires (!std::is_trivially_default_constructible<TTarget>::value)\n\t\tstruct is_value_safely_constructible_base<TTarget> : tc::constant<true> {\n\t\t\tstatic_assert(!std::is_reference<TTarget>::value);\n\t\t};\n\n\t\ttemplate <typename TTarget, typename TSource> requires std::is_union<TTarget>::value\n\t\tstruct is_value_safely_constructible_base<TTarget, TSource>\n\t\t\t// allow classes to control their convertibility to unions, we have conversion to CURRENCY somewhere\n\t\t\t: tc::constant<\n\t\t\t\tstd::is_same<TTarget, std::remove_cvref_t<TSource>>::value || std::is_class<std::remove_reference_t<TSource>>::value\n\t\t\t>\n\t\t{\n\t\t\tstatic_assert(!std::is_reference<TTarget>::value);\n\t\t};\n\n\t\t// If TTarget is arithmetic\n\t\t//   - Character types must not be mixed with other arithmetic types.\n\t\t//   - Any arithmetic type (except character types) can be assigned to floating point.\n\t\t//   - Unsigned integral types can be assigned to any integral type if the upper bound is large enough.\n\t\t//   - Signed integral types can be assigned to signed integral types if upper and lower bounds are large enough.\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tstruct is_arithmetic_value_safely_constructible final\n\t\t\t: tc::constant<false>\n\t\t{};\n\n\t\ttemplate<typename TTarget, typename TSource> requires std::is_class<std::remove_reference_t<TSource>>::value\n\t\tstruct is_arithmetic_value_safely_constructible<TTarget, TSource> final\n\t\t\t: tc::constant<true>\n\t\t{\n\t\t\tstatic_assert(std::is_arithmetic<TTarget>::value);\n\t\t};\n\n\t\ttemplate<typename TSource> requires std::is_pointer<std::remove_reference_t<TSource>>::value || std::is_same<std::remove_cvref_t<TSource>, std::nullptr_t>::value\n\t\tstruct is_arithmetic_value_safely_constructible<bool, TSource> final // explicit conversion from pointers/std::nullptr_t to bool is allowed in tc::no_adl::is_value_safely_constructible\n\t\t\t: tc::constant<true>\n\t\t{};\n\nMODIFY_WARNINGS_BEGIN(\n\t((disable)(4018)) // signed/unsigned mismatch\n\t((disable)(4388)) // signed/unsigned mismatch\n\t((disable)(4804)) // '<=': unsafe use of type 'bool' in operation\n)\n\n\t\ttemplate<typename TSource, typename TTarget>\n\t\tstruct is_safely_convertible_between_arithmetic_values\n\t\t\t: tc::constant<\n\t\t\t\tstd::is_same<tc::decay_t<TSource>, TTarget>::value // covers bool and various char types, which are only convertible within their own type\n\t\t\t\t|| (\n\t\t\t\t\t(\n\t\t\t\t\t\t(std::floating_point<TSource> && std::floating_point<TTarget>)\n\t\t\t\t\t\t||\n\t\t\t\t\t\t(tc::actual_integer<TSource> && tc::actual_integer<TTarget>)\n\t\t\t\t\t)\n\t\t\t\t\t&& (\n\t\t\t\t\t\tstd::is_signed<TSource>::value\n\t\t\t\t\t\t?\tstd::is_signed<TTarget>::value\n\t\t\t\t\t\t\t&& std::numeric_limits<TSource>::max() <= std::numeric_limits<TTarget>::max()\n\t\t\t\t\t\t\t&& std::numeric_limits<TTarget>::lowest() <= std::numeric_limits<TSource>::lowest()\n\t\t\t\t\t\t:\t// conversion to unsigned (Warning 4018 and 4388) is ok here:\n\t\t\t\t\t\t\tstd::numeric_limits<TSource>::max() <= std::numeric_limits<TTarget>::max()\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t|| (\n\t\t\t\t\ttc::actual_integer<TSource> && std::floating_point<TTarget>\t&&\n\t\t\t\t\tstd::numeric_limits<TTarget>::is_iec559 &&\n\t\t\t\t\tstd::numeric_limits<TSource>::max() <= std::numeric_limits<TTarget>::max() &&\n\t\t\t\t\tstd::numeric_limits<TTarget>::lowest() <= std::numeric_limits<TSource>::lowest() &&\n\t\t\t\t\tstd::numeric_limits<TSource>::digits <= std::numeric_limits<TTarget>::digits\n\t\t\t\t)\n\t\t\t>\n\t\t{\n\t\t\tstatic_assert(std::convertible_to<TSource, TTarget>);\n\t\t};\n\nMODIFY_WARNINGS_END\n\n\t\ttemplate<typename TTarget, typename TSource> requires std::is_arithmetic<std::remove_reference_t<TSource>>::value\n\t\tstruct is_arithmetic_value_safely_constructible<TTarget, TSource> final\n\t\t\t: is_safely_convertible_between_arithmetic_values<std::remove_reference_t<TSource>, TTarget>\n\t\t{\n\t\t\tstatic_assert(std::is_arithmetic<TTarget>::value);\n\t\t};\n\t\n\t\ttemplate <typename TTarget, typename TSource> requires std::is_arithmetic<TTarget>::value\n\t\tstruct is_value_safely_constructible_base<TTarget, TSource>\n\t\t\t// disable unwanted arithmetic conversions\n\t\t\t: tc::constant<\n\t\t\t\tis_arithmetic_value_safely_constructible<TTarget, TSource>::value\n\t\t\t>\n\t\t{\n\t\t\tstatic_assert(!std::is_reference<TTarget>::value);\n\t\t};\n\n#ifdef TC_MAC\n\t\ttemplate<typename T>\n\t\tstruct is_objc_block : tc::constant<false> {};\n\n\t\ttemplate<typename R, typename... Args>\n\t\tstruct is_objc_block<R (^)(Args...)> : tc::constant<true> {};\n#endif\n\n\t\ttemplate <typename TTarget, typename TSource>\n\t\trequires std::is_enum<TTarget>::value\n\t\t\t|| std::is_pointer<TTarget>::value\n\t\t\t|| std::is_member_pointer<TTarget>::value\n\t\t\t|| std::is_same<TTarget,std::nullptr_t>::value\n#ifdef TC_MAC\n\t\t\t|| is_objc_block<TTarget>::value\n#endif\n\t\t\n\t\tstruct is_value_safely_constructible_base<TTarget, TSource>\n\t\t\t// std::is_constructible does the right thing for enums, pointers, and std::nullptr_t\n\t\t\t: tc::constant<true>\n\t\t{\n\t\t\tstatic_assert(!std::is_reference<TTarget>::value);\n\t\t};\n\n\t\ttemplate <typename TTarget, typename... Args>\n\t\tstruct is_value_safely_constructible final : is_value_safely_constructible_base<TTarget, Args...> {}; // Has customizations\n\n\t\ttemplate <typename TSource, typename TTarget>\n\t\tstruct is_safely_convertible_to_reference final  {\n\t\t\t// creates no reference to temporary\n\t\t\t// For target references that may bind to temporaries, i.e., const&, &&, const&&\n\t\t\t// prevent initialization by\n\t\t\t//  - value -> (const)&&\n\t\t\t//  - value or (const)&& -> const&\n\t\t\t// binding to reference is only allowed to same type or derived to base conversion\n\n\t\t\tstatic auto constexpr value = \n\t\t\t\t// 1. a mutable lvalue reference does not bind to temporary objects, so it is safe to allow it\n\t\t\t\t(std::is_lvalue_reference<TTarget>::value && !std::is_const<std::remove_reference_t<TTarget>>::value)\n\t\t\t\t|| \n\t\t\t\t// 2. same type or derived to base (const)& -> const& does not bind to temporary objects\n\t\t\t\t// 3. same type or derived to base (const)& -> const&& does not bind to temporary objects\n\t\t\t\t// 4. same type or derived to base && -> (const)&& does not bind to temporary objects\n\t\t\t\t// 5. same type or derived to base const&& -> const&& does not bind to temporary objects\n\t\t\t\t(\n\t\t\t\t\t(\n\t\t\t\t\t\tstd::is_lvalue_reference<TSource>::value\n\t\t\t\t\t\t|| (std::is_rvalue_reference<TSource>::value && std::is_rvalue_reference<TTarget>::value)\n\t\t\t\t\t)\n\t\t\t\t\t&&\n\t\t\t\t\ttc::derived_from<\n\t\t\t\t\t\tstd::remove_reference_t<TSource>,\n\t\t\t\t\t\tstd::remove_reference_t<TTarget>\n\t\t\t\t\t>\n\t\t\t\t);\n\t\t};\n\t}\n\n\tnamespace safely_convertible_to_detail {\n\t\ttemplate<typename TSource, typename TTarget>\n\t\tconcept expanded_convertible_to =\n\t\t\t// 1. std::convertible_to\n\t\t\tstd::convertible_to<TSource, TTarget> // void could only std::convertible_to or from void\n\t\t\t||\n\t\t\t// 2. or, if TTarget is const&&, consider std::convertible_to const& also convertible_to const&&. static_cast is needed in this case.\n\t\t\t(\n\t\t\t\tstd::is_rvalue_reference<TTarget>::value &&\n\t\t\t\tstd::is_const<std::remove_reference_t<TTarget>>::value &&\n\t\t\t\tstd::convertible_to<TSource, std::remove_reference_t<TTarget>&>\n\t\t\t);\n\n\t\t// used when expanded_convertible_to is met\n\t\ttemplate<typename TSource, typename TTarget>\n\t\tconcept safely_convertible_to_reference = std::is_reference<TTarget>::value && no_adl::is_safely_convertible_to_reference<TSource, TTarget>::value;\n\n\t\t// used when expanded_convertible_to is met\n\t\ttemplate<typename TSource, typename TTarget>\n\t\tconcept safely_convertible_to_value =\n\t\t\t(!std::is_reference<TTarget>::value)\n\t\t\t&&\n\t\t\t!(\n\t\t\t\tstd::same_as<std::remove_cv_t<TTarget>, bool> &&\n\t\t\t\tstd::is_pointer<std::remove_reference_t<TSource>>::value\n\t\t\t) // pointers should not be implicitly convertible to bool (std::nullptr_t is already not std::convertible_to bool)\n\t\t\t&&\n\t\t\tno_adl::is_value_safely_constructible<std::remove_cv_t<TTarget>, TSource>::value;\n\t}\n\n\t// Disable unwanted conversions despite true==std::convertible_to<TSource, TTarget>\n\t// See some static_assert in type_traits.cpp.\n\ttemplate<typename TSource, typename TTarget>\n\tconcept safely_convertible_to =\n\t\tstd::same_as<TTarget, TSource> // optimistically assume guaranteed copy elision\n\t\t||\n\t\t(\n\t\t\tsafely_convertible_to_detail::expanded_convertible_to<TSource, TTarget>\n\t\t\t&&\n\t\t\t(\n\t\t\t\tsafely_convertible_to_detail::safely_convertible_to_reference<TSource, TTarget>\n\t\t\t\t||\n\t\t\t\tsafely_convertible_to_detail::safely_convertible_to_value<TSource, TTarget>\n\t\t\t)\n\t\t);\n\n\t// TODO: similar to std::convertible_to, implicit_uniform_construction_from should check if the function\n\t//\t\tT F() { return { Arg1, Arg2, Arg3.... }; }\n\t// would compile. Currently, we only check the weaker expression\n\t//\t\tG({ Arg1, Arg2, Arg3.... });\n\t// where G is a method accepting a value of T.\n\tnamespace is_implicitly_constructible_detail {\n\t\ttemplate<typename T>\n\t\tvoid check_construction(T); // unevaluated\n\n\t\ttemplate<typename T, typename... Args>\n\t\tconcept implicit_uniform_construction_from = requires { check_construction<T>({std::declval<Args>()...}); };\n\n\t\ttemplate<typename TTarget, typename... Args>\n\t\tconcept implicit_constructible_from_not_single_source =\n\t\t\t1 != sizeof...(Args) &&\n\t\t\tstd::is_class<TTarget>::value &&\n\t\t\timplicit_uniform_construction_from<TTarget, Args...> &&\n\t\t\ttc::no_adl::is_value_safely_constructible<std::remove_cv_t<TTarget>, Args...>::value;\n\n\t\ttemplate<typename TTarget, typename Arg0>\n\t\tconcept implicit_constructible_from_single_source = tc::safely_convertible_to<Arg0,TTarget>;\n\t}\n\n\ttemplate<typename TTarget, typename... Args>\n\tconcept implicit_constructible_from =\n\t\tis_implicitly_constructible_detail::implicit_constructible_from_single_source<TTarget, tc::mp_only<boost::mp11::mp_list<Args...>>> ||\n\t\tis_implicitly_constructible_detail::implicit_constructible_from_not_single_source<TTarget, Args...>;\n\n\tnamespace safely_constructible_from_detail {\n\t\t// We can't use std::is_constructible/std::constructible_from for types with private destructors.\n\t\ttemplate<typename TTarget, typename ... Args>\n\t\tconcept object_constructible_from = requires(Args&&... args) {\n\t\t\t// Note: Using the global placement new fails if TTarget is a reference type.\n\t\t\t::new(static_cast<void*>(nullptr)) TTarget(tc_move_if_owned(args)...);\n\t\t};\n\n\t\ttemplate<typename TTarget, typename... Args>\n\t\tconcept safely_constructible_from_not_single_source =\n\t\t\t// Require std::is_class<TTarget>:\n\t\t\t// - class types and const references to class types are is_constructible from two or more aguments. Initializing\n\t\t\t//\t a const reference using uniform initialization with multiple arguments would bind the reference to a temporary,\n\t\t\t//   which we do not allow,\n\t\t\t// - non-reference types may be std::is_constructible from zero arguments. We do not want this for native types like int.\n\t\t\t1!=sizeof...(Args) &&\n\t\t\tstd::is_class<TTarget>::value &&\n\t\t\tobject_constructible_from<TTarget, Args...> &&\n\t\t\tno_adl::is_value_safely_constructible<std::remove_cv_t<TTarget>, Args...>::value;\n\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tconcept reference_safely_constructible_from =\n\t\t\tstd::is_reference<TTarget>::value &&\n\t\t\ttc::safely_convertible_to<TSource, TTarget>;\n\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tconcept value_safely_constructible_from_single_source =\n\t\t\t(!std::is_reference<TTarget>::value) &&\n\t\t\t(\n\t\t\t\tobject_constructible_from<TTarget, TSource> ||\n\t\t\t\tstd::is_same<TTarget, TSource>::value // optimistically assume guaranteed copy elision\n\t\t\t) &&\n\t\t\t(\n\t\t\t\t(\n\t\t\t\t\tstd::floating_point<std::remove_cv_t<TTarget>> &&\n\t\t\t\t\tstd::floating_point<std::remove_cvref_t<TSource>>\n\t\t\t\t) ||\n\t\t\t\tno_adl::is_value_safely_constructible<std::remove_cv_t<TTarget>, TSource>::value\n\t\t\t);\n\n\t\ttemplate<typename TTarget, typename TSource>\n\t\tconcept safely_constructible_from_single_source =\n\t\t\treference_safely_constructible_from<TTarget, TSource> ||\n\t\t\tvalue_safely_constructible_from_single_source<TTarget, TSource>;\n\t}\n\n\ttemplate<typename TTarget, typename... Args>\n\tconcept safely_constructible_from =\n\t\tsafely_constructible_from_detail::safely_constructible_from_single_source<TTarget, tc::mp_only<boost::mp11::mp_list<Args...>>> ||\n\t\tsafely_constructible_from_detail::safely_constructible_from_not_single_source<TTarget, Args...>;\n\n\ttemplate<typename TTarget, typename TSource>\n\tconcept safely_assignable_from =\n\t\tstd::is_assignable<TTarget, TSource>::value &&\n\t\tno_adl::is_value_safely_constructible<std::remove_reference_t<TTarget>, TSource>::value;\n}\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <typename T, typename U>\n\t\tstruct common_type_decayed_impl {}; // no common type\n\t}\n\n\t// 1. tc::common_type_t:\n\t//\t\ta) input: any\n\t//\t\tb) result: std::common_type_t of the decayed input types if the decayed types are tc::safely_convertible_to the result type.\n\t//\t\tc) customization: Yes (many)\n\t//\t\td) SFINAE friendly: Yes\n\ttemplate<typename... T>\n\tusing common_type_t = tc::mp_fold_with_front<boost::mp11::mp_list<tc::decay_t<T>...>, boost::mp11::mp_quote_trait<no_adl::common_type_decayed_impl>::template fn>;\n\n\tnamespace no_adl {\n\t\ttemplate<typename T0, typename T1> requires\n\t\t\ttc::safely_convertible_to<T0, std::common_type_t<T0, T1>> &&\n\t\t\ttc::safely_convertible_to<T1, std::common_type_t<T0, T1>>\n\t\tstruct common_type_decayed_impl<T0, T1> : std::common_type<T0, T1> {};\n\n\t\ttemplate<typename T, typename U, U u>\n\t\tstruct common_type_decayed_impl<T, std::integral_constant<U, u>> : common_type_decayed_impl<T, U> {};\n\n\t\ttemplate<typename T, T t, typename U>\n\t\tstruct common_type_decayed_impl<std::integral_constant<T, t>, U> : common_type_decayed_impl<T, U> {};\n\n\t\ttemplate<typename T, T t, typename U, U u>\n\t\tstruct common_type_decayed_impl<std::integral_constant<T, t>, std::integral_constant<U, u>> : std::conditional_t<\n\t\t\tt == u,\n\t\t\tstd::type_identity<std::integral_constant<tc::common_type_t<T, U>, t>>,\n\t\t\tcommon_type_decayed_impl<T, U>\n\t\t> {};\n\t} // namespace no_adl\n\n\tnamespace no_adl {\n\t\ttemplate <typename T0, typename T1>\n\t\tstruct common_base_fallback {};\n\n\t\ttemplate <typename T>\n\t\tstruct common_base_fallback<T, T> {\n\t\t\tusing type = T;\n\t\t};\n\n\t\ttemplate <typename T0, typename T1> requires tc::derived_from<T0, T1>\n\t\tstruct common_base_fallback<T0, T1> {\n\t\t\tusing type = T1;\n\t\t};\n\n\t\ttemplate <typename T0, typename T1> requires tc::derived_from<T1, T0>\n\t\tstruct common_base_fallback<T0, T1> {\n\t\t\tusing type = T0;\n\t\t};\n\n\t\ttemplate <typename T0, typename T1>\n\t\tstruct common_base_impl : common_base_fallback<T0, T1> {};\n\t}\n\n\t// 2. tc::common_base_t:\n\t//\t\ta) input: non-cvref-qualified types\n\t//\t\tb) result: the most-derived common base class of the types\n\t//\t\tc) customization: Yes (types derived from Obj)\n\t//\t\td) SFINAE friendly: Yes\n\t// Note: this is non-variadic as the default implementation is not-associative:\n\t// `common_base_t<common_base_t<Base, Derived1>, Derived2>` is `Base`, but `common_base_t<Base, common_base_t<Derived1, Derived2>>` does not exist.\n\ttemplate <typename T0, typename T1> requires std::same_as<T0, std::remove_cvref_t<T0>> && std::same_as<T1, std::remove_cvref_t<T1>>\n\tusing common_base_t = typename no_adl::common_base_impl<T0, T1>::type;\n\n\tnamespace no_adl {\n\t\ttemplate <typename T0, typename T1>\n\t\tstruct actual_common_reference {};\n\n\t\ttemplate <typename T0, typename T1>\n\t\t\trequires std::is_reference<T0>::value && std::is_reference<T1>::value\n\t\t\t\t&& requires { typename tc::common_base_t<std::remove_cvref_t<T0>, std::remove_cvref_t<T1>>; }\n\t\tstruct actual_common_reference<T0, T1> {\n\t\t\tusing T0Value = std::remove_reference_t<T0>;\n\t\t\tusing T1Value = std::remove_reference_t<T1>;\n\n\t\t\ttemplate<typename ValueType>\n\t\t\tusing referenceness = std::conditional_t<\n\t\t\t\tstd::is_lvalue_reference<T0>::value && std::is_lvalue_reference<T1>::value,\n\t\t\t\tValueType&,\n\t\t\t\tValueType&&\n\t\t\t>;\n\n\t\t\ttemplate<typename ValueType>\n\t\t\tusing constness = std::conditional_t<\n\t\t\t\tstd::is_const<T0Value>::value || std::is_const<T1Value>::value || std::is_rvalue_reference<T0>::value != std::is_rvalue_reference<T1>::value,\n\t\t\t\tstd::add_const_t<ValueType>,\n\t\t\t\tValueType\n\t\t\t>;\n\n\t\t\ttemplate<typename ValueType>\n\t\t\tusing volatileness = std::conditional_t<\n\t\t\t\tstd::is_volatile<T0Value>::value || std::is_volatile<T1Value>::value,\n\t\t\t\tstd::add_volatile_t<ValueType>,\n\t\t\t\tValueType\n\t\t\t>;\n\n\t\t\tusing type = referenceness<constness<volatileness<common_base_t<std::remove_cv_t<T0Value>, std::remove_cv_t<T1Value>>>>>;\n\t\t\tstatic_assert(tc::safely_convertible_to<T0, type>);\n\t\t\tstatic_assert(tc::safely_convertible_to<T1, type>);\n\t\t};\n\t}\n\n\ttemplate <typename ... T>\n\tusing actual_common_reference_t = tc::mp_fold_with_front<boost::mp11::mp_list<T...>, boost::mp11::mp_quote_trait<no_adl::actual_common_reference>::template fn>;\n\n\tnamespace no_adl {\n\t\t// This trait can be specialized to add further common reference types.\n\t\ttemplate <typename T0, typename T1>\n\t\tstruct common_reference_impl {};\n\t\ttemplate <typename ... T>\n\t\tusing common_reference_impl_t = tc::mp_fold_with_front<boost::mp11::mp_list<T...>, boost::mp11::mp_quote_trait<common_reference_impl>::template fn>;\n\n\t\ttemplate <typename ... T>\n\t\tstruct common_reference {};\n\n\t\ttemplate <typename ... T> requires\n\t\t\trequires { typename actual_common_reference_t<T...>; }\n\t\tstruct common_reference<T...> {\n\t\t\tusing type = actual_common_reference_t<T...>;\n\t\t};\n\n\t\ttemplate <typename ... T> requires\n\t\t\trequires { typename common_reference_impl_t<T...>; }\n\t\t\t&& (!requires { typename actual_common_reference_t<T...>; })\n\t\tstruct common_reference<T...> {\n\t\t\tusing type = common_reference_impl_t<T...>;\n\t\t\tstatic_assert((tc::safely_convertible_to<T, type> && ...));\n\t\t};\n\n\t\ttemplate <typename ... T> requires\n\t\t\t(!requires { typename common_reference_impl_t<T...>; })\n\t\t\t&& (!requires { typename actual_common_reference_t<T...>; })\n\t\t\t&& requires { typename tc::common_type_t<T...>; }\n\t\tstruct common_reference<T...> {\n\t\t\tusing type = tc::common_type_t<T...>;\n\t\t};\n\t}\n\n\t// 3. tc::common_reference_t:\n\t//\t\ta) input: any\n\t//\t\tb) result:\n\t//\t\t\ti) all types are references to the same/base/derived types: base type with correct cv ref (actual_common_reference)\n\t//\t\t\tii) if customized: user-defined type with reference semantics\n\t//\t\t\tiii) else: tc::common_type_t\n\t//\t\t\tNote: if input has at least 1 prvalue, the result (if it exists) will be a prvalue.\n\t//\t\tc) customization: Yes (tc::span, tc::subrange)\n\t//\t\td) SFINAE friendly: Yes\n\ttemplate <typename... T>\n\tusing common_reference_t = typename no_adl::common_reference<T...>::type;\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct has_operator_arrow final : tc::constant<false> {};\n\t\ttemplate <typename T> requires\n\t\t\trequires { std::declval<T>().operator->(); }\n\t\t\t\t|| std::is_pointer<std::decay_t<T>>::value && (\n\t\t\t\t\t// Pseudo destructor access is legal for scalars types.\n\t\t\t\t\tstd::is_class<std::remove_pointer_t<std::decay_t<T>>>::value ||\n\t\t\t\t\tstd::is_union<std::remove_pointer_t<std::decay_t<T>>>::value ||\n\t\t\t\t\tstd::is_scalar<std::remove_pointer_t<std::decay_t<T>>>::value\n\t\t\t\t)\n\t\tstruct has_operator_arrow<T> final : tc::constant<true> {};\n\t}\n\tusing no_adl::has_operator_arrow;\n\n\ttemplate <typename...>\n\tstruct dependent_false : tc::constant<false> {};\n\n\tnamespace no_adl {\n\t\tstruct sfinae_dependency_dummy; /*undefined*/\n\n\t\ttemplate<typename T, typename DummyT>\n\t\tstruct sfinae_dependent_type;\n\t\t\n\t\ttemplate<typename T>\n\t\tstruct sfinae_dependent_type<T, sfinae_dependency_dummy> final {\n\t\t\tusing type = T;\n\t\t};\n\n\t\ttemplate<typename T, typename DummyT>\n\t\tusing sfinae_dependent_type_t = typename sfinae_dependent_type<T, DummyT>::type;\n\t}\n\n#define ENABLE_SFINAE \\\n\ttypename EnableSfinaeDependencyT = tc::no_adl::sfinae_dependency_dummy\n\n#define SFINAE_TYPE(...) \\\n\ttc::no_adl::sfinae_dependent_type_t<__VA_ARGS__, EnableSfinaeDependencyT>\n\n#define SFINAE_VALUE(...) \\\n\t(SFINAE_TYPE(void)(), __VA_ARGS__)\n\n\tnamespace no_adl {\n\t\ttemplate<typename F>\n\t\tstruct is_noexcept_function : tc::constant<false> {};\n\t\ttemplate<typename Ret, typename... Args>\n\t\tstruct is_noexcept_function<Ret(Args...) noexcept> : tc::constant<true> {};\n\t\ttemplate<typename Ret, typename... Args>\n\t\tstruct is_noexcept_function<Ret(Args..., ...) noexcept> : tc::constant<true> {};\n\n\t\ttemplate< typename T >\n\t\tstruct is_noexcept_member_function_pointer_helper : tc::constant<false> {};\n\t\ttemplate< typename T, typename U>\n\t\tstruct is_noexcept_member_function_pointer_helper<T U::*> : is_noexcept_function<std::remove_cvref_t<T>> {};\n \n\t\ttemplate< typename T >\n\t\tstruct is_noexcept_member_function_pointer : is_noexcept_member_function_pointer_helper<T> {};\n\t}\n\tusing no_adl::is_noexcept_function;\n\tusing no_adl::is_noexcept_member_function_pointer;\n\n\tnamespace no_adl {\n\t\ttemplate<typename T, typename = void>\n\t\tstruct is_equality_comparable : tc::constant<false> {};\n\n\t\ttemplate<typename T> requires tc::safely_convertible_to<decltype(std::declval<T const&>() == std::declval<T const&>()), bool>\n\t\tstruct is_equality_comparable<T> : tc::constant<true> {\n\t\t\tSTATICASSERTSAME(\n\t\t\t\tdecltype(std::declval<T const&>() == std::declval<T const&>()),\n\t\t\t\tdecltype(std::declval<T const&>() != std::declval<T const&>())\n\t\t\t);\n\t\t};\n\t}\n\tusing no_adl::is_equality_comparable;\n}\n"
  },
  {
    "path": "tc/base/utility.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"return_decltype.h\"\n\n#include <utility>\n\nnamespace tc {\n\t//////////////////////////////////////////////////////////////////////////\n\t// make_integer_sequence/make_reverse_integer_sequence\n\n\tnamespace offset_integer_sequence_impl {\n\t\ttemplate<typename TIndex, TIndex IdxFrom, TIndex IdxTo, bool bIncreasing>\n\t\tstruct offset_integer_sequence final {\n\t\tprivate:\n\t\t\tstatic_assert(IdxFrom <= IdxTo);\n\n\t\t\ttemplate<TIndex IdxFirst, TIndex... Is>\n\t\t\tstatic constexpr std::integer_sequence<TIndex, (bIncreasing ? IdxFirst + Is : IdxFirst - Is)...> make(std::integer_sequence<TIndex, Is...>);\n\t\tpublic:\n\t\t\tusing type = decltype(make<(bIncreasing ? IdxFrom : IdxTo - 1)>(std::make_integer_sequence<TIndex, IdxTo - IdxFrom>()));\n\t\t};\n\t}\n\n\ttemplate<typename TIndex, TIndex IdxFrom, TIndex IdxTo>\n\tusing make_integer_sequence = typename offset_integer_sequence_impl::offset_integer_sequence<TIndex, IdxFrom, IdxTo, /* bIncreasing */ true>::type;\n\n\ttemplate<typename TIndex, TIndex IdxFrom, TIndex IdxTo>\n\tusing make_reverse_integer_sequence = typename offset_integer_sequence_impl::offset_integer_sequence<TIndex, IdxFrom, IdxTo, /* bIncreasing */ false>::type;\n\n\tnamespace concat_integer_sequence_impl {\n\t\ttemplate <typename T, T ... Lhs, typename U, U ... Rhs>\n\t\tstd::integer_sequence<tc::common_type_t<T, U>, Lhs..., Rhs...> operator+(std::integer_sequence<T, Lhs...>, std::integer_sequence<U, Rhs...>);\n\t\ttemplate <typename T, T ... Lhs>\n\t\tstd::integer_sequence<T, Lhs...> operator+(std::integer_sequence<T, Lhs...>, std::integer_sequence<bool>); // std::integer_sequence<bool> is the identity element\n\n\t\ttemplate <typename ... Sequence>\n\t\tconsteval auto concat_integer_sequence(Sequence... seqs) noexcept {\n\t\t\t// We initialize with std::integer_sequence<bool> as the default type for empty sequences.\n\t\t\treturn (seqs + ... + std::integer_sequence<bool>{});\n\t\t}\n\t}\n\ttemplate <typename ... Sequence>\n\tusing concat_integer_sequence = decltype(concat_integer_sequence_impl::concat_integer_sequence(Sequence{}...));\n\ttemplate <typename ... Sequence>\n\tusing concat_index_sequence = concat_integer_sequence<std::index_sequence<>, Sequence...>;\n\n\tnamespace repeat_integer_sequence_impl {\n\t\ttemplate <std::size_t Count, auto Value>\n\t\tstruct repeat_one {\n\t\t\ttemplate <std::size_t ... Idx>\n\t\t\tstatic auto get(std::index_sequence<Idx...>) {\n\t\t\t\treturn std::integer_sequence<std::remove_const_t<decltype(Value)>, ((void)Idx, Value)...>{};\n\t\t\t}\n\t\t\tusing type = decltype(get(std::make_index_sequence<Count>{}));\n\t\t};\n\n\t\ttemplate <typename Counts, typename Sequence>\n\t\tstruct repeat_integer_sequence;\n\t\ttemplate <std::size_t ... Counts, typename T, T ... Values>\n\t\tstruct repeat_integer_sequence<std::index_sequence<Counts...>, std::integer_sequence<T, Values...>> {\n\t\t\tusing type = concat_integer_sequence<std::integer_sequence<T>, typename repeat_one<Counts, Values>::type...>;\n\t\t};\n\t}\n\t// repeat_integer_sequence<index_sequence<2, 1, 2>, index_sequence<1, 2, 3>> -> index_sequence<1, 1, 2, 3, 3>\n\ttemplate <typename Counts, typename Sequence>\n\tusing repeat_integer_sequence = typename repeat_integer_sequence_impl::repeat_integer_sequence<Counts, Sequence>::type;\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// is_contiguous_integer_sequence\n\n\tnamespace is_contiguous_integer_sequence_impl {\n\t\ttemplate<typename TIndex, TIndex IFirst, TIndex... Is>\n\t\tconstexpr std::is_same<std::integer_sequence<TIndex, IFirst, Is...>, tc::make_integer_sequence<TIndex, IFirst, IFirst + sizeof...(Is) + 1>> is_contiguous_integer_sequence(std::integer_sequence<TIndex, IFirst, Is...>);\n\n\t\ttemplate<typename TIndex>\n\t\tconstexpr tc::constant<true> is_contiguous_integer_sequence(std::integer_sequence<TIndex>);\n\n\t\tconstexpr tc::constant<false> is_contiguous_integer_sequence(...);\n\t}\n\n\ttemplate<typename IntSequence>\n\tusing is_contiguous_integer_sequence = decltype(is_contiguous_integer_sequence_impl::is_contiguous_integer_sequence(std::declval<IntSequence>()));\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// select_nth\n\n\ttemplate <std::size_t N>\n\tconstexpr void select_nth() noexcept {\n\t\tstatic_assert(tc::dependent_false<tc::constant<N>>::value, \"index out of range\");\n\t}\n\ttemplate <std::size_t N>\n\t[[nodiscard]] constexpr decltype(auto) select_nth(auto&& a0, auto&&... args) noexcept {\n\t\tif constexpr (0 == N) {\n\t\t\treturn tc_move_if_owned(a0);\n\t\t} else {\n\t\t\treturn tc::select_nth<N - 1>(tc_move_if_owned(args)...);\n\t\t}\n\t}\n\ttemplate <std::size_t N>\n\t[[nodiscard]] constexpr decltype(auto) select_nth(auto&& a0, auto&& a1, auto&&... args) noexcept {\n\t\tif constexpr (0 == N) {\n\t\t\treturn tc_move_if_owned(a0);\n\t\t} else if constexpr (1 == N) {\n\t\t\treturn tc_move_if_owned(a1);\n\t\t} else {\n\t\t\treturn tc::select_nth<N - 2>(tc_move_if_owned(args)...);\n\t\t}\n\t}\n\ttemplate <std::size_t N>\n\t[[nodiscard]] constexpr decltype(auto) select_nth(auto&& a0, auto&& a1, auto&& a2, auto&&... args) noexcept {\n\t\tif constexpr (0 == N) {\n\t\t\treturn tc_move_if_owned(a0);\n\t\t} else if constexpr (1 == N) {\n\t\t\treturn tc_move_if_owned(a1);\n\t\t} else if constexpr (2 == N) {\n\t\t\treturn tc_move_if_owned(a2);\n\t\t} else {\n\t\t\treturn tc::select_nth<N - 3>(tc_move_if_owned(args)...);\n\t\t}\n\t}\n\ttemplate <std::size_t N>\n\t[[nodiscard]] constexpr decltype(auto) select_nth(auto&& a0, auto&& a1, auto&& a2, auto&& a3, auto&&... args) noexcept {\n\t\tif constexpr (0 == N) {\n\t\t\treturn tc_move_if_owned(a0);\n\t\t} else if constexpr (1 == N) {\n\t\t\treturn tc_move_if_owned(a1);\n\t\t} else if constexpr (2 == N) {\n\t\t\treturn tc_move_if_owned(a2);\n\t\t} else if constexpr (3 == N) {\n\t\t\treturn tc_move_if_owned(a3);\n\t\t} else {\n\t\t\treturn tc::select_nth<N - 4>(tc_move_if_owned(args)...);\n\t\t}\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// forward_like\n\n\ttemplate<typename Cvref, typename T>\n\t[[nodiscard]] constexpr decltype(auto) forward_like(T& t) noexcept {\n\t\treturn static_cast<tc::apply_cvref_t<T, Cvref>&&>(t);\n\t}\n\n\t//////////////////////////////////////////////////////////////////////////\n\t// tuple_like\n\n\ttemplate<typename Tuple>\n\tconcept tuple_like = tc::actual_integer<decltype(std::tuple_size<tc::remove_ref_temporary_t<Tuple>>::value)>;\n}\n\n//////////////////////////////////////////////////////////////////////////\n// get\n\nnamespace tc_get_impl_adl { // Outside tc namespace to avoid finding tc::get leading to infinite recursion.\n#ifdef __GNUC__\n\t// TODO: GCC 13.1 still crashes without the workaround, 13.2 compiles\n\ttemplate<typename T> void get() = delete;\n\ttemplate<std::size_t I> void get() = delete;\n#endif\n\ttemplate<typename T>\n\tconstexpr decltype(auto) get_impl(auto&& tpl) noexcept {\n\t\treturn /*adl*/get<T>(tc_move_if_owned(tpl));\n\t}\n\n\ttemplate<std::size_t I>\n\tconstexpr decltype(auto) get_impl(auto&& tpl) noexcept {\n\t\treturn /*adl*/get<I>(tc_move_if_owned(tpl));\n\t}\n}\n\nnamespace tc_get_impl {\n\ttemplate <typename T>\n\t[[nodiscard]] constexpr decltype(auto) get(auto&& tpl) noexcept {\n\t\treturn tc_get_impl_adl::get_impl<T>(tc_move_if_owned(tpl));\n\t}\n\n\ttemplate <std::size_t I>\n\t[[nodiscard]] constexpr decltype(auto) get(auto&& tpl) noexcept {\n\t\treturn tc_get_impl_adl::get_impl<I>(tc_move_if_owned(tpl));\n\t}\n\n\ttemplate<typename T, typename Src> requires std::same_as<T, std::remove_cvref_t<Src>>\n\t[[nodiscard]] constexpr decltype(auto) get(Src&& src) noexcept {\n\t\treturn tc_move_if_owned(src);\n\t}\n}\n\nnamespace tc {\n\t// Introduces a tc::get in a way that is invisible to ADL.\n\tusing namespace tc_get_impl;\n\n\tnamespace temporary_adl {\n\t\ttemplate <typename T, typename Tuple, unsigned Lifetime>\n\t\tconstexpr decltype(auto) get(temporary<Tuple, Lifetime> tpl) noexcept {\n\t\t\tif constexpr (std::is_reference<T>::value) {\n\t\t\t\treturn tc::get<T>(tc_unwrap_temporary(tc_move(tpl)));\n\t\t\t} else {\n\t\t\t\treturn tc_rewrap_temporary(TC_FWD(tc::temporary<Tuple, Lifetime>), tc::get<T>(tc_unwrap_temporary(tc_move(tpl))));\n\t\t\t}\n\t\t}\n\n\t\ttemplate <std::size_t I, typename Tuple, unsigned Lifetime>\n\t\tconstexpr decltype(auto) get(temporary<Tuple, Lifetime> tpl) noexcept {\n\t\t\tif constexpr (std::is_reference<std::tuple_element_t<I, Tuple>>::value) {\n\t\t\t\treturn tc::get<I>(tc_unwrap_temporary(tc_move(tpl)));\n\t\t\t} else {\n\t\t\t\treturn tc_rewrap_temporary(TC_FWD(tc::temporary<Tuple&&, Lifetime>), tc::get<I>(tc_unwrap_temporary(tc_move(tpl))));\n\t\t\t}\n\t\t}\n\t}\n}\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct deduce_tag;\n\t}\n\tusing no_adl::deduce_tag;\n}\n\n//////////////////////////////////////////////////////////////////////////\n// swap\n//\n// Must be outside the tc namespace, so that it won't call tc::swap recursively.\n// tc::swap could still be called via ADL, if a type is missing an ADL barrier namespace.\nnamespace tc_swap_impl\n{\n\tusing std::swap;\n\n\ttemplate<typename T>\n\tconstexpr void swap_impl(T&& a, T&& b) return_MAYTHROW(\n\t\tswap(tc_move_if_owned(a), tc_move_if_owned(b))\n\t)\n\n\tnamespace named_swap\n\t{\n\t\t// Note: Using two template arguments here ensures that if this function and std::swap are both visible (via \"using namespace\") then\n\t\t// std::swap is chosen because it is more specialized.\n\t\t// T1 and T2 still have to be the same type because swap_impl takes two parameters with the same type.\n\t\ttemplate<typename T1, typename T2>\n\t\tconstexpr void swap(T1&& a, T2&& b) return_MAYTHROW(\n\t\t\tswap_impl(tc_move_if_owned(a), tc_move_if_owned(b))\n\t\t)\n\t}\n}\n\nnamespace tc\n{\n\t// Introduces a tc::swap name in a way that is invisible to ADL.\n\tusing tc_swap_impl::named_swap::swap;\n}\n\n//////////////////////////////////////////////////////////////////////////\n// tc_as_constexpr\n\nnamespace tc::as_constexpr_no_adl {\n\tnamespace {\n\t\ttemplate<typename TInit>\n\t\tstruct SValueHolder final {\n#ifndef __clang__\n\t\t\tstatic constexpr auto value = TInit::value();\n#else\n\t\t\tstatic constexpr auto value = TInit::value()();\n#endif\n\t\t};\n\t}\n}\n\n#if defined(__clang__) // https://bugs.llvm.org/show_bug.cgi?id=32766\n#define tc_as_constexpr(...) \\\n\t([]() constexpr noexcept -> auto const& { \\\n\t\tstruct SConstexprInit final { \\\n\t\t\tstatic constexpr auto value() noexcept { return []() constexpr noexcept { return __VA_ARGS__; }; } \\\n\t\t}; \\\n\t\treturn tc::as_constexpr_no_adl::SValueHolder<SConstexprInit>::value; \\\n\t}())\n#else\n#define tc_as_constexpr(...) \\\n\t([]() constexpr noexcept -> auto const& { \\\n\t\tstruct SConstexprInit final { \\\n\t\t\tstatic constexpr auto value() noexcept { return __VA_ARGS__; } \\\n\t\t}; \\\n\t\treturn tc::as_constexpr_no_adl::SValueHolder<SConstexprInit>::value; \\\n\t}())\n#endif\n\n#ifdef MSVC_WORKAROUND\nnamespace tc::static_auto_constexpr_no_adl {\n\ttemplate<typename Func>\n\tstruct SValueHolder final {\n\t\tstatic constexpr auto value=Func{};\n\t};\n\n\tstruct assigner_t final: tc::nonmovable {\n\t\ttemplate<typename Func>\n\t\tconstexpr auto const& operator=(Func) && noexcept {\n\t\t\treturn SValueHolder<Func>::value;\n\t\t}\n\t};\n}\n\n// Workaround MSVC code generation bug since 19.34: https://developercommunity.visualstudio.com/t/code-generation-bug-on-static-variable-i/10541326\n// We use static constexpr local variables for optimization purpose. They are initialized at compile time and will not be copied onto stack during runtime.\n// But they may or may not have multiple instantiations.\n#define tc_static_auto_constexpr(var, ...) constexpr auto const& var = tc_as_constexpr(__VA_ARGS__)\n#define tc_static_auto_constexpr_lambda(f) constexpr auto const& f = tc::static_auto_constexpr_no_adl::assigner_t{} // We can step into lambdas during debugging\n// A lambda expression can use a variable without capturing it if the variable is a reference that has been initialized with a constant expression.\n// MSVC sometimes cannot use constexpr variable/reference in lambdas at all even with explicit capture.\n// In such cases we have to use const reference and capture (which is not needed by standard).\n#define tc_static_auto_constexpr_capture(var, ...) auto const& var = tc_as_constexpr(__VA_ARGS__)\n#define tc_static_auto_constexpr_lambda_capture(f) auto const& f = tc::static_auto_constexpr_no_adl::assigner_t{} // We can step into lambdas during debugging\n#define IF_MSVC_STATIC_WORKAROUND(...) __VA_ARGS__ // unnecessary capture of const reference of static constexpr values needed by MSVC\n#define tc_static_auto_constexpr_litstr(var, ...) constexpr decltype(auto) var = __VA_ARGS__;\n#define tc_static_auto_constexpr_litstr_capture(var, ...) decltype(auto) var = __VA_ARGS__;\n#else\n#define tc_static_auto_constexpr(var, ...) static auto constexpr var = __VA_ARGS__\n#define tc_static_auto_constexpr_lambda(f) static auto constexpr f\n#define tc_static_auto_constexpr_capture(var, ...) tc_static_auto_constexpr(TC_FWD(var), TC_FWD(__VA_ARGS__))\n#define tc_static_auto_constexpr_lambda_capture(f) tc_static_auto_constexpr_lambda(TC_FWD(f))\n#define IF_MSVC_STATIC_WORKAROUND(...)\n#define tc_static_auto_constexpr_litstr(var, ...) static constexpr decltype(auto) var = __VA_ARGS__;\n#define tc_static_auto_constexpr_litstr_capture(var, ...) tc_static_auto_constexpr_litstr(TC_FWD(var), TC_FWD(__VA_ARGS__))\n#endif\n\nnamespace tc {\n\t// Pass cheaply-copied types by value and others by reference to const.\n\ttemplate<typename T>\n\tusing in_arg_opt_t = std::conditional_t<\n\t\tsizeof(std::remove_cvref_t<T>) <= sizeof(void*) * 2 && std::is_trivially_constructible<std::remove_cvref_t<T>, T&&>::value,\n\t\tstd::remove_cvref_t<T>,\n\t\tstd::conditional_t<\n\t\t\tstd::is_lvalue_reference<T>::value,\n\t\t\tstd::remove_reference_t<T> const&,\n\t\t\tT&&\n\t\t>\n\t>;\n}\n\n//////////////////////////////////////////////////////////////////////////\n// make_lazy/tc_lazy\n\nnamespace tc {\n\tnamespace make_lazy_adl {\n\t\ttemplate<typename Func>\n\t\tstruct make_lazy /*not final*/ : Func {\n\t\t\tstatic_assert(tc::decayed<Func>);\n\n\t\t\tconstexpr make_lazy() noexcept = default;\n\t\t\tconstexpr explicit make_lazy(Func func) noexcept : Func(tc_move(func)) {}\n\n\t\t\tconstexpr operator decltype(std::declval<Func const&>()())() const&& MAYTHROW {\n\t\t\t\treturn (*this)();\n\t\t\t}\n\t\t};\n\t}\n\tusing make_lazy_adl::make_lazy;\n}\n\n#ifndef __clang__ // TODO: try MSVC after 19.31\n\t// lazy rvalues are returned by value - avoid decltype on __VA_ARGS__, because expression usually contains lambdas\n\t#define tc_lazy( ... ) tc::make_lazy([&](auto&&...) MAYTHROW -> decltype(auto) { return tc::lvalue_or_decay(__VA_ARGS__); })\n\t// tc_lazy_prvalue allows copy elision\n\t#define tc_lazy_prvalue( ... ) tc::make_lazy([&](auto&&...) MAYTHROW { return __VA_ARGS__; })\n#else\n\t#define tc_lazy( ... ) tc::make_lazy([&](auto&&...) MAYTHROW -> decltype(auto) { \\\n\t\tif constexpr (std::is_reference<decltype((__VA_ARGS__))>::value) { \\\n\t\t\treturn tc::lvalue_or_decay(__VA_ARGS__); \\\n\t\t} else { \\\n\t\t\treturn __VA_ARGS__; \\\n\t\t} \\\n\t})\n\t#define tc_lazy_prvalue(...) tc_lazy(__VA_ARGS__)\n#endif\n\n//////////////////////////////////////////////////////////////////////////\n// tc::unused\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct unused final {\n\t\t\tconstexpr unused() noexcept = default;\n\t\t\ttemplate<typename T>\n\t\t\tconstexpr unused(T const&) noexcept {}\n\t\t};\n\t}\n\tusing no_adl::unused;\n}\n"
  },
  {
    "path": "tc/base/utility.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n\n#include \"assert_defs.h\"\n#include \"enum.h\"\n#include \"explicit_cast.h\"\n#include \"return_decltype.h\"\n#include \"utility.h\"\n#include \"type_traits.h\"\n\nnamespace {\n\tnamespace make_integer_sequence_test {\n\t\tSTATICASSERTSAME(TC_FWD(tc::make_integer_sequence<int, -1, 3>),TC_FWD( std::integer_sequence<int, -1, 0, 1, 2>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::make_integer_sequence<int, 2, 2>), std::integer_sequence<int>);\n\n\t\tSTATICASSERTSAME(TC_FWD(tc::make_reverse_integer_sequence<int, -1, 3>), TC_FWD(std::integer_sequence<int, 2, 1, 0, -1>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::make_reverse_integer_sequence<int, 2, 2>), std::integer_sequence<int>);\n\n\t\tSTATICASSERTSAME(tc::concat_integer_sequence<>, std::integer_sequence<bool>);\n\t\tSTATICASSERTSAME(TC_FWD(tc::concat_integer_sequence<std::integer_sequence<char, 1, 2, 3>>), TC_FWD(std::integer_sequence<char, 1, 2, 3>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::concat_integer_sequence<std::integer_sequence<int, 1, 2, 3>>), TC_FWD(std::integer_sequence<int, 1, 2, 3>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::concat_integer_sequence<std::integer_sequence<unsigned, 1, 2, 3>, std::integer_sequence<std::size_t, 4, 5, 6>>), TC_FWD(std::integer_sequence<std::size_t, 1, 2, 3, 4, 5, 6>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::concat_integer_sequence<std::integer_sequence<unsigned, 1, 2, 3>, std::integer_sequence<std::size_t, 4, 5, 6>, std::integer_sequence<unsigned char, 7>>), TC_FWD(std::integer_sequence<std::size_t, 1, 2, 3, 4, 5, 6, 7>));\n\t\tSTATICASSERTSAME(tc::concat_index_sequence<>, std::index_sequence<>);\n\n\t\tSTATICASSERTSAME(TC_FWD(tc::repeat_integer_sequence<std::index_sequence<0, 1, 2>, std::index_sequence<1, 2, 3>>), TC_FWD(std::index_sequence<2, 3, 3>));\n\t\tSTATICASSERTSAME(TC_FWD(tc::repeat_integer_sequence<std::index_sequence<>, std::integer_sequence<long>>), std::integer_sequence<long>);\n\t}\n\n\tnamespace is_contiguous_integer_sequence_test {\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<std::make_index_sequence<0>>::value);\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<std::make_index_sequence<1>>::value);\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<std::make_index_sequence<2>>::value);\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<std::make_index_sequence<10>>::value);\n\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<tc::make_integer_sequence<int, 1, 1>>::value);\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<tc::make_integer_sequence<int, 1, 5>>::value);\n\t\tstatic_assert(!tc::is_contiguous_integer_sequence<tc::make_reverse_integer_sequence<int, 1, 3>>::value);\n\n\t\tstatic_assert(tc::is_contiguous_integer_sequence<std::integer_sequence<int, -2, -1, 0, 1, 2, 3>>::value);\n\t\tstatic_assert(!tc::is_contiguous_integer_sequence<std::integer_sequence<int, 0, 2>>::value);\n\t\tstatic_assert(!tc::is_contiguous_integer_sequence<std::integer_sequence<int, 0, 2, 3>>::value);\n\n\t\tstatic_assert(!tc::is_contiguous_integer_sequence<int>::value);\n\t}\n\n\tnamespace constant_test {\n\t\tstatic_assert( tc::constant<2>() == 2 );\n\t\tstatic_assert( std::is_same<tc::constant<2>, std::integral_constant<int,2>>::value );\n\n\t\tSTATICASSERTSAME( TC_FWD(tc::common_type_t<tc::constant<2>, long long>), long long );\n\t\tSTATICASSERTSAME( TC_FWD(tc::common_type_t<tc::constant<2>, tc::constant<3ll>>), long long );\n\t\tSTATICASSERTSAME( TC_FWD(tc::common_type_t<tc::constant<2>, tc::constant<2ll>>), tc::constant<2ll> );\n\n\t\tTC_DEFINE_ENUM(MyEnum,myenum,(ONE)(TWO))\n\n\t\tstatic_assert( tc::constant<myenumONE>() == myenumONE );\n\t\tstatic_assert( std::is_same<tc::constant<myenumONE>, std::integral_constant<MyEnum,myenumONE>>::value );\n\n\t\tSTATICASSERTSAME( TC_FWD(tc::common_type_t<tc::constant<myenumONE>, tc::constant<myenumONE>>), tc::constant<myenumONE> );\n\t\tSTATICASSERTSAME( TC_FWD(tc::common_type_t<tc::constant<myenumONE>, tc::constant<myenumTWO>>), MyEnum );\n\n\t\tstatic_assert( tc::explicit_cast<tc::constant<myenumONE>>(myenumONE) == myenumONE );\n\t\tSTATICASSERTSAME( decltype(tc::explicit_cast<tc::constant<myenumONE>>(myenumONE)), tc::constant<myenumONE> );\n\t}\n\n\tnamespace decltype_return_test {\n\t\tstruct A {\n\t\t\tint a;\n\t\t\tvoid access_a() & noexcept {\n\t\t\t\tSTATICASSERTSAME(decltype(a), int);\n\t\t\t\tSTATICASSERTSAME(decltype((a)), int&);\n\t\t\t}\n\t\t\tint& b;\n\t\t\tvoid access_b() & noexcept {\n\t\t\t\tSTATICASSERTSAME(decltype(b), int&);\n\t\t\t\tSTATICASSERTSAME(decltype((b)), int&);\n\t\t\t}\n\t\t\tint&& c;\n\t\t\tvoid access_c() & noexcept {\n\t\t\t\tSTATICASSERTSAME(decltype(c), int&&);\n\t\t\t\tSTATICASSERTSAME(decltype((c)), int&);\n\t\t\t}\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "tc/compat.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"container/container.h\" // tc::vector\n#include \"container/insert.h\"\n#include \"range/filter_adaptor.h\"\n\n\n#include <array>\n\nMODIFY_WARNINGS_BEGIN(((disable)(4018)))\n#include <boost/range/category.hpp>\n#include <boost/range/iterator_range.hpp>\nMODIFY_WARNINGS_END\n\nnamespace lookup {\n\tstruct NoBegin final {};\n}\n\nnamespace {\n\tusing HasStdBegin = tc::vector<int>;\n\tusing HasNoBegin = lookup::NoBegin;\n\tusing HasBoostBegin = boost::iterator_range< tc::iterator_t<std::array<unsigned long,1> const> >;\n\n\tSTATIC_ASSERT(tc::range_with_iterators<HasStdBegin>);\n\tSTATIC_ASSERT(tc::range_with_iterators<HasBoostBegin>);\n\tSTATIC_ASSERT(!tc::range_with_iterators<HasNoBegin>);\n\n\tstruct TransFilterTest final {\n\t\ttemplate <typename T>\n\t\tstruct wrapped final {\n\t\t\texplicit wrapped(T const& t) noexcept : m_t(t) {}\n\t\t\tT getT() const& noexcept { return m_t; }\n\n\t\t\tT m_t;\n\t\t};\n\n\t\tusing wrapped_long = wrapped<long>;\n\t\tstatic bool filter35( wrapped_long const& wl ) noexcept { return wl.getT() == 3 || wl.getT() == 5; }\n\t\tstatic std::size_t transf_times_100( wrapped_long const& wl ) noexcept { std::size_t color = wl.getT() * 100; return color; }\n\n\t\tusing WlList = tc::vector< wrapped_long > const&;\n\t\t//using WlList = tc::vector< wrapped_long >;        // works!\n\t\tWlList getWlList() const& noexcept { return m_list; }\n\n\t\tusing WlFilterdList = tc::filter_adaptor<decltype(&filter35), WlList>;\n\t\tauto getWlFilterdList() const& return_decltype_noexcept( tc::filter(getWlList(), &filter35) )\n\n\t\t// This is where it gets weird, as soon as you somehow use has_range_iterator<WlFilterdList> (here at class scope)\n\t\t// things go crashing down, even though has_range_iterator<WlFilterdList> is perfectly fine one line later at function scope\n\n\t\tusing WlFilterdTransformedList = tc::transform_adaptor<decltype(&transf_times_100), WlFilterdList, true>; STATIC_ASSERT(tc::range_with_iterators<WlFilterdList>);\n\t\t//using WlFilterdTransformedList = transform_adaptor<decltype(&transf_times_100), WlFilterdList, tc::range_with_iterators<WlFilterdList>>;\n\t\t//using WlFilterdTransformedList = transform_adaptor<decltype(&transf_times_100), WlFilterdList>;\n\t\tWlFilterdTransformedList getWlFilterdTransformedList() const& noexcept {\n\t\t\tSTATIC_ASSERT(tc::range_with_iterators<WlFilterdList>);\n\t\t\tSTATIC_ASSERT(tc::range_with_iterators<WlFilterdTransformedList>);\n\n\t\t\treturn  tc::transform(getWlFilterdList(), &transf_times_100 );\n\t\t}\n\n\t\tTransFilterTest() noexcept {\n\t\t\tTEST_init_hack(tc::vector, wrapped_long, list, {wrapped_long(1),wrapped_long(2),wrapped_long(3),wrapped_long(4),wrapped_long(5),wrapped_long(6)});\n\t\t\tm_list = list;\n\t\t}\n\n\t\tprivate:\n\t\t\ttc::vector<wrapped_long> m_list;\n\t};\n\n\nUNITTESTDEF( TransFilterTest ) {\n\n\tTransFilterTest t;\n\ttc_auto_cref( res, t.getWlFilterdTransformedList() );\n\n\tUNUSED_TEST_VARIABLE(res);\n\tTEST_init_hack(tc::vector, std::size_t, original, {std::size_t(300), std::size_t(500)});\n}\n\nUNITTESTDEF( boost_iterator_range_compat ) {\n\n\tTEST_init_hack(tc::vector, unsigned long, original, {1,2,3,4,5,6,7,8});\n\ttc::vector<unsigned long> v = original;\n\n\tTEST_init_hack(tc::vector, unsigned long, baul_exp, {6});\n\tstd::array<unsigned long, 1> baul; tc::front(baul) = 6;\n\n\tauto mutable_range = boost::make_iterator_range(v); TEST_RANGE_LENGTH(mutable_range, 8);\n\tTEST_RANGE_EQUAL(original, mutable_range);\n\n\tboost::iterator_range< tc::iterator_t<std::array<unsigned long,1> const> > const baul_r = boost::make_iterator_range(baul);\n\n\tSTATIC_ASSERT(tc::range_with_iterators<decltype(baul)>);\n\n\tTEST_RANGE_EQUAL(baul_exp, baul_r);\n\n\tauto baul_our_r = tc::all(baul);\n\tTEST_RANGE_EQUAL(baul_exp, baul_our_r);\n\n}\n\nUNITTESTDEF( boost_range_traits_compat ) {\n\tTEST_init_hack(tc::vector, unsigned long, original, {1,2,3,4,5,6,7,8});\n\tTEST_init_hack(tc::vector, unsigned long, exp, {2,4,6,8});\n\n\tauto fr = tc::filter(original, [](unsigned long const i) noexcept { return i%2==0; });\n\n\tSTATIC_ASSERT(std::is_same<decltype(std::begin(fr)), decltype(tc::begin(fr))>::value);\n\n\tauto bir = boost::make_iterator_range(fr);\n\tTEST_RANGE_EQUAL(exp, bir);\n}\n\nstruct inner final {\n\tinner(int id) noexcept : i(id) {}\n\tint id() const& noexcept { return i*100; }\nprivate:\n\tfriend struct free_id;\n\tint i;\n};\n\nstruct free_id final { int operator()(inner const& in) const& noexcept { return in.id(); } };\nstruct filter_stub final { bool operator()(tc::unused) const& noexcept { return true; } };\n\nstruct outer final {\n\ttc::vector<inner> m_in;\n\n\touter() noexcept {\n\t\tTEST_init_hack(tc::vector, inner, tmp, {1,2,3,4,5,6,7,8});\n\t\tm_in = tmp;\n\t}\n\n\tusing TRange = tc::filter_adaptor< filter_stub, tc::transform_adaptor< free_id, tc::vector<inner> const& , true>, true >;\n\tTRange trans_range() & noexcept {\n\t\treturn tc::filter( tc::transform(tc::as_const(m_in), free_id()), filter_stub() );\n\t}\n};\n\nUNITTESTDEF( deduce_traits ) {\n\tTEST_init_hack(tc::vector, int, exp, {100,200,300,400,500,600,700,800});\n\touter o;\n\n\tauto trange = tc::filter(tc::transform(tc::as_const(o.m_in), free_id()), filter_stub());\n\tTEST_RANGE_EQUAL( exp, trange );\n\n\ttc::vector<int> res;\n\ttc::for_each( o.trans_range(), [&](int const id) noexcept { tc::cont_emplace_back(res, id); } );\n\tTEST_RANGE_EQUAL(exp, res);\n}\n\n}\n"
  },
  {
    "path": "tc/const.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"container/container.h\" // tc::vector\n#include \"range/filter_adaptor.h\"\n#include \"range/transform_adaptor.h\"\n\nnamespace {\n\tstatic_assert(!tc::range_with_iterators<int>, \"has..._iterator reports that int has an iterator\");\n\tstatic_assert(tc::range_with_iterators<tc::vector<int>>, \"has..._iterator reports that vector has no iterator\");\n\nUNITTESTDEF( const_range ) {\n\n\ttc::vector<int> original {1,2,3,4,5,6,7,8};\n\ttc::vector<int> modified {2,3,4,5,6,7,8,9};\n\n\ttc::vector<int> v = original;\n\n\tauto mutable_range = tc::all(v); TEST_RANGE_LENGTH(mutable_range, 8);\n\n\tTEST_RANGE_EQUAL(original, mutable_range);\n\tTEST_RANGE_NOT_EQUAL(modified, mutable_range);\n\ttc::for_each(mutable_range, [](int& i) noexcept { i += 1; });\n\tTEST_RANGE_EQUAL(modified, mutable_range);\n\tTEST_RANGE_NOT_EQUAL(original, mutable_range);\n\n\tv = original;\n\tauto const_range = tc::all(tc::as_const(v)); TEST_RANGE_LENGTH(const_range, 8);\n\n\tTEST_RANGE_EQUAL(original, const_range);\n\tTEST_RANGE_NOT_EQUAL(modified, const_range);\n\t//tc::for_each(const_range, [](int& i) noexcept { i += 1; });        // breaks with a horrible error msg. Todo: see if we can make a better msg.\n\t//tc::for_each(const_range, [](int const i) noexcept { i += 1; });  // breaks with clear msg as it should.\n\ttc::for_each(const_range, [](int const&) noexcept { });\n\tTEST_RANGE_EQUAL(original, const_range);\n\tTEST_RANGE_NOT_EQUAL(modified, const_range);\n}\n\nUNITTESTDEF( filter_const_filter_test ) {\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\n\tauto fr = tc::filter(v, [](int const i) noexcept { return i % 2 == 0; });\n\n\ttc::discard( tc::filter(tc::as_const(fr), [](int const i) noexcept { return i % 2 == 0; }) );\n\ttc::discard( tc::filter(fr, [](int const i) noexcept { return i % 2 == 0; }) );\n}\n\nUNITTESTDEF( filter_filter_const_test ) {\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\n\tauto frc = tc::filter(tc::as_const(v), [](int const i) noexcept { return i % 2 == 0; });\n\n\ttc::discard( tc::filter(frc, [](int const i) noexcept { return i % 2 == 0; }) );\n\ttc::discard( tc::filter(tc::as_const(frc), [](int const i) noexcept { return i % 2 == 0; }) );\n\ttc::discard( tc::filter(tc::filter(tc::as_const(v), [](int const i) noexcept { return i % 2 == 0; }), [](int const i) noexcept { return i % 2 == 0; }) );\n}\n\nUNITTESTDEF( transform_const_transform_test ) {\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\n\tauto tr = tc::transform(v, [](int const i) noexcept { return i * 2; });\n\n\ttc::discard( tc::transform(tc::as_const(tr), [](int const i) noexcept { return i * 2; }) );\n\ttc::discard( tc::transform(tr, [](int const i) noexcept { return i * 2; }) );\n}\n\nUNITTESTDEF( transform_transform_const_test ) {\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\n\tauto trc = tc::transform(tc::as_const(v), [](int const i) noexcept { return i * 2; });\n\n\ttc::discard( tc::transform(trc, [](int const i) noexcept { return i * 2; }) );\n\ttc::discard( tc::transform(tc::transform(tc::as_const(v), [](int const i) noexcept { return i * 2; }), [](int const i) noexcept { return i * 2; }) );\n\n}\n\n//-----------------------------------------------------------------------------------------------------------------------------\n// mixed ranges constness tests\n\nUNITTESTDEF( transform_const_filter_test ) {\n\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\n\tauto tr = tc::filter(v, [](int const i) noexcept { return i % 2 == 0; });\n\n\ttc::discard( tc::transform(tc::as_const(tr), [](int const i) noexcept { return i * 2; }) );\n\ttc::discard( tc::transform(tr, [](int const i) noexcept { return i * 2; }) );\n}\n\n//-----------------------------------------------------------------------------------------------------------------------------\n\n// Todo: more tests with more complex setups, i.e. chains of (sub)ranges with variying constness\n\n}\n\n"
  },
  {
    "path": "tc/container/cont_assign.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../algorithm/append.h\"\n#include \"container.h\"\n#include \"cont_reserve.h\"\n#include \"insert.h\"\n\n#include <boost/range/algorithm/copy.hpp>\n\nnamespace tc {\n\n\t////////////////////////\n\t// generic container algorithms\n\n\tstatic_assert(tc::instance<tc::vector<int>, std::vector>);\n\n\tnamespace cont_assign_default {\n\t\tnamespace detail {\n\t\t\ttemplate<typename Cont, typename Rng0, tc::appendable<Cont&>... Rng>\n\t\t\t\trequires (!std::same_as<tc::iterator_t<Cont>, tc::iterator_t<Cont const>>) // we assume \"deep const\" <=> \"assignment assigns elements\"\n\t\t\t\t\t&& std::same_as<std::remove_cvref_t<Cont>, Rng0> && tc::safely_assignable_from<Cont&, Rng0&&>\n\t\t\tconstexpr void cont_assign_impl(Cont&& cont, Rng0&& rng0, Rng&&... rng) MAYTHROW {\n\t\t\t\tcont=tc_move_if_owned(rng0);\n\t\t\t\tif constexpr(0<sizeof...(Rng)) {\n\t\t\t\t\ttc::append(cont, tc_move_if_owned(rng)...);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ttemplate< typename Cont, typename... Rng>\n\t\t\tconstexpr void cont_assign_impl(Cont&& cont, Rng&&... rng) MAYTHROW {\n\t\t\t\tif constexpr( has_mem_fn_clear<Cont> ) {\n\t\t\t\t\tstatic_assert( std::is_lvalue_reference<Cont>::value );\n\t\t\t\t\tcont.clear();\n\t\t\t\t\tif constexpr (0<sizeof...(Rng)) {\n\t\t\t\t\t\tif constexpr( has_mem_fn_lower_bound<Cont> || has_mem_fn_hash_function<Cont> ) {\n\t\t\t\t\t\t\ttc::cont_must_insert_range(cont, tc::concat(tc_move_if_owned(rng)...)); // MAYTHROW\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttc::append(cont, tc_move_if_owned(rng)...); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tauto itOut = tc::begin(cont);\n#ifdef _CHECKS\n\t\t\t\t\tauto const itEnd = tc::end(cont);\n#endif\n\t\t\t\t\ttc::for_each(tc::concat(tc_move_if_owned(rng)...), [&](auto&& t) noexcept {\n\t\t\t\t\t\t*VERIFYPRED(itOut, itEnd!=_) = tc_move_if_owned(t);\n\t\t\t\t\t\t++itOut;\n\t\t\t\t\t}); // MAYTHROW\n\t\t\t\t\t_ASSERT(itEnd==itOut);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttemplate< typename Cont, typename... Rng>\n\t\tconstexpr void cont_assign_impl(Cont&& cont, Rng&&... rng) MAYTHROW {\n\t\t\tif( !std::is_constant_evaluated() ) {\n\t\t\t\t(tc::assert_no_overlap(cont, tc_move_if_owned(rng)), ...);\n\t\t\t}\n\t\t\tdetail::cont_assign_impl(tc_move_if_owned(cont), tc_move_if_owned(rng)...); // MAYTHROW\n\t\t}\n\t}\n\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(cont_assign)\n\n\ttemplate<typename Cont, typename Rng>\n\tvoid cont_change_with_or(Cont& cont, Rng const& rng, bool& flag) noexcept {\n\t\tcont_change_with_or(cont, rng, flag, true);\n\t}\n\n\ttemplate< typename Cont, typename Rng >\n\tbool cont_change(Cont& cont, Rng const& rng) noexcept {\n\t\tif constexpr(std::is_same<Rng, tc::empty_range>::value) {\n\t\t\t// TODO: make work with generators, then this branch should be subsumed in it\n\t\t\tif(!tc::empty(cont)) {\n\t\t\t\ttc::cont_assign(cont);\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tauto itcont=tc::begin(cont);\n\t\t\tauto const itcontEnd=tc::end(cont);\n\t\t\tauto itrng=tc::begin(rng);\n\t\t\tauto const itrngEnd=tc::end(rng);\n\t\t\tfor(;;) {\n\t\t\t\tif( itcont==itcontEnd ) {\n\t\t\t\t\tif( itrng==itrngEnd ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( itrng==itrngEnd || !tc::equal_to(*itcont, *itrng) ) {\n\t\t\t\t\ttc::take_inplace( cont, itcont );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t++itcont;\n\t\t\t\t++itrng;\n\t\t\t}\n\t\t\ttc::append(cont,tc::drop(rng,itrng));\n\t\t\treturn true;\n\t\t}\n\t}\n\n\ttemplate<typename T, std::size_t N, typename Rng>\n\tbool cont_change(T (&a)[N], Rng const& rng) noexcept {\n\t\tauto it = tc::begin(rng);\n\t\ttc::any_accu anyChanged;\n\t\tfor(std::size_t i=0; i<N; ++i) {\n\t\t\t_ASSERT(it != tc::end(rng));\n\t\t\tanyChanged(tc::change(a[i], *it));\n\t\t\t++it;\n\t\t}\n\n\t\t_ASSERTEQUAL(it, tc::end(rng));\n\t\treturn anyChanged;\n\t}\n\n\ttemplate<typename Cont, typename Rng, typename Flag>\n\tvoid cont_change_with_or(Cont& cont, Rng const& rng, Flag& flag, Flag flagChanged) noexcept {\n\t\t_ASSERTINITIALIZED(flag);\n\t\tif( flag==flagChanged ) {\n\t\t\ttc::cont_assign(cont, rng);\n\t\t} else if( tc::cont_change(cont, rng) ) {\n\t\t\tflag=tc_move(flagChanged);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/container/cont_assign.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"cont_assign.h\"\n#include \"container.h\"\n#include \"../unittest.h\"\n#include \"../range/empty_range.h\"\n#include \"../range/literal_range.h\"\n\nUNITTESTDEF(cont_assign_vec) {\n\ttc::vector<int> vec;\n\n\ttc::cont_assign(vec, tc::literal_range_of<1, 2, 3, 4, 5, 6>);\n\tTEST_RANGE_EQUAL(vec, (tc::literal_range_of<1, 2, 3, 4, 5, 6>));\n\n\ttc::cont_assign(vec, tc::literal_range_of<10, 20, 30>, tc::literal_range_of<40>);\n\tTEST_RANGE_EQUAL(vec, (tc::literal_range_of<10, 20, 30, 40>));\n\n\ttc::cont_assign(vec);\n\tTEST_RANGE_EQUAL(vec, tc::empty_range{});\n}\n\nUNITTESTDEF(cont_assign_slice) {\n\ttc::vector<int> vec = {-1, -1, 0, 0, 0, -1, -1};\n\n\ttc::cont_assign(tc::slice(vec, tc::begin(vec) + 2, tc::end(vec) - 2), tc::literal_range_of<1, 2, 3>);\n\tTEST_RANGE_EQUAL(vec, (tc::literal_range_of<-1, -1, 1, 2, 3, -1, -1>));\n}\n\nUNITTESTDEF(cont_assign_take_drop) {\n\ttc::vector<int> vec = {0, 0, 0, -1, 0, 0, 0};\n\n\ttc::cont_assign(tc::begin_next<tc::return_take>(vec, 3), tc::literal_range_of<1, 2, 3>);\n\ttc::cont_assign(tc::begin_next<tc::return_drop>(vec, 4), tc::literal_range_of<4, 5, 6>);\n\tTEST_RANGE_EQUAL(vec, (tc::literal_range_of<1, 2, 3, -1, 4, 5, 6>));\n\n\ttc::cont_assign(tc::begin_next<tc::return_take>(vec, 3), tc::begin_next<tc::return_drop>(vec, 4));\n\tTEST_RANGE_EQUAL(vec, (tc::literal_range_of<4, 5, 6, -1, 4, 5, 6>));\n}\n"
  },
  {
    "path": "tc/container/cont_reserve.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../range/meta.h\"\n#include \"../algorithm/minmax.h\"\n#include \"../algorithm/empty.h\"\n#include \"../algorithm/filter_inplace.h\"\n#include \"../algorithm/element.h\"\n\n#include <boost/container/container_fwd.hpp>\n\nnamespace tc {\n\n\ttemplate <typename SizeT>\n\tSizeT cont_extended_memory(SizeT const nCurrentCapacity, std::type_identity_t<SizeT> const nRequestedCapacity) noexcept {\n\t\t// 64 bit is enough to hold any memory money can buy\n\t\treturn tc::max(nRequestedCapacity, static_cast<SizeT>(static_cast<std::uint64_t>(nCurrentCapacity)*8/5));\n\t}\n\n\ttemplate< typename Cont >\n\ttypename boost::range_size< Cont >::type cont_extended_memory(Cont const& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type const n) noexcept {\n\t\t// factor*cont.size() does not suffice for memory operation guarantee\n\t\treturn tc::cont_extended_memory(cont.capacity(), n);\n\t}\n\n\ttemplate< typename Cont >\n\tvoid cont_reserve( Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n ) noexcept {\n\t\tif constexpr( has_mem_fn_reserve<Cont> ) {\n\t\t\tif( cont.capacity()<n ) {\n\t\t\t\tNOEXCEPT( cont.reserve(cont_extended_memory(cont,n) ));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename Cont >\n\tauto safe_cont_erase( Cont& cont, tc::iterator_t<Cont const> it ) noexcept {\n\t\t[[maybe_unused]] auto vt=tc::decay_copy(tc_move_always_even_const(*it)); // *it may be const&\n\t\treturn cont.erase(it);\n\t}\n\n\t// safer against reentrance in destructor of value by first moving the value out of the container, then erasing the element in the container and then letting the value go out of scope\n\ttemplate<typename Cont>\n\tvoid safe_cont_clear( Cont& cont ) noexcept {\n\t\tif constexpr( tc::range_filter_by_move_element<Cont>::value ) {\n\t\t\tauto it=tc::end(cont);\n\t\t\tauto itBegin=tc::begin(cont);\n\t\t\tif( it!=itBegin ) {\n\t\t\t\tfor(;;) {\n\t\t\t\t\t--it;\n\t\t\t\t\tif (it==itBegin) break;\n\t\t\t\t\tit=tc::safe_cont_erase(cont,it);\n\t\t\t\t}\n\t\t\t\t// special treatment of last iteration necessary because it!=itBegin cannot be tested anymore after itBegin has been erased\n\t\t\t\ttc::safe_cont_erase(cont,it);\n\t\t\t}\n\t\t} else {\n\t\t\tauto it=tc::begin(cont);\n\t\t\tauto itEnd=tc::end(cont);\n\t\t\twhile( it!=itEnd ) {\n\t\t\t\tit=tc::safe_cont_erase(cont,it);\n\t\t\t}\n\t\t}\n\t\t_ASSERT(tc::empty(cont)); // no one put anything into the container during reentrance\n\t}\n\n\tnamespace cont_extend_detail {\n\t\ttemplate<typename Cont, typename... Args> requires\n\t\t\trequires { std::declval<Cont&>().resize(std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>(), std::declval<Args&&>()...); }\n\t\tvoid cont_extend_impl(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n, Args&&... args) noexcept {\n\t\t\t_ASSERT( cont.size()<=n );\n\t\t\ttc::cont_reserve(cont, n);\n\t\t\tNOBADALLOC(cont.resize(n, tc_move_if_owned(args)...));\n\t\t}\n\t}\n\n\t// value initialize extended elements\n\ttemplate<typename Cont, typename... Args> requires\n\t\trequires { std::declval<Cont&>().resize(std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>(), std::declval<Args&&>()...); }\n\tvoid cont_extend(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n, Args&&... args) noexcept {\n\t\ttc::cont_extend_detail::cont_extend_impl(cont, n, tc_move_if_owned(args)...);\n\t}\n\n\t// default initialize extended elements\n\ttemplate<typename Cont> requires\n\t\t// Many containers don't support default initialization of trivially default constructible types and use value initialization instead.\n\t\t// We enable boost::container::default_init tag where needed.\n\t\t//   1. for containers that support boost::container::default_init_t, forward it.\n\t\t//   2. for containers that do not support boost::container::default_init_t: do not forward it and use cont.resize(n) (most likely value initialization) if available.\n\t\t//      TODO: use the right format once default initialization is supported\n\t\trequires { std::declval<Cont&>().resize(std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>(), boost::container::default_init); } ||\n\t\trequires { std::declval<Cont&>().resize(std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>()); }\n\tvoid cont_extend(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n, boost::container::default_init_t) noexcept {\n\t\tif constexpr (requires { cont.resize(n, boost::container::default_init);}) {\n\t\t\ttc::cont_extend_detail::cont_extend_impl(cont, n, boost::container::default_init);\n\t\t} else {\n\t\t\ttc::cont_extend_detail::cont_extend_impl(cont, n); // should be default initialized but container does not support it yet and use value initialization instead.\n\t\t}\n\t}\n\n\ttemplate< typename Cont, typename... Args,\n\t\ttypename = decltype(tc::cont_extend(std::declval<Cont&>(), std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>(), std::declval<Args&&>()...))\n\t>\n\tvoid cont_fill( Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n,  Args &&... args) noexcept {\n\t\tcont.clear();\n\t\tcont_extend( cont, n, tc_move_if_owned(args)...);\n\t}\n\n\ttemplate< typename Cont, typename... Args,\n\t\ttypename = decltype(tc::cont_extend(std::declval<Cont&>(), std::declval<typename boost::range_size< std::remove_reference_t<Cont> >::type>()+1, std::declval<Args&&>()...))\n\t>\n\t[[nodiscard]] decltype(auto) cont_extend_at(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n, Args &&... args) noexcept {\n\t\tif( cont.size()<=n ) {\n\t\t\tcont_extend( cont, n+1, tc_move_if_owned(args)...);\n\t\t}\n\t\tstatic_assert( !tc::is_stashing_element<decltype(tc::at<tc::return_element>(cont,n))>::value );\n\t\treturn tc::at(cont,n);\n\t}\n}\n"
  },
  {
    "path": "tc/container/container.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"../base/assert_defs.h\"\n#include \"../base/type_traits.h\"\n#include \"../base/change.h\"\n#include \"../algorithm/compare.h\"\n#include <vector>\n#include <memory>\n#include <stack>\n#include <set>\n#include <map>\n#include <unordered_map>\n#include <unordered_set>\n#include <list>\n\n#if defined(TC_PRIVATE) && !defined(__cpp_lib_generic_unordered_lookup)\n\t#include <boost/multi_index_container.hpp>\n\t#include <boost/multi_index/identity.hpp>\n\t#include <boost/multi_index/hashed_index.hpp>\n#endif\n\nnamespace tc {\n\ttemplate<typename T, typename Alloc=std::allocator<T> >\n\tusing vector=std::vector<T,Alloc>;\n\n\ttemplate<typename T, typename Alloc=std::allocator<T> >\n\tusing simple_stack=std::stack<T, vector<T, Alloc> >;\n\n\ttemplate<typename Rng, typename Compare=decltype(tc::lessfrom3way(tc::fn_lexicographical_compare_3way())), typename Alloc=std::allocator<Rng>>\n\tusing set_range=std::set<Rng, Compare, Alloc>;\n\n#ifdef TC_PRIVATE\n\ttemplate<typename Result, typename T>\n\tstruct fn_hash_range;\n\n#ifdef __cpp_lib_generic_unordered_lookup\n\ttemplate<\n\t\ttypename Rng,\n\t\ttypename Hash=tc::fn_hash_range<std::size_t, tc::range_value_t<Rng&>>,\n\t\ttypename KeyEqual=tc::fn_equal,\n\t\ttypename Alloc=std::allocator<Rng>\n\t>\n\tusing unordered_set_range=std::unordered_set<Rng, Hash, KeyEqual, Alloc>;\n#else // missing on apple clang\n\ttemplate<\n\t\ttypename Rng,\n\t\ttypename Hash=tc::fn_hash_range<std::size_t, tc::range_value_t<Rng&>>,\n\t\ttypename KeyEqual=tc::fn_equal,\n\t\ttypename Alloc=std::allocator<Rng>\n\t>\n\tusing unordered_set_range=boost::multi_index_container<\n\t\tRng,\n\t\tboost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::identity<Rng>, Hash, KeyEqual>>,\n\t\tAlloc\n\t>;\n#endif\n\ttemplate<typename Rng, typename T, typename Compare=decltype(tc::lessfrom3way(tc::fn_lexicographical_compare_3way())), typename Alloc=std::allocator<std::pair<Rng const, T>>>\n\tusing map_range=std::map<Rng, T, Compare, Alloc>;\n\n\t// no equivalent interface with multi_index_container\n\ttemplate<\n\t\ttypename Rng,\n\t\ttypename T,\n\t\ttypename Hash=tc::fn_hash_range<std::size_t, tc::range_value_t<Rng&>>,\n\t\ttypename KeyEqual=tc::fn_equal,\n\t\ttypename Alloc=std::allocator<std::pair<Rng const, T>>\n\t>\n\tusing unordered_map_range=std::unordered_map<Rng, T, Hash, KeyEqual, Alloc>;\n\n\ttemplate<typename Result, typename T>\n\tstruct fn_hash;\n\n\ttemplate<typename Key, typename Hash=tc::fn_hash<std::size_t, Key>, typename KeyEqual=tc::decay_t<decltype(tc::equal_to)>, typename Alloc=std::allocator<Key>>\n\tusing unordered_set=std::unordered_set<Key, Hash, KeyEqual, Alloc>;\n\n\ttemplate<typename Key, typename T, typename Hash=tc::fn_hash<std::size_t, Key>, typename KeyEqual=tc::decay_t<decltype(tc::equal_to)>, typename Alloc=std::allocator<std::pair<Key const, T>>>\n\tusing unordered_map=std::unordered_map<Key, T, Hash, KeyEqual, Alloc>;\n#else\n\ttemplate<\n\t\ttypename Rng,\n\t\ttypename Hash=std::hash<Rng>,\n\t\ttypename KeyEqual=tc::fn_equal,\n\t\ttypename Alloc=std::allocator<Rng>\n\t>\n\tusing unordered_set_range = std::unordered_set<Rng, Hash, KeyEqual, Alloc>;\n\n\ttemplate<\n\t\ttypename Rng,\n\t\ttypename T,\n\t\ttypename Hash=std::hash<Rng>,\n\t\ttypename KeyEqual=tc::fn_equal,\n\t\ttypename Alloc=std::allocator<std::pair<Rng const, T>>\n\t>\n\tusing unordered_map_range = std::unordered_map<Rng, T, Hash, KeyEqual, Alloc>;\n\n\tusing std::unordered_set;\n\tusing std::unordered_map;\n#endif\n\n\tnamespace less_key_adl {\n\t\tDEFINE_ADL_TAG_TYPE(less_key_tag)\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Lhs, typename Rhs, typename Enable=void>\n\t\tstruct has_adl_less_key_helper final: tc::constant<false> {};\n\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\tstruct has_adl_less_key_helper<Lhs, Rhs, decltype(less_key_helper(std::declval<Lhs const&>(), std::declval<Rhs const&>()), void())> final: tc::constant<true>{};\n\n\t\ttemplate<typename Lhs, typename Rhs, typename Enable=void>\n\t\tstruct has_adl_tag_less_key_helper final: tc::constant<false> {};\n\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\tstruct has_adl_tag_less_key_helper<Lhs, Rhs, decltype(less_key_helper(tc::less_key_adl::less_key_tag, std::declval<Lhs const&>(), std::declval<Rhs const&>()), void())> final: tc::constant<true>{};\n\n\t\tstruct less_key final {\n\t\t\ttemplate<typename Lhs, typename Rhs> requires (!has_adl_less_key_helper<Lhs, Rhs>::value) && (!has_adl_tag_less_key_helper<Lhs, Rhs>::value)\n\t\t\tbool operator()(Lhs const& lhs, Rhs const& rhs) const& noexcept {\n\t\t\t\treturn tc::less(lhs, rhs);\n\t\t\t}\n\n\t\t\ttemplate<typename Lhs, typename Rhs> requires has_adl_less_key_helper<Lhs, Rhs>::value\n\t\t\tbool operator()(Lhs const& lhs, Rhs const& rhs) const& noexcept {\n\t\t\t\treturn less_key_helper(lhs, rhs);\n\t\t\t}\n\n\t\t\ttemplate<typename Lhs, typename Rhs> requires has_adl_tag_less_key_helper<Lhs, Rhs>::value\n\t\t\tbool operator()(Lhs const& lhs, Rhs const& rhs) const& noexcept {\n\t\t\t\treturn less_key_helper(tc::less_key_adl::less_key_tag, lhs, rhs);\n\t\t\t}\n\n\t\t\tusing is_transparent = void;\n\t\t};\n\t}\n\tusing no_adl::less_key;\n\n\ttemplate<typename Key, typename Compare=tc::less_key, typename Alloc=std::allocator<Key>>\n\tusing set=std::set<Key, Compare, Alloc>;\n\n\ttemplate<typename Key, typename T, typename Compare=tc::less_key, typename Alloc=std::allocator<std::pair<Key const, T>>>\n\tusing map=std::map<Key, T, Compare, Alloc>;\n\n\tnamespace no_adl {\n\t\tBOOST_MPL_HAS_XXX_TRAIT_DEF(mapped_type)\n\t}\n\tusing no_adl::has_mapped_type;\n}\n"
  },
  {
    "path": "tc/container/container_traits.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/has_xxx.h\"\n#include \"../range/meta.h\"\n\n#include <boost/mpl/has_xxx.hpp>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <typename Cont, typename... T>\n\t\tstruct has_emplace_back : std::false_type {};\n\n\t\ttemplate <typename Cont, typename... T> requires requires (Cont& cont, T&&... ts) { cont.emplace_back(tc_move_if_owned(ts)...); }\n\t\tstruct has_emplace_back<Cont, T...> : std::true_type {};\n\t}\n\tusing no_adl::has_emplace_back;\n\n\t// Todo: move those below into namespace\n}\n\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( sort, &)\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( reverse, &)\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( splice, &, std::declval<tc::iterator_t<T const>>(), std::declval<T>() ) // pretty good indication that datastructure is list-like: assume erase(itBegin,itEnd) is cheap and preserves iterators\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( splice_after, &, std::declval<tc::iterator_t<T const>>(), std::declval<T>() ) // pretty good indication that datastructure is forward_list-like\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( lower_bound, const&, std::declval<typename T::key_type const&>() ) // pretty good indication that datastructure is tree-like: assume erase(itBegin,itEnd) is cheap and preserves iterators\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( assign, &, std::declval<tc::range_value_t<T&> const*>(), std::declval<tc::range_value_t<T&> const*>() )\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( size, /*not const&, files might flush*/ )\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( empty, /*not const&, files might flush*/ )\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( data, const&)\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( reserve, &, 1 )\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( clear, & )\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF(push_back, &, std::declval<tc::range_value_t<T&>>())\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF(pop_front, &)\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF(pop_back, &)\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF( hash_function, const&) // indicate the datastructure is a hashset/hashtable\nTC_HAS_MEM_FN_XXX_CONCEPT_DEF(capacity, const&)\n\nBOOST_MPL_HAS_XXX_TRAIT_DEF(efficient_erase)\n\n\n"
  },
  {
    "path": "tc/container/insert.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/explicit_cast.h\"\n#include \"../range/meta.h\"\n#include \"../algorithm/element.h\"\n#include \"../algorithm/for_each.h\"\n#include \"container.h\"\n#include \"container_traits.h\"\n\n#include <boost/range/iterator.hpp>\n#include <boost/intrusive/set.hpp>\n\nnamespace tc {\n\t// std::set/map returns pair with bool=inserted?\n\ttemplate< typename It >\n\tIt&& verify_inserted(std::pair<It,bool>&& pairitb) noexcept {\n\t\t_ASSERT(pairitb.second);\n\t\treturn tc_move(pairitb).first;\n\t}\n\n\t// std::multiset/multimap always inserts and thus returns only iterator\n\ttemplate< typename It >\n\tIt&& verify_inserted(It&& it) noexcept {\n\t\treturn tc_move_if_owned(it);\n\t}\n\n\ttemplate< typename Cont, typename It>\n\tIt&& verify_at_upper_bound(Cont const& cont, It&& it) noexcept {\n\t\treturn tc_move_if_owned(it);\n\t}\n\n\ttemplate< typename Cont, typename It> requires tc::instance<Cont, std::multiset> || tc::instance<Cont, std::multimap> || tc::instance<Cont, boost::intrusive::multiset>\n\tIt&& verify_at_upper_bound(Cont const& cont, It&& it) noexcept {\n#ifdef _DEBUG\n\t\t/* standard says: the inserted element has to be placed at upper bound */\n\t\tauto itNext = tc_modified(it, ++_);\n\t\t_ASSERTDEBUG(tc::end(cont) == itNext || cont.value_comp()(*it, *itNext));\n#endif\n\t\treturn tc_move_if_owned(it);\n\t}\n\n\ttemplate< typename Cont, typename TValue > // use extra template parameter instead of Cont::value_type to have both move and copy semantics\n\tauto intrusive_cont_must_insert(Cont& cont, TValue& val) MAYTHROW {\n\t\treturn verify_inserted( verify_at_upper_bound( cont, NOBADALLOC(cont.insert(val)) ) );\n\t}\n\n\ttemplate< typename Cont, typename... Args> requires tc::explicit_castable_from<tc::range_value_t<Cont&>, Args&& ... >\n\tauto cont_must_emplace_before(Cont& cont, tc::iterator_t<Cont const> itHint, Args&& ... args) MAYTHROW {\n\t#ifdef _CHECKS\n\t\tauto const c=cont.size();\n\t#endif\n\t\tauto it = tc::with_lazy_explicit_cast<tc::range_value_t<Cont&>>(\n\t\t\t[&](auto&&... args2) MAYTHROW -> decltype(auto) { return NOBADALLOC(cont.emplace_hint(itHint, tc_move_if_owned(args2)...)); },\n\t\t\ttc_move_if_owned(args)...\n\t\t); // MAYTHROW\n\t\t_ASSERTEQUAL( cont.size(), c+1 );\n\t\t_ASSERTEQUAL(tc_modified(it, ++_), itHint);\n\t\treturn it;\n\t}\n\n\tnamespace cont_emplace_back_detail {\n\t\ttemplate<typename RangeReturn, typename Cont, typename... T>\n\t\tconstexpr auto cont_emplace_back_impl(Cont& cont, T&& ... value) noexcept {\n\t\t\tif constexpr (has_mem_fn_lower_bound<Cont>) {\n\t\t\t\treturn [&]() return_decltype_MAYTHROW(\n\t\t\t\t\tRangeReturn::pack_element(tc::cont_must_emplace_before(cont, tc::end(cont), tc_move_if_owned(value)...), cont)\n\t\t\t\t);\n\t\t\t} else if constexpr (0 == sizeof...(T) || tc::safely_constructible_from<tc::range_value_t<Cont&>, T&& ... >) {\n\t\t\t\treturn [&]() noexcept(std::is_nothrow_constructible<tc::range_value_t<Cont&>, T...>::value) -> decltype(auto) {\n\t\t\t\t\tif constexpr (has_emplace_back<Cont, T...>::value) {\n\t\t\t\t\t\tNOBADALLOC( cont.emplace_back(tc_move_if_owned(value)...) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif constexpr (1 == sizeof...(T)) {\n\t\t\t\t\t\t\tNOBADALLOC( cont.push_back(tc_move_if_owned(value)...) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tNOBADALLOC( cont.push_back(tc::range_value_t<Cont&>(tc_move_if_owned(value)...)) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn tc::back<RangeReturn>(cont);\n\t\t\t\t};\n\t\t\t} else if constexpr (tc::explicit_castable_from<tc::range_value_t<Cont&>, T&&...>) {\n\t\t\t\treturn [&]() return_decltype_MAYTHROW(\n\t\t\t\t\tcont_emplace_back_impl<RangeReturn>(cont, tc::lazy_explicit_cast<tc::range_value_t<Cont&>>(tc_move_if_owned(value)...))()\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename RangeReturn, typename Cont, typename... T>\n\tconstexpr auto cont_emplace_back(Cont& cont, T&& ... value) return_decltype_MAYTHROW(\n\t\tcont_emplace_back_detail::cont_emplace_back_impl<RangeReturn>(cont, tc_move_if_owned(value)...)()\n\t)\n\n\ttemplate<int = 0, typename Cont, typename... T> // Make first template argument non-type to avoid instantiation error\n\tconstexpr auto cont_emplace_back(Cont& cont, T&& ... value) return_decltype_MAYTHROW(\n\t\t*cont_emplace_back_detail::cont_emplace_back_impl<tc::return_element>(cont, tc_move_if_owned(value)...)()\n\t)\n\n\ttemplate <typename Cont>\n\tvoid emplace_back_by_index( Cont& cont, typename boost::range_size<Cont>::type n ) noexcept {\n\t\ttc::cont_emplace_back( cont, tc_lazy( tc::at(cont, n) ) );\n\t}\n\n\ttemplate< typename Cont, typename... Args >\n\tauto cont_must_emplace(Cont& cont, Args&& ... args) MAYTHROW {\n\t\treturn verify_inserted( verify_at_upper_bound(\n\t\t\tcont,\n\t\t\ttc::with_lazy_explicit_cast<tc::range_value_t<Cont&>>(\n\t\t\t\t[&](auto&&... args2) MAYTHROW -> decltype(auto) { return NOBADALLOC(cont.emplace(tc_move_if_owned(args2)...)); },\n\t\t\t\ttc_move_if_owned(args)...\n\t\t\t) // MAYTHROW\n\t\t));\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Cont>\n\t\tstruct fn_cont_must_emplace { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tCont& m_cont;\n\t\t\tvoid operator()(auto&& u) const& MAYTHROW {\n\t\t\t\ttc::cont_must_emplace(m_cont, tc_move_if_owned(u));\n\t\t\t}\n\t\t};\n\t}\n\n\n\ttemplate< typename Cont, typename Rng >\n\tvoid cont_must_insert_range(Cont& cont, Rng&& rng) MAYTHROW {\n\t\ttc::for_each(tc_move_if_owned(rng), no_adl::fn_cont_must_emplace<Cont>{cont});\n\t}\n\n\ttemplate< typename Cont, typename... Args >\n\tauto cont_try_emplace(Cont& cont, Args&& ... args) MAYTHROW {\n\t\tauto const pairitb = tc::with_lazy_explicit_cast<tc::range_value_t<Cont&>>(\n\t\t\t[&](auto&&... args2) MAYTHROW -> decltype(auto) { return NOBADALLOC(cont.emplace(tc_move_if_owned(args2)...)); },\n\t\t\ttc_move_if_owned(args)...\n\t\t); // MAYTHROW\n\t\tSTATICASSERTSAME(decltype(pairitb.second), bool);\n\t\treturn pairitb;\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Cont>\n\t\tstruct fn_cont_try_emplace { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tCont& m_cont;\n\t\t\tvoid operator()(auto&& u) const& MAYTHROW {\n\t\t\t\ttc::cont_try_emplace(m_cont, tc_move_if_owned(u));\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate< typename Cont, typename Rng >\n\tvoid cont_try_insert_range(Cont& cont, Rng&& rng) MAYTHROW {\n\t\t/*\n\t\t\tIt might be more efficient for a container to insert a range at once\n\t\t\twith insert(begin(rng),end(rng)), but on the other hand, it is more\n\t\t\tefficient to access a range as generator range: If filters and costly\n\t\t\ttransforms are involved, a generator range needs to dereference only once.\n\t\t*/\n\t\ttc::for_each(tc_move_if_owned(rng), no_adl::fn_cont_try_emplace<Cont>{cont});\n\t}\n\n\t// std::map::try_emplace enforces eager construction of the key_type object\n\ttemplate<typename Key, typename Val, typename Compare, typename Alloc>\n\tauto map_try_emplace(tc::map<Key, Val, Compare, Alloc>& map, auto&& key, auto&& val) MAYTHROW\n\t\t-> std::pair<tc::iterator_t<tc::map<Key, Val, Compare, Alloc>>, bool>\n\t{\n\t\tif (auto it = map.lower_bound(key); tc::end(map) == it || map.key_comp()(key, it->first)) {\n\t\t\treturn {\n\t\t\t\ttc::cont_must_emplace_before(map, tc_move(it), tc_move_if_owned(key), tc_move_if_owned(val)),\n\t\t\t\ttrue\n\t\t\t};\n\t\t} else {\n\t\t\treturn {tc_move(it), false};\n\t\t}\n\t}\n\n\ttemplate<typename Key, typename Val, typename Compare, typename Alloc>\n\tvoid map_emplace_or_assign(tc::map<Key, Val, Compare, Alloc>& map, auto&& key, auto&& val) MAYTHROW {\n\t\tif (auto it = map.lower_bound(key); tc::end(map) == it || map.key_comp()(key, it->first)) {\n\t\t\ttc::cont_must_emplace_before(map, tc_move(it), tc_move_if_owned(key), tc_move_if_owned(val)); // MAYTHROW\n\t\t} else {\n\t\t\ttc::assign_explicit_cast(it->second, tc_move_if_owned(val)); // MAYTHROW\n\t\t}\n\t}\n\n\ttemplate<typename Key, typename T, typename Hash, typename KeyEqual, typename Allocator, typename ...Args, typename K>\n\tvoid map_emplace_or_assign(tc::unordered_map<Key, T, Hash, KeyEqual, Allocator>& map, K&& key, Args&& ...args) MAYTHROW {\n\t\tif (auto const pairitb = map.try_emplace(tc::reluctant_explicit_cast<std::remove_reference_t<decltype(map)>::key_type>(tc_move_if_owned(key)), tc_move_if_owned(args)...); !pairitb.second ) { // MAYTHROW\n\t\t\ttc::assign_explicit_cast( pairitb.first->second, tc_move_if_owned(args)... ); // MAYTHROW\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/container/string.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"../base/assert_defs.h\"\n#include \"../base/return_decltype.h\"\n#include <string>\n#ifndef TC_PRIVATE\n#include <string_view>\n#endif\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename Char>\n\t\tstruct char_traits_selector;\n\n\t\ttemplate<typename Char> requires tc::char_like<Char> && (!(std::is_same<Char, char>::value && std::is_signed<char>::value))\n\t\tstruct char_traits_selector<Char> final {\n\t\t\tusing type = std::char_traits<Char>;\n\t\t};\n\n\t\ttemplate<typename Char> requires std::is_same<Char, char>::value && std::is_signed<char>::value\n\t\tstruct char_traits_selector<Char> final {\n\t\t\tstruct type final: std::char_traits<char> {\n\t\t\t\tstatic constexpr bool lt(char_type lhs, char_type rhs) noexcept {\n\t\t\t\t\treturn lhs < rhs;\n\t\t\t\t}\n\n\t\t\t\tstatic constexpr int compare(char_type const* lhs, char_type const* rhs, std::size_t count) noexcept {\n\t\t\t\t\tfor (; 0<count; --count, ++lhs, ++rhs) {\n\t\t\t\t\t\tif (lt(*lhs, *rhs))\n\t\t\t\t\t\t\treturn -1;\n\t\t\t\t\t\tif (lt(*rhs, *lhs))\n\t\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\t}\n\n\t// tc::char_traits<char>: compares chars as chars\n\t// std::char_traits<char>: compares chars as if they are unsigned chars\n\ttemplate<typename Char>\n\tusing char_traits = typename tc::no_adl::char_traits_selector<Char>::type;\n\n\t// We want consistent result when lexicographically comparing char ranges. When it comes to element comparison,\n\t//   1. All the other char ranges except std::basic_string<char> simply compare elements with less operator,\n\t//   2. std::basic_string<char, std::char_traits<char>> compares elements via std::char_traits<char>::lt() which\n\t//      casts elements to unsigned chars before comparing. This might change the signedness of a char value on\n\t//      x86 platforms and eventually lead to inconsistent comparing result.\n\t// Therefore we introduce tc::string with tc::char_traits as the CharTraits to make comparisons between char ranges consistent.\n\ttemplate<typename Char, typename Alloc=std::allocator<Char>>\n\tusing string = std::basic_string<Char, tc::char_traits<Char>, Alloc>;\n\n}\n\n#ifndef TC_PRIVATE // We don't want std::hash.\ntemplate <typename Alloc> requires std::is_signed<char>::value\nstruct std::hash<std::basic_string<char, tc::char_traits<char>, Alloc>> {\n\tauto operator()(std::basic_string<char, tc::char_traits<char>, Alloc> const& str) const& return_decltype_MAYTHROW(std::hash<std::string_view>{}(std::string_view(str.data(), str.size())))\n};\n#endif\n"
  },
  {
    "path": "tc/create.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"container/container.h\" // tc::vector\n#include \"container/string.h\" // tc::string\n#include \"interval.h\"\n\n#include <forward_list>\n\nnamespace {\n\nUNITTESTDEF( create_range ) {\n\n\tint arr[] = {1,2,3,4,5,6,7};  UNUSED_TEST_VARIABLE(arr);\n\ttc::vector<int> v {1,2,3,4,5,6,7,8};\n\tstd::forward_list<int> l {1,2,3,4,5,6,7,8,9};\n\ttc::vector<int> exp_sub_r {3,4,5};\n\n\tchar const* cch = \"char const*\"; UNUSED_TEST_VARIABLE(cch);\n\tchar ach[] = \"char*\";\n\tchar* mch = ach; UNUSED_TEST_VARIABLE(mch);\n\twchar_t const* cwch = L\"wchar_t const*\"; UNUSED_TEST_VARIABLE(cwch);\n\twchar_t awch[] = L\"wchar_t*\";\n\twchar_t* mwch = awch; UNUSED_TEST_VARIABLE(mwch);\n\n\ttc::string<char> str = \"string\";\n\n\tauto arr_r = tc::all(arr); TEST_RANGE_LENGTH(arr_r, 7);\n\tauto v_r = tc::all(v); TEST_RANGE_LENGTH(v_r, 8);\n\n\tauto sub_r = tc::slice_by_interval(v_r, tc::make_interval(2, 5)); TEST_RANGE_LENGTH(sub_r, 3);\n\tTEST_RANGE_EQUAL(exp_sub_r, sub_r);\n\n\tauto str_r = tc::all(str); TEST_RANGE_LENGTH(str_r, 6);\n\n\tauto wchar_ir = tc::slice_by_interval(mwch, tc::make_interval(0, 8)); TEST_RANGE_LENGTH(wchar_ir, 8);\n}\n\n}\n\n"
  },
  {
    "path": "tc/dense_map.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"array.h\"\n#include \"base/enum.h\"\n#include \"base/tag_type.h\"\n#include \"base/as_lvalue.h\"\n#include \"algorithm/algorithm.h\"\n#include \"algorithm/compare.h\"\n#include \"algorithm/round.h\"\n#include \"container/cont_assign.h\"\n#include \"range/iota_range.h\"\n#include \"range/zip_range.h\"\n#include \"range/cartesian_product_adaptor.h\"\n\n#ifdef TC_PRIVATE\n#include \"Library/Persistence/types.h\"\n#endif\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<>\n\t\tstruct [[nodiscard]] all_values<bool> final {\n\t\t\tstatic auto constexpr c_rngsete = tc::transform(tc::iota_range_constant<0, 2>(), tc::fn_static_cast<bool>());\n\n\t\tpublic:\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::begin(c_rngsete);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::end(c_rngsete);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<2>{};\n\t\t\t}\n\n\t\t\tstatic constexpr std::size_t index_of(bool const b) noexcept {\n\t\t\t\treturn tc::to_underlying(b);\n\t\t\t}\n#ifdef _MSC_VER\n\t\tprivate:\n\t\t\tstatic auto constexpr _natvis_begin = false; // natvis visualizations cannot call functions even if they are constexpr.\n#endif\n\t\t};\n\n\t\ttemplate<>\n\t\tstruct [[nodiscard]] all_values<std::weak_ordering> final {\n\t\t\tstatic auto constexpr c_rngsetorders = tc::make_array(tc::aggregate_tag, std::weak_ordering::less, std::weak_ordering::equivalent, std::weak_ordering::greater);\n\n\t\tpublic:\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::begin(c_rngsetorders);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::end(c_rngsetorders);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<3>{};\n\t\t\t}\n\n\t\t\tstatic constexpr std::size_t index_of(std::weak_ordering order) noexcept {\n\t\t\t\treturn tc::find_unique<tc::return_element_index>(c_rngsetorders, order);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<>\n\t\tstruct [[nodiscard]] all_values<std::partial_ordering> final {\n\t\t\tstatic auto constexpr c_rngsetorders = tc::make_array(tc::aggregate_tag, std::partial_ordering::less, std::partial_ordering::equivalent, std::partial_ordering::greater, std::partial_ordering::unordered);\n\n\t\tpublic:\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::begin(c_rngsetorders);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::end(c_rngsetorders);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<4>{};\n\t\t\t}\n\n\t\t\tstatic constexpr std::size_t index_of(std::partial_ordering order) noexcept {\n\t\t\t\treturn tc::find_unique<tc::return_element_index>(c_rngsetorders, order);\n\t\t\t}\n\t\t};\n\t\t\n\t\ttemplate<typename... Ts>\n\t\tstruct [[nodiscard]] all_values<tc::tuple<Ts...>> final : decltype(tc::cartesian_product(tc::all_values<Ts>()...)) {\n\t\t\tconstexpr std::size_t index_of(tc::tuple<Ts...> const& tpl) const& noexcept {\n\t\t\t\treturn tc::find_unique<tc::return_element_index>(tc::cartesian_product(tc::all_values<Ts>()...), tpl);\n\t\t\t}\n\t\t};\n\t}\n\n\t// all_values are views\n\tnamespace dense_map_adl {\n#ifdef TC_PRIVATE\n\t\ttemplate< typename Key, typename Value >\n\t\tstruct dense_map;\n\n\t\ttemplate< typename Key, typename Value >\n\t\tvoid LoadType_impl( dense_map<Key, Value>& dm, CXmlReader& loadhandler ) THROW(ExLoadFail);\n#endif\n\t\ttemplate< typename Key, typename Value >\n\t\tstruct dense_map {\n\t\t\tstatic constexpr tc::all_values<Key> c_rngkey{};\n\t\tprivate:\n\t\t\ttemplate<typename KeyOther, typename ValueOther>\n\t\t\tfriend struct dense_map;\n\n\t\t\ttemplate<typename ValueOther>\n\t\t\tusing other_dense_map = dense_map<Key, ValueOther>;\n\n\t\t\tstatic_assert(std::is_reference<Value>::value ? std::is_lvalue_reference<Value>::value : !std::is_const<Value>::value && !std::is_volatile<Value>::value);\n\n\t\t\tusing Array = std::conditional_t<\n\t\t\t\tstd::is_reference<Value>::value,\n\t\t\t\ttc::array<Value, tc::size(c_rngkey)>,\n\t\t\t\tstd::array<Value, tc::size(c_rngkey)>\n\t\t\t>;\n\n\t\t\tArray m_a;\n\t\tpublic:\n\t\t\tusing dense_map_key_type = Key;\n\n\t\t\t// We cannot tell if *this is constructed using value-initialization syntax or default-initialization syntax. Therefore, we must value-initialize here.\n\t\t\tconstexpr dense_map() noexcept(std::is_nothrow_default_constructible<Value>::value) requires std::is_default_constructible<decltype(m_a)>::value: m_a{} {}\n\n\t\t\t// std::is_default_constructible checks for value-initialization, instead of default-initialization. However, T cannot be const, so there should be no observable difference\n\t\t\texplicit dense_map(boost::container::default_init_t) noexcept(std::is_nothrow_constructible<Value>::value) requires std::is_default_constructible<Value>::value {}\n\n\t\t\ttemplate<typename... Args> requires (0 < sizeof...(Args)) // dense_map(fill_tag) could exist, but it should be explicit\n\t\t\tconstexpr dense_map( tc::fill_tag_t, Args&&... val ) noexcept\n\t\t\t: tc_member_init(m_a, tc::fill_tag, tc_move_if_owned(val)...) {}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tconstexpr dense_map(tc::range_tag_t, Rng&& rng) noexcept : tc_member_init( m_a, tc_move_if_owned(rng) ) {}\n\n\t\t\t// aggregate construction of tc::dense_map does not require tc::aggregate_tag because\n\t\t\t//   1. number of arguments must be the same as the size of dense_map,\n\t\t\t//   2. it's very inconvenient for derived types, e.g. geo types.\n\t\t\t// make sure forwarding ctor has at least two parameters, so no ambiguity with filling ctor and implicit copy/move ctors\n\t\t\ttemplate< typename First, typename Second, typename... Args>\n\t\t\t\trequires\n\t\t\t\t\t(!tc::tag<std::remove_reference_t<First>>)\n\t\t\t\t\t&& (tc::econstructionIMPLICIT == tc::elementwise_construction_restrictiveness<Value, First&&, Second&&, Args&&...>::value)\n\t\t\tconstexpr dense_map(First&& first, Second&& second, Args&& ...args) noexcept(noexcept(tc::explicit_cast<decltype(m_a)>(tc::aggregate_tag, tc_move_if_owned(first), tc_move_if_owned(second), tc_move_if_owned(args)...)))\n\t\t\t: tc_member_init(m_a, tc::aggregate_tag, tc_move_if_owned(first), tc_move_if_owned(second), tc_move_if_owned(args)...) {}\n\n\t\t\ttemplate< typename First, typename Second, typename... Args>\n\t\t\t\trequires\n\t\t\t\t\t(!tc::tag<std::remove_reference_t<First>>)\n\t\t\t\t\t&& (tc::econstructionEXPLICIT == tc::elementwise_construction_restrictiveness<Value, First&&, Second&&, Args&&...>::value)\n\t\t\tconstexpr explicit dense_map(First&& first, Second&& second, Args&& ...args) noexcept(noexcept(tc::explicit_cast<decltype(m_a)>(tc::aggregate_tag, tc_move_if_owned(first), tc_move_if_owned(second), tc_move_if_owned(args)...)))\n\t\t\t\t: tc_member_init( m_a, tc::aggregate_tag, tc_move_if_owned(first), tc_move_if_owned(second), tc_move_if_owned(args)... )\n\t\t\t{}\n\n\t\t\ttemplate< typename Func > requires tc::invocable<Func&, Key>\n\t\t\tconstexpr dense_map(tc::func_tag_t, Func func) noexcept(\n\t\t\t\tnoexcept(tc_invoke(func, std::declval<Key>())) &&\n\t\t\t\t(\n\t\t\t\t\tstd::same_as<Value, decltype(tc_invoke(func, std::declval<Key>()))> || // guaranteed copy elision\n\t\t\t\t\tstd::is_nothrow_constructible<Value, decltype(tc_invoke(func, std::declval<Key>()))>::value\n\t\t\t\t)\n\t\t\t)\n\t\t\t\t: tc_member_init( m_a, tc::func_tag, [&func](std::size_t const n) MAYTHROW -> Value { // force return of Value\n\t\t\t\t\t//STATICASSERTSAME(decltype(tc_at_nodebug(c_rngkey, n))&&, Key&&); does not hold, if c_rngkey is all_values<tuple<...>>\n\t\t\t\t\t// TODO Remove static_cast<Key> below after we change counting_iterator::operator*() to return small trivial by value.\n\t\t\t\t\tstatic_assert(\n\t\t\t\t\t\tstd::is_same<Value, decltype(tc_invoke(func, std::declval<Key>()))>::value || // guaranteed copy elision, Value does not need to be copy/move constructible\n\t\t\t\t\t\ttc::safely_constructible_from<Value, decltype(tc_invoke(func, std::declval<Key>()))>\n\t\t\t\t\t);\n\t\t\t\t\treturn tc_invoke(func, static_cast<Key>(tc_at_nodebug(c_rngkey, n)));\n\t\t\t\t} )\n\t\t\t{}\n\n\t\t\ttemplate< typename Func > requires (!tc::invocable<Func&, Key>)\n\t\t\tconstexpr dense_map(tc::func_tag_t, Func func) MAYTHROW\n\t\t\t\t: dense_map(tc::func_tag, [&](auto const key) MAYTHROW -> Value {\n\t\t\t\t\treturn {tc::func_tag, [&](auto const... keys) return_decltype_MAYTHROW( tc_invoke_pack(func, key, keys) )};\n\t\t\t\t})\n\t\t\t{}\n\n\t\t\ttemplate< typename Value2 >\n\t\t\texplicit dense_map(Key keyPri, other_dense_map<Value2> const& mapOther) noexcept(std::is_nothrow_constructible<dense_map, Value2 const&, Value2 const&>::value)\n\t\t\t\t: dense_map(mapOther[keyPri], mapOther[~keyPri])\n\t\t\t{}\n\n\t\t\ttemplate< typename Value2 >\n\t\t\texplicit dense_map(Key keyPri, other_dense_map<Value2>&& mapOther) noexcept(std::is_nothrow_constructible<dense_map, Value2, Value2>::value)\n\t\t\t\t: dense_map(tc_move_always(mapOther[keyPri]), tc_move_always(mapOther[~keyPri]))\n\t\t\t{}\n\n\t\t\ttemplate< typename Func, typename Value2 >\n\t\t\tconstexpr dense_map(transform_tag_t, other_dense_map<Value2> const& mapOther, Func&& func) noexcept(noexcept(tc::explicit_cast<decltype(m_a)>(tc::transform(mapOther.m_a, tc_move_if_owned(func)))))\n\t\t\t\t: tc_member_init( m_a, tc::transform(mapOther.m_a, tc_move_if_owned(func)) )\n\t\t\t{}\n\n\t\t\ttemplate< typename Func, typename Value2 >\n\t\t\tconstexpr dense_map(transform_tag_t, other_dense_map<Value2>&& mapOther, Func func) noexcept(noexcept(tc::explicit_cast<decltype(m_a)>(tc::transform(mapOther.m_a, tc::chained(tc_move_if_owned(func), tc::fn_static_cast<Value2&&>())))))\n\t\t\t\t: tc_member_init( m_a,\n\t\t\t\t\t// TODO rvalue elements for rvalue ranges: tc::transform(tc_move(mapOther.m_a), tc_move_if_owned(func))\n\t\t\t\t\ttc::transform(mapOther.m_a, tc::chained(tc_move_if_owned(func), tc::fn_static_cast<Value2&&>()))\n\t\t\t\t)\n\t\t\t{}\n\n\t\t\tDEFINE_MEMBER_TRANSFORM(other_dense_map, tc::mp_identity, Value)\n\n\t\t\ttemplate< typename ValuePri, typename ValueSec > requires (2 == tc::size(c_rngkey))\n\t\t\tconstexpr dense_map(Key const keyPri, ValuePri&& valPri, ValueSec&& valSec) noexcept(noexcept(tc::explicit_cast<Value>(std::declval<ValuePri&&>())) && noexcept(tc::explicit_cast<Value>(std::declval<ValueSec&&>()))) :\n\t\t\t\tdense_map(tc::func_tag, [&](auto const key) MAYTHROW -> Value {\n\t\t\t\t\tif(key == keyPri) {\n\t\t\t\t\t\tif constexpr(tc::safely_convertible_to<ValuePri&&, Value>) {\n\t\t\t\t\t\t\treturn tc_move_if_owned(valPri);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::explicit_cast<Value>(tc_move_if_owned(valPri));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if constexpr(tc::safely_convertible_to<ValueSec&&, Value>) {\n\t\t\t\t\t\treturn tc_move_if_owned(valSec);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn tc::explicit_cast<Value>(tc_move_if_owned(valSec));\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t{}\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<Value, Value2 const&>::value)\n\t\t\tconstexpr dense_map(other_dense_map<Value2> const& mapOther) noexcept(std::is_nothrow_constructible<Value, Value2 const&>::value)\n\t\t\t\t: tc_member_init( m_a, mapOther.m_a )\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<Value, Value2 const&>::value) && (!(tc::actual_integer<Value> && std::floating_point<Value2>))\n\t\t\tconstexpr explicit dense_map(other_dense_map<Value2> const& mapOther) noexcept(std::is_nothrow_constructible<dense_map, transform_tag_t, decltype(mapOther), tc::fn_explicit_cast<Value>>::value)\n\t\t\t\t: dense_map(transform_tag, mapOther, tc::fn_explicit_cast<Value>())\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<Value, Value2 const&>::value) && tc::actual_integer<Value> && std::floating_point<Value2>\n\t\t\tconstexpr explicit dense_map(other_dense_map<Value2> const& mapOther) noexcept\n\t\t\t\t: dense_map(transform_tag, mapOther, [](auto const f) noexcept { return tc::explicit_cast<Value>(f, tc::roundNEAREST); }) // TODO: replace with tc::fn_explicit_cast as soon as geometry no longer relies on it\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<Value, Value2&&>::value)\n\t\t\tconstexpr dense_map(other_dense_map<Value2>&& mapOther) noexcept(std::is_nothrow_constructible<Value, Value2&&>::value)\n\t\t\t\t: tc_member_init( m_a, tc_move(mapOther).m_a )\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<Value, Value2&&>::value) && (!(tc::actual_integer<Value> && std::floating_point<Value2>))\n\t\t\tconstexpr explicit dense_map(other_dense_map<Value2>&& mapOther) noexcept(std::is_nothrow_constructible<dense_map, transform_tag_t, decltype(tc_move(mapOther)), tc::fn_explicit_cast<Value>>::value)\n\t\t\t\t: dense_map(transform_tag, tc_move(mapOther), tc::fn_explicit_cast<Value>())\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<Value, Value2&&>::value) && tc::actual_integer<Value> && std::floating_point<Value2>\n\t\t\tconstexpr explicit dense_map(other_dense_map<Value2>&& mapOther) noexcept\n\t\t\t\t: dense_map(transform_tag, tc_move(mapOther), [](auto const f) noexcept { return tc::explicit_cast<Value>(f, tc::roundNEAREST); }) // TODO: replace with tc::fn_explicit_cast as soon as geometry no longer relies on it\n\t\t\t{}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::safely_assignable_from<Value&, Value2 const&>)\n\t\t\tdense_map& operator=(other_dense_map<Value2> const& rhs) & noexcept(std::is_nothrow_assignable<Array, typename other_dense_map<Value2>::Array const&>::value) {\n\t\t\t\ttc::cont_assign(m_a, rhs.m_a);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <typename Value2>\n\t\t\t\trequires (tc::safely_assignable_from<Value&, Value2&&>)\n\t\t\tdense_map& operator=(other_dense_map<Value2>&& rhs) & noexcept(std::is_nothrow_assignable<Array, typename other_dense_map<Value2>::Array&&>::value) {\n\t\t\t\ttc::cont_assign(m_a, tc_move(rhs).m_a);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\t// access\n\t\t\t[[nodiscard]] constexpr Value& operator[](Key key) & noexcept {\n\t\t\t\tif constexpr (std::is_reference<Value>::value) {\n\t\t\t\t\treturn m_a[c_rngkey.index_of(key)];\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::at(m_a, c_rngkey.index_of(key));\n\t\t\t\t}\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr Value const& operator[](Key key) const& noexcept {\n\t\t\t\tif constexpr (std::is_reference<Value>::value) {\n\t\t\t\t\treturn m_a[c_rngkey.index_of(key)];\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::at(m_a, c_rngkey.index_of(key));\n\t\t\t\t}\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr Value&& operator[](Key key) && noexcept {\n\t\t\t\treturn static_cast<Value &&>((*this)[key]);\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr Value const&& operator[](Key key) const&& noexcept {\n\t\t\t\treturn static_cast<Value const&&>((*this)[key]);\n\t\t\t}\n\n\t\t\t// comparison\n\t\t\ttemplate<typename Key_, typename LHS, typename RHS>\n\t\t\tfriend constexpr bool operator==( dense_map<Key_, LHS> const& lhs, dense_map<Key_, RHS> const& rhs ) noexcept;\n\n\t\t\t// iterators\n\t\t\tconstexpr auto begin() const& noexcept {\n\t\t\t\treturn tc::begin(m_a);\n\t\t\t}\n\t\t\tconstexpr auto end() const& noexcept {\n\t\t\t\treturn tc::end(m_a);\n\t\t\t}\n\t\t\tconstexpr auto begin() & noexcept {\n\t\t\t\treturn tc::begin(m_a);\n\t\t\t}\n\t\t\tconstexpr auto end() & noexcept {\n\t\t\t\treturn tc::end(m_a);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::constexpr_size<tc::all_values<Key>>;\n\t\t\t}\n\t\t\t\n#ifdef _DEBUG\n\t\t\tfriend void uninitialize_impl(dense_map& dm) noexcept {\n\t\t\t\tUNINITIALIZED(dm.m_a);\n\t\t\t}\n#endif\n\n#ifdef TC_PRIVATE\n\t\t\t// persistence\n\t\t\tfriend void LoadType_impl<>( dense_map<Key, Value>& dm, CXmlReader& loadhandler ) THROW(ExLoadFail);\n\t\t\tvoid DoSave(CSaveHandler& savehandler) const& MAYTHROW;\n\n\t\tprivate:\n\t\t\ttemplate<typename HashAlgorithm>\n\t\t\tvoid hash_append_impl(HashAlgorithm& h) const& noexcept;\n\n\t\t\ttemplate<typename HashAlgorithm>\n\t\t\tfriend void hash_append_impl(HashAlgorithm& h, dense_map const& dm) noexcept {\n\t\t\t\tdm.hash_append_impl(h);\n\t\t\t}\n#endif\n\t\t};\n\n\t\ttemplate<typename Key_, typename LHS, typename RHS>\n\t\t[[nodiscard]] constexpr bool operator==(dense_map<Key_, LHS> const& lhs, dense_map<Key_, RHS> const& rhs) noexcept {\n\t\t\treturn EQUAL_MEMBERS(m_a);\n\t\t}\n\n\t} // namespace dense_map_adl\n\tusing dense_map_adl::dense_map;\n\n\ttemplate <typename Map, typename T>\n\tconcept indexed_by = std::same_as<typename Map::dense_map_key_type, T>;\n\n\t////////////////////\n\t// special RangeReturns for dense_maps\n\n\tstruct return_element_key final {\n\t\tstatic constexpr bool requires_iterator = true;\n\n\t\ttemplate<typename It, typename DenseMap>\n\t\tstatic typename std::remove_reference_t<DenseMap>::dense_map_key_type pack_element(It&& it, DenseMap&& rng, tc::unused /*ref*/={}) noexcept {\n\t\t\treturn tc_at_nodebug(rng.c_rngkey, it - tc::begin(rng));\n\t\t}\n\t\ttemplate<typename DenseMap>\n\t\tstatic typename std::remove_reference_t<DenseMap>::dense_map_key_type pack_no_element(DenseMap&& rng) noexcept {\n\t\t\t_ASSERTFALSE;\n\t\t\treturn tc_front_nodebug(rng.c_rngkey);\n\t\t}\n\t};\n\n\tstruct return_element_key_or_none final {\n\t\tstatic constexpr bool requires_iterator = true;\n\n\t\ttemplate<typename It, typename DenseMap>\n\t\tstatic std::optional<typename std::remove_reference_t<DenseMap>::dense_map_key_type> pack_element(It&& it, DenseMap&& rng, tc::unused /*ref*/={}) noexcept {\n\t\t\treturn tc_at_nodebug(rng.c_rngkey, it - tc::begin(rng));\n\t\t}\n\t\ttemplate<typename DenseMap>\n\t\tstatic std::optional<typename std::remove_reference_t<DenseMap>::dense_map_key_type> pack_no_element(DenseMap&&) noexcept {\n\t\t\treturn std::nullopt;\n\t\t}\n\t};\n\n\ttemplate <typename Key, typename Func>\n\t[[nodiscard]] constexpr auto make_dense_map(tc::func_tag_t, Func&& func) return_ctor_MAYTHROW(\n\t\tTC_FWD(tc::dense_map<Key, tc::decay_t<decltype(tc_invoke(tc::as_lvalue(tc::decay_copy(func)), tc_front_nodebug(tc::all_values<Key>())))>>),\n\t\t(tc::func_tag, tc_move_if_owned(func))\n\t)\n\n\ttemplate <typename Key, /*always deduce Ts, otherwise use dense_map<Key, T>*/int = 0, typename... Ts>\n\t[[nodiscard]] constexpr auto make_dense_map(tc::fill_tag_t, Ts&&... ts) noexcept {\n\t\treturn tc::dense_map<Key, tc::common_type_t<Ts...>>(tc::fill_tag, tc_move_if_owned(ts)...);\n\t}\n\n\ttemplate <typename Key, typename Rng>\n\t[[nodiscard]] constexpr auto make_dense_map(tc::range_tag_t, Rng&& rng) noexcept {\n\t\treturn tc::dense_map<Key, tc::range_value_t<Rng>>(tc::range_tag, tc_move_if_owned(rng));\n\t}\n\n\ttemplate <typename Key, /*always deduce Ts, otherwise use dense_map<Key, T>*/int = 0, typename... Ts>\n\t[[nodiscard]] constexpr auto make_dense_map(Ts&&... ts) noexcept {\n\t\treturn tc::dense_map<Key, tc::common_type_t<Ts...>>(tc_move_if_owned(ts)...);\n\t}\n\n\tnamespace no_adl {\n\t\t///////////////////\n\t\t// all_values specialization dense_maps\n\t\ttemplate< typename Key, typename Value >\n\t\tstruct [[nodiscard]] all_values<tc::dense_map<Key,Value>> final {\n\t\tprivate:\n\t\t\tusing baserng = tc::all_values<boost::mp11::mp_repeat_c<tc::tuple<Value>, tc::size(tc::all_values<Key>())>>;\n\t\t\tstatic constexpr baserng c_baserng{};\n\t\t\tstatic constexpr auto c_rngmapkv = tc::transform(c_baserng, tc_fn(tc::dense_map<Key, Value>));\n\n\t\tpublic:\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::begin(c_rngmapkv);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::end(c_rngmapkv);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::constexpr_size<baserng>;\n\t\t\t}\n\n\t\t\tstatic constexpr std::size_t index_of(tc::dense_map<Key, Value> const& mapkv) noexcept {\n\t\t\t\treturn c_baserng.index_of(tc_apply([&](auto... key) { return tc::make_tuple(mapkv[key]...); }, tc::all_constants<Key>));\n\t\t\t}\n#ifdef _MSC_VER\n\t\tprivate:\n\t\t\tstatic auto constexpr _natvis_begin = false; // natvis visualizations cannot call functions even if they are constexpr.\n#endif\n\t\t};\n\t}\n\n\tnamespace less_key_adl {\n\t\ttemplate<typename Key, typename ValueLhs, typename ValueRhs>\n\t\tbool less_key_helper(less_key_tag_t, tc::dense_map<Key, ValueLhs> const& lhs, tc::dense_map<Key, ValueRhs> const& rhs) noexcept {\n\t\t\treturn std::is_lt(tc::lexicographical_compare_3way(lhs, rhs));\n\t\t}\n\t}\n\n\ttemplate<typename DenseMap, typename... DenseMaps> requires\n\t\ttc::instance_or_derived<std::remove_reference_t<DenseMap>, tc::dense_map> &&\n\t\t(... && tc::instance_or_derived<std::remove_reference_t<DenseMaps>, tc::dense_map>)\n\t[[nodiscard]] constexpr auto zip(DenseMap&& dm, DenseMaps&&... dms) noexcept {\n\t\tstatic_assert((tc::indexed_by<std::remove_reference_t<DenseMaps>, typename std::remove_reference_t<DenseMap>::dense_map_key_type> && ...));\n\n\t\treturn tc::make_dense_map<\n\t\t\ttypename std::remove_reference_t<DenseMap>::dense_map_key_type\n\t\t>(tc::func_tag, [&](auto const key) noexcept\n\t\t\t-> tc::tuple<tc::xvalue_decay_t<decltype(std::declval<DenseMap>()[key])>, tc::xvalue_decay_t<decltype(std::declval<DenseMaps>()[key])>...>\n\t\t{\n\t\t\treturn {tc_move_if_owned(dm)[key], tc_move_if_owned(dms)[key]...};\n\t\t});\n\t}\n\n\ttemplate<typename DenseMap> requires tc::instance_or_derived<std::remove_reference_t<DenseMap>, tc::dense_map>\n\t[[nodiscard]] constexpr auto enumerate(DenseMap&& dm) noexcept {\n\t\tusing Key = typename std::remove_reference_t<DenseMap>::dense_map_key_type;\n\t\treturn tc::zip(tc::dense_map<Key, Key>(tc::func_tag, tc::identity()), tc_move_if_owned(dm));\n\t}\n\n\tnamespace dense_map_adl {\n\t\ttemplate<\n\t\t\ttypename NestedDenseMap,\n\t\t\ttypename FirstKey = typename std::remove_reference_t<NestedDenseMap>::dense_map_key_type,\n\t\t\ttypename SecondKey = typename std::remove_reference_t<tc::range_value_t<NestedDenseMap>>::dense_map_key_type\n\t\t>\n\t\tauto join_impl(NestedDenseMap&& dm) noexcept\n\t\t\t-> tc::dense_map<\n\t\t\t\ttc::tuple<FirstKey, SecondKey>,\n\t\t\t\ttc::xvalue_decay_t<decltype(std::declval<NestedDenseMap>()[std::declval<FirstKey>()][std::declval<SecondKey>()])>\n\t\t\t>\n\t\t{\n\t\t\treturn {tc::func_tag, [&](auto const key0, auto const key1) return_decltype_allow_xvalue_noexcept(\n\t\t\t\ttc_move_if_owned(dm)[tc_unwrap_temporary(key0)][tc_unwrap_temporary(key1)]\n\t\t\t)};\n\t\t}\n\t}\n}\n\n#define TC_DENSE_MAP_SUPPORT_1(class_name) \\\n\tTC_DENSE_MAP_SUPPORT_2(class_name, tc::mp_identity)\n\n#define TC_DENSE_MAP_SUPPORT_2(class_name, value_template) \\\n\tclass_name() noexcept(std::is_nothrow_default_constructible<base_>::value) requires std::is_default_constructible<base_>::value \\\n\t\t: base_() {} \\\n\t\\\n\texplicit class_name(boost::container::default_init_t) noexcept(std::is_nothrow_constructible<base_, boost::container::default_init_t>::value) requires std::is_constructible<base_, boost::container::default_init_t>::value \\\n\t\t: base_(boost::container::default_init) {} \\\n\t\\\n\t/* inherit default ctor and constructors with at least two arguments from dense_map*/ \\\n\ttemplate <typename A0, typename A1, typename... Args> \\\n\t\trequires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<base_, A0&&, A1&&, Args&&...>::value) \\\n\tconstexpr class_name(A0&& a0, A1&& a1, Args&& ... args) noexcept(std::is_nothrow_constructible<base_, A0, A1, Args...>::value) \\\n\t\t: base_(tc_move_if_owned(a0), tc_move_if_owned(a1), tc_move_if_owned(args)...) \\\n\t{} \\\n\t\\\n\ttemplate <typename A0, typename A1, typename... Args> \\\n\t\trequires (tc::econstructionEXPLICIT==tc::construction_restrictiveness<base_, A0&&, A1&&, Args&&...>::value) \\\n\tconstexpr explicit class_name(A0&& a0, A1&& a1, Args&& ... args) noexcept(std::is_nothrow_constructible<base_, A0, A1, Args...>::value) \\\n\t\t: base_(tc_move_if_owned(a0), tc_move_if_owned(a1), tc_move_if_owned(args)...) \\\n\t{} \\\n\t\\\n\t/* inherit implicit copy and move constructors from dense_map (only if argument is actual class_name<T>)*/ \\\n\ttemplate <typename T2> \\\n\t\trequires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<base_, typename class_name<T2>::base_ const&>::value) \\\n\tclass_name(class_name<T2> const& other) noexcept(std::is_nothrow_constructible<base_, typename class_name<T2>::base_ const&>::value) \\\n\t\t: base_(tc::base_cast<typename class_name<T2>::base_>(other)) \\\n\t{} \\\n\t\\\n\ttemplate <typename T2> \\\n\t\trequires (tc::econstructionIMPLICIT==tc::construction_restrictiveness<base_, typename class_name<T2>::base_&&>::value) \\\n\tclass_name(class_name<T2>&& other) noexcept(std::is_nothrow_constructible<base_, typename class_name<T2>::base_&&>::value) \\\n\t\t: base_(tc::base_cast<typename class_name<T2>::base_>(tc_move(other))) \\\n\t{} \\\n\t\\\n\t/* inherit implicit and explicit copy and move constructors from dense_map (only if argument is actual dense_map<base_::dense_map_key_type, T>) as explict constructors*/ \\\n\ttemplate <typename K, typename T2> \\\n\t\trequires tc::explicit_castable_from<base_, tc::dense_map<K, T2> const&> \\\n\texplicit class_name(tc::dense_map<K, T2> const& other) noexcept(std::is_nothrow_constructible<base_, tc::dense_map<K, T2> const&>::value) \\\n\t\t: base_(other) \\\n\t{ \\\n\t\tSTATICASSERTSAME(K, typename base_::dense_map_key_type); /*Should use tc::dense_map<dense_map_key_type, T2> for parameter above, but MSVC turns this into dense_map<int, T2>*/ \\\n\t} \\\n\ttemplate <typename K, typename T2> \\\n\t\trequires tc::explicit_castable_from<base_, tc::dense_map<K, T2>&&> \\\n\texplicit class_name(tc::dense_map<K, T2>&& other) noexcept(std::is_nothrow_constructible<base_, tc::dense_map<K, T2>&&>::value) \\\n\t\t: base_(other) \\\n\t{ \\\n\t\tSTATICASSERTSAME(K, typename base_::dense_map_key_type); /*Should use tc::dense_map<dense_map_key_type, T2> for parameter above, but MSVC turns this into dense_map<int, T2>*/ \\\n\t} \\\n\t\\\n\t/* inherit assignment */ \\\n\ttemplate <typename T2> \\\n\t\trequires tc::safely_assignable_from<base_&, typename class_name<T2>::base_ const&> \\\n\tclass_name& operator=(class_name<T2> const& rhs) & noexcept(std::is_nothrow_assignable<base_, typename class_name<T2>::base_ const&>::value) { \\\n\t\ttc::base_cast<base_>(*this)=tc::base_cast<typename class_name<T2>::base_>(rhs); \\\n\t\treturn *this; \\\n\t} \\\n\t\\\n\ttemplate <typename T2> \\\n\t\trequires tc::safely_assignable_from<base_&, typename class_name<T2>::base_&&> \\\n\tclass_name& operator=(class_name<T2>&& rhs) & noexcept(std::is_nothrow_assignable<base_, typename class_name<T2>::base_&&>::value) { \\\n\t\ttc::base_cast<base_>(*this)=tc::base_cast<typename class_name<T2>::base_>(tc_move(rhs)); \\\n\t\treturn *this; \\\n\t} \\\n\t\\\n\t/* inherit transform */ \\\n\tDEFINE_MEMBER_TRANSFORM(class_name, value_template)\n\n#define TC_DENSE_MAP_SUPPORT(...) \\\n\tBOOST_PP_OVERLOAD(TC_DENSE_MAP_SUPPORT_, __VA_ARGS__)(__VA_ARGS__)\n\n#define TC_DENSE_MAP_DEDUCTION_GUIDES_1(template_name) \\\n\tTC_DENSE_MAP_DEDUCTION_GUIDES_2(template_name, tc::mp_identity)\n\n#define TC_DENSE_MAP_DEDUCTION_GUIDES_2(template_name, type_function) \\\n\ttemplate< typename Arg > \\\n\ttemplate_name(tc::fill_tag_t, Arg&&) -> template_name< type_function< tc::decay_t<Arg> > >; \\\n\ttemplate< typename Arg, typename... Args> requires (std::is_same<tc::decay_t<Arg>, tc::decay_t<Args>>::value && ...) \\\n\ttemplate_name(Arg&&, Args&&...) -> template_name<type_function<tc::decay_t<Arg>>>; \\\n\ttemplate< typename Rng > \\\n\ttemplate_name(tc::range_tag_t, Rng&&) -> template_name< type_function< tc::range_value_t<Rng> > >; \\\n\ttemplate< typename DenseMap, typename Func > \\\n\ttemplate_name(tc::transform_tag_t, DenseMap&&, Func&&) -> template_name< type_function< tc::transform_value_t<Func, decltype(std::declval<DenseMap>()[{}])> > >; \\\n\ttemplate< typename Key, typename ValuePri, typename ValueSec > requires std::same_as<tc::decay_t<ValuePri>, tc::decay_t<ValueSec>> && std::same_as<Key, typename template_name<type_function<tc::decay_t<ValuePri>>>::dense_map_key_type> \\\n\ttemplate_name(Key, ValuePri&&, ValueSec&&) -> template_name<type_function<tc::decay_t<ValuePri>>>;\n\n#define TC_DENSE_MAP_DEDUCTION_GUIDES(...) \\\n\tBOOST_PP_OVERLOAD(TC_DENSE_MAP_DEDUCTION_GUIDES_, __VA_ARGS__)(__VA_ARGS__)\n"
  },
  {
    "path": "tc/dense_map.natvis",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?> \n<AutoVisualizer xmlns=\"http://schemas.microsoft.com/vstudio/debugger/natvis/2010\">\n\t<Type Name=\"tc::array_adl::array&lt;*,*&gt;\">\n\t\t<Expand>\n\t\t\t<IndexListItems>\n\t\t\t\t<Size>$T2</Size>\n\t\t\t\t<ValueNode>*m_a[$i]</ValueNode>\n\t\t\t</IndexListItems>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::NQE::dense_map&lt;*,*&gt;\">\n\t\t<DisplayString>dense_map</DisplayString>\n\t\t<Expand>\n\t\t\t<CustomListItems Condition=\"m_a.m_a[0]\" Optional=\"true\">\n\t\t\t\t<Variable Name=\"index\" InitialValue=\"0\" />\n\t\t\t\t<Size>sizeof(m_a)/sizeof(void*)</Size>\n\t\t\t\t<Loop>\n\t\t\t\t\t<Item Name=\"[{($T1)((int)tc::NQ::all_values&lt;$T1&gt;::_natvis_begin + index),en}]\">m_a[index]</Item>\n\t\t\t\t\t<Exec>++index</Exec>\n\t\t\t\t</Loop>\n\t\t\t</CustomListItems>\n\t\t\t<CustomListItems>\n\t\t\t\t<Variable Name=\"index\" InitialValue=\"0\" />\n\t\t\t\t<Size>sizeof(m_a)/sizeof(m_a[0])</Size>\n\t\t\t\t<Loop>\n\t\t\t\t\t<Item Name=\"[{($T1)((int)tc::NQ::all_values&lt;$T1&gt;::_natvis_begin + index),en}]\">m_a[index]</Item>\n\t\t\t\t\t<Exec>++index</Exec>\n\t\t\t\t</Loop>\n\t\t\t</CustomListItems>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::NQ5::interval&lt;*&gt;\">\n\t\t<DisplayString>interval ({m_a[0]}, {m_a[1]})</DisplayString>\n\t\t<Expand>\n\t\t\t<Item Name=\"begin\">m_a[0]</Item>\n\t\t\t<Item Name=\"end\">m_a[1]</Item>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::geo::vec_adl::vec&lt;*&gt;\">\n\t\t<DisplayString>vec ({m_a[0]}, {m_a[1]})</DisplayString>\n\t\t<Expand>\n\t\t\t<Item Name=\"x\">m_a[0]</Item>\n\t\t\t<Item Name=\"y\">m_a[1]</Item>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::geo::NQA::point&lt;*&gt;\">\n\t\t<DisplayString>point ({m_a[0]}, {m_a[1]})</DisplayString>\n\t\t<Expand>\n\t\t\t<Item Name=\"x\">m_a[0]</Item>\n\t\t\t<Item Name=\"y\">m_a[1]</Item>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::geo::rect_adl::rect&lt;*&gt;\">\n\t\t<DisplayString>rect ({m_a[0].m_a[0]}, {m_a[1].m_a[0]})..({m_a[0].m_a[1]}, {m_a[1].m_a[1]}) [{m_a[0].m_a[1] - m_a[0].m_a[0]}x{m_a[1].m_a[1] - m_a[1].m_a[0]}] </DisplayString>\n\t\t<Expand>\n\t\t\t<Item Name=\"left\"> m_a[0].m_a[0] </Item>\n\t\t\t<Item Name=\"top\"> m_a[1].m_a[0] </Item>\n\t\t\t<Item Name=\"right\"> m_a[0].m_a[1] </Item>\n\t\t\t<Item Name=\"bottom\"> m_a[1].m_a[1] </Item>\n\t\t</Expand>\n\t</Type>\n\n\t<Type Name=\"tc::geo::margin_adl::margin&lt;*&gt;\">\n\t\t<DisplayString>margin (left: {m_a[0].m_a[0]}, top: {m_a[1].m_a[0]}, right: {m_a[0].m_a[1]}, bottom: {m_a[1].m_a[1]}) </DisplayString>\n\t\t<Expand>\n\t\t\t<Item Name=\"left\"> m_a[0].m_a[0] </Item>\n\t\t\t<Item Name=\"top\"> m_a[1].m_a[0] </Item>\n\t\t\t<Item Name=\"right\"> m_a[0].m_a[1] </Item>\n\t\t\t<Item Name=\"bottom\"> m_a[1].m_a[1] </Item>\n\t\t</Expand>\n\t</Type>\n</AutoVisualizer>\n"
  },
  {
    "path": "tc/dense_map.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"dense_map.h\"\n#include \"enumset.h\"\n\nstatic_assert(!std::convertible_to<tc::array<int&,10>, tc::array<int&, 9>>);\nstatic_assert(!std::convertible_to<tc::array<int&,9>, tc::array<int&, 10>>);\n\nTC_DEFINE_ENUM(\n\tMyEnum,\n\tmyenum,\n\t(ONE)(TWO)\n)\n\nstruct NonCopyNonMoveable {\n\tNonCopyNonMoveable(NonCopyNonMoveable const&) = delete;\n\tNonCopyNonMoveable(NonCopyNonMoveable&&) = delete;\n\n\tNonCopyNonMoveable(int) {}\n};\n\nUNITTESTDEF(dense_map_with_non_moveable_type) {\n\n\ttc::dense_map<MyEnum, NonCopyNonMoveable> anoncopy(tc::fill_tag, 17);\n\n\tstatic_assert(\n\t\ttc::econstructionFORBIDDEN==tc::construction_restrictiveness<NonCopyNonMoveable, NonCopyNonMoveable&&>::value,\n\t\t\"not forbidden...?\"\n\t);\n\tstatic_assert(\n\t\t!std::is_move_constructible<tc::dense_map<MyEnum, NonCopyNonMoveable>>::value,\n\t\t\"Is  move constructible\"\n\t);\n\n\t[[maybe_unused]] auto const asanoncopy = tc::explicit_cast<std::array<std::array<NonCopyNonMoveable, 2>, 2>>(tc::fill_tag, tc::fill_tag, 17);\n\n\ttc::dense_map<\n\t\tMyEnum,\n\t\ttc::dense_map<MyEnum, NonCopyNonMoveable>\n\t> aanoncopy(tc::fill_tag, tc::fill_tag, 17);\n\n\tstatic_cast<void>(myenumONE);\n\tstatic_cast<void>(myenumTWO);\n\n\t// https://developercommunity.visualstudio.com/t/chained-copy-elision-with-function-resul/1404507\n\t[[maybe_unused]] auto anoncopyFromTransform = tc::make_dense_map<MyEnum>(47, 11).transform([](int const n) {\n\t\treturn NonCopyNonMoveable(n);\n\t});\n}\n\nUNITTESTDEF(test_dense_map_recursive_transform) {\n\tauto const dm = tc::make_dense_map<MyEnum>(5, 10);\n\tauto const dm2 = dm.transform([](auto const n) noexcept { return n * 0.5; });\n\t_ASSERTEQUAL(dm2[myenumONE], 2.5);\n\t_ASSERTEQUAL(dm2[myenumTWO], 5);\n\n\tauto const dm3 = tc::make_dense_map<MyEnum>(tc::make_dense_map<bool>(5, 10), tc::make_dense_map<bool>(3, 6));\n\tauto const dm4 = dm3.transform<1>([](auto const n) noexcept { return n * 0.5; });\n\t_ASSERTEQUAL(dm4[myenumONE][false], 2.5);\n\t_ASSERTEQUAL(dm4[myenumONE][true], 5);\n\t_ASSERTEQUAL(dm4[myenumTWO][false], 1.5);\n\t_ASSERTEQUAL(dm4[myenumTWO][true], 3);\n}\n\nnamespace {\n\tconstexpr tc::dense_map<MyEnum, int> an(tc::func_tag, [n = 0](auto e) mutable noexcept {\n\t\treturn n++ | tc::to_underlying(e) << 4;\n\t});\n\n\tstatic_assert( 0x00 == an[myenumONE] );\n\tstatic_assert( 0x11 == an[myenumTWO] );\n}\n\nUNITTESTDEF(test_dense_map_recursive_func_tag) {\n\ttc::dense_map<MyEnum, tc::dense_map<MyEnum, tc::dense_map<bool, int>>> aaan(tc::func_tag, [n = 0](auto e1, auto e2, bool const b3) mutable noexcept {\n\t\treturn n++ | tc::to_underlying(e1) << 6 | tc::to_underlying(e2) << 5 | tc::to_underlying(b3) << 4;\n\t});\n\n\t_ASSERTEQUAL( aaan[myenumONE][myenumONE][false], 0x00 );\n\t_ASSERTEQUAL( aaan[myenumONE][myenumONE][true], 0x11 );\n\t_ASSERTEQUAL( aaan[myenumONE][myenumTWO][false], 0x22 );\n\t_ASSERTEQUAL( aaan[myenumONE][myenumTWO][true], 0x33 );\n\t_ASSERTEQUAL( aaan[myenumTWO][myenumONE][false], 0x44 );\n\t_ASSERTEQUAL( aaan[myenumTWO][myenumONE][true], 0x55 );\n\t_ASSERTEQUAL( aaan[myenumTWO][myenumTWO][false], 0x66 );\n\t_ASSERTEQUAL( aaan[myenumTWO][myenumTWO][true], 0x77 );\n}\n\nUNITTESTDEF(test_dense_map_enumset_as_key) {\n\tconstexpr tc::dense_map<tc::enumset<MyEnum>, int> dm(1,2,3,4);\n\tstatic_assert(dm[tc::empty_range()] == 1);\n\tstatic_assert(dm[tc::enumset<MyEnum>(myenumONE)] == 2);\n\tstatic_assert(dm[tc::enumset<MyEnum>(myenumTWO)] == 3);\n\tstatic_assert(dm[myenumONE | myenumTWO] == 4);\n\t_ASSERT(tc::equal(dm, tc::iota(1, 5)));\n}\n\nUNITTESTDEF(test_dense_map_transform_move) {\n\tauto const dm = tc::dense_map<MyEnum, int>(1,2).transform([](int&& n) {\n\t\treturn n;\n\t});\n\t_ASSERT(tc::equal(dm, tc::iota(1, 3)));\n}\n\nUNITTESTDEF(test_make_array_from_range) {\n\tconstexpr int an0[] = {1, 2};\n\tconstexpr auto an1 = tc::make_array(an0);\n\tstatic_assert(tc::equal(an0, an1));\n\tconstexpr int an2[] ={1, 2, 3, 4, 5};\n\tconstexpr auto an3 = tc::make_array(an2);\n\tstatic_assert(tc::equal(an2, an3));\n\tconstexpr int an4[] ={1};\n\tconstexpr auto an5 = tc::make_array(an4);\n\tstatic_assert(tc::equal(an4, an5));\n\n\tGCC_WORKAROUND_STATIC_ASSERT(tc::equal(an0, tc::make_array<2>(tc::make_generator_range(an0))));\n}\n\nUNITTESTDEF(test_dense_map_with_ordering_key) {\n\tconstexpr tc::dense_map<std::weak_ordering, int> dm1(1,2,3);\n\tstatic_assert(dm1[std::weak_ordering::less] == 1);\n\tstatic_assert(dm1[std::weak_ordering::equivalent] == 2);\n\tstatic_assert(dm1[std::weak_ordering::equivalent] == 2);\n\tstatic_assert(dm1[std::weak_ordering::greater] == 3);\n\tstatic_assert(tc::equal(dm1, tc::iota(1, 4)));\n\n\tconstexpr tc::dense_map<std::weak_ordering, int> dm2(1,2,3);\n\tstatic_assert(dm2[std::weak_ordering::less] == 1);\n\tstatic_assert(dm2[std::weak_ordering::equivalent] == 2);\n\tstatic_assert(dm2[std::weak_ordering::greater] == 3);\n\tstatic_assert(tc::equal(dm2, tc::iota(1, 4)));\n\n\tconstexpr tc::dense_map<std::partial_ordering, int> dm3(1,2,3,4);\n\tstatic_assert(dm3[std::partial_ordering::less] == 1);\n\tstatic_assert(dm3[std::partial_ordering::equivalent] == 2);\n\tstatic_assert(dm3[std::partial_ordering::greater] == 3);\n\tstatic_assert(dm3[std::partial_ordering::unordered] == 4);\n\tstatic_assert(tc::equal(dm3, tc::iota(1, 5)));\n}\n\nUNITTESTDEF(dense_map_tuple) {\n\tusing T = tc::tuple<bool, MyEnum>;\n\ttc_static_auto_constexpr(dm, tc::make_dense_map<T>(1,2,3,4));\n\t_ASSERTEQUAL((dm[T{false, myenumONE}]), 1);\n\t_ASSERTEQUAL((dm[T{false, myenumTWO}]), 2);\n\t_ASSERTEQUAL((dm[T{true, myenumONE}]), 3);\n\t_ASSERTEQUAL((dm[T{true, myenumTWO}]), 4);\n\tstatic_assert(tc::equal(dm, tc::iota(1, 5)));\n\t_ASSERT(tc::equal(tc::all_values<T>(), tc::make_array(tc::aggregate_tag, T{false, myenumONE}, T{false, myenumTWO}, T{true, myenumONE}, T{true, myenumTWO})));\n\n\tSTATICASSERTSAME(decltype(tc::all_constants<MyEnum>), TC_FWD(tc::tuple<tc::constant<myenumONE>, tc::constant<myenumTWO>> const));\n\n#if defined(__clang__) || defined(_MSC_VER) // Fixed in GCC 13: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92505\n\tSTATICASSERTSAME(decltype(tc::all_constants<tc::tuple<MyEnum, MyEnum>>), TC_FWD(tc::tuple<\n\t\ttc::constant<tc::make_tuple(myenumONE, myenumONE)>,\n\t\ttc::constant<tc::make_tuple(myenumONE, myenumTWO)>,\n\t\ttc::constant<tc::make_tuple(myenumTWO, myenumONE)>,\n\t\ttc::constant<tc::make_tuple(myenumTWO, myenumTWO)>\n\t> const));\n#endif\n}\n\nUNITTESTDEF(dense_map_dense_map) {\n\ttc::dense_map<\n\t\ttc::dense_map<MyEnum, MyEnum>,\n\t\ttc::dense_map<MyEnum, MyEnum>\n\t> dmdm(tc::func_tag, [](auto dm) noexcept {\n\t\ttc::reverse_inplace(dm);\n\t\treturn dm;\n\t});\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumONE, myenumONE}][myenumONE]), myenumONE);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumONE, myenumONE}][myenumTWO]), myenumONE);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumONE, myenumTWO}][myenumONE]), myenumTWO);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumONE, myenumTWO}][myenumTWO]), myenumONE);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumTWO, myenumONE}][myenumONE]), myenumONE);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumTWO, myenumONE}][myenumTWO]), myenumTWO);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumTWO, myenumTWO}][myenumONE]), myenumTWO);\n\t_ASSERTEQUAL(TC_FWD(dmdm[{myenumTWO, myenumTWO}][myenumTWO]), myenumTWO);\n}\n"
  },
  {
    "path": "tc/enumset.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/accessors.h\"\n#include \"base/bitfield.h\"\n#include \"base/enum.h\"\n#include \"base/integer.h\"\n#include \"base/tag_type.h\"\n#include \"algorithm/binary_operators.h\"\n#include \"algorithm/compare.h\"\n#include \"algorithm/element.h\"\n#include \"algorithm/equal.h\"\n#include \"algorithm/size.h\"\n#include \"range/iota_range.h\"\n#include \"range/transform.h\"\n#include \"range/empty_range.h\"\n#include \"interval_types.h\"\n\nnamespace tc {\n\tDEFINE_TAG_TYPE(enumset_from_underlying_tag)\n\tDEFINE_TAG_TYPE(union_tag)\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename EnumSuper, typename EnumSub> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr tc::enumset<EnumSuper> explicit_convert_impl(adl_tag_t, std::type_identity<tc::enumset<EnumSuper>>, tc::enumset<EnumSub> const setesub) noexcept;\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr tc::enumset<EnumSub> explicit_convert_impl(adl_tag_t, std::type_identity<tc::enumset<EnumSub>>, tc::enumset<EnumSuper> const setesuper) noexcept;\n\t}\n\n\tnamespace enumset_adl {\n#ifdef TC_PRIVATE\n\t\ttemplate< typename Enum >\n\t\tstruct enumset;\n\n\t\ttemplate<typename Enum>\n\t\tvoid LoadType_impl(enumset<Enum>& sete, CXmlReader& loadhandler) THROW(ExLoadFail);\n#endif\n\n\t\ttemplate< typename Enum >\n\t\tstruct enumset /*final*/\n\t\t\t: tc::setlike<tc::index_range_adaptor<\n\t\t\t\tenumset<Enum>,\n\t\t\t\ttc::all_values<Enum>,\n\t\t\t\ttc::index_range_adaptor_flags::inherit_dereference|tc::index_range_adaptor_flags::inherit_end\n\t\t\t>>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = enumset;\n\t\t\tstatic constexpr tc::all_values<Enum> c_rnge{};\n\t\tpublic:\n\t\t\tusing typename this_type::index_range_adaptor::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex = tc::has_stashing_index<tc::all_values<Enum>>::value;\n\n\t\t\tfriend tc::counting_iterator<enumset<Enum>>;\n\t\t\ttemplate< typename OtherEnum > friend struct enumset;\n\n\t\t\ttemplate<typename EnumSuper, typename EnumSub> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\t\tfriend constexpr tc::enumset<EnumSuper> tc::explicit_convert_adl::explicit_convert_impl(tc::explicit_convert_adl::adl_tag_t, std::type_identity<tc::enumset<EnumSuper>>, tc::enumset<EnumSub> const setesub) noexcept;\n\n\t\t\ttemplate<typename EnumSub, typename EnumSuper> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\t\tfriend constexpr tc::enumset<EnumSub> tc::explicit_convert_adl::explicit_convert_impl(tc::explicit_convert_adl::adl_tag_t, std::type_identity<tc::enumset<EnumSub>>, tc::enumset<EnumSuper> const setesuper) noexcept;\n\n#ifdef TC_PRIVATE\n\t\t\tvoid DoSave(CSaveHandler& savehandler) const& MAYTHROW;\n\t\t\tfriend void LoadType_impl<>(enumset& sete, CXmlReader& loadhandler) THROW(ExLoadFail);\n#endif\n\n\t\t\tusing bitset_type = tc::uint_least_t<tc::size(c_rnge)>;\n\t\t\tPUBLIC_MEMBER_PUBLIC_ACCESSOR(bitset_type, m_bitset); // Necessarily public so enumset can be used as a template parameter.\n\t\tprivate:\n\n\t\t\ttemplate<typename N>\n\t\t\tstatic constexpr bitset_type lsb_mask(N const nDigits) noexcept {\n\t\t\t\tif (0 == nDigits) {\n\t\t\t\t\treturn 0;\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERTE(0 < nDigits);\n\t\t\t\t\treturn static_cast<bitset_type>(-1)>>(std::numeric_limits<bitset_type>::digits - nDigits);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tstatic constexpr tc_index make_index(int nIndex) noexcept {\n\t\t\t\treturn tc_modified(tc::begin_index(c_rnge), tc::advance_index(c_rnge, _, tc::explicit_cast<typename boost::range_size<tc::all_values<Enum>>::type>(nIndex)));\n\t\t\t}\n\n\t\tpublic:\n\t\t\tstatic constexpr bitset_type mask() noexcept {\n\t\t\t\treturn lsb_mask(tc::size(c_rnge));\n\t\t\t}\n\t\t\t\n\t\t\tconstexpr enumset() noexcept : m_bitset(0) {} // makes all bits 0\n\t\t\tconstexpr enumset(tc::empty_range) noexcept: enumset() {}\n\t\t\tconstexpr enumset(tc::all_values<Enum>) noexcept : m_bitset(mask()) {}\n\t\t\ttemplate<typename U>\n\t\t\tconstexpr enumset(enumset_from_underlying_tag_t, U bitset) noexcept : tc_member_init( m_bitset, bitset ) {\n\t\t\t\t_ASSERTE( !(m_bitset&~mask()) );\n\t\t\t}\n\t\t\tconstexpr enumset(Enum e) noexcept : enumset(enumset_from_underlying_tag, tc::explicit_cast<bitset_type>(1) << c_rnge.index_of(e)) {}\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr enumset(tc::interval<SFINAE_TYPE(Enum)> const& intvle) noexcept\n\t\t\t\t: enumset(enumset_from_underlying_tag,\n\t\t\t\t\t(tc::explicit_cast<tc::uint_least_t<tc::size(c_rnge) + 1>>(1) << c_rnge.index_of(intvle[tc::hi]))\n\t\t\t\t\t- (tc::explicit_cast<tc::uint_least_t<tc::size(c_rnge) + 1>>(1) << c_rnge.index_of(intvle[tc::lo]))\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t_ASSERTE( !intvle.empty_inclusive() );\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tconstexpr enumset(tc::union_tag_t, Rng&& rng) MAYTHROW : m_bitset(0)\n\t\t\t{\n\t\t\t\ttc::for_each(tc_move_if_owned(rng), [&](enumset const& sete) noexcept { // MAYTHROW\n\t\t\t\t\t*this |= sete;\n\t\t\t\t});\n\t\t\t}\n\t\t\ttemplate<typename Func>\n\t\t\tconstexpr enumset(tc::func_tag_t, Func func) MAYTHROW : m_bitset(0) {\n\t\t\t\t// Could be implemented in terms of union_tag constructor and filter, but it wasn't to avoid dependency on filter.\n\t\t\t\ttc::for_each(c_rnge, [&](auto e) noexcept {\n\t\t\t\t\tif (tc::explicit_cast<bool>(func(tc::as_const(e)))) { // MAYTHROW\n\t\t\t\t\t\t*this |= e;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tconstexpr void bitwise_not() & noexcept {\n\t\t\t\tm_bitset^=mask();\n\t\t\t}\n\t\t\t// operators\n\t\t\tconstexpr enumset operator~() const& noexcept {\n\t\t\t\tenumset copy=*this;\n\t\t\t\tcopy.bitwise_not();\n\t\t\t\treturn copy;\n\t\t\t}\n\t\t\tconstexpr enumset& operator&=( enumset const& sete ) & noexcept {\n\t\t\t\tm_bitset&=sete.m_bitset;\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr enumset& operator|=( enumset const& sete ) & noexcept {\n\t\t\t\tm_bitset|=sete.m_bitset;\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr enumset& operator^=( enumset const& sete ) & noexcept {\n\t\t\t\tm_bitset^=sete.m_bitset;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr enumset& operator-=( enumset const& sete ) & noexcept {\n\t\t\t\tm_bitset&=~sete.m_bitset;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tfriend constexpr bool operator==( enumset const& lhs, enumset const& rhs ) noexcept {\n\t\t\t\treturn EQUAL_MEMBERS(m_bitset);\n\t\t\t}\n\t\t\tfriend constexpr bool operator==( enumset const& lhs, Enum rhs ) noexcept {\n\t\t\t\treturn lhs==enumset(rhs);\n\t\t\t}\n\t\t\tconstexpr bool is_singleton() const& noexcept {\n\t\t\t\t//return std::has_single_bit(m_bitset);\n\t\t\t\treturn 0!=m_bitset && 0==(m_bitset & (m_bitset - 1));\n\t\t\t}\n\t\n\t\t\tconstexpr std::size_t size() const& noexcept {\n\t\t\t\treturn std::popcount(m_bitset);\n\t\t\t}\n\t\t\tconstexpr explicit operator bool() const& noexcept {\n\t\t\t\treturn 0!=m_bitset;\n\t\t\t}\n\n\t\t\tstatic constexpr enumset none() noexcept {\n\t\t\t\treturn enumset<Enum>();\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn 0 == m_bitset ? this->end_index() : make_index(tc::index_of_least_significant_bit(m_bitset));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERT( idx != this->end_index() );\n\t\t\t\tbitset_type const bitsetRemaining = m_bitset & ~lsb_mask(tc::distance_to_index(c_rnge, tc::begin_index(c_rnge), idx) + 1);\n\t\t\t\tidx = 0 == bitsetRemaining ? this->end_index() : make_index(tc::index_of_least_significant_bit(bitsetRemaining));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERT( idx != this->begin_index() );\n\t\t\t\tidx = make_index(tc::index_of_most_significant_bit(tc::explicit_cast<unsigned long>(m_bitset & lsb_mask(tc::distance_to_index(c_rnge, tc::begin_index(c_rnge), idx)))));\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Enum> enumset(Enum) -> enumset<Enum>;\n\t\ttemplate<typename Enum> enumset(all_values<Enum>) -> enumset<Enum>;\n\t\ttemplate<typename Enum> enumset(interval<Enum>) -> enumset<Enum>;\n\t} // enumset_adl\n\tusing enumset_adl::enumset;\n\n\ttemplate<tc::actual_integer_like NSub, tc::actual_integer_like NSuper>\n\t[[nodiscard]] constexpr bool is_subset(NSub const nSub, NSuper const nSuper) noexcept {\n\t\treturn !(tc::as_unsigned(nSub) & ~tc::as_unsigned(nSuper));\n\t}\n\n\ttemplate<typename Enum>\n\t[[nodiscard]] constexpr bool is_subset(tc::enumset<Enum> const& seteSub, tc::enumset<Enum> const& seteSuper) noexcept {\n\t\treturn !(seteSub & ~seteSuper);\n\t}\n\n\ttemplate<typename Enum>\n\t[[nodiscard]] constexpr bool is_subset(Enum const eSub, tc::enumset<Enum> const& seteSuper) noexcept {\n\t\treturn tc::is_subset(tc::enumset<Enum>(eSub), seteSuper);\n\t}\n\n\ttemplate<typename Enum>\n\t[[nodiscard]] constexpr bool is_subset(tc::enumset<Enum> const& seteSub, Enum const eSuper) noexcept {\n\t\treturn tc::is_subset(seteSub, tc::enumset<Enum>(eSuper));\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Enum>\n\t\tstruct [[nodiscard]] all_values<tc::enumset<Enum>> final {\n\t\tpublic:\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\tconstexpr auto size_all_values_enum = tc::constexpr_size<tc::all_values<Enum>>();\n\t\t\t\tstatic_assert(size_all_values_enum < std::size_t(std::numeric_limits<std::size_t>::digits));\n\t\t\t\treturn tc::least_uint_constant<std::size_t(1) << size_all_values_enum>{};\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstatic auto constexpr c_rngsete = tc::transform(tc::iota_range_constant<static_cast<decltype(size().value)>(0), size().value>(), [](auto const n) noexcept {\n\t\t\t\treturn tc::enumset<Enum>(tc::enumset_from_underlying_tag, n);\n\t\t\t});\n\n\t\tpublic:\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::begin(c_rngsete);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::end(c_rngsete);\n\t\t\t}\n\n\t\t\tstatic constexpr std::size_t index_of(tc::enumset<Enum> const& sete) noexcept {\n\t\t\t\treturn sete.m_bitset_();\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename EnumSuper, typename EnumSub> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr tc::enumset<EnumSuper> explicit_convert_impl(adl_tag_t, std::type_identity<tc::enumset<EnumSuper>>, tc::enumset<EnumSub> const setesub) noexcept {\n\t\t\treturn tc::enumset<EnumSuper>(\n\t\t\t\ttc::enumset_from_underlying_tag,\n\t\t\t\ttc::explicit_cast<typename tc::enumset<EnumSuper>::bitset_type>(setesub.m_bitset_()) << tc::all_values<EnumSuper>::index_of(tc::explicit_cast<EnumSuper>(tc::contiguous_enum<EnumSub>::begin()))\n\t\t\t);\n\t\t}\n\n\t\ttemplate<typename EnumSub, typename EnumSuper> requires tc::is_sub_enum_of<EnumSub, EnumSuper>::value\n\t\tconstexpr tc::enumset<EnumSub> explicit_convert_impl(adl_tag_t, std::type_identity<tc::enumset<EnumSub>>, tc::enumset<EnumSuper> const setesuper) noexcept {\n\t\t\t_ASSERTE(tc::is_subset(setesuper, tc::explicit_cast<tc::enumset<EnumSuper>>(tc::enumset(tc::all_values<EnumSub>()))));\n\t\t\treturn tc::enumset<EnumSub>(\n\t\t\t\ttc::enumset_from_underlying_tag,\n\t\t\t\tsetesuper.m_bitset_() >> tc::all_values<EnumSuper>::index_of(tc::explicit_cast<EnumSuper>(tc::contiguous_enum<EnumSub>::begin()))\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/interval.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/type_traits.h\"\n#include \"base/tag_type.h\"\n#include \"base/integer.h\"\n#include \"algorithm/binary_operators.h\"\n#include \"algorithm/round.h\"\n#include \"algorithm/algorithm.h\"\n#include \"container/container.h\" \n#include \"range/iota_range.h\"\n#include \"interval_types.h\"\n#include \"dense_map.h\"\n\n#ifdef TC_PRIVATE\n#include \"Library/Persistence/PersistentType.h\"\n#include \"Library/Persistence/PersistentStruct.h\"\n#endif\n\n#include <chrono>\n#include <set>\n\nnamespace tc {\n\ttemplate<typename T>\n\tconstexpr tc::interval<T> all_values_interval;\n\n\t// It is expected that the semantic of comparisons between objects is not influenced by cvref/volatile qualifiers.\n\ttemplate<typename T> requires (!tc::decayed<T>)\n\tconstexpr tc::interval<tc::decay_t<T>> all_values_interval<T> = all_values_interval<tc::decay_t<T>>;\n\n\ttemplate<typename T> requires tc::contiguous_enum<T>::value\n\tconstexpr tc::interval<T> all_values_interval<T> = tc::interval<T>(tc::contiguous_enum<T>::begin(), tc::contiguous_enum<T>::end());\n\n\ttemplate<std::integral T>\n\tconstexpr tc::interval<T> all_values_interval<T> = tc::interval<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());\n\n\ttemplate<std::floating_point T>\n\tconstexpr tc::interval<T> all_values_interval<T> = tc::interval<T>(-std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());\n\n\ttemplate<typename Clock, typename Duration>\n\tconstexpr tc::interval<std::chrono::time_point<Clock, Duration>> all_values_interval<std::chrono::time_point<Clock, Duration>> = tc::interval<std::chrono::time_point<Clock, Duration>>(std::chrono::time_point<Clock, Duration>::min(), std::chrono::time_point<Clock,Duration>::max());\n\n\tnamespace zero_adl {\n\t\tDEFINE_ADL_TAG_TYPE(zero)\n\n\t\ttemplate<tc::actual_arithmetic T>\n\t\tconstexpr T explicit_convert_impl(std::type_identity<T>, zero_t) noexcept {\n\t\t\treturn 0;\n\t\t}\n\n\t\ttemplate<tc::instance<std::chrono::duration> Duration>\n\t\tconstexpr Duration explicit_convert_impl(std::type_identity<Duration>, zero_t) noexcept {\n\t\t\treturn Duration::zero();\n\t\t}\n\t}\n\tusing zero_adl::zero_t;\n\tusing zero_adl::zero;\n\n#ifdef TC_PRIVATE\n\ttemplate< typename T >\n\tconcept chrono_like =\n\t\ttc::instance<T, std::chrono::time_point> ||\n\t\ttc::instance<T, std::chrono::duration>;\n\n\ttemplate< typename T >\n\tconcept floating_point_or_chrono_like =\n\t\ttc::floating_point_like<T> ||\n\t\tchrono_like<T>;\n#endif\n\n\tnamespace no_adl {\n\t\tstruct use_set_impl_tag_t;\n\t\tstruct use_vector_impl_tag_t;\n\t}\n\tusing no_adl::use_set_impl_tag_t;\n\tusing no_adl::use_vector_impl_tag_t;\n\n\tnamespace interval_set_adl {\n\t\ttemplate<typename T, typename TInterval=tc::interval<T>, typename SetOrVectorImpl=use_set_impl_tag_t> struct interval_set;\n\t}\n\tusing interval_set_adl::interval_set;\n\n\tnamespace no_adl {\n\t\ttemplate< typename T >\n\t\tstruct difference {\n\t\t\tusing type = decltype(std::declval<T>() - std::declval<T>());\n\t\t};\n\t}\n\tTC_HAS_EXPR(minus, (T), std::declval<T>()-std::declval<T>())\n\n\t// TODO: consider using \"nextup\" and \"nextdown\" which are single argument C functions\n\t// (but only for floats) standardized in IEEE 754-2008 revision and proposed in C TS 18661-1,2\n\n\ttemplate<typename T>\n\tconstexpr void nextafter_inplace(T& t) noexcept {\n\t\tif constexpr( std::floating_point<T> ) {\n\t\t\tt = std::nextafter(t, std::numeric_limits<T>::infinity());\n\t\t} else {\n\t\t\t++t;\n\t\t}\n\t}\n\n\ttemplate<typename T>\n\tconstexpr void nextbefore_inplace(T& t) noexcept {\n\t\tif constexpr( std::floating_point<T> ) {\n\t\t\tt = std::nextafter(t, -std::numeric_limits<T>::infinity());\n\t\t} else {\n\t\t\t--t;\n\t\t}\n\t} \n\n\ttemplate<typename T1, typename T2>\n\t[[nodiscard]] constexpr interval<tc::common_type_t<T1, T2>> make_interval_sort(T1&& t1, T2&& t2) noexcept;\n\n\tnamespace interval_detail::no_adl {\n\t\tstruct swap_if_negative_scalar final : tc::no_prepost_scalar_operation {\n\t\t\ttemplate<typename T, typename Scalar>\n\t\t\tstatic void post(tc::interval<T>& intvl, Scalar const& scalar) {\n\t\t\t\tif( scalar < tc::explicit_cast<Scalar>(tc::zero) ) intvl.swap();\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace interval_adl {\n\t\ttemplate<typename T>\n\t\tstruct interval\n\t\t\t: tc::dense_map<tc::lohi, T>\n\t\t\t,\n#ifdef TC_PRIVATE\n\t\t\t  PersistentTypeT<\n#endif\n\t\t\t\ttc::scalar_multipliable<\n\t\t\t\t\ttc::scalar_dividable<\n\t\t\t\t\t\ttc::scalar_addable<tc::scalar_subtractable<>>,\n\t\t\t\t\t\t/*nTransformDepth*/0,\n\t\t\t\t\t\tinterval_detail::no_adl::swap_if_negative_scalar\n\t\t\t\t\t>,\n\t\t\t\t\t/*nTransformDepth*/0,\n\t\t\t\t\tinterval_detail::no_adl::swap_if_negative_scalar\n\t\t\t\t>\n#ifdef TC_PRIVATE\n\t\t\t> \n#endif\n\t\t{\n\t\tprivate:\n\t\t\tusing newT = tc::decay_t<T>;\n\t\t\tusing difference_type = typename std::conditional_t<\n\t\t\t\ttc::has_minus<T>\n\t\t\t\t,/*?*/tc::no_adl::difference<T const&> //Evaluation of ::type must be delayed, because it only compiles if the predicate is true\n\t\t\t\t,/*:*/boost::mpl::identity<void>\n\t\t\t>::type;\n\n\t\tpublic:\n\t\t\tusing base_ = typename interval::dense_map;\n\n\t\t\tTC_DENSE_MAP_SUPPORT(interval)\n\n\t\t\ttemplate< typename Func > \n\t\t\t[[nodiscard]] constexpr auto transform_sort(Func func) const& MAYTHROW {\n\t\t\t\t// _ASSERT( !((*this)[tc::hi] < (*this)[tc::lo]) ); // see comments for AssertSameOrder(...) below\n\t\t\t\treturn tc::make_interval_sort( func((*this)[tc::lo]), func((*this)[tc::hi]) );\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate< typename TPos, typename TExtent >\n\t\t\tstatic constexpr interval<T> from_extent_impl( TPos&& pos, TExtent&& extent, tc::lohi const lohi ) noexcept {\n\t\t\t\tswitch_no_default(lohi) {\n\t\t\t\t\tcase tc::lo: {\n\t\t\t\t\t\tauto end = pos + tc_move_if_owned(extent);\n\t\t\t\t\t\tstatic_assert(tc::safely_convertible_to<decltype(end)&&, T>, \"Cannot initialize an interval with an unsafe conversion\");\n\t\t\t\t\t\treturn interval<T>(tc_move_if_owned(pos), tc_move(end));\n\t\t\t\t\t}\n\t\t\t\t\tcase tc::hi: {\n\t\t\t\t\t\tauto begin = pos - tc_move_if_owned(extent);\n\t\t\t\t\t\tstatic_assert(tc::safely_convertible_to<decltype(begin)&&, T>, \"Cannot initialize an interval with an unsafe conversion\");\n\t\t\t\t\t\treturn interval<T>(tc_move(begin), tc_move_if_owned(pos));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate< bool bGeneralized, typename TPos, typename TExtent >\n\t\t\tstatic constexpr interval<T> centered_interval_impl(TPos&& pos, TExtent&& extent) noexcept {\n\t\t\t\tSTATICASSERTSAME(tc::decay_t<TExtent>, difference_type, \"Ambiguous interpretation: convert the base position or the provided extent, so that their types match\");\n\t\t\t\t// make use of the precondition center(a + c, b + c) = c + center(a, b)\n\t\t\t\tauto begin = tc_move_if_owned(pos) - tc::internal_lower_half<bGeneralized>(extent);\n\t\t\t\tauto end = begin + tc_move_if_owned(extent);\n\t\t\t\tstatic_assert( tc::safely_convertible_to<decltype(begin)&&, T> );\n\t\t\t\tstatic_assert( tc::safely_convertible_to<decltype(end)&&, T> );\n\t\t\t\treturn interval<T>( tc_move(begin), tc_move(end) );\n\t\t\t}\n\n\t\tpublic:\n\t\t\ttemplate< typename TPos, typename TExtent >\n\t\t\t[[nodiscard]] static constexpr interval<T> from_extent( TPos&& pos, TExtent&& extent, tc::lohi const lohi ) noexcept\n\t\t\t{\n\t\t\t\treturn from_extent_impl(tc_move_if_owned(pos), tc_move_if_owned(extent), lohi);\n\t\t\t}\n\n\t\t\ttemplate< bool bGeneralized, typename TPos, typename TExtent >\n\t\t\t[[nodiscard]] static constexpr interval<T> centered_interval(TPos&& pos, TExtent&& extent) noexcept \n\t\t\t{\n\t\t\t\treturn centered_interval_impl<bGeneralized>(tc_move_if_owned(pos), tc_move_if_owned(extent));\n\t\t\t}\n\n\t\t\ttemplate< typename TPos, typename TExtent >\n\t\t\t[[nodiscard]] static constexpr interval<T> from_extent( TPos&& pos, TExtent&& extent, EAlign const ealign ) noexcept\n\t\t\t{\n\t\t\t\tswitch_no_default(ealign) {\n\t\t\t\t\tcase ealignLOW: {\n\t\t\t\t\t\treturn from_extent_impl(tc_move_if_owned(pos), tc_move_if_owned(extent), tc::lo);\n\t\t\t\t\t}\n\t\t\t\t\tcase ealignHIGH: {\n\t\t\t\t\t\treturn from_extent_impl(tc_move_if_owned(pos), tc_move_if_owned(extent), tc::hi);\n\t\t\t\t\t}\n\t\t\t\t\tcase ealignCENTER: {\n\t\t\t\t\t\treturn centered_interval_impl</*bGeneralized*/false>(tc_move_if_owned(pos), tc_move_if_owned(extent));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate< typename TExtent >\n\t\t\tconstexpr void expand(TExtent&& extent) & noexcept {\n\t\t\t\t(*this)[tc::lo] -= extent;\n\t\t\t\t(*this)[tc::hi] += tc_move_if_owned(extent);\n\t\t\t}\n\n\t\t\ttemplate< typename TExtent >\n\t\t\tconstexpr void expand_to(TExtent&& extent) {\n\t\t\t\t*this = interval<newT>::template centered_interval</*bGeneralized*/true>(tc::internal_midpoint</*bGeneralized*/true>((*this)[tc::lo], (*this)[tc::hi]), tc_move_if_owned(extent));\n\t\t\t}\n\n\t\t\tconstexpr void expand_to_integer() & noexcept {\n\t\t\t\tstatic_assert(std::floating_point<T>);\n\t\t\t\t// Rounding an empty interval may make it non-empty, which might not be intended.\n\t\t\t\t_ASSERTE(!empty());\n\t\t\t\t(*this)[tc::lo] = tc::floor((*this)[tc::lo]);\n\t\t\t\t(*this)[tc::hi] = std::ceil((*this)[tc::hi]);\n\t\t\t}\n\n\t\t\ttemplate <typename TTarget>\n\t\t\t[[nodiscard]] interval<TTarget> expanding_cast() const& noexcept;\n\n\t\t\ttemplate <typename TTarget>\n\t\t\t[[nodiscard]] interval<TTarget> expanding_cast_inclusive() const& noexcept;\n\n\t\t\ttemplate< typename TExtent >\n\t\t\tconstexpr void expand_length(TExtent&& extent) & noexcept {\n\t\t\t\texpand_to(length() + tc_move_if_owned(extent));\n\t\t\t}\n\n\t\t\ttemplate< typename TExtent >\n\t\t\tconstexpr void ensure_length(TExtent&& extent) & noexcept {\n\t\t\t\tif (length() < extent) {\n\t\t\t\t\texpand_to(tc_move_if_owned(extent));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconstexpr void swap() & noexcept {\n\t\t\t\ttc::swap((*this)[tc::lo], (*this)[tc::hi]);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr bool empty() const& noexcept {\n\t\t\t\treturn !( (*this)[tc::lo] < (*this)[tc::hi] );\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr bool empty_inclusive() const& noexcept {\n\t\t\t\treturn (*this)[tc::hi] < (*this)[tc::lo];\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr difference_type distance(T const& t) const& noexcept {\n\t\t\t\t_ASSERTE( !empty() );\n\t\t\t\tif( t < (*this)[tc::lo] ) {\n\t\t\t\t\treturn (*this)[tc::lo] - t;\n\t\t\t\t} else if( (*this)[tc::hi] < t ) {\n\t\t\t\t\treturn tc_modified(t - (*this)[tc::hi], tc::nextafter_inplace(_));\n\t\t\t\t} else {\n\t\t\t\t\ttc_return_cast(tc::zero);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr difference_type distance_inclusive(T const& t) const& noexcept {\n\t\t\t\t_ASSERTE( !empty_inclusive() );\n\t\t\t\tif( t < (*this)[tc::lo] ) {\n\t\t\t\t\treturn (*this)[tc::lo] - t;\n\t\t\t\t} else if( (*this)[tc::hi] < t ) {\n\t\t\t\t\treturn t - (*this)[tc::hi];\n\t\t\t\t} else {\n\t\t\t\t\ttc_return_cast(tc::zero);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr difference_type distance_inclusive(interval const& intvl) const& noexcept {\n\t\t\t\t_ASSERTE( !empty_inclusive() );\n\t\t\t\t_ASSERTE( !intvl.empty_inclusive() );\n\t\t\t\tif( intvl[tc::hi] < (*this)[tc::lo] ) {\n\t\t\t\t\treturn (*this)[tc::lo] - intvl[tc::hi];\n\t\t\t\t} else if( (*this)[tc::hi] < intvl[tc::lo] ) {\n\t\t\t\t\treturn intvl[tc::lo] - (*this)[tc::hi];\n\t\t\t\t} else {\n\t\t\t\t\ttc_return_cast(tc::zero);\n\t\t\t\t}\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<typename Self, typename S, typename R = tc::common_reference_t<tc::apply_cvref_t<T, Self&&>, S&&>>\n\t\t\tstatic R clamp_inclusive_(Self&& self, S&& s) noexcept {\n\t\t\t\t_ASSERT( !self.empty_inclusive() );\n\t\t\t\tif( s<self[tc::lo] ) {\n\t\t\t\t\treturn static_cast<R>(tc_move_if_owned(self)[tc::lo]); // static_cast to convert from const& to const&&.\n\t\t\t\t} else if( self[tc::hi]<s ) {\n\t\t\t\t\treturn static_cast<R>(tc_move_if_owned(self)[tc::hi]);\n\t\t\t\t} else {\n\t\t\t\t\treturn static_cast<R>(tc_move_if_owned(s));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename Self, typename S>\n\t\t\tstatic tc::apply_cvref_t<T, Self&&> closest_boundary_(Self&& self, S&& s) noexcept {\n\t\t\t\t_ASSERTE( !self.empty_inclusive() );\n\t\t\t\treturn tc_move_if_owned(self)[tc::not_if(s < self.midpoint(), tc::hi)];\n\t\t\t}\n\n\t\t\ttemplate<typename Self, typename S>\n\t\t\tstatic tc::apply_cvref_t<T, Self&&> farthest_boundary_(Self&& self, S&& s) noexcept {\n\t\t\t\t_ASSERTE( !self.empty_inclusive() );\n\t\t\t\treturn tc_move_if_owned(self)[tc::not_if(s < self.midpoint(), tc::lo)];\n\t\t\t}\n\n\t\t\ttemplate<typename Self, typename S>\n\t\t\tstatic tc::apply_cvref_t<T, Self&&> opposite_boundary_(Self&& self, S&& s) noexcept {\n\t\t\t\treturn tc_move_if_owned(self)[tc::not_if(self[tc::lo] == s || (_ASSERTE(self[tc::hi] == s), false), tc::lo)];\n\t\t\t}\n\n\t\tpublic:\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(clamp_inclusive)\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(closest_boundary)\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(farthest_boundary)\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(opposite_boundary)\n\n\t\t\ttemplate<typename T2>\n\t\t\t[[nodiscard]] constexpr tc::common_type_t<T, T2&&> clamp_exclusive(T2&& t) const& noexcept {\n\t\t\t\tstatic_assert(\n#ifdef TC_PRIVATE\n\t\t\t\t\t!tc::floating_point_or_chrono_like<tc::decay_t<decltype(t)>>,\n#else\n\t\t\t\t\t!tc::floating_point_like<tc::decay_t<decltype(t)>>,\n#endif\n\t\t\t\t\t\"For floating-point-like types, use clamp_inclusive and clearly state what you want\"\n\t\t\t\t);\n\t\t\t\tif( t<(*this)[tc::lo] ) {\n\t\t\t\t\treturn (*this)[tc::lo];\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::min(tc_modified((*this)[tc::hi], --_), tc_move_if_owned(t));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr newT midpoint() const& noexcept {\n\t\t\t\treturn tc::midpoint((*this)[tc::lo], (*this)[tc::hi]);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr newT midpoint_rounded() const& noexcept {\n\t\t\t\treturn tc::internal_midpoint</*bGeneralized*/true>((*this)[tc::lo], (*this)[tc::hi]);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr decltype(auto) length() const& noexcept {\n\t\t\t\t// overflows with EmptyInterval()\nMODIFY_WARNINGS(((suppress)(4552))) // '-': operator has no effect; expected operator with side-effect\n\t\t\t\treturn (*this)[tc::hi] - (*this)[tc::lo];\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr difference_type saturated_length() const& noexcept {\n\t\t\t\t// This should also work for unsigned integers (returning length clamped to [0..max]), but this probably wouldn't be an intended behavior\n\t\t\t\tstatic_assert(tc::actual_integer<T> && std::is_signed<T>::value);\n\t\t\t\treturn (*this)[tc::lo] < 0\n\t\t\t\t\t? (*this)[tc::hi] < std::numeric_limits<T>::max() + (*this)[tc::lo] ? (*this)[tc::hi] - (*this)[tc::lo] : std::numeric_limits<T>::max()\n\t\t\t\t\t: std::numeric_limits<T>::lowest() + (*this)[tc::lo] < (*this)[tc::hi] ? (*this)[tc::hi] - (*this)[tc::lo] : std::numeric_limits<T>::lowest();\n\t\t\t}\n\n\t\t\t//returns a value X such that tc_modified(intvl, _.ensure_length(this->length())).contains(*this + X)\n\t\t\t[[nodiscard]] constexpr difference_type OffsetToFit(interval<T> const& intvl) const& noexcept {\n\t\t\t\t_ASSERTE( !empty_inclusive() ); // intvl[tc::lo]==intvl[tc::hi] is treated like intvl very small\n\t\t\t\tif( (*this)[tc::lo] < intvl[tc::lo] ) {\n\t\t\t\t\tauto t=intvl[tc::lo]-(*this)[tc::lo];\n\t\t\t\t\tif( intvl[tc::hi] < (*this)[tc::hi]+t ) {\n\t\t\t\t\t\t// if *this does not fit into intvl, center *this on intvl\n\t\t\t\t\t\tt=tc::internal_midpoint</*bGeneralized*/true>(intvl[tc::lo],intvl[tc::hi])-tc::internal_midpoint</*bGeneralized*/true>((*this)[tc::lo],(*this)[tc::hi]);\n\t\t\t\t\t}\n\t\t\t\t\treturn t;\n\t\t\t\t} else if( intvl[tc::hi] < (*this)[tc::hi] ) {\n\t\t\t\t\tauto t=intvl[tc::hi]-(*this)[tc::hi];\n\t\t\t\t\tif( (*this)[tc::lo]+t < intvl[tc::lo] ) {\n\t\t\t\t\t\t// if *this does not fit into intvl, center *this on intvl\n\t\t\t\t\t\tt=tc::internal_midpoint</*bGeneralized*/true>(intvl[tc::lo],intvl[tc::hi])-tc::internal_midpoint</*bGeneralized*/true>((*this)[tc::lo],(*this)[tc::hi]);\n\t\t\t\t\t}\n\t\t\t\t\treturn t;\n\t\t\t\t} else {\n\t\t\t\t\ttc_return_cast( tc::zero );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconstexpr void FitInsideOf(interval<T> const& intvl) & noexcept {\n\t\t\t\ttc_auto_cref(tLength, length());\n\t\t\t\tif(!(tLength < intvl.length())) {\n\t\t\t\t\t*this = intvl;\n\t\t\t\t} else if((*this)[tc::lo] < intvl[tc::lo]) {\n\t\t\t\t\t(*this)[tc::hi]=intvl[tc::lo]+tLength;\n\t\t\t\t\t(*this)[tc::lo]=intvl[tc::lo];\n\t\t\t\t\t_ASSERTE(!(intvl[tc::hi]<(*this)[tc::hi]));\n\t\t\t\t} else if(intvl[tc::hi] < (*this)[tc::hi]) {\n\t\t\t\t\t(*this)[tc::lo]=intvl[tc::hi]-tLength;\n\t\t\t\t\t(*this)[tc::hi]=intvl[tc::hi];\n\t\t\t\t\t_ASSERTE(!((*this)[tc::lo]<intvl[tc::lo]));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttc::dense_map<tc::lohi, T> margin_to_outer(interval<T> const& intvlOuter) const& noexcept {\n\t\t\t\treturn tc::dense_map<tc::lohi, T>(\n\t\t\t\t\t(*this)[tc::lo]-intvlOuter[tc::lo],\n\t\t\t\t\tintvlOuter[tc::hi]-(*this)[tc::hi]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr newT Val(EAlign const ealign) const& noexcept {\n\t\t\t\tswitch_no_default(ealign) {\n\t\t\t\t\tcase ealignLOW:\n\t\t\t\t\t\treturn (*this)[tc::lo];\n\t\t\t\t\tcase ealignHIGH:\n\t\t\t\t\t\treturn (*this)[tc::hi];\n\t\t\t\t\tcase ealignCENTER:\n\t\t\t\t\t\treturn midpoint();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename SetOrVectorImpl>\n\t\t\t[[nodiscard]] bool contains( interval_set<T, interval<T>, SetOrVectorImpl> const& intvlset ) const& noexcept {\n\t\t\t\treturn tc::empty(intvlset) || contains( intvlset.bound_interval() );\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\t[[nodiscard]] constexpr bool naive_contains( interval<U> const& intvl ) const& noexcept {\n\t\t\t\t// no special treatment for empty or inverse intervals\n\t\t\t\treturn !( intvl[tc::lo]<(*this)[tc::lo] || (*this)[tc::hi]<intvl[tc::hi] );\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\t[[nodiscard]] constexpr bool contains( interval<U> const& intvl ) const& noexcept {\n\t\t\t\treturn intvl.empty() || naive_contains(intvl);\n\t\t\t}\n\n\t\t\ttemplate<typename S> \n\t\t\t[[nodiscard]] constexpr bool contains(S const& t) const& noexcept {\n\t\t\t\treturn !(t<(*this)[tc::lo]) && t<(*this)[tc::hi];\n\t\t\t}\n\n\t\t\ttemplate<typename S> \n\t\t\t[[nodiscard]] constexpr bool contains_inclusive(S const& t) const& noexcept {\n\t\t\t\treturn !(t<(*this)[tc::lo] || (*this)[tc::hi]<t);\n\t\t\t}\n\n\t\t\ttemplate<typename S>\n\t\t\t[[nodiscard]] constexpr bool contains_exclusive(S const& t) const& noexcept {\n\t\t\t\treturn (*this)[tc::lo] < t && t < (*this)[tc::hi];\n\t\t\t}\n\n\t\t\ttemplate<typename SetOrVectorImpl>\n\t\t\t[[nodiscard]] bool intersects( interval_set<T, interval<T>, SetOrVectorImpl> const& intvlset ) const& noexcept {\n\t\t\t\tauto itinterval=intvlset.upper_bound(*this);\n\t\t\t\treturn (itinterval!=tc::end(intvlset) && intersects(*itinterval)) \n\t\t\t\t\t|| (itinterval!=tc::begin(intvlset) && intersects(*(--itinterval)));\n\t\t\t}\n\n\t\t\ttemplate<typename S> \n\t\t\t[[nodiscard]] constexpr bool intersects(interval<S> const& intvl) const& noexcept {\n\t\t\t\tbool const bLhsEndFirst= (*this)[tc::hi]<intvl[tc::hi];\n\t\t\t\tif( (*this)[tc::lo]<intvl[tc::lo] ) {\n\t\t\t\t\treturn ( bLhsEndFirst ? intvl[tc::lo] < (*this)[tc::hi] : intvl[tc::lo] < intvl[tc::hi] );\n\t\t\t\t} else {\n\t\t\t\t\treturn ( bLhsEndFirst ? (*this)[tc::lo] < (*this)[tc::hi] : (*this)[tc::lo] < intvl[tc::hi] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename S> \n\t\t\t[[nodiscard]] constexpr bool naive_intersects(interval<S> const& intvl) const& noexcept {\n\t\t\t\t// no special treatment for empty or inverse intervals\n\t\t\t\treturn (*this)[tc::lo] < intvl[tc::hi] && intvl[tc::lo] < (*this)[tc::hi];\n\t\t\t}\n\n\t\t\ttemplate<typename S>\n\t\t\t[[nodiscard]] constexpr bool intersects_inclusive(interval<S> const& intvl) const& noexcept {\n\t\t\t\t// no special treatment for empty or inverse intervals\n\t\t\t\treturn !(intvl[tc::hi]<(*this)[tc::lo]) && !((*this)[tc::hi]<intvl[tc::lo]);\n\t\t\t}\n\n\t\t\ttemplate<typename Rhs> requires tc::instance_or_derived<std::remove_reference_t<Rhs>, tc::interval>\n\t\t\tconstexpr interval<T>& operator&=(Rhs&& rhs) & noexcept {\n\t\t\t\tstatic_assert(\n\t\t\t\t\tstd::is_same<newT, tc::range_value_t<Rhs>>::value,\n\t\t\t\t\t\"Are you sure you want to intersect intervals of different types? \"\n\t\t\t\t\t\"Consider tc::all_values_interval<T> != tc::all_values_interval<U>. \"\n\t\t\t\t\t\"Use implicit_cast to enable the operation.\"\n\t\t\t\t);\n\t\t\t\ttc::assign_max( (*this)[tc::lo], tc_move_if_owned(rhs)[tc::lo] );\n\t\t\t\ttc::assign_min( (*this)[tc::hi], tc_move_if_owned(rhs)[tc::hi] );\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr void CanonicalEmpty() & noexcept {\n\t\t\t\tif (empty()) {\n\t\t\t\t\t*this = EmptyInterval();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\tconstexpr void include(U&& u) & noexcept {\n\t\t\t\tstatic_assert( tc::safely_convertible_to<U&&, newT> );\n\t\t\t\t_ASSERTE( EmptyInterval()==*this || !empty() );\n\t\t\t\tnewT t = tc_move_if_owned(u);\n\t\t\t\ttc::assign_min( (*this)[tc::lo], t );\n\t\t\t\ttc::nextafter_inplace(t);\n\t\t\t\ttc::assign_max( (*this)[tc::hi], tc_move(t) );\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\tconstexpr void include_inclusive(U&& u) & noexcept {\n\t\t\t\t_ASSERTE( EmptyInterval()==*this || !empty_inclusive() );\n\t\t\t\ttc::assign_min( (*this)[tc::lo], u );\n\t\t\t\ttc::assign_max( (*this)[tc::hi], tc_move_if_owned(u) );\n\t\t\t}\n\n\t\t\ttemplate<typename Rhs> requires tc::instance_or_derived<std::remove_reference_t<Rhs>, tc::interval>\n\t\t\tconstexpr interval<T>& operator|=(Rhs&& rhs) & noexcept {\n\t\t\t\tstatic_assert(\n\t\t\t\t\tstd::is_same<newT, tc::range_value_t<Rhs>>::value,\n\t\t\t\t\t\"Are you sure you want to take the union of intervals of different types? \"\n\t\t\t\t\t\"Consider interval<T>::EmptyInterval() != interval<U>::EmptyInterval(). \"\n\t\t\t\t\t\"Use implicit_cast to enable the operation.\"\n\t\t\t\t);\n\t\t\t\t_ASSERTDEBUG( EmptyInterval()==*this || !empty_inclusive() );\n\t\t\t\t_ASSERTDEBUG( rhs.EmptyInterval()==rhs || !rhs.empty_inclusive() );\n\t\t\t\ttc::assign_min( (*this)[tc::lo], tc_move_if_owned(rhs)[tc::lo] );\n\t\t\t\ttc::assign_max( (*this)[tc::hi], tc_move_if_owned(rhs)[tc::hi] );\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr interval<newT> operator-() const& noexcept {\n\t\t\t\tinterval<newT> copy=*this;\n\t\t\t\tcopy.negate();\n\t\t\t\treturn copy;\n\t\t\t}\n\n\t\t\tconstexpr void negate() & noexcept {\n\t\t\t\t-tc::inplace((*this)[tc::lo]);\n\t\t\t\t-tc::inplace((*this)[tc::hi]);\n\t\t\t\tswap();\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr auto range() const& noexcept {\n\t\t\t\t// tc::iota does not support end < begin. So for such empty ranges, we need to return tc::iota(begin, begin)\n\t\t\t\treturn tc::iota( (*this)[tc::lo], tc::max((*this)[tc::lo], (*this)[tc::hi]) );\n\t\t\t}\n\n\t\t\t[[nodiscard]] static constexpr interval<newT> EmptyInterval() noexcept { // neutral element for operator|\n\t\t\t\treturn interval<newT>( tc::all_values_interval<newT>[tc::hi], tc::all_values_interval<newT>[tc::lo]  );\n\t\t\t}\n\n#ifdef TC_PRIVATE\n\t\tprivate:\n\t\t\tvoid LoadTypeImpl(CXmlReader& loadhandler) & THROW(ExLoadFail);\n\t\t\tfriend void LoadType_impl(interval& intvl, CXmlReader& loadhandler) THROW(ExLoadFail) {\n\t\t\t\tintvl.LoadTypeImpl(loadhandler); // THROW(ExLoadFail)\n\t\t\t}\n\t\t\tLOADMETHODDECL( typename interval::PersistentType )\n\t\t\tSAVEMETHODDECL;\n#endif\n\t\t};\n\n\t\tTC_DENSE_MAP_DEDUCTION_GUIDES(interval)\n\n\t\ttemplate< typename Arg, typename Arg2> requires std::is_same<tc::decay_t<Arg>, tc::decay_t<Arg2>>::value\n\t\tinterval(tc::lohi lohi, Arg&&, Arg2&&) -> interval<tc::decay_t<Arg>>;\n\n\t\ttemplate<typename T>\n\t\ttemplate<typename TTarget>\n\t\tinterval<TTarget> interval<T>::expanding_cast_inclusive() const& noexcept {\n\t\t\t_ASSERT(!empty_inclusive());\n\t\t\treturn {\n\t\t\t\ttc::rounding_cast<TTarget>( (*this)[tc::lo], tc::roundFLOOR ),\n\t\t\t\ttc::rounding_cast<TTarget>( (*this)[tc::hi], tc::roundCEIL )\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename T>\n\t\ttemplate<typename TTarget>\n\t\tinterval<TTarget> interval<T>::expanding_cast() const& noexcept {\n\t\t\t_ASSERT(!empty()); // Rounding an empty interval may make it non-empty, which might not be intended.\n\t\t\treturn expanding_cast_inclusive<TTarget>();\n\t\t}\n\n\t\ttemplate<typename T>\n\t\t[[nodiscard]] constexpr tc::enumset<T> operator~(tc::interval<T> const& intvl) noexcept {\n\t\t\treturn ~tc::enumset<T>(intvl);\n\t\t}\n\t}\n\n// In addition to intervals where the values of .begin and .end represent definite geometric positions in a 1-dimenional, ordered universe modelled by T, we use\n// interval<T> for ordered pairs of T where values form abstract positions in a more general sense, e.g., interval< Ref<CGridline> >.\n//\n// For intervals of the second kind, T::operator< might not exist at all, or - as in Ref<CGridline> - may implement a different ordering than the one we mean.\n// One must not perform any operation involving operator< on such intervals. This includes algebraic operators, tests for emptiness and intersection, but also\n// AssertSameOrder, which was formerly used for checking the result of interval<T>::transform. We clearly want to use interval<T>::transform for intervals of the\n// second kind, so I took it out. -- Valentin\n//\n// Alternative paths (discussion with Volker, Vladimir, Edgar):\n//\n// - \"use a std::pair for intervals of the second type\"\n//   BAD IDEA, obscures semantic, we clearly want some parts of the interval interface, e.g., transform.\n//\n// - \"intervals of non-fundamental T are of second type\"\n//   COUNTEREXAMPLE: gridvalue.\n//\n// - \"intervals of fundamental T are of first type\". (path taken by Volker for former implementation of AssertSameOrder, see below)\n//   COUNTEREXAMPLE: ForEachPentagonSpan, [tc::lo] and [tc::hi] are gridline anchor indices.\n//\n// - \"customize interval with a predicate for less\"\n//   Blows up the type for something that was never needed until today (with exception of AssertSameOrder). In addition, the order may be incomputable\n//   from the values of T alone.\n//\n// - \"provide a second interval type implementing the non-arithmetic parts of the interval interface only\"\n//   Sensible, could be considered later.\n//\t\t- Make sure intervals of the first kind can be passed as intervals of the second kind (could use inheritance).\n//\t\t- In generic code, can we always tell which type of interval interface should be used (in particular, when passing intervals to some facility specified by user)?\n\n//template<typename T1, typename T2>\n//std::enable_if_t< std::is_arithmetic<T1>::value && std::is_arithmetic<T2>::value >\n//AssertSameOrder(interval<T1> const& intvl1, interval<T2> const& intvl2) {\n//\t_ASSERTEQUAL( tc::empty(intvl1), tc::empty(intvl2) );\n//}\n//\n//template<typename T1, typename T2>\n//std::enable_if_t<!( std::is_arithmetic<T1>::value && std::is_arithmetic<T2>::value )>\n//AssertSameOrder(interval<T1> const& intvl1, interval<T2> const& intvl2) {\n//\t/* cannot evaluate order */;\n//}\n\n\t// tc::common_type_t is already decayed\n\ttemplate<typename T1, typename T2>\n\t[[nodiscard]] constexpr auto make_interval(T1&& begin, T2&& end) return_ctor_MAYTHROW( // MAYTHROW if the conversion from T1 or T2 to their common_type may throw. (or their copy constructor, if they are the same type)\n\t\tTC_FWD(interval<tc::common_type_t<T1, T2>>), (tc_move_if_owned(begin), tc_move_if_owned(end))\n\t)\n\n\ttemplate<typename T1, typename T2>\n\t[[nodiscard]] constexpr interval< tc::common_type_t< T1, T2 > > make_interval_sort(T1&& t1, T2&& t2) noexcept {\n\t\ttc::assert_not_isnan(t1);\n\t\ttc::assert_not_isnan(t2);\n\t\tif( t2 < t1 ) {\n\t\t\treturn interval< tc::common_type_t< T1, T2 > >(tc_move_if_owned(t2), tc_move_if_owned(t1));\n\t\t} else {\n\t\t\treturn interval< tc::common_type_t< T1, T2 > >(tc_move_if_owned(t1), tc_move_if_owned(t2));\n\t\t}\n\t}\n\n\ttemplate<typename T, typename Extent>\n\t[[nodiscard]] constexpr auto make_interval(T&& pos, Extent&& extent, EAlign ealign)\n\t\treturn_decltype_noexcept( interval< tc::decay_t<T> >::from_extent(tc_move_if_owned(pos), tc_move_if_owned(extent), ealign) )\n\t\n\ttemplate<typename T, typename Extent>\n\t[[nodiscard]] constexpr auto make_interval(T&& pos, Extent&& extent, tc::lohi lohi)\n\t\treturn_decltype_noexcept( interval< tc::decay_t<T> >::from_extent(tc_move_if_owned(pos), tc_move_if_owned(extent), lohi) )\n\n\ttemplate<typename Rng> requires tc::is_iota_range<Rng>::value\n\t[[nodiscard]] constexpr auto make_interval(Rng const& rng) return_decltype_MAYTHROW(\n\t\ttc::make_interval(*tc::begin(rng), *tc::end(rng))\n\t)\n\n\ttemplate<typename T, typename Extent>\n\t[[nodiscard]] constexpr auto make_centered_interval(T&& pos, Extent&& extent)\n\t\treturn_decltype_noexcept(interval< tc::decay_t<T> >::template centered_interval</*bGeneralized*/false>(tc_move_if_owned(pos), tc_move_if_owned(extent) ) )\n\n\ttemplate<typename Func>\n\t[[nodiscard]] constexpr auto make_interval_func(Func func)\n\t\treturn_decltype_MAYTHROW(tc::make_interval(func(tc::lo), func(tc::hi)))\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto make_singleton_interval(T&& value) noexcept {\n\t\treturn interval<tc::decay_t<T>>(tc_move_if_owned(value), tc_modified(value, tc::nextafter_inplace(_)));\n\t}\n\n\tnamespace interval_adl {\n\t\ttemplate<typename Lhs, typename Rhs> requires\n\t\t\ttc::instance_or_derived<std::remove_reference_t<Lhs>, tc::interval> &&\n\t\t\ttc::instance_or_derived<std::remove_reference_t<Rhs>, tc::interval>\n\t\t[[nodiscard]] constexpr auto operator&(Lhs&& lhs, Rhs&& rhs) noexcept {\n\t\t\tstatic_assert(\n\t\t\t\tstd::is_same<tc::range_value_t<Lhs>, tc::range_value_t<Rhs>>::value,\n\t\t\t\t\"Are you sure you want to intersect intervals of different types? \"\n\t\t\t\t\"Consider tc::all_values_interval<T> != tc::all_values_interval<U>. \"\n\t\t\t\t\"Use implicit_cast to enable the operation.\"\n\t\t\t);\n\t\t\treturn tc::make_interval(\n\t\t\t\ttc::max(tc_move_if_owned(lhs)[tc::lo], tc_move_if_owned(rhs)[tc::lo]),\n\t\t\t\ttc::min(tc_move_if_owned(lhs)[tc::hi], tc_move_if_owned(rhs)[tc::hi])\n\t\t\t);\n\t\t}\n\n\t\ttemplate<typename Lhs, typename Rhs> requires\n\t\t\ttc::instance_or_derived<std::remove_reference_t<Lhs>, tc::interval> &&\n\t\t\ttc::instance_or_derived<std::remove_reference_t<Rhs>, tc::interval>\n\t\t[[nodiscard]] constexpr auto operator|(Lhs&& lhs, Rhs&& rhs) noexcept {\n\t\t\tstatic_assert(\n\t\t\t\tstd::is_same<tc::range_value_t<Lhs>, tc::range_value_t<Rhs>>::value,\n\t\t\t\t\"Are you sure you want to take the union of intervals of different types? \"\n\t\t\t\t\"Consider interval<T>::EmptyInterval() != interval<U>::EmptyInterval(). \"\n\t\t\t\t\"Use implicit_cast to enable the operation.\"\n\t\t\t);\n\t\t\t_ASSERTE( tc::interval<tc::range_value_t<Lhs>>::EmptyInterval()==lhs || !lhs.empty_inclusive() );\n\t\t\t_ASSERTE( tc::interval<tc::range_value_t<Rhs>>::EmptyInterval()==rhs || !rhs.empty_inclusive() );\n\t\t\treturn tc::make_interval(\n\t\t\t\ttc::min(tc_move_if_owned(lhs)[tc::lo], tc_move_if_owned(rhs)[tc::lo]),\n\t\t\t\ttc::max(tc_move_if_owned(lhs)[tc::hi], tc_move_if_owned(rhs)[tc::hi])\n\t\t\t);\n\t\t}\n\t}\n\n\ttemplate< typename T, typename Rng >\n\t[[nodiscard]] constexpr interval<T> bound_interval( Rng const& rngintvl ) noexcept {\n\t\treturn tc::accumulate(rngintvl, interval<T>::EmptyInterval(), tc::fn_assign_bit_or());\n\t}\n\n\ttemplate<typename Rng, typename Pred>\n\t[[nodiscard]] constexpr auto minmax_interval(Rng&& rng, Pred const& pred) noexcept {\n\t\tstd::optional<tc::interval<tc::range_value_t<Rng>>> ointvlMinMax;\n\t\ttc::for_each(tc_move_if_owned(rng), [&](auto&& t) noexcept {\n\t\t\tif(!ointvlMinMax) {\n\t\t\t\ttc::optional_emplace(ointvlMinMax, t, t);\n\t\t\t} else if(!tc::assign_better(pred, (*ointvlMinMax)[tc::lo], tc_move_if_owned(t))) {\n\t\t\t\ttc::assign_better(std::not_fn(pred), (*ointvlMinMax)[tc::hi], tc_move_if_owned(t));\n\t\t\t}\n\t\t});\n\t\treturn *VERIFY(tc_move(ointvlMinMax));\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] constexpr auto minmax_interval(Rng&& rng) noexcept {\n\t\treturn tc::minmax_interval(tc_move_if_owned(rng), fn_less());\n\t}\n\n\ttemplate<typename Rng>\n\t[[nodiscard]] auto minmax_interval_elements(Rng&& rng) noexcept {\n\t\tauto pairit = std::minmax_element(tc::begin(rng), tc::end(rng)); // libcxx doesn't have std::ranges::minmax_element yet\n\t\treturn tc::make_interval(pairit.first, pairit.second);\n\t}\n\n\ttemplate<typename T>\n\tbool empty(interval<T> const&) noexcept = delete;\n\n\ttemplate< typename Rng, typename T >\n\t[[nodiscard]] constexpr auto slice_by_interval(Rng&& rng, tc::interval<T> const& intvl) return_decltype_MAYTHROW(\n\t\ttc::slice(tc_move_if_owned(rng),\n\t\t\ttc::begin_next<tc::return_border>(rng, tc::explicit_cast<typename boost::range_size<std::remove_reference_t<Rng>>::type>(intvl[tc::lo])),\n\t\t\ttc::begin_next<tc::return_border>(rng, tc::explicit_cast<typename boost::range_size<std::remove_reference_t<Rng>>::type>(intvl[tc::hi]))\n\t\t)\n\t)\n\n\tnamespace no_adl {\n\t\ttemplate <typename Src, typename Dst, typename Shift>\n\t\tstruct flip_and_shift_transform;\n\n\t\ttemplate<typename Src, typename Dst = Src>\n\t\tstruct [[nodiscard]] linear_interval_transform final {\n\t\tprivate:\n\t\t\ttc::interval<Src> m_intvlsrc;\n\t\t\ttc::interval<Dst> m_intvldst;\n\n\t\tpublic:\n\t\t\ttemplate <typename OtherSrc, typename OtherDst>\n\t\t\tfriend struct linear_interval_transform;\n\t\t\ttemplate <typename OtherSrc, typename OtherDst, typename Shift>\n\t\t\tfriend struct flip_and_shift_transform;\n\n\t\t\tlinear_interval_transform() noexcept = default;\n\n\t\t\ttemplate <typename OtherSrc, typename OtherDst>\n\t\t\texplicit linear_interval_transform(linear_interval_transform<OtherSrc,OtherDst> const& func) noexcept\n\t\t\t\t: tc_member_init( m_intvlsrc, func.m_intvlsrc )\n\t\t\t\t, tc_member_init( m_intvldst, func.m_intvldst )\n\t\t\t{}\n\n\t\t\tlinear_interval_transform(tc::interval<Src> const& intvlsrc, tc::interval<Dst> const& intvldst) noexcept\n\t\t\t\t: m_intvlsrc(intvlsrc)\n\t\t\t\t, m_intvldst(intvldst)\n\t\t\t{\n\t\t\t\tif( m_intvlsrc.empty_inclusive() ) {\n\t\t\t\t\tm_intvlsrc.swap();\n\t\t\t\t\tm_intvldst.swap();\n\t\t\t\t}\n\t\t\t\t_ASSERT( m_intvlsrc[tc::lo] != m_intvlsrc[tc::hi] || m_intvldst[tc::lo] == m_intvldst[tc::hi] );\n\t\t\t\tif constexpr( std::floating_point<Src> ) {\n\t\t\t\t\t_ASSERT( std::isfinite(m_intvlsrc.length()) );\n\t\t\t\t}\n\t\t\t\tif constexpr( std::floating_point<Dst> ) {\n\t\t\t\t\t_ASSERT( std::isfinite(m_intvldst.length()) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename Dst2, typename Shift>\n\t\t\t[[nodiscard]] linear_interval_transform<Src, Dst2> transform_output(flip_and_shift_transform<Dst, Dst2, Shift> const& func) const& noexcept;\n\n\t\t\t/* Desired properties of f = interval_transform(src, dst):\n\t\t\t\texactness: f(s[lohi]) == d[lohi]\n\t\t\t\tmonotonicity: cmp(f(t0),f(t1)) * cmp(t0,t1) * cmp(src[lo],src[hi]) * cmp(dst[lo],dst[hi]) >= 0, where cmp is an arithmetic three-way comparison function\n\t\t\t\tdeterminacy: !isnan(f(t)) || dst[lo]==dst[hi] && !isfinite(t)\n\t\t\t\tboundedness: !src.contains_inclusive(t) || isfinite(f(t))\n\t\t\t\tconsistency: !src.contains_inclusive(t) || dst.contains_inclusive(f(t))\n\t\t\t*/\n\t\t\t[[nodiscard]] Dst operator()(Src const& src) const& noexcept {\n\t\t\t\tif constexpr( tc::floating_point_like<Dst> ) {\n\t\t\t\t\tauto const sign = tc::not_if(m_intvlsrc.midpoint() < src, tc::sign::pos); // Because midpoint() is rounded down, src has to be strictly greater than it before we use hi interval end (important for integral Src).\n\t\t\t\t\treturn tc::best(\n\t\t\t\t\t\ttc::directed(tc::fn_less(), tc::negate_if(m_intvldst.empty_inclusive(), sign)),\n\t\t\t\t\t\tm_intvldst[tc::lo*sign] + length_transform()(src - m_intvlsrc[tc::lo*sign]),\n\t\t\t\t\t\tm_intvldst.midpoint()\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn m_intvldst[tc::lo] + length_transform()(src - m_intvlsrc[tc::lo]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto length_transform() const& noexcept {\n\t\t\t\treturn [srcdiff = m_intvlsrc.length(), dstdiff = m_intvldst.length()](auto const& srcdiffOffset) noexcept {\n\t\t\t\t\tif( tc::explicit_cast<decltype(srcdiff)>(tc::zero) == srcdiff ) {\n\t\t\t\t\t\t// The inclusive source interval is a single point. The operations is well-defined (\"0*0/0\") if,\n\t\t\t\t\t\t//  * 0 == m_intvldst.length() guaranteed by constructor, and\n\t\t\t\t\t\t_ASSERTEQUAL( srcdiffOffset, tc::explicit_cast<decltype(srcdiff)>(tc::zero) );\n\t\t\t\t\t\treturn tc::explicit_cast<decltype(dstdiff)>(tc::zero);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn tc::scale_muldiv(dstdiff, srcdiffOffset, srcdiff);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\t\n\t\t\t[[nodiscard]] linear_interval_transform<Dst, Src> inverted() const& noexcept {\n\t\t\t\treturn {m_intvldst, m_intvlsrc};\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Src, typename Dst>\n\t\tlinear_interval_transform(tc::interval<Src> const&, tc::interval<Dst> const&) -> linear_interval_transform<Src, Dst>;\n\t}\n\tusing no_adl::linear_interval_transform;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Src, typename Dst = Src, typename Shift = tc::common_type_t<Src, Dst>>\n\t\tstruct flip_and_shift_transform {\n\t\tprivate:\n\t\t\ttc::sign m_sign;\n\t\t\tShift m_shift;\n\n\t\tpublic:\n\t\t\tflip_and_shift_transform(tc::sign sign, Shift shift) noexcept\n\t\t\t\t: m_sign(sign)\n\t\t\t\t, m_shift(shift)\n\t\t\t{}\n\n\t\t\t[[nodiscard]] Dst operator()(Src const& src) const& noexcept {\n\t\t\t\treturn src*m_sign + m_shift;\n\t\t\t}\n\n\t\t\t[[nodiscard]] flip_and_shift_transform<Dst, Src, Shift> inverted() const& noexcept {\n\t\t\t\treturn {m_sign, -m_shift*m_sign};\n\t\t\t}\n\n\t\t\ttemplate<typename Dst2>\n\t\t\t[[nodiscard]] linear_interval_transform<Src, Dst2> transform_output(linear_interval_transform<Dst, Dst2> const& func) const& noexcept {\n\t\t\t\t// tc::chained(func, *this) without intermediate rounding to Dst\n\t\t\t\treturn {func.m_intvlsrc.transform(inverted()), func.m_intvldst};\n\t\t\t}\n\n\t\t\ttemplate<typename Dst2, typename Shift2>\n\t\t\t[[nodiscard]] flip_and_shift_transform<Src, Dst2, tc::decay_t<decltype(std::declval<Shift>() + std::declval<Shift2>())>> transform_output(flip_and_shift_transform<Dst, Dst2, Shift2> const& func) const& noexcept {\n\t\t\t\t// tc::chained(func, *this) without intermediate rounding to Dst\n\t\t\t\treturn {m_sign*func.m_sign, m_shift*func.m_sign + func.m_shift};\n\t\t\t}\n\t\t};\n\t\ttemplate<typename Shift>\n\t\tflip_and_shift_transform(tc::sign sign, Shift shift) -> flip_and_shift_transform<Shift>;\n\n\t\ttemplate<typename Src, typename Dst>\n\t\ttemplate<typename Dst2, typename Shift>\n\t\t[[nodiscard]] linear_interval_transform<Src, Dst2> linear_interval_transform<Src,Dst>::transform_output(flip_and_shift_transform<Dst, Dst2, Shift> const& func) const& noexcept {\n\t\t\t// tc::chained(func, *this) without intermediate rounding to Dst\n\t\t\treturn {m_intvlsrc, m_intvldst.transform(func)};\n\t\t}\n\t}\n\tusing no_adl::flip_and_shift_transform;\n\n\tnamespace no_adl {\n\t\ttemplate<typename T, typename TInterval>\n\t\tstruct less_begin final {\n\t\t\tbool operator()(TInterval const& intvlLeft, TInterval const& intvlRight) const& noexcept {\n\t\t\t\treturn intvlLeft[tc::lo] < intvlRight[tc::lo];\n\t\t\t}\n\n\t\t\tusing is_transparent = void;\n\t\t\tbool operator()(TInterval const& intvlLeft, T const& tRight) const& noexcept {\n\t\t\t\treturn intvlLeft[tc::lo] < tRight;\n\t\t\t}\n\t\t\tbool operator()(T const& tLeft, TInterval const& intvlRight) const& noexcept {\n\t\t\t\treturn tLeft < intvlRight[tc::lo];\n\t\t\t}\n\t\t};\t\n\n\t\t// deprecated, had disadvantage that you can only sort by one criterion, not different criterions in different parts of the code\n\t\ttemplate<typename T, typename _Pr>\n\t\tstruct vector_as_set : tc::vector< T > {\n\t\t\tusing iterator = tc::iterator_t<tc::vector<T>>;\n\t\t\tusing const_iterator = tc::iterator_t<tc::vector<T> const>;\n\t\t\tusing base_ = tc::vector< T >;\n\t\n\t\t\titerator lower_bound(T const& t) & noexcept {\n\t\t\t\treturn tc::lower_bound<tc::return_border>(*this, t, _Pr());\n\t\t\t}\n\n\t\t\tconst_iterator lower_bound(T const& t) const& noexcept {\n\t\t\t\treturn tc::lower_bound<tc::return_border>(*this, t, _Pr());\n\t\t\t}\n\n\t\t\titerator upper_bound(T const& t) & noexcept {\n\t\t\t\treturn tc::upper_bound<tc::return_border>(*this, t, _Pr());\n\t\t\t}\n\n\t\t\tconst_iterator upper_bound(T const& t) const& noexcept {\n\t\t\t\treturn tc::upper_bound<tc::return_border>(*this, t, _Pr());\n\t\t\t}\n\n\t\t\ttemplate< typename A0 >\n\t\t\titerator emplace_hint(iterator& itWhere, A0&& a0) & noexcept {\n\t\t\t\titerator it = base_::emplace(itWhere, tc_move_if_owned(a0) );\n\t\t\t\titWhere = it;\n\t\t\t\t++itWhere;\n\t\t\t\treturn it;\n\t\t\t}\n\n\t\t\ttemplate< typename A0, typename A1 >\n\t\t\titerator emplace_hint(iterator& itWhere, A0&& a0, A1&& a1) & noexcept {\n\t\t\t\titerator it = tc::vector< T >::emplace(itWhere, tc_move_if_owned(a0), tc_move_if_owned(a1) );\n\t\t\t\titWhere = it;\n\t\t\t\t++itWhere;\n\t\t\t\treturn it;\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace interval_set_adl {\n\t\ttemplate<typename T, typename TInterval, typename SetOrVectorImpl>\n\t\tstruct interval_set :\n\t\t\ttc::setlike<>\n\t\t{\n\t\tprivate:\n\t\t\tusing Cont=std::conditional_t<\n\t\t\t\tstd::is_same< SetOrVectorImpl, use_set_impl_tag_t >::value,\n\t\t\t\ttc::set< TInterval, tc::no_adl::less_begin< T, TInterval > >,\n\t\t\t\ttc::no_adl::vector_as_set< TInterval, tc::no_adl::less_begin< T, TInterval > >\n\t\t\t>;\n\t\t\tCont m_cont;\n\n\t\tpublic:\n\t\t\tusing const_iterator = tc::iterator_t<Cont const>;\n\t\n\t\t\tinterval_set() noexcept\n\t\t\t{}\n\n\t\t\texplicit interval_set(TInterval const& intvl) noexcept {\n\t\t\t\t*this |= intvl;\n\t\t\t}\n\n\t\t\ttemplate<typename Iterator>\n\t\t\tinterval_set( Iterator itBegin, Iterator itEnd ) noexcept \n\t\t\t\t: m_cont( itBegin, itEnd )\n\t\t\t{}\n\n\t\t\tconst_iterator begin() const& noexcept {\n\t\t\t\treturn tc::begin(m_cont);\n\t\t\t}\n\n\t\t\tconst_iterator end() const& noexcept {\n\t\t\t\treturn tc::end(m_cont);\n\t\t\t}\n\n\t\t\tbool empty() const& noexcept {\n\t\t\t\treturn tc::empty(m_cont);\n\t\t\t}\n\n\t\t\tTInterval bound_interval() const& noexcept {\n\t\t\t\t_ASSERT(!empty());\n\t\t\t\treturn TInterval(tc::front(*this)[tc::lo], tc::back(*this)[tc::hi]);\n\t\t\t}\n\n\t\t\tinterval_set& operator|=(TInterval const& interval) & noexcept {\n\t\t\t\tif (!interval.empty()) {\n\t\t\t\t\tauto itinterval = m_cont.upper_bound(interval);\n\n\t\t\t\t\ttc::iterator_t<Cont> itintervalAdd;\n\n\t\t\t\t\tif (itinterval != tc::begin(m_cont)) {\n\t\t\t\t\t\titintervalAdd = itinterval;\n\t\t\t\t\t\t--itintervalAdd;\n\t\t\t\t\t\tif ((*itintervalAdd)[tc::hi] < interval[tc::lo]) {\n\t\t\t\t\t\t\titintervalAdd = m_cont.emplace_hint(itinterval, interval);\n\t\t\t\t\t\t} else if (!((*itintervalAdd)[tc::hi] < interval[tc::hi])) {\n\t\t\t\t\t\t\treturn *this;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\titintervalAdd = m_cont.emplace_hint(itinterval, interval);\n\t\t\t\t\t}\n\n\t\t\t\t\twhile (itinterval != tc::end(m_cont) && !(interval[tc::hi] < (*itinterval)[tc::hi])) {\n\t\t\t\t\t\titinterval = m_cont.erase(itinterval);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (itinterval != tc::end(m_cont) && !(interval[tc::hi] < (*itinterval)[tc::lo])) {\n\t\t\t\t\t\ttc::as_mutable(*itintervalAdd)[tc::hi] = (*itinterval)[tc::hi];\n\t\t\t\t\t\tm_cont.erase(itinterval);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttc::as_mutable(*itintervalAdd)[tc::hi] = interval[tc::hi];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tinterval_set& operator-=(TInterval const& interval) & noexcept {\n\t\t\t\tif (!interval.empty()) {\n\t\t\t\t\tauto itinterval = m_cont.lower_bound(interval);\n\n\t\t\t\t\tif (itinterval != tc::begin(m_cont)) {\n\t\t\t\t\t\tauto itintervalOverlap = itinterval;\n\t\t\t\t\t\t--itintervalOverlap;\n\t\t\t\t\t\tif (interval[tc::lo] < (*itintervalOverlap)[tc::hi]) {\n\t\t\t\t\t\t\tif (interval[tc::hi] < (*itintervalOverlap)[tc::hi]) {\n\t\t\t\t\t\t\t\tTInterval intervalRemainder(interval[tc::hi], (*itintervalOverlap)[tc::hi]);\n\t\t\t\t\t\t\t\ttc::as_mutable(*itintervalOverlap)[tc::hi] = interval[tc::lo];\n\t\t\t\t\t\t\t\tm_cont.emplace_hint(itinterval, intervalRemainder);\n\t\t\t\t\t\t\t\treturn *this;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttc::as_mutable(*itintervalOverlap)[tc::hi] = interval[tc::lo];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\twhile (itinterval != tc::end(m_cont) && !(interval[tc::hi] < (*itinterval)[tc::hi])) {\n\t\t\t\t\t\titinterval = m_cont.erase(itinterval);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (itinterval != tc::end(m_cont) && (*itinterval)[tc::lo] < interval[tc::hi]) {\n\t\t\t\t\t\tTInterval intervalInsert(interval[tc::hi], (*itinterval)[tc::hi]);\n\t\t\t\t\t\t_ASSERT(!intervalInsert.empty());\n\t\t\t\t\t\titinterval = m_cont.erase(itinterval);\n\t\t\t\t\t\tm_cont.emplace_hint(itinterval, intervalInsert);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tinterval_set& operator-=(interval_set const& intvlset) & noexcept {\n\t\t\t\ttc::for_each(intvlset.m_cont, [this]( TInterval const& intvl ) noexcept {\n\t\t\t\t\t*this-=intvl;\n\t\t\t\t});\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tvoid erase(T const& t) & noexcept {\n\t\t\t\t*this -= TInterval(t, tc_modified(t, ++_));\n\t\t\t}\n\n\t\t\tbool intersects(TInterval const& intvl) const& noexcept {\n\t\t\t\tconst_iterator it=upper_bound(intvl);\n\t\t\t\treturn (it!=end() && it->intersects(intvl))\n\t\t\t\t|| (it!=begin() && (--it)->intersects(intvl));\n\t\t\t}\n\n\t\t\tbool contains(TInterval const& intvl) const& noexcept {\n\t\t\t\treturn intvl.empty() || tc::and_then(\n\t\t\t\t\tupper_bound<tc::return_element_before_or_null>(intvl),\n\t\t\t\t\t[&](auto const& intvlInsideSet) noexcept {\n\t\t\t\t\t\treturn !(intvlInsideSet[tc::hi]<intvl[tc::hi]);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tbool contains(T const& t) const& noexcept {\n\t\t\t\treturn tc::and_then(\n\t\t\t\t\tupper_bound<tc::return_element_before_or_null>(t),\n\t\t\t\t\t[&](auto const& intvlInsideSet) noexcept {\n\t\t\t\t\t\treturn t<intvlInsideSet[tc::hi];\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvoid erase_to(T const& t) & noexcept {\n\t\t\t\tauto itinterval = m_cont.lower_bound(t);\n\t\t\t\tif( itinterval!=tc::begin(m_cont) ) {\n\t\t\t\t\tauto itintervalPartial=itinterval;\n\t\t\t\t\t--itintervalPartial;\n\t\t\t\t\tif( t < (*itintervalPartial)[tc::hi] ) {\n\t\t\t\t\t\titinterval=tc::cont_must_emplace_before( m_cont, itinterval, t, (*itintervalPartial)[tc::hi] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tm_cont.erase( tc::begin(m_cont), itinterval );\n\t\t\t}\n\n\t\t\tvoid erase_from(T const& t) & noexcept {\n\t\t\t\tauto itinterval = m_cont.lower_bound(t);\n\t\t\t\tif( itinterval!=tc::begin(m_cont) ) {\n\t\t\t\t\tauto itintervalPartial=itinterval;\n\t\t\t\t\t--itintervalPartial;\n\t\t\t\t\tif( t < (*itintervalPartial)[tc::hi] ) {\n\t\t\t\t\t\ttc::as_mutable(*itintervalPartial)[tc::hi]=t;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttc::take_inplace( m_cont, itinterval );\n\t\t\t}\n\n\t\t\tinterval_set& operator&=(TInterval const& interval) & noexcept {\n\t\t\t\t// special case not for correctness, but only to avoid superfluous insert below\n\t\t\t\tif (interval.empty()) {\n\t\t\t\t\tm_cont.clear();\n\t\t\t\t\treturn *this;\n\t\t\t\t}\n\n\t\t\t\terase_to(interval[tc::lo]);\n\t\t\t\terase_from(interval[tc::hi]);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconst_iterator interval_below( T const& t ) const& noexcept {\n\t\t\t\treturn upper_bound<tc::return_element_before>(t);\n\t\t\t}\n\n\t\t\t// closest_below must exist\n\t\t\tT const& closest_below( T const& t) const& noexcept {\n\t\t\t\treturn tc::min(t, (*interval_below(t))[tc::hi]);\n\t\t\t}\n\n\t\t\tconst_iterator interval_above( T const& t ) const& noexcept {\n\t\t\t\t_ASSERT( !tc::empty(m_cont) );\n\n\t\t\t\tauto itintervalSup = m_cont.upper_bound(t);\n\t\t\n\t\t\t\tif( itintervalSup==tc::begin(m_cont) ) {\n\t\t\t\t\treturn itintervalSup;\n\t\t\t\t} else {\n\t\t\t\t\tauto itintervalInf = itintervalSup;\n\t\t\t\t\t--itintervalInf;\n\t\t\t\t\tif( t<(*itintervalInf)[tc::hi] ) {\n\t\t\t\t\t\treturn itintervalInf;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERT( itintervalSup!=tc::end(m_cont) ); // there must be interval space at or above t\n\t\t\t\t\t\treturn itintervalSup;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// closest_above must exist\n\t\t\tT const& closest_above( T const& t) const& noexcept {\n\t\t\t\t_ASSERT( !tc::empty(m_cont) );\n\n\t\t\t\tauto itinterval = m_cont.upper_bound(t);\n\n\t\t\t\tif( itinterval != tc::begin(m_cont) && t < (*tc_modified(itinterval, --_))[tc::hi] ) {\n\t\t\t\t\treturn t;\n\t\t\t\t} else {\n\t\t\t\t\treturn (*itinterval)[tc::lo];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tT const& closest_missing_above( T const& t) const& noexcept {\n\t\t\t\treturn closest_missing(t, tc::hi);\n\t\t\t}\n\n\t\t\tT const& closest_missing_below( T const& t) const& noexcept {\n\t\t\t\treturn closest_missing(t, tc::lo);\n\t\t\t}\n\n\t\t\tT const& closest_missing(T const& t, tc::lohi const lohi) const& noexcept {\n\t\t\t\tif (tc_auto_cref(itinterval, upper_bound<tc::return_element_before_or_null>(t))) {\n\t\t\t\t\tif( t < (*itinterval)[tc::hi] ) {\n\t\t\t\t\t\treturn (*itinterval)[lohi];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn t;\n\t\t\t}\n\n\t\t\tT closest_missing_above(T t, T const& tLength) const& noexcept {\n\t\t\t\tauto itinterval = upper_bound<tc::return_element_before_or_null>(t);\n\t\t\t\tif (itinterval) {\n\t\t\t\t\tt = tc::max(t, (*itinterval)[tc::hi]);\n\t\t\t\t\t++itinterval;\n\t\t\t\t} else {\n\t\t\t\t\titinterval = tc::begin(m_cont);\n\t\t\t\t}\n\t\t\t\twhile(itinterval != tc::end(m_cont) && (*itinterval)[tc::lo] < t + tLength) {\n\t\t\t\t\tt = (*itinterval)[tc::hi];\n\t\t\t\t\t++itinterval;\n\t\t\t\t}\n\t\t\t\treturn t;\n\t\t\t}\n\n\t\t\t// returns end() if empty()\n\t\t\tconst_iterator closest_interval( T const& t ) const& noexcept {\n\t\t\t\tauto itintervalSup = m_cont.upper_bound(t);\n\n\t\t\t\t// below first one or empty\n\t\t\t\tif( itintervalSup == tc::begin(m_cont) ) return itintervalSup;\n\n\t\t\t\tauto itintervalInf=itintervalSup;\n\t\t\t\t--itintervalInf;\n\t\t\t\tif( itintervalSup==tc::end(m_cont) || t-(*itintervalInf)[tc::hi] < (*itintervalSup)[tc::lo]-t ) {\n\t\t\t\t\treturn itintervalInf;\n\t\t\t\t} else {\n\t\t\t\t\treturn itintervalSup;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tT const& closest( T const& t) const& noexcept {\n\t\t\t\t_ASSERT( !tc::empty(m_cont) );\n\n\t\t\t\tauto itintervalSup = m_cont.upper_bound(t);\n\n\t\t\t\t// below first one\n\t\t\t\tif( itintervalSup == tc::begin(m_cont) ) return (*itintervalSup)[tc::lo];\n\n\t\t\t\tauto itintervalInf=itintervalSup;\n\t\t\t\t--itintervalInf;\n\t\t\t\tif( t < (*itintervalInf)[tc::hi]) {\n\t\t\t\t\treturn t;\n\t\t\t\t} else if( itintervalSup==tc::end(m_cont) || t-(*itintervalInf)[tc::hi] < (*itintervalSup)[tc::lo]-t ) {\n\t\t\t\t\treturn (*itintervalInf)[tc::hi];\n\t\t\t\t} else {\n\t\t\t\t\treturn (*itintervalSup)[tc::lo];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tT strict_closest(T const& t) const& noexcept {\n\t\t\t\tstatic_assert(std::integral<T>);\n\t\t\t\t_ASSERT( !tc::empty(m_cont) );\n\n\t\t\t\tauto itintervalSup = m_cont.upper_bound(t);\n\t\t\t\tif( itintervalSup == tc::begin(m_cont) ) return (*itintervalSup)[tc::lo];\n\n\t\t\t\tT const& tInfEnd = (*tc_modified(itintervalSup, --_))[tc::hi];\n\t\t\t\tif( t < tInfEnd ) {\n\t\t\t\t\treturn t;\n\t\t\t\t} else {\n\t\t\t\t\tT tInfLast=tInfEnd;\n\t\t\t\t\t--tInfLast;\n\t\t\t\t\tif( itintervalSup == tc::end(m_cont) || t - tInfLast < (*itintervalSup)[tc::lo] - t ) {\n\t\t\t\t\t\treturn tInfLast;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn (*itintervalSup)[tc::lo];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename OtherSetOrVectorImpl>\n\t\t\tbool contains( interval_set<T, TInterval, OtherSetOrVectorImpl> const& intvlset ) const& noexcept {\n\t\t\t\tif( tc::empty(intvlset) ) return true;\n\t\t\t\tif( empty() ) return false;\n\n\t\t\t\tauto itintervalA = tc::begin(m_cont);\n\t\t\t\tauto itintervalB = tc::begin(intvlset.m_cont);\n\t\t\t\tfor(;;) {\n\t\t\t\t\tif( (*itintervalA)[tc::hi]<(*itintervalB)[tc::hi] ) {\n\t\t\t\t\t\t++itintervalA;\n\t\t\t\t\t\tif( itintervalA==tc::end(m_cont) ) return false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif( (*itintervalB)[tc::lo]<(*itintervalA)[tc::lo] ) return false;\n\t\t\t\t\t\t++itintervalB;\n\t\t\t\t\t\tif( itintervalB==tc::end(intvlset.m_cont) ) return true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfriend bool operator==( interval_set<T, TInterval, SetOrVectorImpl> const& lhs, interval_set<T, TInterval, SetOrVectorImpl> const& rhs ) noexcept {\n\t\t\t\treturn tc::equal(lhs,rhs);\n\t\t\t}\n\n\t\t\tinterval_set operator~() const& noexcept {\n\t\t\t\tinterval_set intvlset;\n\t\t\t\tif(empty()) {\n\t\t\t\t\ttc::cont_must_emplace( intvlset.m_cont, tc::all_values_interval<T> );\n\t\t\t\t} else {\n\t\t\t\t\tconst_iterator itintervalPrevious=begin();\n\t\t\t\t\tconst_iterator itinterval=itintervalPrevious;\n\t\t\t\t\t++itinterval;\n\n\t\t\t\t\tTInterval intvl( tc::all_values_interval<T>[tc::lo], (*itintervalPrevious)[tc::lo] );\n\t\t\t\t\tif(!intvl.empty()) tc::cont_must_emplace_before( intvlset.m_cont, tc::end(intvlset.m_cont), intvl );\n\t\t\t\n\t\t\t\t\tfor(; itinterval!=end(); ++itinterval) {\n\t\t\t\t\t\tintvl=TInterval( (*itintervalPrevious)[tc::hi], (*itinterval)[tc::lo] );\n\t\t\t\t\t\t_ASSERT(!intvl.empty());\n\t\t\t\t\t\ttc::cont_must_emplace_before( intvlset.m_cont, tc::end(intvlset.m_cont), intvl );\n\t\t\t\t\n\t\t\t\t\t\titintervalPrevious=itinterval;\n\t\t\t\t\t}\n\n\t\t\t\t\tintvl=TInterval( (*itintervalPrevious)[tc::hi], tc::all_values_interval<T>[tc::hi] );\n\t\t\t\t\tif(!intvl.empty()) tc::cont_must_emplace_before( intvlset.m_cont, tc::end(intvlset.m_cont), intvl );\n\t\t\t\t}\n\t\t\t\treturn intvlset;\n\t\t\t}\n\n\t\t\tinterval_set& operator|=( interval_set<T, TInterval, SetOrVectorImpl> const& intvlset) & noexcept {\n\t\t\t\tCont cont;\n\n\t\t\t\tauto itintervalA = tc::begin(m_cont);\n\t\t\t\tauto itintervalB = tc::begin(intvlset.m_cont);\n\n\t\t\t\tfor(;;) {\n\t\t\t\t\tif( itintervalA==end() ) {\n\t\t\t\t\t\ttc::append(cont, tc::drop(intvlset.m_cont, itintervalB));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if( itintervalB==tc::end(intvlset) ) {\n\t\t\t\t\t\ttc::append(cont, tc::drop(m_cont, itintervalA));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tT tIntervalBegin=tc::min( (*itintervalA)[tc::lo], (*itintervalB)[tc::lo] );\n\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\tif( (*itintervalA)[tc::hi] < (*itintervalB)[tc::lo] ) goto end_from_A;\n\t\t\t\t\t\tif( (*itintervalB)[tc::hi] < (*itintervalA)[tc::lo] ) goto end_from_B;\n\n\t\t\t\t\t\tif( (*itintervalA)[tc::hi] < (*itintervalB)[tc::hi] ) {\n\t\t\t\t\t\t\t++itintervalA;\n\t\t\t\t\t\t\tif( itintervalA==end() ) goto end_from_B;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t++itintervalB;\n\t\t\t\t\t\t\tif( itintervalB==tc::end(intvlset) ) goto end_from_A;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\tend_from_A:\n\t\t\t\t\ttc::cont_must_emplace_before( cont, tc::end(cont), tc::make_interval( tIntervalBegin, (*itintervalA)[tc::hi] ) );\n\t\t\t\t\t++itintervalA;\n\t\t\t\t\tcontinue;\n\t\tend_from_B:\n\t\t\t\t\ttc::cont_must_emplace_before( cont, tc::end(cont), tc::make_interval( tIntervalBegin, (*itintervalB)[tc::hi] ) );\n\t\t\t\t\t++itintervalB;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tm_cont.swap( cont );\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tauto all_intervals() const& noexcept -> Cont const& {\n\t\t\t\treturn m_cont;\n\t\t\t}\n\n\t\t\tvoid filter_inplace(auto func) & noexcept {\n\t\t\t\ttc::filter_inplace(m_cont, func);\n\t\t\t}\n\n\t\t\ttemplate<typename OtherSetOrVectorImpl, typename Func>\n\t\t\tauto for_each_intersecting_interval(interval_set<T, TInterval, OtherSetOrVectorImpl> const& intvlset, Func func) const& MAYTHROW  -> tc::common_type_t<\n\t\t\t\tdecltype(tc::continue_if_not_break(func, *tc::begin(m_cont), *tc::begin(intvlset.m_cont), std::declval<TInterval&>())),\n\t\t\t\ttc::constant<tc::continue_>\n\t\t\t> {\n\t\t\t\tif(!empty() && !intvlset.empty()) {\n\t\t\t\t\tconst_iterator itintervalA = tc::begin(m_cont);\n\t\t\t\t\tconst_iterator itintervalB = tc::begin(intvlset.m_cont);\n\t\t\t\t\tif((*itintervalA)[tc::lo]<(*itintervalB)[tc::lo]) {\n\t\t\t\t\t\titintervalA=m_cont.upper_bound( *itintervalB );\n\t\t\t\t\t\t--itintervalA;\n\t\t\t\t\t} else {\n\t\t\t\t\t\titintervalB=intvlset.m_cont.upper_bound( *itintervalA );\n\t\t\t\t\t\t--itintervalB;\n\t\t\t\t\t}\n\n\t\t\t\t\twhile(itintervalA!=tc::end(m_cont) && itintervalB!=tc::end(intvlset.m_cont)) {\n\t\t\t\t\t\tTInterval intvl=*itintervalA & *itintervalB;\n\t\t\t\t\t\tif( !intvl.empty() ) {\n\t\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break( func, *itintervalA, *itintervalB, intvl))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((*itintervalA)[tc::hi] < (*itintervalB)[tc::hi]) {\n\t\t\t\t\t\t\t++itintervalA;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t++itintervalB;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\n\t\t\ttemplate<typename OtherSetOrVectorImpl>\n\t\t\tbool intersects(interval_set<T, TInterval, OtherSetOrVectorImpl> const& intvlset ) const& noexcept {\n\t\t\t\tbool bIntersects = false;\n\t\t\t\tfor_each_intersecting_interval(intvlset,\n\t\t\t\t\t[&]( tc::unused, tc::unused, tc::unused) noexcept {\n\t\t\t\t\t\tVERIFY(tc::change(bIntersects, true));\n\t\t\t\t\t\treturn tc::constant<tc::break_>();\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\treturn bIntersects;\n\t\t\t}\n\n\t\t\ttemplate<typename OtherSetOrVectorImpl>\n\t\t\tinterval_set<T, TInterval, SetOrVectorImpl>& operator&=( interval_set<T, TInterval, OtherSetOrVectorImpl> const& intvlset) & noexcept {\n\t\t\t\tCont contIntersection;\n\t\t\t\tfor_each_intersecting_interval(intvlset, \n\t\t\t\t\t[&]( tc::unused, tc::unused, TInterval const& intvl ) noexcept {\n\t\t\t\t\t\ttc::cont_must_emplace_before( contIntersection, tc::end(contIntersection),intvl);\n\t\t\t\t\t});\n\t\t\t\tm_cont=tc_move(contIntersection);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tfriend void swap( interval_set& lhs, interval_set& rhs ) noexcept {\n\t\t\t\ttc::swap( lhs.m_cont, rhs.m_cont );\n\t\t\t}\n\n\t\t\tfriend bool operator==(  interval_set<T, TInterval, SetOrVectorImpl> const& lhs, TInterval const& rhs ) noexcept {\n\t\t\t\tif( rhs.empty() ) {\n\t\t\t\t\treturn lhs.empty();\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::contains_single( lhs.m_cont, rhs );\n\t\t\t\t}\n\t\t\t}\n\n#ifdef TC_PRIVATE\n\t\t\tvoid DoSave(CSaveHandler& savehandler) const& MAYTHROW;\n\t\t\ttemplate<typename U, typename UInterval, typename USetOrVectorImpl>\n\t\t\tfriend void LoadType_impl(interval_set<U, UInterval, USetOrVectorImpl>& ent, CXmlReader& loadhandler) THROW(ExLoadFail);\n#endif\n\n\t\t\t// DEPRECATED\n\t\t\tusing iterator = tc::iterator_t<Cont>;\n\n\t\t\ttemplate <typename RangeReturn = tc::return_border, typename K>\n\t\t\tdecltype(auto) lower_bound(K const& k) const& noexcept {\n\t\t\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\t\t\treturn RangeReturn::pack_border(m_cont.lower_bound(k), *this);\n\t\t\t}\n\n\t\t\ttemplate <typename RangeReturn = tc::return_border, typename K>\n\t\t\tdecltype(auto) upper_bound(K const& k) const& noexcept {\n\t\t\t\tstatic_assert( RangeReturn::allowed_if_always_has_border );\n\t\t\t\treturn RangeReturn::pack_border(m_cont.upper_bound(k), *this);\n\t\t\t}\n\n\t\t\titerator begin() & noexcept {\n\t\t\t\treturn tc::begin(m_cont);\n\t\t\t}\n\n\t\t\titerator end() & noexcept {\n\t\t\t\treturn tc::end(m_cont);\n\t\t\t}\n\n\t\t\tstd::size_t interval_count() const& noexcept {\n\t\t\t\treturn tc::size(m_cont);\n\t\t\t}\n\n\t\t\tT accumulated_length() const& noexcept {\n\t\t\t\treturn tc::accumulate( tc::transform( m_cont, tc_mem_fn(.length) ), tc::explicit_cast<T>(tc::zero), tc::fn_assign_plus() );\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename ResultWrapper, typename RngIntvl, typename Less>\n\t[[nodiscard]] auto ordered_overlapping_intervals_impl(ResultWrapper resultwrapper, RngIntvl&& rngintvl, Less less) noexcept {\n\t\treturn [rngintvl=tc::make_reference_or_value(tc_move_if_owned(rngintvl)), resultwrapper = tc_move(resultwrapper), less = tc_move(less)](auto sink) noexcept {\n\t\t\tif(!tc::empty(*rngintvl)) {\n\t\t\t\t_ASSERTDEBUG(tc::is_sorted(*rngintvl, tc::projected(less, tc_member([tc::lo]))));\n\t\t\t\tauto itintvlOverlapBegin=tc::begin(*rngintvl);\n\t\t\t\tauto itintvlLastOverlap=itintvlOverlapBegin;\n\t\t\t\ttc_return_if_break(tc::for_each(tc::make_range_of_iterators(tc::begin_next<tc::return_drop>(*rngintvl)), [&](auto const& itintvlCurr) noexcept {\n\t\t\t\t\ttc_auto_cref(intvlLastOverlap, *itintvlLastOverlap);\n\t\t\t\t\ttc_auto_cref(intvlCurr, *itintvlCurr);\n\t\t\t\t\tif(less(intvlLastOverlap[tc::hi], intvlCurr[tc::lo])) {\n\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, resultwrapper(*rngintvl, itintvlOverlapBegin, itintvlCurr, itintvlLastOverlap)))\n\t\t\t\t\t\titintvlOverlapBegin=itintvlCurr;\n\t\t\t\t\t\titintvlLastOverlap=itintvlCurr;\n\t\t\t\t\t} else if(less(intvlLastOverlap[tc::hi], intvlCurr[tc::hi])) {\n\t\t\t\t\t\titintvlLastOverlap=itintvlCurr;\n\t\t\t\t\t}\n\t\t\t\t\treturn tc::continue_;\n\t\t\t\t}));\n\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, resultwrapper(*rngintvl, itintvlOverlapBegin, tc::end(*rngintvl), itintvlLastOverlap)))\n\t\t\t}\n\t\t\treturn tc::continue_;\n\t\t};\n\t}\n\n\ttemplate<typename RngIntvl, typename Less = tc::fn_less>\n\t[[nodiscard]] auto ordered_overlapping_intervals(RngIntvl&& rngintvl, Less&& less = Less()) noexcept {\n\t\treturn ordered_overlapping_intervals_impl(\n\t\t\t[](auto const& rngintvl, auto const& itBegin, auto const& itEnd, tc::unused /*itMax*/) noexcept {\n\t\t\t\treturn tc::slice(rngintvl, itBegin, itEnd);\n\t\t\t},\n\t\t\ttc_move_if_owned(rngintvl),\n\t\t\ttc_move_if_owned(less)\n\t\t);\n\t}\n\n\ttemplate<typename RngIntvl, typename Project, typename Less = tc::fn_less>\n\tauto ordered_concatenated_intervals(RngIntvl&& rngintvl, Project project, Less&& less = Less()) noexcept {\n\t\treturn ordered_overlapping_intervals_impl(\n\t\t\t[](tc::unused /*rng*/, auto const& itBegin, tc::unused /*itEnd*/, auto const& itMax) noexcept {\n\t\t\t\treturn tc::make_interval((*itBegin.element_base())[tc::lo], (*itMax.element_base())[tc::hi]);\n\t\t\t},\n\t\t\ttc::transform(\n\t\t\t\ttc_move_if_owned(rngintvl),\n\t\t\t\t[project = tc_move(project)](auto const& intvl) noexcept {\n\t\t\t\t\treturn intvl.transform(project);\n\t\t\t\t}\n\t\t\t),\n\t\t\ttc_move_if_owned(less)\n\t\t);\n\t}\n} // namespace tc\n"
  },
  {
    "path": "tc/interval.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"interval.h\"\n#include \"algorithm/round.h\"\n\n#if TC_PRIVATE\n#include \"Library/HeaderOnly/chrono.h\"\n#endif\n\nSTATICASSERTEQUAL( sizeof(tc::interval<int>), sizeof(int) * 2 );\n\nUNITTESTDEF(interval_center) {\n\n\t{\n\t\ttc_static_auto_constexpr_lambda(TestCenterContained) = [](auto low, auto high, auto center) noexcept {\n\t\t\tauto const intvl = tc::make_interval(tc_move_if_owned(low), tc_move_if_owned(high));\n\t\t\t_ASSERTEQUAL( intvl.midpoint(), center );\n\t\t\t_ASSERT( intvl.empty() || intvl.contains(intvl.midpoint()) ); // The empty interval contains nothing, not even its center\n\t\t};\n\t\t\n\t\tTestCenterContained(0, 1, 0);\n\t\tTestCenterContained(-1, 0, -1);\n\t\tTestCenterContained(0, 0, 0);\n\n\t\tTestCenterContained(0.0, 1.0, 0.5);\n\t}\n\t{\n\t\ttc_static_auto_constexpr_lambda(TestCenterContained) = [](auto pos, auto extent) noexcept {\n\t\t\tauto intvl = tc::make_centered_interval(pos, tc_move(extent));\n\t\t\t_ASSERTEQUAL( intvl.midpoint(), pos );\n\t\t\t_ASSERT( intvl.contains(pos) );\n\t\t\treturn intvl;\n\t\t};\n\t\t\n\t\t_ASSERTEQUAL( TestCenterContained(2,5), tc::make_interval(0,5) );\n\t\t_ASSERTEQUAL( TestCenterContained(-3, 5), tc::make_interval(-5, 0));\n\n\t\t// TestCenterContained(2.5, 5); // Doesn't compile: ambiguous interpretation\n\t\t// TestCenterContained(0, 5.0); // Doesn't compile: ambiguous interpretation\n\t}\n\n#if TC_PRIVATE\n\ttc::chrono::sys_days const tp = tc::chrono::year_month_day(2000,1,1).time_point();\n\n\ttc_static_auto_constexpr_lambda(AddDays) = [](tc::chrono::sys_days const& tpBase, int const nDays) noexcept {\n\t\treturn tpBase + tc::chrono::days(nDays);\n\t};\n#endif\n\t//expand_length roundtrips\n\t{\n\t\ttc_static_auto_constexpr_lambda(TestRoundtrip) = [](auto intvl, auto extent, auto intvlExpanded) noexcept {\n\t\t\t_ASSERTEQUAL(\n\t\t\t\ttc_modified(intvl, {\n\t\t\t\t\t_.expand_length(extent);\n\t\t\t\t\tVERIFYEQUAL(_, intvlExpanded).expand_length(-extent);\n\t\t\t\t}),\n\t\t\t\tintvl\n\t\t\t);\n\t\t};\n\n\t\t//int\n\t\tTestRoundtrip(tc::make_interval(-1, 1), 8, tc::make_interval(-5, 5));\n\t\tTestRoundtrip(tc::make_interval(-1, 1), 0, tc::make_interval(-1, 1));\n\t\tTestRoundtrip(tc::make_interval(0, 1), 1, tc::make_interval(-1, 1));\n\t\tTestRoundtrip(tc::make_interval(-1, 0), 1, tc::make_interval(-2, 0));\n\t\tTestRoundtrip(tc::make_interval(-1, 1), -4, tc::make_interval(1, -1));\n\n\t\t//double\n\t\tTestRoundtrip(tc::make_interval(-1.0, 1.0), 8.0, tc::make_interval(-5.0, 5.0));\n\t\tTestRoundtrip(tc::make_interval(-1.0, 1.0), 0.0, tc::make_interval(-1.0, 1.0));\n\t\tTestRoundtrip(tc::make_interval(0.0, 1.0), 1.0, tc::make_interval(-0.5, 1.5));\n\t\tTestRoundtrip(tc::make_interval(-1.0, 0.0), 1.0, tc::make_interval(-1.5, 0.5));\n\t\tTestRoundtrip(tc::make_interval(-1.0, 1.0), -4.0, tc::make_interval(1.0, -1.0));\n\n#if TC_PRIVATE\n\t\t//time_point\n\t\tTestRoundtrip(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::chrono::days(8), tc::make_interval(AddDays(tp, -5), AddDays(tp, 5)));\n\t\tTestRoundtrip(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::chrono::days(0), tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)));\n\t\tTestRoundtrip(tc::make_interval(tp, AddDays(tp, 1)), tc::chrono::days(1), tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)));\n\t\tTestRoundtrip(tc::make_interval(AddDays(tp, -1), tp), tc::chrono::days(1), tc::make_interval(AddDays(tp, -2), tp));\n\t\tTestRoundtrip(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::chrono::days(-4), tc::make_interval(AddDays(tp, 1), AddDays(tp, -1)));\n#endif\n\t}\n\t//OffsetToFit\n\t{\n\t\ttc_static_auto_constexpr_lambda(TestOffsetToFit) = [](auto intvlToFit, auto intvlFitTarget) noexcept {\n\t\t\tauto const offset = intvlToFit.OffsetToFit(intvlFitTarget);\n\t\t\tif (intvlToFit.length() <= intvlFitTarget.length()) {\n\t\t\t\t_ASSERT( intvlFitTarget.contains(intvlToFit + offset) );\n\t\t\t} else {\n\t\t\t\tintvlFitTarget.expand_to(intvlToFit.length());\n\t\t\t\t_ASSERTEQUAL(intvlFitTarget, intvlToFit + offset);\n\t\t\t}\n\t\t\t_ASSERT(\n\t\t\t\t(intvlToFit + offset)[tc::lo]==intvlFitTarget[tc::lo]\n\t\t\t\t|| (intvlToFit + offset)[tc::hi]==intvlFitTarget[tc::hi]\n\t\t\t);\n\t\t};\n\n\t\t//int\n\t\tTestOffsetToFit(tc::make_interval(-1, 1), tc::make_interval(0, 10));\n\t\tTestOffsetToFit(tc::make_interval(-1, 1), tc::make_interval(-10, 0));\n\t\tTestOffsetToFit(tc::make_interval(-1, 1), tc::make_interval(-1, 1));\n\t\tTestOffsetToFit(tc::make_interval(-1, 1), tc::make_interval(0, 0));\n\n\t\t//double\n\t\tTestOffsetToFit(tc::make_interval(-1.0, 1.0), tc::make_interval(0.0, 10.0));\n\t\tTestOffsetToFit(tc::make_interval(-1.0, 1.0), tc::make_interval(-10.0, 0.0));\n\t\tTestOffsetToFit(tc::make_interval(-1.0, 1.0), tc::make_interval(-1.0, 1.0));\n\t\tTestOffsetToFit(tc::make_interval(-1.0, 1.0), tc::make_interval(0.0, 0.0));\n\n#if TC_PRIVATE\n\t\t//time_point\n\t\tTestOffsetToFit(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::make_interval(tp, AddDays(tp, 10)));\n\t\tTestOffsetToFit(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::make_interval(AddDays(tp, -10), tp));\n\t\tTestOffsetToFit(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)));\n\t\tTestOffsetToFit(tc::make_interval(AddDays(tp, -1), AddDays(tp, 1)), tc::make_interval(tp, tp));\n#endif\n\t}\n}\n\n\nnamespace {\n\ttemplate<typename T>\n\tvoid AssertNextAfter() noexcept {\n\t\t// checking suitability of tc::nextafter_inplace for generating right exclusive intervals\n\t\tT const fInfinity = std::numeric_limits<T>::infinity();\n\t\tT const fZero = 0;\n\t\tT const fOne = 1;\n\t\t_ASSERT(0 < tc_modified(fZero, tc::nextafter_inplace(_)));\n\t\t_ASSERTEQUAL(tc_modified(fZero, tc::nextafter_inplace(_)) / 2, 0);\n\t\t_ASSERTEQUAL(tc_modified(fOne, tc::nextafter_inplace(_)) - fOne, std::numeric_limits<T>::epsilon());\n\t\t_ASSERTEQUAL(tc_modified(std::numeric_limits<T>::max(), tc::nextafter_inplace(_)), fInfinity);\n\t\t_ASSERTEQUAL(tc_modified(fInfinity, tc::nextafter_inplace(_)), fInfinity);\n\t}\n}\n\nUNITTESTDEF(nextafter) {\n\tAssertNextAfter<float>();\n\tAssertNextAfter<double>();\n}\n\n\nUNITTESTDEF(linear_invert) {\n\ttc::linear_interval_transform<int> intvltransformf(tc::make_interval(2, 5), tc::make_interval(1, 5));\n\tauto const intvltransformfInverse = intvltransformf.inverted();\n\t_ASSERTEQUAL(intvltransformfInverse(intvltransformf(0)), 0);\n\t_ASSERTEQUAL(intvltransformfInverse(intvltransformf(1)), 1);\n}\n\nUNITTESTDEF(minmax_interval) {\n\t_ASSERTEQUAL(tc::minmax_interval(tc::vector<int>{1,2,3}), tc::make_interval(1,3));\n}\n\nUNITTESTDEF(linear_interval_transform) {\n\ttc_static_auto_constexpr_lambda(Test) = [](auto srcLo, auto srcHi, auto dstLo, auto dstHi, auto... pairsrcdst) noexcept {\n\t\ttc::linear_interval_transform const intvltrans(tc::interval(srcLo, srcHi), tc::interval(dstLo, dstHi));\n\t\ttc::for_each(\n\t\t\ttc::tie(\n\t\t\t\t// check exactness\n\t\t\t\tstd::make_pair(srcLo, dstLo),\n\t\t\t\tstd::make_pair(srcHi, dstHi),\n\t\t\t\tpairsrcdst...\n\t\t\t),\n\t\t\t[&](auto const src, auto const dst) noexcept {\n\t\t\t\t_ASSERTEQUAL( intvltrans(src), dst );\n\t\t\t\t// check monotonicity\n\t\t\t\tif ( srcLo != srcHi ) {\n\t\t\t\t\tif( dstLo == dstHi ) {\n\t\t\t\t\t\t_ASSERTEQUAL( intvltrans(tc_modified(src, tc::nextafter_inplace(_))), dst );\n\t\t\t\t\t\t_ASSERTEQUAL( intvltrans(tc_modified(src, tc::nextbefore_inplace(_))), dst );\n\t\t\t\t\t} else if( srcLo < srcHi == dstLo < dstHi ) {\n\t\t\t\t\t\t_ASSERT( dst <= intvltrans(tc_modified(src, tc::nextafter_inplace(_))) );\n\t\t\t\t\t\t_ASSERT( intvltrans(tc_modified(src, tc::nextbefore_inplace(_))) <= dst );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERT( intvltrans(tc_modified(src, tc::nextafter_inplace(_))) <= dst );\n\t\t\t\t\t\t_ASSERT( dst <= intvltrans(tc_modified(src, tc::nextbefore_inplace(_))) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t};\n\n\t// int -> int\n\tTest(0, 0, 0, 0);\n\tTest(0, 3, 1, 1);\n\tTest(0, 3, -100, -200, std::make_pair(-1, -67), std::make_pair(1, -133), std::make_pair(2, -167), std::make_pair(4, -233));\n\n\t// int -> double\n\tTest(0, 3, 1.0, 1.0);\n\tTest(0, 3, 0.0, 1.0, std::make_pair(1, tc::fdiv(1, 3)), std::make_pair(2, 1 - tc::fdiv(1, 3)));\n\tTest(0, 4, -1.0, -2.0, std::make_pair(-1, -0.75), std::make_pair(1, -1.25), std::make_pair(2, -1.5), std::make_pair(3, -1.75), std::make_pair(5, -2.25));\n\n\t// double -> int\n\tTest(0.0, 1.0, 0, 0);\n\tTest(0.0, 1.0, 0, 4, std::make_pair(0.25, 1), std::make_pair(0.5, 2), std::make_pair(0.75, 3));\n\n\t// double -> double\n\tTest(0.0, 1.0, 0.0, 0.0, std::make_pair(1e308, 0.0));\n\tTest(-1.0, 1.0, -1.0, -2.0, std::make_pair(-0.5, -1.25), std::make_pair(0.0, -1.5), std::make_pair(0.5, -1.75), std::make_pair(2.0, -2.5), std::make_pair(3.0, -3));\n\tTest(1e-20, 1e20, 1e30, -1e-20);\n}\n"
  },
  {
    "path": "tc/interval_types.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/enum.h\"\n#include \"base/inplace.h\"\n#include \"base/modified.h\"\n\n#ifdef TC_PRIVATE\n#include \"Library/Persistence/SaveableTraits.h\"\n#endif\n\n//////////////////////////////////////\n// EAlign\n\n// persistent\nTC_DEFINE_ENUM_WITH_OFFSET(EAlign, ealign, -1,\n\t(LOW)\n\t(CENTER)\n\t(HIGH)\n)\n\nnamespace EAlign_adl {\n\t[[nodiscard]] constexpr EAlign operator-(EAlign const ealign) noexcept {\n\t\treturn ealignLOW+(ealignHIGH-ealign);\n\t}\n}\n\nnamespace tc {\n\tTC_DEFINE_UNPREFIXED_ENUM(lohi, (lo)(hi))\n\n\tnamespace lohi_adl {\n\t\t// support for multiplication with tc::sign\n\t\t[[nodiscard]] constexpr lohi operator-(lohi lohi_) noexcept {\n\t\t\treturn ~lohi_;\n\t\t}\n\t}\n\n\t[[nodiscard]] constexpr EAlign lohi_to_ealign(lohi lohi_) noexcept {\n\t\tif( lohi::lo == lohi_ ) {\n\t\t\treturn ealignLOW;\n\t\t} else {\n\t\t\treturn ealignHIGH;\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T negate_if( bool_context b, T t ) noexcept {\n\t\tif(b) -tc::inplace(t);\n\t\treturn t;\n\t}\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T not_if( bool_context b, T t ) noexcept {\n\t\tif(b) ~tc::inplace(t);\n\t\treturn t;\n\t}\n\n\tnamespace interval_adl {\n\t\ttemplate< typename T > struct interval;\n\t}\n\tusing interval_adl::interval;\n\n\tTC_DEFINE_SCOPED_ENUM(sign,/*no prefix*/,(neg)(pos))\n\n\tnamespace sign_adl {\n\t\t// support for multiplication with tc::sign\n\t\t[[nodiscard]] constexpr sign operator-(sign sign_) noexcept {\n\t\t\treturn ~sign_;\n\t\t}\n\n\t\ttemplate<typename T>\n\t\tconstexpr T& operator*=(T& t, sign sign_) noexcept {\n\t\t\tif( sign::neg==tc::verify_not_end(sign_) ){\n\t\t\t\t-tc::inplace(t);\n\t\t\t}\n\t\t\treturn t;\n\t\t}\n\n\t\ttemplate<typename T>\n\t\t[[nodiscard]] constexpr tc::decay_t<T> operator*(T&& t, sign sign_) noexcept {\n\t\t\treturn tc_modified( tc_move_if_owned(t), _ *= sign_ );\n\t\t}\n\n\t\ttemplate<tc::decayed T>\n\t\t[[nodiscard]] constexpr T&& operator*(T&& t, sign sign_) noexcept {\n\t\t\tt *= sign_;\n\t\t\treturn tc_move(t);\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\t// cannot be implemented as a lambda because lambdas are not assignable\n\t\ttemplate<typename Func>\n\t\tstruct [[nodiscard]] directed {\n\t\tprivate:\n\t\t\tstatic_assert(tc::decayed<Func>);\n\t\t\tFunc m_func;\n\t\t\ttc::sign m_sign;\n\n\t\tpublic:\n\t\t\ttemplate<typename FuncArg>\n\t\t\tconstexpr directed(FuncArg&& func, tc::sign sign) noexcept\n\t\t\t\t: m_func(tc_move_if_owned(func))\n\t\t\t\t, m_sign(sign)\n\t\t\t{}\n\n\t\t\ttemplate<typename Lhs, typename Rhs>\n\t\t\tconstexpr auto operator()(Lhs && lhs, Rhs && rhs) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::sign::neg==m_sign\n\t\t\t\t?\tm_func( tc_move_if_owned(rhs), tc_move_if_owned(lhs) )\n\t\t\t\t:\tm_func(tc_move_if_owned(lhs), tc_move_if_owned(rhs) )\n\t\t\t)\n\t\t};\n\n\t\ttemplate<typename Func>\n\t\tdirected(Func&&, tc::sign) -> directed<tc::decay_t<Func>>;\n\t}\n\tusing no_adl::directed;\n}\n\n#ifdef TC_PRIVATE\nnamespace tc::sign_adl {\n\t// persistence of old EDirection was -1/1, which we must stay compatible with\n\tvoid LoadType_impl(sign& t, CXmlReader& loadhandler) THROW(ExLoadFail);\n}\n\nnamespace no_adl {\n\ttemplate<>\n\tstruct SaveableTraits<tc::sign> final {\n\t\tstatic void DoSave(tc::sign t, CSaveHandler& savehandler) MAYTHROW;\n\t};\n}\n#endif\n"
  },
  {
    "path": "tc/optional.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/assert_defs.h\"\n#include \"base/conditional.h\"\n#include \"base/utility.h\"\n#include \"base/as_lvalue.h\"\n#include \"base/explicit_cast_fwd.h\"\n#include \"base/scope.h\"\n#include \"range/meta.h\"\n#include \"storage_for.h\"\n#include <optional>\n\nnamespace tc {\n\ttemplate<typename T>\n\tconcept dereferencable = requires { *std::declval<T>(); };\n\n\ttemplate<typename T>\n\tconcept optional_like = tc::explicit_castable_from<bool, T> && tc::dereferencable<T>;\n\n\t// TODO implement fully functional tc::optional\n\n\t// In most std::optional implementations, the \"holding a value\" flag is false during con- and destruction.\n\t// For them it actually doesn't matter, because querying the status from inside is undefined according to 16.4.6.9 [reentrancy]\n\t// > Except where explicitly specified in this document, it is implementation-defined which functions in the C++ standard library may be recursively reentered.\n\t// We explicitly want optionals to be accessible during con- and destruction so we implement this custom type\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct optional {\n\t\t\tusing value_type = T;\n\t\n\t\t\tconstexpr optional() noexcept : m_bValue(false) {}\n\t\t\tconstexpr optional(std::nullopt_t) noexcept : m_bValue(false) {}\n\n\t\t\toptional(optional const& rhs) noexcept(noexcept(construct(*rhs.m_oValue)))\n\t\t\t: m_bValue(rhs.m_bValue) {\n\t\t\t\tif (m_bValue) {\n\t\t\t\t\tconstruct(*rhs.m_oValue);\n\t\t\t\t} \n\t\t\t}\n\t\t\toptional(optional&& rhs) noexcept(noexcept(construct(*tc_move(rhs).m_oValue)))\n\t\t\t: m_bValue(rhs.m_bValue) {\n\t\t\t\tif (m_bValue) {\n\t\t\t\t\tconstruct(*tc_move(rhs).m_oValue);\n\t\t\t\t} \n\t\t\t}\n\n\t\t\ttemplate <tc::optional_like U> requires tc::explicit_castable_from<T, decltype(*std::declval<U>())>\n\t\t\texplicit(!tc::safely_convertible_to<decltype(*std::declval<U>()), T>) optional(U&& rhs) noexcept(noexcept(construct(*tc_move_if_owned(rhs))))\n\t\t\t: tc_member_init(m_bValue, rhs) {\n\t\t\t\tif (m_bValue) {\n\t\t\t\t\tconstruct(*tc_move_if_owned(rhs));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate <typename... Args> requires tc::explicit_castable_from<T, Args&&...>\n\t\t\toptional(std::in_place_t, Args&& ... args) noexcept(noexcept(construct(tc_move_if_owned(args)...)))\n\t\t\t: m_bValue(true) {\n\t\t\t\tconstruct(tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\t\t~optional() {\n\t\t\t\t*this = std::nullopt;\n\t\t\t}\n\t\n\t\t\ttemplate <typename... Args> requires tc::explicit_castable_from<T, Args&&...>\n\t\t\tT& emplace(Args&& ... args) & noexcept(noexcept(construct(tc_move_if_owned(args)...))) {\n\t\t\t\tif constexpr (1 == sizeof...(Args) && requires(T& dest, Args&&... args) { dest = (tc_move_if_owned(args), ...); }) {\n\t\t\t\t\tif (m_bValue) {\n\t\t\t\t\t\treturn *m_oValue = (tc_move_if_owned(args), ...); // optimization: assignment instead of dtor + ctor pair\n\t\t\t\t\t} else {\n\t\t\t\t\t\tVERIFY(tc::change(m_bValue, true));\n\t\t\t\t\t\tconstruct(tc_move_if_owned(args)...);\n\t\t\t\t\t\treturn *m_oValue;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t*this = std::nullopt;\n\t\t\t\t\tVERIFY(tc::change(m_bValue, true));\n\t\t\t\t\tconstruct(tc_move_if_owned(args)...);\n\t\t\t\t\treturn *m_oValue;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\toptional& operator=(std::nullopt_t) & noexcept {\n\t\t\t\tif (tc::change(m_bValue, false)) { // allow querying the flag to prevent double-destruction\n#ifdef _CHECKS\n\t\t\t\t\t_ASSERT(!m_bInsideDtor);\n\t\t\t\t\ttc_scoped_assign(m_bInsideDtor, true);\n#endif\n\t\t\t\t\tm_oValue.dtor();\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\toptional& operator=(optional const& other) & noexcept(noexcept(construct(*other.m_oValue))) {\n\t\t\t\tif (other) {\n\t\t\t\t\templace(*other.m_oValue);\n\t\t\t\t} else {\n\t\t\t\t\t*this = std::nullopt;\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\toptional& operator=(optional&& other) & noexcept(noexcept(construct(*tc_move(other).m_oValue))) {\n\t\t\t\tif (other) {\n\t\t\t\t\templace(*tc_move(other).m_oValue);\n\t\t\t\t} else {\n\t\t\t\t\t*this = std::nullopt;\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <tc::optional_like U> requires tc::safely_convertible_to<decltype(*std::declval<U>()), T>\n\t\t\toptional& operator=(U&& other) & noexcept(noexcept(construct(*tc_move_if_owned(other)))) {\n\t\t\t\tif (other) {\n\t\t\t\t\templace(*tc_move_if_owned(other));\n\t\t\t\t} else {\n\t\t\t\t\t*this = std::nullopt;\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\n\t\t\tconstexpr bool has_value() const& noexcept {\n\t\t\t\treturn m_bValue;\n\t\t\t}\n\t\t\tconstexpr explicit operator bool() const& noexcept {\n\t\t\t\treturn has_value();\n\t\t\t}\n\t\n\t\t\tT const* operator->() const& noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn m_oValue.operator->();\n\t\t\t}\n\t\t\tT* operator->() & noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn m_oValue.operator->();\n\t\t\t}\n\t\t\tT const& operator*() const& noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn *m_oValue;\n\t\t\t}\n\t\t\tT const&& operator*() const&& noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn *tc_move(m_oValue);\n\t\t\t}\n\t\t\tT& operator*() & noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn *m_oValue;\n\t\t\t}\n\t\t\tT&& operator*() && noexcept {\n\t\t\t\t_ASSERT(*this || m_bInsideDtor);\n\t\t\t\treturn *tc_move(m_oValue);\n\t\t\t}\n\t\n\t\tprivate:\n\t\t\tbool m_bValue;\n#ifdef _CHECKS\n\t\t\t// The constructor is allowed to be re-entrant, the destructor is not\n\t\t\tbool m_bInsideDtor = false;\n#endif\n\t\t\ttc::storage_for<T> m_oValue;\n\t\n\t\t\ttemplate <typename... Args>\n\t\t\tvoid construct(Args&& ... args) & noexcept(noexcept(std::declval<storage_for<T>&>().ctor(tc_move_if_owned(args)...))) {\n\t\t\t\t_ASSERT(m_bValue); // allow querying the flag to prevent double-construction\n\t\t\t\t_ASSERT(!m_bInsideDtor);\n\t\t\t\tif constexpr (noexcept(m_oValue.ctor(tc_move_if_owned(args)...))) {\n\t\t\t\t\tm_oValue.ctor(tc_move_if_owned(args)...);\n\t\t\t\t} else { // MSVC doesn't inline functions with try/catch\n\t\t\t\t\ttry {\t\n\t\t\t\t\t\tm_oValue.ctor(tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t\t} catch( ... ) {\n\t\t\t\t\t\tm_bValue = false;\n\t\t\t\t\t\tthrow; // MSVC and gcc: throw in catch block of a noexcept function triggers warning even if try block never throws\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\ttemplate<tc::empty_type TEmpty>\n\t\tstruct optional<TEmpty> {\n\t\t\tconstexpr optional() noexcept = default;\n\t\t\tconstexpr optional(std::nullopt_t) noexcept {}\n\n\t\t\ttemplate <tc::optional_like U> requires tc::explicit_castable_from<TEmpty, decltype(*std::declval<U>())>\n\t\t\texplicit(!tc::safely_convertible_to<decltype(*std::declval<U>()), TEmpty>) optional(U&& rhs) noexcept(noexcept(construct(*tc_move_if_owned(rhs))))\n\t\t\t: tc_member_init(m_bValue, rhs) {\n\t\t\t\tif (m_bValue) {\n\t\t\t\t\tconstruct(*tc_move_if_owned(rhs));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate <typename... Args> requires tc::explicit_castable_from<TEmpty, Args&&...>\n\t\t\tconstexpr optional(std::in_place_t, Args&& ... args) noexcept(noexcept(construct(tc_move_if_owned(args)...))) : m_bValue(true) {\n\t\t\t\tconstruct(tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\t\ttemplate <typename... Args> requires tc::explicit_castable_from<TEmpty, Args&&...>\n\t\t\tconstexpr TEmpty emplace(Args&& ... args) noexcept(noexcept(tc::explicit_cast<TEmpty>(tc_move_if_owned(args)...))) {\n\t\t\t\tm_bValue = true;\n\t\t\t\tconstruct(tc_move_if_owned(args)...);\n\t\t\t\treturn TEmpty();\n\t\t\t}\n\t\n\t\t\tconstexpr optional& operator=(std::nullopt_t) & noexcept {\n\t\t\t\tm_bValue = false;\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttemplate <tc::optional_like U> requires tc::safely_convertible_to<decltype(*std::declval<U>()), TEmpty>\n\t\t\tconstexpr optional& operator=(U&& other) & noexcept(noexcept(tc::explicit_cast<TEmpty>(*tc_move_if_owned(other)))) {\n\t\t\t\tm_bValue = tc::explicit_cast<bool>(other);\n\t\t\t\tif (m_bValue) {\n\t\t\t\t\tconstruct(*tc_move_if_owned(other));\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\n\t\t\tconstexpr bool has_value() const& noexcept {\n\t\t\t\treturn m_bValue;\n\t\t\t}\n\t\t\tconstexpr explicit operator bool() const& noexcept {\n\t\t\t\treturn has_value();\n\t\t\t}\n\t\n\t\tprivate:\n\t\t\tstruct pointer final {\n\t\t\t\tTEmpty m_t;\n\t\t\t\tconstexpr TEmpty* operator->() && noexcept { return std::addressof(m_t); }\n\t\t\t};\n\t\tpublic:\n\t\t\tconstexpr auto operator->() const& noexcept {\n\t\t\t\t_ASSERT(*this);\n\t\t\t\treturn pointer();\n\t\t\t}\n\t\t\tconstexpr TEmpty operator*() const& noexcept {\n\t\t\t\t_ASSERT(*this);\n\t\t\t\treturn TEmpty();\n\t\t\t}\n\n\t\tprivate:\n\t\t\tbool m_bValue = false;\n\n\t\t\ttemplate <typename... Args>\n\t\t\tvoid construct(Args&& ... args) & noexcept(noexcept(tc::explicit_cast<TEmpty>(tc_move_if_owned(args)...))) {\n\t\t\t\t_ASSERT(m_bValue); // allow querying the flag to prevent double-construction\n\t\t\t\tif constexpr (std::is_trivially_constructible<TEmpty, Args&&...>::value) {\n\t\t\t\t\t// no side-effects that need to be executed\n\t\t\t\t} else if constexpr (noexcept(tc::explicit_cast<TEmpty>(tc_move_if_owned(args)...))) {\n\t\t\t\t\ttc::discard(tc::explicit_cast<TEmpty>(tc_move_if_owned(args)...));\n\t\t\t\t} else { // MSVC doesn't inline functions with try/catch\n\t\t\t\t\ttry {\t\n\t\t\t\t\t\ttc::discard(tc::explicit_cast<TEmpty>(tc_move_if_owned(args)...)); // MAYTHROW\n\t\t\t\t\t} catch( ... ) {\n\t\t\t\t\t\tm_bValue = false;\n\t\t\t\t\t\tthrow; // MSVC and gcc: throw in catch block of a noexcept function triggers warning even if try block never throws\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename TRef> requires std::is_reference<TRef>::value\n\t\tstruct optional<TRef> {\n\t\t\ttemplate<typename U>\n\t\t\tfriend struct optional;\n\n\t\t\tconstexpr optional() noexcept = default;\n\t\t\tconstexpr optional(std::nullopt_t) noexcept {}\n\n\t\t\ttemplate<typename U> requires tc::safely_constructible_from<TRef, U&&>\n\t\t\tconstexpr optional(U&& u) noexcept(noexcept(static_cast<TRef>(tc_move_if_owned(u))))\n\t\t\t\t: m_pt(std::addressof(tc::as_lvalue(static_cast<TRef>(tc_move_if_owned(u))))) // tc::safely_constructible_from makes sure no reference to temporary is created\n\t\t\t{}\n\n\t\t\ttemplate <tc::optional_like U> requires tc::safely_constructible_from<TRef, decltype(*std::declval<U>())>\n\t\t\texplicit(!tc::safely_convertible_to<decltype(*std::declval<U>()), TRef>) constexpr optional(U&& rhs) noexcept\n\t\t\t\t: m_pt([&]() noexcept {\n\t\t\t\t\treturn rhs ? std::addressof(tc::as_lvalue(*tc_move_if_owned(rhs))) : nullptr;\n\t\t\t\t}())\n\t\t\t{}\n\n\t\t\tconstexpr optional& operator=(std::nullopt_t) /*no &*/ noexcept {\n\t\t\t\tm_pt = nullptr;\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttemplate <tc::optional_like U> requires tc::safely_convertible_to<decltype(*std::declval<U>()), TRef>\n\t\t\tconstexpr optional& operator=(U&& rhs) /* no & */ noexcept {\n\t\t\t\tm_pt = rhs ? std::addressof(tc::as_lvalue(*tc_move_if_owned(rhs))) : nullptr;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate<typename U> requires tc::safely_constructible_from<TRef, U&&>\n\t\t\tconstexpr TRef emplace(U&& u) /*no &*/ noexcept(noexcept(static_cast<TRef>(tc_move_if_owned(u)))) {\n\t\t\t\tm_pt = std::addressof(tc::as_lvalue(static_cast<TRef>(tc_move_if_owned(u)))); // tc::safely_constructible_from makes sure no reference to temporary is created\n\t\t\t\treturn *m_pt;\n\t\t\t}\n\n\t\t\tconstexpr bool has_value() const& noexcept {\n\t\t\t\treturn m_pt;\n\t\t\t}\n\t\t\tconstexpr explicit operator bool() const& noexcept {\n\t\t\t\treturn has_value();\n\t\t\t}\n\n\t\t\tconstexpr std::remove_reference_t<TRef>& operator*() const& noexcept {\n\t\t\t\t_ASSERT(*this);\n\t\t\t\treturn *m_pt;\n\t\t\t}\n\n\t\t\tconstexpr TRef operator*() const&& noexcept {\n\t\t\t\t_ASSERT(*this);\n\t\t\t\treturn static_cast<TRef>(*m_pt);\n\t\t\t}\n\n\t\t\tconstexpr auto operator->() const& noexcept {\n\t\t\t\t_ASSERT(*this);\n\t\t\t\treturn m_pt;\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstd::remove_reference_t<TRef>* m_pt = nullptr;\n\t\t};\n\t}\n\tusing no_adl::optional;\n\n\ttemplate <typename T>\n\tusing optional_reference_or_value = std::conditional_t<\n\t\ttc::empty_type<std::remove_cvref_t<T>> || std::is_rvalue_reference<T&&>::value,\n\t\ttc::optional<std::remove_cvref_t<T>>,\n\t\ttc::optional<T>\n\t>;\n\n\ttemplate <typename T> requires (!tc::empty_type<T>)\n\t[[nodiscard]] constexpr optional_reference_or_value<T&> make_optional_reference_or_value(T& ref) noexcept {\n\t\treturn ref;\n\t}\n\ttemplate <typename T> requires tc::empty_type<std::remove_cvref_t<T>> || std::is_rvalue_reference<T&&>::value\n\t[[nodiscard]] constexpr optional_reference_or_value<T> make_optional_reference_or_value(T&& ref) noexcept {\n\t\treturn {std::in_place, tc_move_if_owned(ref)};\n\t}\n\n\ttemplate<tc::optional_like Optional, typename T>\n\t[[nodiscard]] constexpr decltype(auto) value_or( Optional&& optional, T&& t ) MAYTHROW {\n\t\tif constexpr( tc::instance_or_derived<std::remove_reference_t<T>, tc::make_lazy> ) {\n\t\t\tstatic_assert( !requires { typename tc::actual_common_reference_t<decltype(*std::declval<Optional>()), T&&>; } ); // Should value_or(std::optional<make_lazy<T>>(), make_lazy<T>()) return make_lazy<T>&& or T?\n\t\t\treturn tc_conditional_prvalue_as_val(optional, *tc_move_if_owned(optional), tc_move_if_owned(t)());\n\t\t} else {\n\t\t\treturn tc_conditional_rvalue_as_ref(optional, *tc_move_if_owned(optional), tc_move_if_owned(t));\n\t\t}\n\t}\n\n\ttemplate<typename Func>\n\tauto not_singleton_or(auto&& t, Func func) noexcept->decltype(func()) {\n\t\tif( tc::explicit_cast<bool>(t) ) {\n\t\t\treturn tc_move_if_owned(t);\n\t\t} else {\n\t\t\treturn func();\n\t\t}\n\t}\n\n\ttemplate<typename Exception, typename... Args>\n\tdecltype(auto) throw_if_null(auto&& t, Args&&... args) THROW(Exception) {\n\t\tif( tc::explicit_cast<bool>(t) ) {\n\t\t\treturn tc_move_if_owned(t);\n\t\t} else {\n\t\t\tif constexpr (tc::explicit_castable_from<Exception, Args&&...>) {\n\t\t\t\tthrow tc::explicit_cast<Exception>(tc_move_if_owned(args)...);\n\t\t\t} else {\n\t\t\t\tthrow Exception();\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Exception>\n\tdecltype(auto) throw_if(auto const& tThrow, auto&& t) THROW(Exception) {\n\t\tif( tThrow==t ) {\n\t\t\tthrow Exception();\n\t\t} else {\n\t\t\treturn tc_move_if_owned(t);\n\t\t}\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// and_then\n\n\tnamespace and_then_detail {\n\t\ttemplate<typename T, typename TypeList, typename=void>\n\t\tstruct and_then_result_impl /*not final*/ {};\n\n\t\ttemplate<typename T>\n\t\tstruct and_then_result_impl<T, boost::mp11::mp_list<>> /*not final*/: std::type_identity<tc::decay_t<T>> {};\n\n\t\ttemplate<>\n\t\tstruct and_then_result_impl<void, boost::mp11::mp_list<>> /*not final*/: std::type_identity<bool> {};\n\n\t\ttemplate<typename Func>\n\t\tconstexpr auto invoke(Func&& func, tc::unused) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\ttc_move_if_owned(func)() // MAYTHROW\n\t\t)\n\n\t\ttemplate<typename Func, tc::dereferencable T>\n\t\tconstexpr auto invoke(Func&& func, T&& t) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\ttc_invoke(tc_move_if_owned(func), *tc_move_if_owned(t)) // MAYTHROW\n\t\t)\n\n\t\ttemplate<typename T, typename Func, typename ...FuncTail>\n\t\tstruct and_then_result_impl<\n\t\t\tT,\n\t\t\tboost::mp11::mp_list<Func, FuncTail...>,\n\t\t\tdecltype(tc::and_then_detail::invoke(std::declval<std::remove_reference_t<Func>>(), std::declval<T>()), void())\n\t\t> /*not final*/: and_then_result_impl<\n\t\t\tdecltype(tc::and_then_detail::invoke(std::declval<std::remove_reference_t<Func>>(), std::declval<T>())),\n\t\t\tboost::mp11::mp_list<FuncTail...>\n\t\t> {};\n\n\t\ttemplate<typename T, typename Func, typename... FuncTail>\n\t\tstruct and_then_result final: and_then_result_impl<T, boost::mp11::mp_list<Func, FuncTail...>> {};\n\t}\n\n\tnamespace and_then_adl {\n\t\tDEFINE_ADL_TAG_TYPE(adl_tag);\n\n\t\ttemplate<typename T, typename Func> requires tc::explicit_castable_from<bool, T&>\n\t\tauto and_then_impl(adl_tag_t, T&& t, Func func) noexcept(noexcept(tc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t))))\n\t\t\t-> typename tc::and_then_detail::and_then_result<T, Func>::type\n\t\t{\n\t\t\tif(t) {\n\t\t\t\tif constexpr(std::is_void<decltype(tc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t)))>::value) {\n\t\t\t\t\ttc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t)); // MAYTHROW\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t)); // MAYTHROW\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\n\t\ttemplate<typename T, typename Func, typename ...FuncTail> requires tc::explicit_castable_from<bool, T&>\n\t\tauto and_then_impl(adl_tag_t, T&& t, Func func, FuncTail&& ...funcTail) noexcept(noexcept(\n\t\t\tand_then_impl(adl_tag, tc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t)), tc_move_if_owned(funcTail)...)\n\t\t)) // noexcept operator cannot see and_then_impl itself without ADL\n\t\t\t-> typename tc::and_then_detail::and_then_result<T, Func, FuncTail...>::type\n\t\t{\n\t\t\tif(t) {\n\t\t\t\treturn and_then_impl( // MAYTHROW\n\t\t\t\t\tadl_tag,\n\t\t\t\t\ttc::and_then_detail::invoke(tc_move(func), tc_move_if_owned(t)), // MAYTHROW\n\t\t\t\t\ttc_move_if_owned(funcTail)...\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename T, typename... Func>\n\tauto and_then(T&& t, Func&&... func) return_decltype_MAYTHROW(\n\t\ttc::and_then_adl::and_then_impl(tc::and_then_adl::adl_tag, tc_move_if_owned(t), tc_move_if_owned(func)...)\n\t)\n\n\t// For `tc::and_then(opt, tc::chained(fn_make_optional, f))`.\n\tDEFINE_FN2(std::make_optional, fn_make_optional);\n\n\ttemplate<typename T, typename... Args>\n\tconstexpr void optional_emplace(tc::optional<T>& o, Args&& ... args)\n\t\tnoexcept(noexcept(o.emplace(tc_move_if_owned(args)...)))\n\t\trequires requires { o.emplace(tc_move_if_owned(args)...); }\n\t{\n\t\to.emplace(tc_move_if_owned(args)...);\n\t}\n}\n\nnamespace tc::begin_end_adl {\n\ttemplate< typename T >\n\tconcept optional = tc::instance<std::remove_const_t<T>, tc::optional> || tc::instance<std::remove_const_t<T>, std::optional>;\n\n\ttemplate<optional Optional>\n\tconstexpr auto* begin(begin_end_tag_t, Optional& ot) noexcept {\n\t\treturn ot ? std::addressof(*ot) : nullptr;\n\t}\n\ttemplate<optional Optional>\n\tconstexpr auto* end(begin_end_tag_t, Optional& ot) noexcept {\n\t\treturn ot ? std::addressof(*ot)+1 : nullptr;\n\t}\n}\n"
  },
  {
    "path": "tc/optional.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"optional.h\"\n#include \"array.h\"\n\nnamespace {\n\ttemplate <typename T>\n\tvoid test_optional_ctor(T const& value) {\n\t\ttc::optional<T> const def;\n\t\t_ASSERT(!def);\n\n\t\ttc::optional<T> const nullopt(std::nullopt);\n\t\t_ASSERT(!nullopt);\n\n\t\ttc::optional<T> const inplace(std::in_place, value);\n\t\t_ASSERT(inplace);\n\t\t_ASSERTEQUAL(*inplace, value);\n\n\t\ttc::optional<T> const copy_def(def);\n\t\t_ASSERT(!copy_def);\n\t\ttc::optional<T> const copy_inplace(inplace);\n\t\t_ASSERT(copy_inplace);\n\t\t_ASSERTEQUAL(*copy_inplace, value);\n\n\t\ttc::optional<T> const move_def(tc::optional<T>{});\n\t\t_ASSERT(!move_def);\n\t\ttc::optional<T> const move_inplace(tc::optional<T>{std::in_place, value});\n\t\t_ASSERT(move_inplace);\n\t\t_ASSERTEQUAL(*move_inplace, value);\n\n\t\ttc::optional<T> const generic_empty(tc::explicit_cast<T*>(nullptr));\n\t\t_ASSERT(!generic_empty);\n\t\ttc::optional<T> const generic_value(&value);\n\t\t_ASSERT(generic_value);\n\t\t_ASSERTEQUAL(*generic_value, value);\n\t}\n\n\ttemplate <typename T, typename U>\n\tvoid test_optional_ops(T const& value1, U const& value2) {\n\t\ttc::optional<T> opt;\n\t\t_ASSERT(!opt);\n\n\t\tauto const fn_emplace = [&](T const& value) {\n\t\t\ttc::optional_emplace(opt, value);\n\t\t\t_ASSERT(opt);\n\t\t\t_ASSERTEQUAL(*opt, value);\n\t\t};\n\t\tauto const fn_assign_nullopt = [&]{\n\t\t\topt = std::nullopt;\n\t\t\t_ASSERT(!opt);\n\t\t};\n\t\tauto const fn_assign_opt = [&](auto&& other) {\n\t\t\tauto save = other;\n\n\t\t\topt = tc_move_if_owned(other);\n\t\t\tif (save) {\n\t\t\t\t_ASSERT(opt);\n\t\t\t\t_ASSERTEQUAL(*opt, *save);\n\t\t\t} else {\n\t\t\t\t_ASSERT(!opt);\n\t\t\t}\n\t\t};\n\n\t\t// reset operations on empty\n\t\topt = std::nullopt; fn_assign_nullopt();\n\t\topt = std::nullopt; fn_assign_opt(tc::optional<T>());\n\t\topt = std::nullopt; fn_assign_opt(tc::as_lvalue(tc::optional<T>()));\n\t\topt = std::nullopt; fn_assign_opt(tc::explicit_cast<T*>(nullptr));\n\n\t\t// emplace operations on empty\n\t\topt = std::nullopt; fn_emplace(value1);\n\t\topt = std::nullopt; fn_assign_opt(tc::optional<T>(std::in_place, value1));\n\t\topt = std::nullopt; fn_assign_opt(tc::as_lvalue(tc::optional<T>(std::in_place, value1)));\n\t\topt = std::nullopt; fn_assign_opt(&value1);\n\n\t\t// reset operations on non-empty\n\t\ttc::optional_emplace(opt, value1); fn_assign_nullopt();\n\t\ttc::optional_emplace(opt, value1); fn_assign_opt(tc::optional<T>());\n\t\ttc::optional_emplace(opt, value1); fn_assign_opt(tc::as_lvalue(tc::optional<T>()));\n\t\ttc::optional_emplace(opt, value1); fn_assign_opt(tc::explicit_cast<T*>(nullptr));\n\n\t\t// emplace operations on non-empty\n\t\ttc::optional_emplace(opt, value2); fn_emplace(value1);\n\t\ttc::optional_emplace(opt, value2); fn_assign_opt(tc::optional<T>(std::in_place, value1));\n\t\ttc::optional_emplace(opt, value2); fn_assign_opt(tc::as_lvalue(tc::optional<T>(std::in_place, value1)));\n\t\ttc::optional_emplace(opt, value2); fn_assign_opt(&value1);\n\n\t\t// self-assign\n\t\topt = std::nullopt; fn_assign_opt(opt);\n\t\topt = std::nullopt; fn_assign_opt(tc_move(opt));\n\t\ttc::optional_emplace(opt, value1); fn_assign_opt(opt);\n\t\t// tc::optional_emplace(opt, value1); fn_assign_opt(tc_move(opt)); - self-move assign is not guaranteed to work according to the standard\n\t}\n}\n\nUNITTESTDEF(optional) {\n\ttest_optional_ctor(11);\n\ttest_optional_ops(11, 42);\n\n\ttest_optional_ctor(std::string(\"This is a string longer than SSO, so we can test actual heap allocation and stuff.\"));\n\ttest_optional_ops(std::string(\"This is a string longer than SSO, so we can test actual heap allocation and stuff.\"), std::string(\"short\"));\n\n\tstruct SEmpty {\n\t\tSEmpty() = default;\n\t\tSEmpty(int) {}\n\n\t\tbool operator==(SEmpty const&) const noexcept = default;\n\t\tbool operator==(int) const noexcept { return true; }\n\t};\n\ttest_optional_ctor(SEmpty{});\n\ttest_optional_ops(SEmpty{}, 11);\n}\n\nUNITTESTDEF(make_optional_reference_or_value) {\n\tint obj = 42;\n\tint const cobj = 42;\n\n\tstd::same_as<tc::optional<int&>> auto opt_obj = tc::make_optional_reference_or_value(obj);\n\t_ASSERTEQUAL(&*opt_obj, &obj);\n\n\tstd::same_as<tc::optional<int const&>> auto opt_cobj = tc::make_optional_reference_or_value(cobj);\n\t_ASSERTEQUAL(&*opt_cobj, &cobj);\n\n\tstd::same_as<tc::optional<int>> auto opt_rvalue = tc::make_optional_reference_or_value(42);\n\t_ASSERTEQUAL(*opt_rvalue, 42);\n\n\tstruct empty {};\n\tempty empty_obj;\n\tempty const empty_cobj;\n\n\tstd::same_as<tc::optional<empty>> auto opt_empty_obj = tc::make_optional_reference_or_value(empty_obj);\n\t_ASSERT(opt_empty_obj);\n\n\tstd::same_as<tc::optional<empty>> auto opt_empty_cobj = tc::make_optional_reference_or_value(empty_cobj);\n\t_ASSERT(opt_empty_cobj);\n\n\tstd::same_as<tc::optional<empty>> auto opt_empty_rvalue = tc::make_optional_reference_or_value(empty());\n\t_ASSERT(opt_empty_rvalue);\n}\n\nUNITTESTDEF(optional_as_range) {\n\tstd::optional<int> on;\n\t_ASSERT(tc::empty(on));\n\t_ASSERTEQUAL(tc::begin(on), tc::end(on));\n\t_ASSERTEQUAL(tc::end(on)-tc::begin(on), 0);\n\ton = 5;\n\tauto const it1 = tc::begin(on);\n\t_ASSERTEQUAL(*it1, 5);\n\tauto& n1 = *it1;\n\t++n1;\n\t_ASSERT(tc::equal(tc::single(6), on));\n\t_ASSERTEQUAL(tc::size(on), 1);\n\ttc::for_each(on, [](auto const n) noexcept {\n\t\t_ASSERTEQUAL(n, 6);\n\t});\n\n\tstd::optional<int> const on2 = 8;\n\tauto itBegin = tc::begin(on2);\n\tauto itEnd = tc::end(on2);\n\t_ASSERTEQUAL(itBegin+1, itEnd);\n\t_ASSERTEQUAL(itEnd-1, itBegin);\n\t_ASSERTEQUAL(itEnd-itBegin, 1);\n\t++itBegin;\n\t_ASSERTEQUAL(itBegin, itEnd);\n\t--itBegin;\n\t_ASSERTEQUAL(itBegin, tc::begin(on2));\n\n\tconstexpr std::optional<bool> ob;\n\tstatic_assert(!tc::any_of(ob));\n\n\tconstexpr std::optional<int> on3 = 10;\n\tconstexpr int n3 = *tc::begin(on3);\n\tstatic_assert(n3 == 10);\n\tstatic_assert(tc::all_of(on3, [](auto const n) constexpr noexcept { return 8 < n; }));\n}\n"
  },
  {
    "path": "tc/range/adjacent_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"iterator_cache.h\"\n#include \"range_adaptor.h\"\n\n#include \"../array.h\"\n#include \"../algorithm/element.h\"\n#include \"../algorithm/size_bounded.h\"\n\nnamespace tc {\n\tnamespace adjacent_adaptor_detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Sink, typename T, std::size_t... i>\n\t\t\tstruct adjacent_adaptor_generator_base_sink { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\t\tstatic auto constexpr N = sizeof...(i) + 1; // corresponds to adjacent_adaptor<Rng, N+1>\n\t\t\t\tSink m_sink;\n\t\t\t\tstd::array<tc::storage_for<T>, N> m_aoval;\n\t\t\t\tstd::size_t m_n = 0;\n\n\t\t\t\tconstexpr ~adjacent_adaptor_generator_base_sink() {\n\t\t\t\t\ttc::for_each(tc::begin_next<tc::return_take>(m_aoval, tc::min(m_n, N)), tc_mem_fn(.dtor));\n\t\t\t\t}\n\n\t\t\t\tconstexpr auto operator()(auto&& u) & MAYTHROW {\n\t\t\t\t\tauto const CallSink = [&]() MAYTHROW {\n\t\t\t\t\t\treturn tc::continue_if_not_break( // MAYTHROW\n\t\t\t\t\t\t\tm_sink,\n\t\t\t\t\t\t\ttc::tie(\n\t\t\t\t\t\t\t\ttc_move_always(*tc::at(m_aoval, m_n % N)),\n\t\t\t\t\t\t\t\t*tc::at(m_aoval, (m_n + i + 1) % N)...,\n\t\t\t\t\t\t\t\tu\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t};\n\t\t\t\t\tif (m_n < N) {\n\t\t\t\t\t\ttc::at(m_aoval, m_n).ctor(tc_move_if_owned(u));\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttc_return_if_break( CallSink() ); // MAYTHROW\n\t\t\t\t\t\ttc::assign_explicit_cast(*tc::at(m_aoval, m_n % N), tc_move_if_owned(u)); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t\t++m_n;\n\t\t\t\t\treturn tc::implicit_cast<tc::common_type_t<decltype(CallSink()), tc::constant<tc::continue_>>>(tc::constant<tc::continue_>());\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename Self, typename Sink, std::size_t... i /*=0,1,...,N-2*/, std::size_t N = sizeof...(i) + 1>\n\t\tconstexpr auto adjacent_adaptor_for_each(Self&& self, Sink sink, std::index_sequence<i...>) MAYTHROW {\n\t\t\tif constexpr (tc::range_with_iterators<decltype(self.base_range())>) {\n\t\t\t\tauto const GenerateAdjacentTuples = [&]() MAYTHROW {\n\t\t\t\t\tauto const itEnd = tc::end(self.base_range());\n\t\t\t\t\tauto it = tc::begin(self.base_range());\n\t\t\t\t\tauto ait=tc::explicit_cast<std::array<\n\t\t\t\t\t\ttc::iterator_cache<decltype(it)>,\n\t\t\t\t\t\tN\n\t\t\t\t\t>>(tc::func_tag, [&](std::size_t) noexcept { return it++; });\n\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tfor (std::size_t n = 0; n<N; ++n) {\n\t\t\t\t\t\t\tif (it == itEnd) {\n\t\t\t\t\t\t\t\treturn tc::continue_if_not_break(sink, tc::tie(*tc_move_always(tc::at(ait, n)), *tc_move_always(tc::at(ait, (n + i + 1) % N))...)); // MAYTHROW\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc::tie(*tc_move_always(tc::at(ait, n)), *tc::at(ait, (n + i + 1) % N)...))) // MAYTHROW\n\t\t\t\t\t\t\ttc::at(ait, n) = it;\n\t\t\t\t\t\t\t++it;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\treturn tc_conditional_prvalue_as_val(\n\t\t\t\t\ttc::size_bounded(self.base_range(), N)<N,\n\t\t\t\t\ttc::constant<tc::continue_>(),\n\t\t\t\t\tGenerateAdjacentTuples() // MAYTHROW\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn tc::for_each(\n\t\t\t\t\ttc_move_if_owned(self).base_range(),\n\t\t\t\t\tstd::ref(tc::as_lvalue(no_adl::adjacent_adaptor_generator_base_sink<\n\t\t\t\t\t\ttc::decay_t<Sink>,\n\t\t\t\t\t\ttc::range_value_t<decltype(std::declval<Self>().base_range())>,\n\t\t\t\t\t\ti...\n\t\t\t\t\t>{tc_move(sink)}))\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tnamespace adjacent_adaptor_adl {\n\t\ttemplate<typename Rng, std::size_t N, bool HasIterator = tc::range_with_iterators<Rng>>\n\t\tstruct adjacent_adaptor;\n\n\t\ttemplate<typename Rng, std::size_t N>\n\t\tstruct [[nodiscard]] adjacent_adaptor<Rng, N, false> : tc::range_adaptor_base_range<Rng> {\n\t\t\tstatic_assert( 1 < N );\n\t\t\tusing tc::range_adaptor_base_range<Rng>::range_adaptor_base_range;\n\n\t\t\ttemplate<tc::decayed_derived_from<adjacent_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn adjacent_adaptor_detail::adjacent_adaptor_for_each(\n\t\t\t\t\ttc_move_if_owned(self),\n\t\t\t\t\ttc_move_if_owned(sink),\n\t\t\t\t\tstd::make_index_sequence<N - (tc::range_with_iterators<Rng> ? 1 : 2)>()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t[[nodiscard]] constexpr auto size() const& MAYTHROW requires tc::has_size<Rng> {\n\t\t\t\treturn tc::compute_range_adaptor_size<[]<typename SizeT>(SizeT const n) noexcept {\n\t\t\t\t\tif( n < N ) {\n\t\t\t\t\t\treturn tc::explicit_cast<SizeT>(0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn tc::explicit_cast<SizeT>(n - (N - 1));\n\t\t\t\t\t}\n\t\t\t\t}>(this->base_range());\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, adjacent_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_list<\n\t\t\t\tboost::mp11::mp_repeat_c<\n\t\t\t\t\ttc::tuple<boost::mp11::mp_apply<\n\t\t\t\t\t\ttc::common_reference_t,\n\t\t\t\t\t\ttc::mp_transform<\n\t\t\t\t\t\t\tstd::add_rvalue_reference_t,\n\t\t\t\t\t\t\ttc::range_output_t<decltype(std::declval<Self>().base_range())>\n\t\t\t\t\t\t>\n\t\t\t\t\t>>,\n\t\t\t\t\tN\n\t\t\t\t>\n\t\t\t> {} // unevaluated\n\t\t};\n\t}\n\n\tnamespace adjacent_adaptor_detail::no_adl {\n\t\ttemplate<typename Rng, std::size_t N>\n\t\tstruct adjacent_index {\n\t\t\tconstexpr adjacent_index() = default;\n\t\t\ttemplate<std::size_t... I>\n\t\t\tconstexpr adjacent_index(Rng const& rng, index_t<std::remove_reference_t<Rng>> idx, std::index_sequence<I...>) noexcept\n\t\t\t\t: m_aidx{idx, ((tc::at_end_index(rng, idx) ? tc::discard(I) : tc::increment_index(rng, idx)), idx)...}\n\t\t\t{\n\t\t\t\tSTATICASSERTSAME(std::index_sequence<I...>, std::make_index_sequence<N - 1>);\n\t\t\t}\n\n\t\t\t// If size(rng) < N, the single index has m_aidx = {begin_index(), ..., end_index(), ... end_index()}.\n\t\t\ttc::index_t<std::remove_reference_t<Rng>> m_aidx[N];\n\n\t\t\tfriend constexpr bool operator==(adjacent_index const& lhs, adjacent_index const& rhs) noexcept {\n\t\t\t\treturn lhs.m_aidx[0] == rhs.m_aidx[0];\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace adjacent_adaptor_adl {\n\t\ttemplate<typename Rng, std::size_t N>\n\t\tstruct [[nodiscard]] adjacent_adaptor<Rng, N, true>\n\t\t\t: adjacent_adaptor<Rng, N, false>\n\t\t\t, tc::range_iterator_from_index<\n\t\t\t\tadjacent_adaptor<Rng, N, true>,\n\t\t\t\tadjacent_adaptor_detail::no_adl::adjacent_index<Rng, N>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = adjacent_adaptor<Rng, N, true>;\n\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=std::disjunction<tc::has_stashing_index<std::remove_reference_t<Rng>>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\t\tusing adjacent_adaptor<Rng, N, false>::adjacent_adaptor;\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn {this->base_range(), this->base_begin_index(), std::make_index_sequence<N - 1>()};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn tc::at_end_index(this->base_range(), idx.m_aidx[N - 1]);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index\n\t\t\t\trequires\n\t\t\t\t\ttc::has_end_index<std::remove_reference_t<Rng>> &&\n\t\t\t\t\ttc::has_decrement_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\tauto const idxBegin = this->base_begin_index();\n\t\t\t\tauto idxBase = this->base_end_index();\n\t\t\t\ttc_index idx;\n\t\t\t\tidx.m_aidx[N - 1] = idxBase;\n\t\t\t\tfor( std::size_t i = N - 1; 0 < i; ) {\n\t\t\t\t\t--i;\n\t\t\t\t\tif( idxBegin == idxBase ) {\n\t\t\t\t\t\tidx = this->begin_index(); // Not return begin_index(); for NRVO\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttc::decrement_index(this->base_range(), idxBase);\n\t\t\t\t\t\tidx.m_aidx[i] = idxBase;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t// std::ranges::move(tc::begin_next<tc::return_drop>(idx.m_aidx), tc::begin(idx.m_aidx));\n\t\t\t\tfor( std::size_t i = 0; i < N - 1; ++i ) {\n\t\t\t\t\tidx.m_aidx[i] = tc_move_always(idx.m_aidx[i + 1]);\n\t\t\t\t}\n\t\t\t\ttc::increment_index(this->base_range(), idx.m_aidx[N - 1]);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\tconstexpr,\n\t\t\t\tdecrement_index\n\t\t\t)(tc_index& idx) const& noexcept -> void requires tc::has_decrement_index<std::remove_reference_t<Rng>> {\n\t\t\t\t// std::ranges::move_backward(tc::end_prev<tc::return_take>(idx.m_aidx), tc::end(idx.m_aidx));\n\t\t\t\tfor( std::size_t i = N - 1; 0 < i; ) {\n\t\t\t\t\t--i;\n\t\t\t\t\tidx.m_aidx[i + 1] = tc_move_always(idx.m_aidx[i]);\n\t\t\t\t}\n\t\t\t\ttc::decrement_index(this->base_range(), idx.m_aidx[0]);\n\t\t\t}\n\n\t\t\ttemplate<std::size_t... I>\n\t\t\tstatic constexpr auto dereference_index_impl(auto& self, auto&& idx, std::index_sequence<I...>) MAYTHROW\n\t\t\t\t-> tc::tuple<decltype(tc::dereference_index(self.base_range(), tc_move_if_owned(idx).m_aidx[I]))...>\n\t\t\t{\n\t\t\t\treturn {{\n\t\t\t\t\t{ tc::dereference_index(self.base_range(), tc_move_if_owned(idx).m_aidx[I]) }...\n\t\t\t\t}};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) const& MAYTHROW {\n\t\t\t\treturn dereference_index_impl(*this, tc_move_if_owned(idx), std::make_index_sequence<N>());\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) & MAYTHROW {\n\t\t\t\treturn dereference_index_impl(*this, tc_move_if_owned(idx), std::make_index_sequence<N>());\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\tconstexpr,\n\t\t\t\tadvance_index\n\t\t\t)(tc_index& idx, typename boost::range_difference<Rng>::type d) const& MAYTHROW -> void requires tc::has_advance_index<std::remove_reference_t<Rng>> {\n\t\t\t\tidx = {this->base_range(), tc_modified(idx.m_aidx[0], tc::advance_index(this->base_range(), _, d)), std::make_index_sequence<N - 1>()};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\tconstexpr,\n\t\t\t\tdistance_to_index\n\t\t\t)(tc_index const& idxLhs, tc_index const& idxRhs) const& noexcept requires tc::has_distance_to_index<std::remove_reference_t<Rng>> {\n\t\t\t\treturn tc::distance_to_index(this->base_range(), idxLhs.m_aidx[0], idxRhs.m_aidx[0]);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\tconstexpr,\n\t\t\t\tmiddle_point\n\t\t\t)(tc_index& idxLhs, tc_index const& idxRhs) const& noexcept -> void requires tc::has_middle_point<std::remove_reference_t<Rng>> {\n\t\t\t\ttc::middle_point(this->base_range(), idxLhs.m_aidx[0], idxRhs.m_aidx[0]);\n\t\t\t\tidxLhs = {this->base_range(), idxLhs.m_aidx[0], std::make_index_sequence<N - 1>()};\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Rng, std::size_t N>\n\tconstexpr auto enable_stable_index_on_move<adjacent_adaptor_adl::adjacent_adaptor<Rng, N, true>> = tc::stable_index_on_move<Rng>;\n\n\ttemplate<std::size_t N, typename Rng>\n\tconstexpr adjacent_adaptor_adl::adjacent_adaptor<Rng, N> adjacent(Rng&& rng) noexcept {\n\t\treturn {tc::aggregate_tag, tc_move_if_owned(rng)};\n\t}\n}\n"
  },
  {
    "path": "tc/range/cartesian_product_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"reverse_adaptor.h\"\n#include \"../array.h\"\n#include \"../algorithm/accumulate.h\"\n\nnamespace tc {\n\tnamespace cartesian_product_adaptor_adl {\n\t\ttemplate<bool HasIterator, typename... Rng>\n\t\tstruct cartesian_product_adaptor;\n\t}\n\n\ttemplate<typename... Rng>\n\tusing cartesian_product_adaptor = cartesian_product_adaptor_adl::cartesian_product_adaptor<(0 < sizeof...(Rng)) && (tc::range_with_iterators<Rng> && ...), Rng...>;\n\n\tnamespace cartesian_product_adaptor_detail {\n\t\ttemplate<bool bLast>\n\t\tconstexpr static decltype(auto) select_element(auto&& val) noexcept {\n\t\t\tif constexpr(bLast) {\n\t\t\t\treturn tc_move_if_owned(val);\n\t\t\t} else {\n\t\t\t\treturn tc_const_forward(val);\n\t\t\t}\n\t\t}\n\n\t\t// MSVC workaround: move out of cartesian_product_adaptor to shorten symbol names.\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Self, typename Sink, typename... Ts>\n\t\t\tstruct cartesian_product_sink;\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Self, typename Sink, typename... Ts>\n\t\t\tstruct cartesian_product_sink {\n\t\t\t\tusing guaranteed_break_or_continue = std::conditional_t<\n\t\t\t\t\tstd::is_same<tc::constant<tc::continue_>, tc::guaranteed_break_or_continue_t<Sink>>::value,\n\t\t\t\t\ttc::constant<tc::continue_>,\n\t\t\t\t\ttc::break_or_continue\n\t\t\t\t>;\n\n\t\t\t\tSelf& m_self;\n\t\t\t\tSink const& m_sink;\n\t\t\t\ttc::tuple<Ts...>& m_ts;\n\n\t\t\t\ttemplate<typename T>\n\t\t\t\tconstexpr auto operator()(T&& val) const& return_decltype_MAYTHROW(\n\t\t\t\t\tcartesian_product_adaptor_for_each_impl( // recursive MAYTHROW\n\t\t\t\t\t\ttc::forward_like<Self>(m_self),\n\t\t\t\t\t\tm_sink,\n\t\t\t\t\t\ttc::tuple_cat(\n\t\t\t\t\t\t\t/*cast to const rvalue*/tc_move_always_even_const(tc::as_const(m_ts)),\n\t\t\t\t\t\t\ttc::tie(\n\t\t\t\t\t\t\t\tcartesian_product_adaptor_detail::select_element</*bLast*/std::remove_reference_t<Self>::c_nCartesianProductAdaptorFactors == sizeof...(Ts) + 1>(\n\t\t\t\t\t\t\t\t\ttc_move_if_owned(val)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t};\n\t\t}\n\t}\n\n\tnamespace cartesian_product_adaptor_adl {\n\t\ttemplate<typename... Rng>\n\t\tstruct [[nodiscard]] cartesian_product_adaptor</*HasIterator*/false, Rng...> {\n\t\tprotected:\n\t\t\ttc::tuple<tc::range_adaptor_base_range<Rng>...> m_tupleadaptbaserng;\n\n\t\tpublic:\n\t\t\tconstexpr cartesian_product_adaptor() = default;\n\t\t\ttemplate<typename... Rhs>\n\t\t\tconstexpr cartesian_product_adaptor(aggregate_tag_t, Rhs&&... rhs) noexcept\n\t\t\t\t: m_tupleadaptbaserng{{ {{aggregate_tag, tc_move_if_owned(rhs)}}... }}\n\t\t\t{}\n\n\t\t\tstatic bool constexpr c_bIsCartesianProductAdaptor = true;\n\t\t\tstatic auto constexpr c_nCartesianProductAdaptorFactors = sizeof...(Rng);\n\n\t\t\tconstexpr auto size() const& MAYTHROW requires (... && tc::has_size<Rng>) {\n\t\t\t\treturn tc_apply([](auto const& ... rng) MAYTHROW {\n\t\t\t\t\treturn tc::compute_range_adaptor_size<[](auto const ... n) noexcept {\n\t\t\t\t\t\treturn tc::as_unsigned((... * n));\n\t\t\t\t\t}>(rng.base_range()...);\n\t\t\t\t}, m_tupleadaptbaserng);\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<typename Self, typename Sink, typename... Ts, std::enable_if_t<sizeof...(Ts) == sizeof...(Rng)>* = nullptr, std::enable_if_t<tc::decayed_derived_from<Self, cartesian_product_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend constexpr auto cartesian_product_adaptor_for_each_impl(Self const&, Sink const& sink, tc::tuple<Ts...> ts) return_decltype_MAYTHROW(\n\t\t\t\ttc::continue_if_not_break(sink, tc_move(ts)) // MAYTHROW\n\t\t\t)\n\n\t\t\ttemplate<typename Self, typename Sink, typename... Ts, std::enable_if_t<sizeof...(Ts) < sizeof...(Rng)>* = nullptr, std::enable_if_t<tc::decayed_derived_from<Self, cartesian_product_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend constexpr auto cartesian_product_adaptor_for_each_impl(Self&& self, Sink const& sink, tc::tuple<Ts...> ts) return_decltype_MAYTHROW(\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::get<sizeof...(Ts)>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range(),\n\t\t\t\t\tcartesian_product_adaptor_detail::no_adl::cartesian_product_sink<Self, Sink, Ts...>{self, sink, ts}\n\t\t\t\t) // recursive MAYTHROW\n\t\t\t)\n\n\t\t\ttemplate<typename Self, typename Sink, std::enable_if_t<tc::decayed_derived_from<Self, cartesian_product_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink const sink) return_decltype_MAYTHROW(\n\t\t\t\tcartesian_product_adaptor_for_each_impl(tc_move_if_owned(self), sink, tc::make_tuple()) // MAYTHROW\n\t\t\t)\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, cartesian_product_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_list<tc::tuple<\n\t\t\t\tboost::mp11::mp_apply<\n\t\t\t\t\ttc::common_reference_t,\n\t\t\t\t\ttc::mp_transform<\n\t\t\t\t\t\tstd::add_rvalue_reference_t,\n\t\t\t\t\t\ttc::range_output_t<decltype(*std::declval<tc::apply_cvref_t<tc::reference_or_value<Rng>, Self>>())>\n\t\t\t\t\t>\n\t\t\t\t>...\n\t\t\t>> {} // unevaluated\n\t\t};\n\n\t\ttemplate <typename RangeReturn, IF_TC_CHECKS(typename CheckUnique,) typename CartesianProductAdaptor, typename... Ts> requires std::remove_reference_t<CartesianProductAdaptor>::c_bIsCartesianProductAdaptor\n\t\t[[nodiscard]] constexpr decltype(auto) find_first_or_unique_impl(std::type_identity<RangeReturn>, IF_TC_CHECKS(CheckUnique bCheckUnique,) CartesianProductAdaptor&& rngtpl, tc::tuple<Ts...> const& tpl) MAYTHROW {\n\t\t\tif constexpr( RangeReturn::requires_iterator ) {\n\t\t\t\ttypename std::remove_reference_t<CartesianProductAdaptor>::tc_index idx;\n\t\t\t\tif (tc::continue_ == tc::for_each(\n\t\t\t\t\ttc::zip(std::remove_reference_t<CartesianProductAdaptor>::base_ranges(tc_move_if_owned(rngtpl)), tpl, idx),\n\t\t\t\t\t[&](auto&& baserng, auto const& t, auto& baseidx) MAYTHROW {\n\t\t\t\t\t\tif( auto it = tc::find_first_or_unique(std::type_identity<tc::return_element_or_null>(), IF_TC_CHECKS(bCheckUnique, ) tc_move_if_owned(baserng), t) ) { // MAYTHROW\n\t\t\t\t\t\t\tbaseidx = tc::iterator2index<decltype(baserng)>(tc_move(it));\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t) ) {\n\t\t\t\t\treturn RangeReturn::pack_element(rngtpl.make_iterator(tc_move(idx)), tc_move_if_owned(rngtpl)); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\treturn RangeReturn::template pack_no_element(tc_move_if_owned(rngtpl));\n\t\t\t\t}\n\t\t\t} else if constexpr( std::same_as<RangeReturn, tc::return_bool> ) {\n\t\t\t\treturn tc::all_of(\n\t\t\t\t\ttc::zip(std::remove_reference_t<CartesianProductAdaptor>::base_ranges(tc_move_if_owned(rngtpl)), tpl),\n\t\t\t\t\t[&](auto&& baserng, auto const& t) MAYTHROW {\n\t\t\t\t\t\treturn tc::find_first_or_unique(std::type_identity<tc::return_bool>(), IF_TC_CHECKS(bCheckUnique, ) tc_move_if_owned(baserng), t); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\ttc::range_value_t<CartesianProductAdaptor> tplFound; // TODO Support non-default constructible and non-assignable types.\n\t\t\t\tif (tc::continue_ == tc::for_each(\n\t\t\t\t\ttc::zip(std::remove_reference_t<CartesianProductAdaptor>::base_ranges(tc_move_if_owned(rngtpl)), tpl, tplFound),\n\t\t\t\t\t[&](auto&& baserng, auto const& t, auto& tFound) MAYTHROW {\n\t\t\t\t\t\tif( auto ot = tc::find_first_or_unique(std::type_identity<tc::return_value_or_none>(), IF_TC_CHECKS(bCheckUnique, ) tc_move_if_owned(baserng), t) ) { // MAYTHROW\n\t\t\t\t\t\t\ttFound = *tc_move(ot);\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t)) {\n\t\t\t\t\treturn RangeReturn::template pack_element<CartesianProductAdaptor>(tc_move_if_owned(tplFound)); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\treturn RangeReturn::template pack_no_element<CartesianProductAdaptor>();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tnamespace cartesian_product_adaptor_detail {\n\t\t // MSVC workaround: move lambdas out of cartesian_product_adaptor to shorten symbol names: (every range would appear twice otherwise)\n\t\tauto constexpr fn_base_begin_index = tc_mem_fn(.base_begin_index);\n\t\tauto constexpr fn_end_index = [](auto const nconst, auto const& adaptbaserng) MAYTHROW {\n\t\t\tif constexpr( 0 == nconst() ) {\n\t\t\t\treturn adaptbaserng.base_end_index(); // MAYTHROW\n\t\t\t} else {\n\t\t\t\treturn adaptbaserng.base_begin_index(); // MAYTHROW\n\t\t\t}\n\t\t};\n\t\tauto constexpr fn_increment_index = [](auto const nconst, auto const& adaptbaserng, auto& baseidx) MAYTHROW {\n\t\t\ttc::increment_index(adaptbaserng.base_range(), baseidx); // MAYTHROW\n\t\t\tif constexpr( 0 != nconst() ) {\n\t\t\t\tif( tc::at_end_index(adaptbaserng.base_range(), baseidx) ) { // MAYTHROW\n\t\t\t\t\tbaseidx = adaptbaserng.base_begin_index(); // MAYTHROW\n\t\t\t\t\treturn tc::continue_;\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::break_;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tauto constexpr fn_decrement_index = [](auto const nconst, auto const& adaptbaserng, auto& baseidx) noexcept {\n\t\t\tif constexpr( 0 != nconst() ) {\n\t\t\t\tif( adaptbaserng.base_begin_index() == baseidx ) { // MAYTHROW\n\t\t\t\t\tbaseidx = adaptbaserng.base_end_index(); // MAYTHROW\n\t\t\t\t\ttc::decrement_index(adaptbaserng.base_range(), baseidx); // MAYTHROW\n\t\t\t\t\treturn tc::continue_;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttc::decrement_index(adaptbaserng.base_range(), baseidx); // MAYTHROW\n\t\t\treturn tc::break_;\n\t\t};\n\n\t\ttemplate<typename DifferenceType>\n\t\tauto constexpr fn_distance_to_index = [](auto& nAccu, auto const nconst, auto const& adaptbaserng, auto const& baseidxLhs, auto const& baseidxRhs) MAYTHROW {\n\t\t\tif constexpr( 0 < nconst() ) {\n\t\t\t\ttc::assign_mul(nAccu, tc::explicit_cast<DifferenceType>(tc::size_raw(adaptbaserng.base_range()))); // MAYTHROW\n\t\t\t}\n\t\t\ttc::assign_add(nAccu, tc::explicit_cast<DifferenceType>(tc::distance_to_index(adaptbaserng.base_range(), baseidxLhs, baseidxRhs))); // MAYTHROW\n\t\t};\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename DifferenceType>\n\t\t\tstruct fn_advance_index {\n\t\t\t\tDifferenceType& m_d;\n\t\t\t\tconstexpr auto operator()(auto const nconst, auto&& adaptbaserng, auto& baseidx) const& MAYTHROW {\n\t\t\t\t\tif constexpr( 0 == nconst() ) {\n\t\t\t\t\t\ttc::advance_index(adaptbaserng.base_range(), baseidx, tc::explicit_cast<typename boost::range_difference<decltype(adaptbaserng.base_range())>::type>(m_d)); // MAYTHROW\n\t\t\t\t\t} else {\n\t\t\t\t\t\tauto const nSize = tc::explicit_cast<DifferenceType>(tc::size_raw(adaptbaserng.base_range()));\n\t\t\t\t\t\tauto const nOldIdx = tc::distance_to_index(adaptbaserng.base_range(), adaptbaserng.base_begin_index(), baseidx);\n\t\t\t\t\t\tauto nNewIdx = nOldIdx + m_d;\n\t\t\t\t\t\tm_d = nNewIdx / nSize;\n\t\t\t\t\t\tnNewIdx %= nSize;\n\t\t\t\t\t\tif(nNewIdx < 0) {\n\t\t\t\t\t\t\tnNewIdx+=nSize;\n\t\t\t\t\t\t\t--m_d;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttc::advance_index(adaptbaserng.base_range(), baseidx, tc::explicit_cast<typename boost::range_difference<decltype(adaptbaserng.base_range())>::type>(nNewIdx - nOldIdx)); // MAYTHROW\n\t\t\t\t\t\treturn tc::continue_if(m_d != 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tstruct fn_middle_point {\n\t\t\t\tbool& m_bAdvanced;\n\t\t\t\tvoid operator()(auto const& adaptbaserng, auto& baseidx, auto const& baseidxEnd) const& MAYTHROW {\n\t\t\t\t\tif( m_bAdvanced ) {\n\t\t\t\t\t\tbaseidx = adaptbaserng.base_begin_index(); // MAYTHROW\n\t\t\t\t\t} else if( baseidx != baseidxEnd ) {\n\t\t\t\t\t\tauto const baseidxBegin = baseidx;\n\t\t\t\t\t\ttc::middle_point(adaptbaserng.base_range(), baseidx, baseidxEnd); // MAYTHROW\n\t\t\t\t\t\tm_bAdvanced = baseidxBegin != baseidx;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\n\tnamespace cartesian_product_adaptor_adl {\n\t\ttemplate<typename Rng0, typename... Rng>\n\t\tstruct [[nodiscard]] cartesian_product_adaptor</*HasIterator*/true, Rng0, Rng...>\n\t\t\t: product_index_range_adaptor<cartesian_product_adaptor, /*IndexTemplate*/tc::tuple, Rng0, Rng...> {\n\t\tprivate:\n\t\t\tusing this_type = cartesian_product_adaptor;\n\t\t\tusing base_ = typename cartesian_product_adaptor::product_index_range_adaptor;\n\t\tpublic:\n\t\t\tconstexpr cartesian_product_adaptor() = default;\n\t\t\tusing base_::base_;\n\n\t\t\tusing typename base_::tc_index;\n\t\t\tusing difference_type = std::ptrdiff_t; // Like .size(), which returns size_t.\n\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\tprivate:\n\t\t\tstatic bool constexpr c_bCommonRange = tc::has_end_index<std::remove_reference_t<Rng0>>;\n\n\t\t\tconstexpr bool internal_at_end_index(tc_index const& idx) const& MAYTHROW {\n\t\t\t\treturn tc::any_of(tc::zip(this->m_tupleadaptbaserng, idx), [](auto const& adaptbaserng, auto const& baseidx) MAYTHROW {\n\t\t\t\t\treturn tc::at_end_index(adaptbaserng.base_range(), baseidx); // MAYTHROW\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& MAYTHROW -> tc_index {\n\t\t\t\tauto idx = tc::tuple_transform(this->m_tupleadaptbaserng, cartesian_product_adaptor_detail::fn_base_begin_index); // MAYTHROW\n\t\t\t\tif constexpr( c_bCommonRange ) {\n\t\t\t\t\tif( internal_at_end_index(idx) ) { // MAYTHROW\n\t\t\t\t\t\ttc::get<0>(idx) = tc::get<0>(this->m_tupleadaptbaserng).base_end_index(); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& MAYTHROW requires c_bCommonRange {\n\t\t\t\treturn tc::tuple_transform(tc::enumerate(this->m_tupleadaptbaserng), cartesian_product_adaptor_detail::fn_end_index);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& MAYTHROW -> bool {\n\t\t\t\tif constexpr( c_bCommonRange ) {\n\t\t\t\t\treturn tc::at_end_index(tc::get<0>(this->m_tupleadaptbaserng).base_range(), tc::get<0>(idx)); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\t// TODO This is suboptimal.\n\t\t\t\t\t// We should represent end by setting the end iterator at the first common range or add a bool to the index, if no factor is a common range.\n\t\t\t\t\t// On may also argue that the index should always contain the bool because increment_index, decrement_index and advance_index usually know\n\t\t\t\t\t// whether the resulting index is at end.\n\t\t\t\t\treturn internal_at_end_index(idx); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& MAYTHROW -> void {\n\t\t\t\ttc::for_each(tc::reverse(tc::enumerate(tc::zip(this->m_tupleadaptbaserng, idx))), cartesian_product_adaptor_detail::fn_increment_index);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& MAYTHROW -> void\n\t\t\t\trequires\n\t\t\t\t\t(tc::has_decrement_index<std::remove_reference_t<Rng0>> && ... && tc::has_decrement_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_end_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\ttc::for_each(tc::reverse(tc::enumerate(tc::zip(this->m_tupleadaptbaserng, idx))), cartesian_product_adaptor_detail::fn_decrement_index);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, advance_index)(tc_index& idx, difference_type d) const& MAYTHROW -> void\n\t\t\t\trequires\n\t\t\t\t\t(tc::has_advance_index<std::remove_reference_t<Rng0>> && ... && tc::has_advance_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_distance_to_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_size<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\tif( d != 0 ) {\n\t\t\t\t\ttc::for_each(\n\t\t\t\t\t\ttc::reverse(tc::enumerate(tc::zip(this->m_tupleadaptbaserng, idx))),\n\t\t\t\t\t\tcartesian_product_adaptor_detail::no_adl::fn_advance_index<difference_type>{d}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& MAYTHROW -> difference_type\n\t\t\t\trequires\n\t\t\t\t\t(tc::has_distance_to_index<std::remove_reference_t<Rng0>> && ... && tc::has_distance_to_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_size<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\treturn tc::accumulate(\n\t\t\t\t\ttc::enumerate(tc::zip(this->m_tupleadaptbaserng, idxLhs, idxRhs)),\n\t\t\t\t\ttc::explicit_cast<difference_type>(0),\n\t\t\t\t\tcartesian_product_adaptor_detail::fn_distance_to_index<difference_type>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, middle_point)(tc_index& idx, tc_index const& idxEnd) const& MAYTHROW -> void\n\t\t\t\trequires\n\t\t\t\t\t(tc::has_middle_point<std::remove_reference_t<Rng0>> && ... && tc::has_middle_point<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\tbool bAdvanced = false;\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx, idxEnd),\n\t\t\t\t\tcartesian_product_adaptor_detail::no_adl::fn_middle_point{bAdvanced}\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename... Rng>\n\tconstexpr auto enable_stable_index_on_move<cartesian_product_adaptor_adl::cartesian_product_adaptor</*HasIterator*/true, Rng...>>\n\t\t= (tc::stable_index_on_move<Rng> && ...);\n\n\ttemplate<typename... Rng>\n\tconstexpr decltype(auto) cartesian_product(Rng&&... rng) noexcept {\n\t\tif constexpr( 0 == sizeof...(Rng) ) {\n\t\t\treturn tc::single(tc::tuple<>());\n\t\t} else {\n\t\t\treturn tc::cartesian_product_adaptor<Rng...>(tc::aggregate_tag, tc_move_if_owned(rng)...);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/range/concat_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/utility.h\"\n#include \"../base/invoke_with_constant.h\"\n\n#include \"../algorithm/size.h\"\n#include \"../algorithm/accumulate.h\"\n#include \"../variant.h\"\n#include \"../algorithm/quantifier.h\"\n#include \"../algorithm/empty.h\"\n#include \"../tuple.h\"\n\n#include \"range_adaptor.h\"\n#include \"index_range.h\"\n#include \"meta.h\"\n#include \"transform.h\"\n#include \"iota_range.h\"\n#include \"transform_adaptor.h\"\n#include \"reverse_adaptor.h\"\n\nnamespace tc {\n\tnamespace concat_adaptor_adl {\n\t\ttemplate<bool HasIterator, typename... Rng>\n\t\tstruct concat_adaptor_impl;\n\t}\n\ttemplate<typename... Rng>\n\tusing concat_adaptor = concat_adaptor_adl::concat_adaptor_impl<tc::ranges_with_common_reference<Rng...>, Rng...>;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct is_concat_range final: tc::constant<false> {};\n\n\t\ttemplate<typename... Rng>\n\t\tstruct is_concat_range<tc::concat_adaptor<Rng ...>> final: tc::constant<true> {};\n\t}\n\tusing no_adl::is_concat_range;\n\n\tnamespace concat_detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename ConcatAdaptor, typename Sink, typename = std::remove_cvref_t<ConcatAdaptor>>\n\t\t\tstruct has_for_each;\n\n\t\t\ttemplate<typename ConcatAdaptor, typename Sink, typename... Rng>\n\t\t\tstruct has_for_each<ConcatAdaptor, Sink, tc::concat_adaptor<Rng...>> : tc::constant<\n\t\t\t\t(tc::has_for_each<tc::apply_cvref_t<Rng, ConcatAdaptor>, tc::decay_t<Sink> const&> && ...)\n\t\t\t> {};\n\n\t\t\ttemplate<typename Sink>\n\t\t\tstruct sink {\n\t\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\t\tusing guaranteed_break_or_continue = guaranteed_break_or_continue_t<Sink>;\n\t\t\t\tSink m_sink;\n\n\t\t\t\ttemplate<typename RngAdaptor>\n\t\t\t\tconstexpr auto operator()(RngAdaptor&& rngadaptor) const& return_MAYTHROW(\n\t\t\t\t\ttc::for_each(tc_move_if_owned(rngadaptor).base_range(), m_sink)\n\t\t\t\t)\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename Sink>\n\t\tconstexpr auto make_sink(Sink&& sink) noexcept { // not inline in for_each_impl because of MSVC\n\t\t\treturn no_adl::sink<tc::decay_t<Sink>>{tc_move_if_owned(sink)};\n\t\t}\n\t}\n\n\tnamespace concat_adaptor_adl {\n\t\ttemplate<\n\t\t\ttypename... Rng\n\t\t>\n\t\tstruct [[nodiscard]] concat_adaptor_impl<false, Rng...>\n\t\t{\n\t\t\tstatic_assert(1<sizeof...(Rng)); // singleton range will be forwarded instead of packed into concat_adaptor\n\t\t\ttc::tuple<tc::range_adaptor_base_range<Rng>...> m_tupleadaptbaserng;\n\n\t\tpublic:\n\t\t\ttemplate<typename... Rhs>\n\t\t\tconstexpr concat_adaptor_impl(tc::aggregate_tag_t, Rhs&&... rhs) noexcept\n\t\t\t\t: m_tupleadaptbaserng{{ {{tc::aggregate_tag, tc_move_if_owned(rhs)}}... }}\n\t\t\t{}\n\n\t\t\tusing index_seq = std::make_index_sequence<sizeof...(Rng)>;\n\n\t\t\ttemplate<typename ConcatRng, std::size_t... I>\n\t\t\tfriend constexpr auto forward_base_ranges_as_tuple(ConcatRng&& rng, std::index_sequence<I...>) noexcept;\n\n\t\tprotected:\n\t\t\ttemplate<typename IntConstant>\n\t\t\tconstexpr auto BaseRangeSize(IntConstant nconstIndex) const& noexcept {\n\t\t\t\treturn tc::size_raw(tc::get<nconstIndex()>(m_tupleadaptbaserng).base_range());\n\t\t\t}\n\t\tpublic:\n\t\t\tconstexpr auto size() const& MAYTHROW requires (... && tc::has_size<Rng>) {\n\t\t\t\treturn tc_apply([](auto const& ... rng) MAYTHROW {\n\t\t\t\t\treturn tc::compute_range_adaptor_size<[](auto const ... n) noexcept {\n\t\t\t\t\t\treturn tc::as_unsigned((... + n));\n\t\t\t\t\t}>(rng.base_range()...);\n\t\t\t\t}, m_tupleadaptbaserng);\n\t\t\t}\n\n\t\t\tconstexpr bool empty() const& noexcept {\n\t\t\t\treturn tc::all_of(m_tupleadaptbaserng, [](auto const& adaptbaserng) noexcept { return tc::empty(adaptbaserng.base_range()); });\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, concat_adaptor_impl>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<boost::mp11::mp_append<\n\t\t\t\ttc::range_output_t<decltype(std::declval<tc::apply_cvref_t<tc::range_adaptor_base_range<Rng>, Self>>().base_range())>...\n\t\t\t>> {} // unevaluated\n\t\t};\n\n\t\t// Using return_decltype_MAYTHROW here and in concat_detail::no_adl::sink::operator() results\n\t\t// in MSVC 19.15 error C1202: Recursive type or function dependency context too complex.\n\t\ttemplate<typename Self, typename Sink> requires concat_detail::no_adl::has_for_each<Self, Sink>::value\n\t\tconstexpr auto for_each_impl(Self&& self, Sink&& sink) return_MAYTHROW(\n\t\t\ttc::for_each(\n\t\t\t\ttc_move_if_owned(self).m_tupleadaptbaserng,\n\t\t\t\tconcat_detail::make_sink(tc_move_if_owned(sink))\n\t\t\t)\n\t\t)\n\n\t\ttemplate<typename Self, typename Sink> requires tc::is_concat_range<std::remove_cvref_t<Self>>::value\n\t\tconstexpr auto for_each_reverse_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\treturn tc::for_each(\n\t\t\t\ttc::reverse(tc_move_if_owned(self).m_tupleadaptbaserng),\n\t\t\t\t[&](auto&& rngadaptor) MAYTHROW {\n\t\t\t\t\treturn tc::for_each(tc::reverse(tc_move_if_owned(rngadaptor).base_range()), sink);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\ttemplate<typename ConcatRng, std::size_t... I>\n\t\t[[nodiscard]] constexpr auto forward_base_ranges_as_tuple(ConcatRng&& rng, std::index_sequence<I...>) noexcept {\n\t\t\treturn tc::tie(tc::get<I>(tc_move_if_owned(rng).m_tupleadaptbaserng).base_range()...);\n\t\t}\n\n\t\tstruct concat_end_index final {\n\t\t\tfriend bool constexpr operator==(concat_end_index const&, concat_end_index const&) noexcept { return true; }\n\t\t};\n\n\t\ttemplate<\n\t\t\ttypename... Rng\n\t\t>\n\t\tstruct [[nodiscard]] concat_adaptor_impl<true, Rng...> :\n\t\t\tconcat_adaptor_impl<false, Rng...>,\n\t\t\ttc::range_iterator_from_index<\n\t\t\t\tconcat_adaptor_impl<true, Rng...>,\n\t\t\t\tstd::variant<\n\t\t\t\t\ttc::index_t<std::remove_reference_t<\n\t\t\t\t\t\tRng\n\t\t\t\t\t>>...,\n\t\t\t\t\tconcat_end_index\n\t\t\t\t>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = concat_adaptor_impl;\n\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=std::disjunction<tc::has_stashing_index<std::remove_reference_t<Rng>>...>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\t\tusing difference_type = tc::common_type_t<typename boost::range_difference<Rng>::type...>;\n\n\t\t\tusing concat_adaptor_impl<false, Rng...>::concat_adaptor_impl;\n\n\t\tprivate:\n\t\t\ttemplate<std::size_t Index>\n\t\t\tconstexpr tc_index create_begin_index(tc::constant<Index>) const& noexcept {\n\t\t\t\tstatic_assert(0 <= Index && Index <= sizeof...(Rng));\n\t\t\t\tif constexpr (sizeof...(Rng) == Index) {\n\t\t\t\t\treturn tc_index(std::in_place_index<Index>, concat_end_index());\n\t\t\t\t} else {\n\t\t\t\t\treturn tc_index(std::in_place_index<Index>, tc::get<Index>(this->m_tupleadaptbaserng).base_begin_index());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<int Index>\n\t\t\tconstexpr tc_index create_end_index(tc::constant<Index>) const& noexcept {\n\t\t\t\tstatic_assert(0 <= Index);\n\t\t\t\tstatic_assert(Index < sizeof...(Rng));\n\t\t\t\treturn tc_index(std::in_place_index<Index>, tc::get<Index>(this->m_tupleadaptbaserng).base_end_index());\n\t\t\t}\n\n\t\t\ttemplate<int IndexFrom>\n\t\t\tconstexpr void correct_index(tc_index& idx) const& noexcept {\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::make_integer_sequence<std::size_t, IndexFrom, sizeof...(Rng)>(),\n\t\t\t\t\t[&](auto const nconstIndex) noexcept {\n\t\t\t\t\t\tif (tc::at_end_index( tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(idx))) {\n\t\t\t\t\t\t\tidx = create_begin_index(tc::constant<nconstIndex() + 1>());\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn tc_modified(\n\t\t\t\t\tcreate_begin_index(tc::constant<tc::explicit_cast<std::size_t>(0)>()),\n\t\t\t\t\tcorrect_index<0>(_)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn create_begin_index(tc::constant<sizeof...(Rng)>());\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn sizeof...(Rng) == idx.index();\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERT(!this->at_end_index(idx));\n\n\t\t\t\ttc::invoke_with_constant<std::index_sequence_for<Rng...>>(\n\t\t\t\t\t[&](auto const nconstIndex) noexcept { \n\t\t\t\t\t\ttc::increment_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(idx));\n\t\t\t\t\t\tcorrect_index<nconstIndex()>(idx);\n\t\t\t\t\t},\n\t\t\t\t\tidx.index()\n\t\t\t\t);\n\t\t\t}\n\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& noexcept -> void\n\t\t\t\trequires\n\t\t\t\t\t(... && tc::has_decrement_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_end_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\ttc::is_equality_comparable<tc_index>::value\n\t\t\t{\n\t\t\t\ttc::invoke_with_constant<std::make_index_sequence<sizeof...(Rng)+1>>(\n\t\t\t\t\t[&](auto const nconstIndexStart) noexcept {\n\t\t\t\t\t\ttc::for_each(\n\t\t\t\t\t\t\ttc::make_reverse_integer_sequence<int, 0, nconstIndexStart() + 1>(),\n\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept {\n\t\t\t\t\t\t\t\tif constexpr (sizeof...(Rng) == nconstIndex()) {\n\t\t\t\t\t\t\t\t\t idx = create_end_index(tc::constant<nconstIndex() - 1>());\n\t\t\t\t\t\t\t\t\t return tc::continue_;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tauto& idxCurrent = tc::get<nconstIndex()>(idx);\n\t\t\t\t\t\t\t\t\tif constexpr (0 == nconstIndex()) {\n\t\t\t\t\t\t\t\t\t\t_ASSERT( tc::get<0>(this->m_tupleadaptbaserng).base_begin_index() != idxCurrent );\n\t\t\t\t\t\t\t\t\t} else if (tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_begin_index() == idxCurrent) {\n\t\t\t\t\t\t\t\t\t\tidx = create_end_index(tc::constant<nconstIndex() - 1>());\n\t\t\t\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t// Remember early out above\n\t\t\t\t\t\t\t\t\ttc::decrement_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), idxCurrent);\n\t\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tidx.index()\n\t\t\t\t);\n\t\t\t}\n\nMODIFY_WARNINGS(((suppress)(4544))) // 'Func2': default template argument ignored on this template declaration\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc::invoke_with_constant<std::index_sequence_for<Rng...>>(\n\t\t\t\t\t[&](auto const nconstIndex) constexpr MAYTHROW -> decltype(auto) { // return_decltype leads to ICE\n\t\t\t\t\t\treturn tc::dereference_index(\n\t\t\t\t\t\t\ttc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\ttc::get<nconstIndex()>(tc_move_if_owned(idx))\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tidx.index()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) & MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc::invoke_with_constant<std::index_sequence_for<Rng...>>(\n\t\t\t\t\t[&](auto const nconstIndex) constexpr MAYTHROW -> decltype(auto) { // return_decltype leads to ICE\n\t\t\t\t\t\treturn tc::dereference_index(\n\t\t\t\t\t\t\ttc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\ttc::get<nconstIndex()>(tc_move_if_owned(idx))\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tidx.index()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, advance_index)(tc_index& idx, difference_type d) const& noexcept -> void\n\t\t\t\trequires\n\t\t\t\t\t(... && tc::has_distance_to_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_end_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_advance_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\ttc::invoke_with_constant<std::make_index_sequence<sizeof...(Rng)+1>>(\n\t\t\t\t\t[&](auto const nconstIndexStart) noexcept {\n\t\t\t\t\t\tif (d < 0) {\n\t\t\t\t\t\t\ttc::for_each(\n\t\t\t\t\t\t\t\ttc::make_reverse_integer_sequence<int, 0, nconstIndexStart() + 1>(),\n\t\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept {\n\t\t\t\t\t\t\t\t\tif constexpr (sizeof...(Rng) == nconstIndex()) {\n\t\t\t\t\t\t\t\t\t\tidx = create_end_index(tc::constant<nconstIndex() - 1>());\n\t\t\t\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t// As of Visual Studio compiler 19.15.26726, obtaining the range difference_type here as:\n\t\t\t\t\t\t\t\t\t\t//\t\tusing range_difference_t =\n\t\t\t\t\t\t\t\t\t\t//\t\t\ttypename boost::range_difference<decltype(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range())>::type;\n\t\t\t\t\t\t\t\t\t\t// triggers a compiler error, because VS does not properly exclude false statements from compilation when using\n\t\t\t\t\t\t\t\t\t\t// an 'if constexpr' inside a lambda, which means VS attempts to eval the type when nconstIndex==sizeof...(Rng).\n\t\t\t\t\t\t\t\t\t\t// Breaking the evaluation of the difference_type in two steps seems to work though.\n\t\t\t\t\t\t\t\t\t\tusing range_t=decltype(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range());\n\t\t\t\t\t\t\t\t\t\tif constexpr(0 == nconstIndex()) {\n\t\t\t\t\t\t\t\t\t\t\ttc::advance_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::explicit_cast<typename boost::range_difference<range_t>::type>(d)\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tauto const dToBegin = tc::distance_to_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_begin_index()\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\tif (!(d < dToBegin)) {\n\t\t\t\t\t\t\t\t\t\t\t\ttc::advance_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\t\t\ttc::explicit_cast<typename boost::range_difference<range_t>::type>(d)\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\td -= dToBegin;\n\t\t\t\t\t\t\t\t\t\t\t\tidx = create_end_index(tc::constant<nconstIndex() - 1>());\n\t\t\t\t\t\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttc::for_each(\n\t\t\t\t\t\t\t\ttc::make_integer_sequence<std::size_t, nconstIndexStart(), sizeof...(Rng)>(),\n\t\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept {\n\t\t\t\t\t\t\t\t\tusing range_difference_t = typename boost::range_difference<decltype(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range())>::type;\n\t\t\t\t\t\t\t\t\tif constexpr (nconstIndex() == sizeof...(Rng)-1) {\n\t\t\t\t\t\t\t\t\t\ttc::advance_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\ttc::explicit_cast<range_difference_t>(d)\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\tcorrect_index<nconstIndex()>(idx);\n\t\t\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tauto const dToEnd = tc::distance_to_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_end_index()\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\tif (d < dToEnd) {\n\t\t\t\t\t\t\t\t\t\t\ttc::advance_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::get<nconstIndex()>(idx),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::explicit_cast<range_difference_t>(d)\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\td -= dToEnd;\n\t\t\t\t\t\t\t\t\t\t\tidx = create_begin_index(tc::constant<nconstIndex() + 1>());\n\t\t\t\t\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tidx.index()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& noexcept -> difference_type\n\t\t\t\trequires\n\t\t\t\t\t(... && tc::has_distance_to_index<std::remove_reference_t<Rng>>) &&\n\t\t\t\t\t(... && tc::has_end_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\tif (idxLhs.index() == idxRhs.index()) {\n\t\t\t\t\treturn tc::invoke_with_constant<std::make_index_sequence<sizeof...(Rng)+1>>(\n\t\t\t\t\t\t[&](auto const nconstIndex) noexcept -> difference_type {\n\t\t\t\t\t\t\tif constexpr (nconstIndex() == sizeof...(Rng)) {\n\t\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn tc::distance_to_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(idxLhs), tc::get<nconstIndex()>(idxRhs));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tidxLhs.index()\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tauto positive_distance = [&](tc_index const& lhs, tc_index const& rhs) noexcept {\n\t\t\t\t\t\treturn tc::accumulate(\n\t\t\t\t\t\t\ttc::transform(\n\t\t\t\t\t\t\t\ttc::iota(lhs.index() + 1, rhs.index()),\n\t\t\t\t\t\t\t\t[&](auto const nIndex) noexcept {\n\t\t\t\t\t\t\t\t\treturn tc::invoke_with_constant<std::index_sequence_for<Rng...>>(\n\t\t\t\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept { return tc::explicit_cast<difference_type>(this->BaseRangeSize(nconstIndex)); },\n\t\t\t\t\t\t\t\t\t\tnIndex\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttc::invoke_with_constant<std::index_sequence_for<Rng...>>(\n\t\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept -> difference_type {\n\t\t\t\t\t\t\t\t\treturn tc::distance_to_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(lhs), tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_end_index());\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tlhs.index()\n\t\t\t\t\t\t\t) + \n\t\t\t\t\t\t\ttc::invoke_with_constant<std::make_index_sequence<sizeof...(Rng)+1>>(\n\t\t\t\t\t\t\t\t[&](auto const nconstIndex) noexcept -> difference_type {\n\t\t\t\t\t\t\t\t\tif constexpr(nconstIndex() == sizeof...(Rng)) {\n\t\t\t\t\t\t\t\t\t\treturn 0;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\treturn tc::distance_to_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_begin_index(), tc::get<nconstIndex()>(rhs));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\trhs.index()\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\ttc::fn_assign_plus()\n\t\t\t\t\t\t);\n\t\t\t\t\t};\n\n\t\t\t\t\tif (idxLhs.index() < idxRhs.index()) {\n\t\t\t\t\t\treturn positive_distance(idxLhs, idxRhs);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn -positive_distance(idxRhs, idxLhs);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename... Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::concat_adaptor_adl::concat_adaptor_impl<true, Rng...>>\n\t\t= (tc::stable_index_on_move<Rng> && ...);\n\n\tnamespace no_adl {\n\t\tstruct fn_concat_impl final {\n\t\t\t[[nodiscard]] constexpr auto operator()() const& noexcept {\n\t\t\t\treturn tc::empty_range();\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\t[[nodiscard]] constexpr decltype(auto) operator()(Rng&& rng) const& noexcept {\n\t\t\t\treturn tc_move_if_owned(rng);\n\t\t\t}\n\n\t\t\ttemplate<typename... Rng> requires (1<sizeof...(Rng))\n\t\t\t[[nodiscard]] constexpr auto operator()(Rng&&... rng) const& noexcept {\n\t\t\t\treturn tc::concat_adaptor<std::remove_cv_t<Rng>...>(tc::aggregate_tag, tc_move_if_owned(rng)...);\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace concat_detail {\n\t\ttemplate<typename Rng>\n\t\t[[nodiscard]] constexpr auto forward_range_as_tuple(Rng&& rng) noexcept {\n\t\t\tif constexpr( tc::safely_convertible_to<Rng&&, tc::empty_range> ) {\n\t\t\t\treturn tc::tuple<>{};\n\t\t\t} else if constexpr( tc::is_concat_range<std::remove_cvref_t<Rng>>::value ) {\n\t\t\t\treturn forward_base_ranges_as_tuple(tc_move_if_owned(rng), typename std::remove_cvref_t<Rng>::index_seq());\n\t\t\t} else {\n\t\t\t\treturn tc::tie(tc_move_if_owned(rng));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename... Rng>\n\t[[nodiscard]] constexpr decltype(auto) concat(Rng&&... rng) noexcept {\n\t\treturn tc_apply(tc::no_adl::fn_concat_impl(), tc::tuple_cat(tc::concat_detail::forward_range_as_tuple(tc_move_if_owned(rng))...));\n\t}\n}\n"
  },
  {
    "path": "tc/range/concat_adaptor.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/compare.h\"\n#include \"../algorithm/append.h\"\n#include \"../array.h\"\n#include \"../string/format.h\"\n#include \"../container/insert.h\"\n\n#include \"concat_adaptor.h\"\n#include \"filter_adaptor.h\"\n#include \"reverse_adaptor.h\"\n\nstruct non_empty_generator {\n\ttemplate<typename Func> void operator()(Func func) const { func(1); }\n};\n\nUNITTESTDEF(concat_void_generator_test) {\n\tauto rng = tc::concat(\n\t\tnon_empty_generator(),\n\t\ttc::single(5)\n\t);\n\n\ttc::vector<int> vecn;\n\tauto const PushBack = [&](int const n) noexcept { tc::cont_emplace_back(vecn, n); };\n\n\ttc::for_each(rng, PushBack);\n\ttc::for_each(tc::as_const(rng), PushBack);\n\ttc::for_each(tc_move(rng), PushBack);\n\n\tTEST_RANGE_EQUAL(vecn, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1, 5, 1, 5, 1, 5)));\n}\n\nUNITTESTDEF(concat_break_or_continue_generator_test) {\n\tauto rng = tc::concat(\n\t\ttc::single(2),\n\t\ttc::make_generator_range(tc::make_vector(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1, 3)))),\n\t\ttc::single(5)\n\t);\n\n\ttc::vector<int> vecn;\n\tauto const PushBack = [&](int const n) noexcept { tc::cont_emplace_back(vecn, n); return tc::continue_if(1 != n); };\n\n\ttc::for_each(rng, PushBack);\n\ttc::for_each(tc::as_const(rng), PushBack);\n\ttc::for_each(tc_move(rng), PushBack);\n\n\tTEST_RANGE_EQUAL(vecn, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 2, 1, 2, 1, 2, 1)));\n}\n\nUNITTESTDEF(concat_index_test) {\n\tauto rng =\n\t\ttc::concat(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 2, 3, 4)),\n\t\t\ttc::single(1),\n\t\t\ttc::single(5)\n\t\t);\n\n\t_ASSERTEQUAL(*tc::begin_next<tc::return_element_after>(rng, 4), 5);\n\t_ASSERTEQUAL(*tc::end_prev<tc::return_element_after>(rng, 5), 2);\n\n\tauto it = tc::begin_next<tc::return_border>(rng, 2);\n\t_ASSERTEQUAL(*(it + 2), 5);\n\t_ASSERTEQUAL(*(it - 2), 2);\n\t_ASSERTEQUAL(*(tc::begin_next<tc::return_border>(rng, 4) - 2), 4);\n\n\t_ASSERTEQUAL(tc::end(rng)-tc::begin(rng), 5);\n\t_ASSERTEQUAL(tc::begin(rng)-tc::end(rng), -5);\n\n\n\ttc::vector<int> vecn;\n\tVERIFYEQUAL(tc::break_, tc::for_each(\n\t\ttc::filter(\n\t\t\ttc::reverse(\n\t\t\t\ttc::concat(\n\t\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1, 3, 4)),\n\t\t\t\t\ttc::single(1),\n\t\t\t\t\ttc::single(5)\n\t\t\t\t)),\n\t\t\t[](int const i) noexcept { return i % 2 == 1; }\n\t\t),\n\t\t[&](int const i) noexcept { tc::cont_emplace_back(vecn, i); return 3 == i ? tc::break_ : tc::continue_; }\n\t));\n\n\tTEST_RANGE_EQUAL(vecn, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 5, 1, 3)));\n\tTEST_RANGE_LENGTH(rng, 5);\n}\n\nUNITTESTDEF(concat_with_empty_test) {\n\tauto rng = tc::concat(\n\t\ttc::make_empty_range<int>(),\n\t\ttc::concat(\n\t\t\ttc::single(1),\n\t\t\ttc::single(2)\n\t\t),\n\t\ttc::concat(\n\t\t\ttc::single(3),\n\t\t\ttc::single(4)\n\t\t)\n\t);\n\n\t_ASSERTEQUAL(*tc::begin(rng), 1);\n\tTEST_RANGE_LENGTH(rng, 4);\n}\n\nUNITTESTDEF(concat_different_value_types_test) {\n\tstruct S {\n\t\tint m_i;\n\t};\n\n\tauto rng =\n\t\ttc::concat(\n\t\t\ttc::single(1),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, S{2}, S{3}, S{4})),\n\t\t\ttc::single(5)\n\t\t);\n\n\tstruct SFunctor {\n\t\ttc::vector<int> m_vec;\n\n\t\tvoid operator()(int const i) & noexcept { tc::cont_emplace_back(m_vec, i); }\n\t\tvoid operator()(S s) & noexcept { tc::cont_emplace_back(m_vec, s.m_i); }\n\t} functor;\n\n\ttc::for_each(rng, std::ref(functor));\n\n\tTEST_RANGE_EQUAL(functor.m_vec, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1, 2, 3, 4, 5)));\n}\n\nUNITTESTDEF(concat_empty_test) {\n\tauto rng = tc::concat(tc::make_empty_range<int>(), tc::make_empty_range<int>());\n\t_ASSERTEQUAL(tc::begin(rng), tc::end(rng));\n}\n\nUNITTESTDEF(concat_shallow_const_test) {\n\ttc::vector<int> vecn{1};\n\tauto const rng = tc::concat(vecn, vecn);\n\tSTATICASSERTSAME(decltype(*tc::begin(rng)), int&);\n\n\t*tc::begin(rng) = 2;\n\tTEST_RANGE_EQUAL(rng, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 2, 2)));\n}\n\nUNITTESTDEF(concat_deep_const_test) {\n\tauto const rng = tc::concat(tc::single(1), tc::single(2));\n\n\tSTATICASSERTSAME(decltype(*tc::begin(rng)), int const&);\n\n\t_ASSERTEQUAL(*tc::begin(rng), 1);\n}\n\nUNITTESTDEF(ConcatAdvanceToEndIterator) {\n\t{\n\t\ttc::vector<int> vecn(1, 0);\n\t\tvoid(tc::begin_next<tc::return_border>(tc::concat(vecn, vecn), tc::size(vecn) * 2));\n\n\t\tauto rng = tc::concat(vecn,vecn);\n\t\tauto it = tc::begin(rng);\n\t\tit +=2;\n\t\t_ASSERTEQUAL(tc::end(rng), it);\n\t\tit += 0;\n\t\tit -= 2;\n\t\t_ASSERTEQUAL(tc::begin(rng), it);\n\t}\n\n\ttc::vector<int> vecn(2,0);\n\ttc::vector<int> vecnEmpty;\n\tauto rng = tc::concat(vecn, vecnEmpty);\n\tauto it = tc::begin(rng);\n\t++it; ++it;\n\tauto it2 = tc::begin(rng);\n\tit2 += 2;\n\t_ASSERTEQUAL(it, it2);\n\t_ASSERTEQUAL(tc::end(rng), it);\n\tit += 0;\n}\n\nUNITTESTDEF(concat_flattening) {\n\ttc::vector<int> vecn1{1,2,3};\n\ttc::vector<int> vecn2{4,5};\n\ttc::vector<int> vecn3{6,7,8};\n\ttc::vector<int> vecn4{9};\n\ttc::vector<int> vecnRhs{1,2,3,4,5,6,7,8,9};\n\tauto const rng = tc::concat(vecn1, tc::empty_range(), vecn2, tc::concat(tc::empty_range(), vecn3, tc::empty_range(), vecn4, tc::empty_range()));\n\t_ASSERT(tc::equal(rng, vecnRhs));\n\tauto const rng2 = tc::concat(vecn1, vecn2, vecn3, vecn4);\n\tSTATICASSERTSAME(decltype(rng), decltype(rng2));\n\tSTATICASSERTSAME(decltype(tc::concat(tc::empty_range(), tc::empty_range())), tc::empty_range);\n\tSTATICASSERTSAME(decltype(tc::concat(vecn1, tc::empty_range())), decltype((vecn1)));\n}\n\nnamespace\n{\n\tTC_HAS_EXPR(decrement_operator, (T), --std::declval<T&>());\n\n\ttemplate<typename Derived>\n\tstruct forward_range_base : tc::range_iterator_from_index<Derived, int> {\n\t\tusing this_type = forward_range_base;\n\t\tint values[3] = { 0, 1, 2 };\n\t\tstatic constexpr bool c_bHasStashingIndex=false;\n\t\tSTATIC_OVERRIDE(begin_index)() const -> int { return 0; }\n\t\tSTATIC_OVERRIDE(end_index)() const -> int { return 3; }\n\t\tSTATIC_OVERRIDE(increment_index)(int& i) const -> void { ++i; }\n\t\tSTATIC_OVERRIDE(dereference_index)(int i) -> int& { return values[i]; }\n\t\tSTATIC_OVERRIDE(dereference_index)(int i) const -> int const& { return values[i]; }\n\t};\n\n\tstruct forward_range : forward_range_base<forward_range> {};\n\n\tstruct bidir_range : forward_range_base<bidir_range> {\n\t\tusing Derived = bidir_range;\n\t\tusing this_type = bidir_range;\n\t\tSTATIC_FINAL(decrement_index)(int& i) const -> void { --i; }\n\t};\n\n\t[[maybe_unused]] void concat_iterator_auto_traversal_static_tests() {\n\t\t// Any concatenation which includes a forward-traversal range should be forward-traversal\n\t\t{\n\t\t\tauto rng = tc::concat(forward_range(), forward_range());\n\t\t\tauto it = tc::begin(rng);\n\t\t\tstatic_assert(!tc::has_decrement_index<decltype(rng)>);\n\t\t\tstatic_assert(!has_decrement_operator<decltype(it)>);\n\t\t\tstatic_assert(std::is_same<typename boost::iterator_traversal<decltype(it)>::type, boost::iterators::forward_traversal_tag>::value);\n\t\t}\n\t\t{\n\t\t\tauto rng = tc::concat(forward_range(), bidir_range());\n\t\t\tauto it = tc::begin(rng);\n\t\t\tstatic_assert(!tc::has_decrement_index<decltype(rng)>);\n\t\t\tstatic_assert(!has_decrement_operator<decltype(it)>);\n\t\t\tstatic_assert(std::is_same<typename boost::iterator_traversal<decltype(it)>::type, boost::iterators::forward_traversal_tag>::value);\n\t\t}\n\t\t{\n\t\t\tauto rng = tc::concat(bidir_range(), forward_range());\n\t\t\tauto it = tc::begin(rng);\n\t\t\tstatic_assert(!tc::has_decrement_index<decltype(rng)>);\n\t\t\tstatic_assert(!has_decrement_operator<decltype(it)>);\n\t\t\tstatic_assert(std::is_same<typename boost::iterator_traversal<decltype(it)>::type, boost::iterators::forward_traversal_tag>::value);\n\t\t}\n\n\t\t// A concatenation of bidirectional ranges should be bidirectional\n\t\t{\n\t\t\tauto rng = tc::concat(bidir_range(), bidir_range());\n\t\t\tauto it = tc::begin(rng);\n\t\t\tstatic_assert(tc::has_decrement_index<decltype(rng)>);\n\t\t\tstatic_assert(has_decrement_operator<decltype(it)>);\n\t\t\tstatic_assert(std::is_same<typename boost::iterator_traversal<decltype(it)>::type, boost::iterators::bidirectional_traversal_tag>::value);\n\t\t}\n\t}\n}\n\nSTATICASSERTSAME(char, tc::range_value_t<decltype(tc::concat(\"abc\", \"def\"))>);\nSTATICASSERTSAME(char, tc::range_value_t<decltype(tc::concat(\"abc\", tc::as_dec(10)))>);\nSTATICASSERTSAME(char, tc::range_value_t<decltype(tc::concat(tc::as_dec(10), \"abc\", tc::string<char>(\"de\")))>);\nSTATICASSERTSAME(char, tc::range_value_t<decltype(tc::concat(tc::as_dec(10), \"abc\", tc::concat(\"xy\", tc::as_dec(5)), tc::string<char>(\"de\")))>);\nSTATICASSERTSAME(int, tc::range_value_t<decltype(tc::transform(tc::concat(\"ab\", tc_utf16(\"cd\")), tc::fn_static_cast<int>()))>);\nstatic_assert(!tc::has_range_value<decltype(tc::concat(\"xy\", tc::as_dec(5), L\"a\"))>);\nstatic_assert(!tc::has_range_value<decltype(tc::concat(\"abc\", tc::as_dec(10), tc::concat(\"xy\", tc::as_dec(5), L\"a\"), tc::string<char>(\"de\")))>);\nstatic_assert(tc::has_range_value<decltype(tc::concat(tc::as_dec(5), tc::as_dec(10)))>);\nstatic_assert(!tc::has_range_value<decltype(tc::transform(tc::concat(\"ab\", tc_utf16(\"cd\")), tc::fn_increment()))>);\nstatic_assert(tc::is_concat_range<decltype(tc::concat(tc::as_dec(5), \"abc\"))>::value);\nstatic_assert(tc::is_concat_range<decltype(tc::concat(\"abc\", L\"def\"))>::value);\nstatic_assert(tc::is_concat_range<decltype(tc::concat(\"abc\", tc::string<char>(\"def\")))>::value);\n"
  },
  {
    "path": "tc/range/conditional_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/type_list.h\"\n#include \"../base/invoke_with_constant.h\"\n\n#include \"../algorithm/size.h\"\n#include \"../variant.h\"\n#include \"../interval.h\"\n\n#include \"range_adaptor.h\"\n#include \"index_range.h\"\n#include \"meta.h\"\n#include \"subrange.h\"\n\n#include <boost/preprocessor/punctuation/comma_if.hpp>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <typename Sink>\n\t\tstruct select_range_visitor { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tconstexpr auto operator()(Rng&& rng) const& MAYTHROW {\n\t\t\t\treturn tc::for_each(*tc_move_if_owned(rng), m_sink);\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace select_range_adaptor_adl {\n\t\ttemplate <bool HasIterator, typename... Rng>\n\t\tstruct select_range_adaptor;\n\n\t\ttemplate <typename... Rng>\n\t\tstruct select_range_adaptor<false, Rng...> {\n\t\t\tstatic_assert( (!std::is_rvalue_reference<Rng>::value && ...) );\n\t\t\tfriend select_range_adaptor<true, Rng...>;\n\n\t\tprivate:\n\t\t\tstd::variant<tc::reference_or_value<Rng, /*bBestAccess*/true>...> m_ubaserng;\n\n\t\tpublic:\n\t\t\ttemplate<typename... FuncRng>\n\t\t\tconstexpr explicit select_range_adaptor(aggregate_tag_t, int n, FuncRng&&... funcrng) MAYTHROW\n\t\t\t\t: m_ubaserng(tc::invoke_with_constant<std::index_sequence_for<FuncRng...>>(\n\t\t\t\t\t[&](auto const nconstIndex) MAYTHROW {\n\t\t\t\t\t\tSTATICASSERTEQUAL(sizeof...(Rng), sizeof...(FuncRng));\n\t\t\t\t\t\treturn decltype(m_ubaserng)(\n\t\t\t\t\t\t\tstd::in_place_index<nconstIndex()>, tc::aggregate_tag, tc::select_nth<nconstIndex()>(tc_move_if_owned(funcrng)...)()\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tn\n\t\t\t\t))\n\t\t\t{}\n\n\t\tprivate:\n\t\t\tstatic constexpr auto same_constexpr_size() noexcept requires (... && tc::has_constexpr_size<Rng>){\n#if 0\n\t\t\t\t// Ideally, but doesn't compile under MSVC - bogus read of uninitialized symbol in constexpr context.\n\t\t\t\treturn tc::all_same_element<tc::return_value_or_none>(tc::make_tuple(tc::constexpr_size<Rng>()...));\n#endif\n\n\t\t\t\tstd::optional<std::size_t> result;\n\t\t\t\tauto const all_same = ((result ? *result == tc::constexpr_size<Rng>() : (result = tc::constexpr_size<Rng>(), true)) && ...);\n\t\t\t\treturn all_same ? result : std::nullopt;\n\t\t\t}\n\n\t\tpublic:\n\t\t\tconstexpr auto size() const& MAYTHROW requires (... && tc::has_size<Rng>) {\n\t\t\t\tauto const runtime_size = [&]() MAYTHROW {\n\t\t\t\t\treturn tc::fn_visit(tc::projected(tc::fn_size_raw(), fn_indirection()))(m_ubaserng);\n\t\t\t\t};\n\n\t\t\t\tif constexpr (( ... && tc::has_constexpr_size<Rng>)) {\n\t\t\t\t\tauto constexpr same_size = same_constexpr_size();\n\t\t\t\t\tif constexpr (same_size) {\n\t\t\t\t\t\treturn tc::least_uint_constant<*same_size>{};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn runtime_size();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn runtime_size();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconstexpr bool empty() const& noexcept {\n\t\t\t\treturn tc::fn_visit([](auto const& baserng) noexcept {\n\t\t\t\t\treturn tc::empty(*baserng);\n\t\t\t\t})(m_ubaserng);\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, select_range_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<boost::mp11::mp_append<\n\t\t\t\ttc::range_output_t<decltype(*std::declval<tc::apply_cvref_t<tc::reference_or_value<Rng, /*bBestAccess*/true>, Self>>())>...\n\t\t\t>> {} // unevaluated\n\n\t\t\ttemplate<typename Self, typename Sink> requires tc::decayed_derived_from<Self, select_range_adaptor>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn tc::fn_visit(no_adl::select_range_visitor<tc::decay_t<Sink>>{tc_move_if_owned(sink)})(tc_move_if_owned_msvc_workaround(Self&&, self).m_ubaserng);\n\t\t\t}\n\n\t\t\ttemplate<typename Self, typename Sink> requires tc::decayed_derived_from<Self, select_range_adaptor>\n\t\t\tfriend constexpr auto for_each_reverse_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn tc::fn_visit([&](auto&& rng) MAYTHROW {\n\t\t\t\t\treturn tc::for_each(tc::reverse(*tc_move_if_owned(rng)), sink);\n\t\t\t\t})(tc_move_if_owned_msvc_workaround(Self&&, self).m_ubaserng);\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename ... Rng>\n\t\tusing select_range_adaptor_index = boost::mp11::mp_apply<std::variant, boost::mp11::mp_unique<boost::mp11::mp_list<tc::index_t<Rng>...>>>;\n\n\t\ttemplate <typename... Rng>\n\t\tstruct select_range_adaptor<true, Rng...>\n\t\t\t: select_range_adaptor<false, Rng...>\n\t\t\t, tc::range_iterator_from_index< select_range_adaptor<true, Rng...>, select_range_adaptor_index<Rng...>>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = select_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex = (... || tc::has_stashing_index<std::remove_reference_t<Rng>>::value);\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\t\tusing difference_type = tc::common_type_t<typename boost::range_difference<Rng>::type...>;\n\n\t\t\tusing select_range_adaptor<false, Rng...>::select_range_adaptor;\n\n\t\tprivate:\n#pragma push_macro(\"forward_to_active\")\n#define forward_to_active(preamble, ...) \\\n\ttc::fn_visit([&](auto& baserng) MAYTHROW -> decltype(auto) { \\\n\t\tusing range_t = decltype(baserng.best_access()); \\\n\t\tusing index_t = tc::index_t<range_t>; \\\n\t\tpreamble; \\\n\t\treturn __VA_ARGS__; \\\n\t})(this->m_ubaserng)\n#pragma push_macro(\"with_range_and_index\")\n#define with_range_and_index auto&& rng = *baserng; auto&& idx=tc::get<index_t>(tc_move_if_owned(idx_));\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& MAYTHROW {\n\t\t\t\treturn forward_to_active(auto&& rng = baserng.best_access(), tc::implicit_cast<tc_index>(tc::begin_index(rng)));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& MAYTHROW\n\t\t\t\trequires (... && tc::has_end_index<Rng>)\n\t\t\t{\n\t\t\t\treturn forward_to_active(auto&& rng = baserng.best_access(), tc::implicit_cast<tc_index>(tc::end_index(rng)));\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx_) const& MAYTHROW {\n\t\t\t\treturn forward_to_active(with_range_and_index, tc::at_end_index(rng, idx));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx_) & MAYTHROW -> decltype(auto) {\n\t\t\t\treturn forward_to_active(with_range_and_index,\n\t\t\t\t\ttc::explicit_cast<tc::common_reference_t<std::iter_reference_t<tc::iterator_t<Rng>>...>>(tc::dereference_index(rng, tc_move_if_owned(idx)))\n\t\t\t\t);\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx_) const& MAYTHROW -> decltype(auto) {\n\t\t\t\treturn forward_to_active(with_range_and_index,\n\t\t\t\t\ttc::explicit_cast<tc::common_reference_t<std::iter_reference_t<tc::iterator_t<Rng const&>>...>>(tc::dereference_index(rng, tc_move_if_owned(idx)))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx_) const& MAYTHROW {\n\t\t\t\tforward_to_active(with_range_and_index,tc::increment_index(rng, idx));\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx_) const& MAYTHROW\n\t\t\t\trequires (... && tc::has_decrement_index<Rng>)\n\t\t\t{\n\t\t\t\tforward_to_active(with_range_and_index, tc::decrement_index(rng, idx));\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, advance_index)(tc_index& idx_, difference_type d) const& MAYTHROW\n\t\t\t\trequires (... && tc::has_advance_index<Rng>)\n\t\t\t{\n\t\t\t\tforward_to_active(with_range_and_index, tc::advance_index(rng, idx, tc::explicit_cast<typename boost::range_difference<std::remove_cvref_t<range_t>>::type>(d)));\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& MAYTHROW\n\t\t\t\trequires (... && tc::has_distance_to_index<Rng>)\n\t\t\t{\n\t\t\t\treturn forward_to_active(auto&& rng = *baserng, tc::distance_to_index(rng, tc::get<index_t>(idxLhs), tc::get<index_t>(idxRhs)));\n\t\t\t}\n\t\t\tSTATIC_FINAL_MOD(constexpr, middle_point)( tc_index& idxBegin, tc_index const& idxEnd ) const& MAYTHROW\n\t\t\t\trequires (... && tc::has_middle_point<Rng>)\n\t\t\t{\n\t\t\t\tforward_to_active(auto&& rng = *baserng, tc::middle_point(rng, tc::get<index_t>(idxBegin), tc::get<index_t>(idxEnd)));\n\t\t\t}\n\n#pragma pop_macro(\"with_range_and_index\")\n#pragma pop_macro(\"forward_to_active\")\n\t\t};\n\n\t\t// While we normally try to use `tc::subrange` in the case of all ranges having the same iterator type,\n\t\t// we can't do that if we have rvalues that we need to aggregate.\n\t\ttemplate <typename... Rng>\n\t\t\trequires (1 == boost::mp11::mp_size<boost::mp11::mp_unique<boost::mp11::mp_list<tc::iterator_t<Rng>...>>>::value)\n\t\tstruct select_range_adaptor<true, Rng...>\n\t\t\t: select_range_adaptor<false, Rng...>\n\t\t{\n\t\tpublic:\n\t\t\tstatic constexpr bool c_bHasStashingIndex = (... || tc::has_stashing_index<std::remove_reference_t<Rng>>::value);\n\n\t\t\tusing select_range_adaptor<false, Rng...>::select_range_adaptor;\n\n\t\t\tauto begin() & MAYTHROW {\n\t\t\t\treturn tc::fn_visit([](auto& refrng) MAYTHROW { return tc::begin(*refrng); })(this->m_ubaserng);\n\t\t\t}\n\t\t\tauto begin() const& MAYTHROW {\n\t\t\t\treturn tc::fn_visit([](auto& refrng) MAYTHROW { return tc::begin(*refrng); })(this->m_ubaserng);\n\t\t\t}\n\n\t\t\tauto end() & MAYTHROW {\n\t\t\t\treturn tc::fn_visit([](auto& refrng) MAYTHROW { return tc::end(*refrng); })(this->m_ubaserng);\n\t\t\t}\n\t\t\tauto end() const& MAYTHROW {\n\t\t\t\treturn tc::fn_visit([](auto& refrng) MAYTHROW { return tc::end(*refrng); })(this->m_ubaserng);\n\t\t\t}\n\t\t};\n\t}\n\ttemplate <typename ... Rng>\n\tusing select_range_adaptor = select_range_adaptor_adl::select_range_adaptor<tc::ranges_with_common_reference<Rng...>, Rng...>;\n\n\ttemplate<typename... FuncRng> requires requires { typename tc::common_reference_t<decltype(std::declval<FuncRng>()())...>; }\n\tconstexpr auto select_range(int n, FuncRng&&... funcrng) MAYTHROW -> tc::common_reference_t<decltype(std::declval<FuncRng>()())...> {\n#ifdef _MSC_VER\n\t\t// The following assert must not hold: A function pointer to a function that returns a fixed size array by reference must also return a fixed size array by reference, not by value!\n\t\t// If MSVC fixed that bug, please unify select_range.\n\t\tstatic_assert(\n\t\t\tstd::is_same<\n\t\t\t\tdecltype(std::declval<\n\t\t\t\t\tint (&())[3]\n\t\t\t\t>()()),\n\t\t\t\tint [3]\n\t\t\t>::value\n\t\t);\n\n\t\ttc::storage_for<tc::common_reference_t<decltype(std::declval<FuncRng>()())...>> result;\n\t\ttc_scope_exit { result.dtor(); };\n\n\t\ttc::invoke_with_constant<std::index_sequence_for<FuncRng...>>(\n\t\t\t[&](auto const nconstIndex) MAYTHROW {\n\t\t\t\tresult.ctor(tc::select_nth<nconstIndex()>(tc_move_if_owned(funcrng)...)());\n\t\t\t},\n\t\t\tn\n\t\t);\n\t\treturn *tc_move(result);\n#else\n\t\tstatic_assert(\n\t\t\tstd::is_same<\n\t\t\t\tdecltype(std::declval<\n\t\t\t\t\tint (&())[3]\n\t\t\t\t>()()),\n\t\t\t\tint (&)[3]\n\t\t\t>::value\n\t\t);\n\n\t\treturn tc::invoke_with_constant<std::index_sequence_for<FuncRng...>>(\n\t\t\t[&](auto const nconstIndex) MAYTHROW -> tc::common_reference_t<decltype(std::declval<FuncRng>()())...> {\n\t\t\t\treturn tc::select_nth<nconstIndex()>(tc_move_if_owned(funcrng)...)();\n\t\t\t},\n\t\t\tn\n\t\t);\n#endif\n\t}\n\ttemplate<typename... FuncRng>\n\tconstexpr auto select_range(int n, FuncRng&&... funcrng) return_ctor_MAYTHROW(\n\t\tselect_range_adaptor<tc::remove_rvalue_reference_t<decltype(std::declval<FuncRng>()())>...>,\n\t\t(aggregate_tag, n, tc_move_if_owned(funcrng)...)\n\t)\n\n\ttemplate<typename FuncRngTrue, typename FuncRngFalse>\n\tconstexpr auto conditional_range(tc::bool_context b, FuncRngTrue&& funcrngTrue, FuncRngFalse&& funcrngFalse) return_decltype_allow_xvalue_MAYTHROW(\n\t\ttc::select_range(b ? 0 : 1, tc_move_if_owned(funcrngTrue), tc_move_if_owned(funcrngFalse))\n\t)\n\ttemplate<typename FuncRngTrue, typename FuncRngFalse>\n\tconstexpr auto conditional_range(tc::constant<true>, FuncRngTrue funcrngTrue, FuncRngFalse&& /*funcrngFalse*/) return_decltype_allow_xvalue_MAYTHROW(\n\t\tfuncrngTrue()\n\t)\n\n\ttemplate<typename FuncRngTrue, typename FuncRngFalse>\n\tconstexpr auto conditional_range(tc::constant<false>, FuncRngTrue&& /*funcrngTrue*/, FuncRngFalse funcrngFalse) return_decltype_allow_xvalue_MAYTHROW(\n\t\tfuncrngFalse()\n\t)\n\n\ttemplate<typename Bool, typename FuncRngTrue>\n\tconstexpr auto conditional_range(Bool&& b, FuncRngTrue&& funcrngTrue) return_decltype_allow_xvalue_MAYTHROW(\n\t\ttc::conditional_range(tc_move_if_owned(b), tc_move_if_owned(funcrngTrue), tc::fn_explicit_cast<tc::empty_range>())\n\t)\n}\n\n#include <boost/vmd/assert.hpp>\n\n// BOOST_PP_VARIADIC_SIZE returns always at least 1, so there is no point of checking against 0. However, empty __VA_ARGS__ will trigger a compilation error in tc_lazy\n#define tc_conditional_range(b, ...) \\\n\tBOOST_VMD_ASSERT(BOOST_PP_LESS_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2)) \\\n\ttc::conditional_range(b, \\\n\t\ttc_lazy(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)) \\\n\t\tBOOST_PP_COMMA_IF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2)) \\\n\t\tBOOST_PP_EXPR_IF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2), tc_lazy(BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__))) \\\n\t)\n\nnamespace tc {\n\ttemplate<typename Bool, typename Rng, typename Fn>\n\tconstexpr decltype(auto) transform_range_if(Bool&& b, Rng&& rng, Fn fn) noexcept {\n\t\treturn tc::conditional_range(tc_move_if_owned(b),\n\t\t\t/*funcrngTrue*/[&]() noexcept -> decltype(auto) { return fn(tc_move_if_owned(rng)); },\n\t\t\t/*funcrngFalse*/[&]() noexcept -> decltype(auto) { return tc_move_if_owned(rng); }\n\t\t);\n\t}\n\n#if defined(__clang__) || defined(_MSC_VER) // gcc internal compiler error\n\tnamespace switch_range_detail {\n\t\ttemplate<typename Enum, typename FuncRng, std::size_t... I>\n\t\tconstexpr auto switch_range_impl(Enum const& e, FuncRng&& funcRng, std::index_sequence<I...>) noexcept {\n\t\t\treturn tc::select_range(\n\t\t\t\ttc::explicit_cast<int>(tc::all_values<Enum>::index_of(e)),\n\t\t\t\t(I, [&]() noexcept -> decltype(auto) {\n\t\t\t\t\treturn funcRng(tc::constant<tc_at_nodebug(tc::all_values<Enum>(), I)>());\n\t\t\t\t})...\n\t\t\t);\n\t\t}\n\t}\n\n\ttemplate<typename Enum, typename... FuncRng>\n\tconstexpr auto switch_range(Enum const& e, FuncRng&&... funcrng) noexcept {\n\t\treturn switch_range_detail::switch_range_impl(\n\t\t\te, tc::make_overload(tc_move_if_owned(funcrng)...),\n\t\t\tstd::make_index_sequence<tc::constexpr_size<tc::all_values<Enum>>()>()\n\t\t);\n\t}\n#endif\n}\n"
  },
  {
    "path": "tc/range/conditional_range.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"conditional_range.h\"\n#include \"literal_range.h\"\n#include \"subrange.h\"\n#include \"transform_adaptor.h\"\n#include \"../algorithm/find.h\"\n\n#include <algorithm>\n#include <list>\n#include <vector>\n\nnamespace {\n\t// For testing purposes, we unconditionally want to create a select_range_adaptor, and not have the common reference.\n\ttemplate<typename... FuncRng>\n\tconstexpr auto make_select_range(int n, FuncRng&&... funcrng) return_ctor_MAYTHROW(\n\t\ttc::select_range_adaptor<tc::remove_rvalue_reference_t<decltype(std::declval<FuncRng>()())>...>,\n\t\t(tc::aggregate_tag, n, tc_move_if_owned(funcrng)...)\n\t)\n\n\ttemplate <typename Lhs, typename Rhs>\n\tbool iterator_range_equal(Lhs const& lhs, Rhs const& rhs) {\n\t\treturn std::equal(tc::begin(lhs), tc::end(lhs), tc::begin(rhs), tc::end(rhs));\n\t}\n}\n\nUNITTESTDEF(conditional_range) {\n\ttc_static_auto_constexpr_lambda(verify) = [](auto&& rng1, auto&& rng2) {\n\t\tauto const select_first = make_select_range(0, tc_lazy(rng1), tc_lazy(rng2));\n\t\tTEST_RANGE_EQUAL(select_first, rng1); // generator\n\t\t_ASSERT(iterator_range_equal(select_first, rng1)); // iterator\n\n\t\tauto const select_second = make_select_range(1, tc_lazy(rng1), tc_lazy(rng2));\n\t\tTEST_RANGE_EQUAL(select_second, rng2); // generator\n\t\t_ASSERT(iterator_range_equal(select_second, rng2)); // iterator\n\n\t\tauto const find_null = tc::find_first<tc::return_element_or_null>(tc::take(select_first, tc_modified(tc::begin(select_first), ++_)), tc::front(rng2));\n\t\t_ASSERT(!find_null);\n\t\tauto const find_elem = tc::find_first<tc::return_element_or_null>(tc::take(select_second, tc_modified(tc::begin(select_second), ++_)), tc::front(rng2));\n\t\t_ASSERTEQUAL(find_elem, tc::begin(select_second));\n\n\t\treturn select_first;\n\t};\n\n\tauto different_indices = verify(std::vector{1, 2, 3}, std::list{4, 5});\n\tstatic_assert(std::same_as<tc::index_t<decltype(different_indices)>, std::variant<tc::index_t<std::vector<int>>, tc::index_t<std::list<int>>>>);\n\n\t[[maybe_unused]] auto same_index = verify(std::vector{1, 2, 3}, tc::transform(std::vector{4, 5}, tc::identity{}));\n\t// TODO, size optimization: STATICASSERTEQUAL(sizeof(tc::index_t<decltype(same_index)>), sizeof(tc::index_t<std::vector<int>>));\n\n\tauto same_iterator = verify(std::vector{1, 2, 3}, std::vector{4, 5});\n\tstatic_assert(std::same_as<tc::iterator_t<decltype(same_iterator)>, tc::iterator_t<std::vector<int>>>);\n}\n"
  },
  {
    "path": "tc/range/empty_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../algorithm/break_or_continue.h\"\n#include \"meta.h\"\n\nnamespace tc {\n\tnamespace empty_range_adl {\n\t\tstruct TC_EMPTY_BASES empty_range {\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<0>{};\n\t\t\t}\n\n\t\t\tconstexpr auto operator()(tc::unused /*sink*/) const& noexcept {\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t};\n\n\t\tconstexpr auto for_each_reverse_impl(empty_range const&, tc::unused /*sink*/) noexcept {\n\t\t\treturn tc::constant<tc::continue_>();\n\t\t}\n\n\t\tauto range_output_t_impl(empty_range const&) noexcept -> boost::mp11::mp_list<>; // declaration only\n\t}\n\tusing empty_range_adl::empty_range;\n}\n"
  },
  {
    "path": "tc/range/filter_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/move.h\" \n#include \"../base/conditional.h\"\n#include \"../base/invoke.h\"\n#include \"../base/trivial_functors.h\"\n\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename Pred, typename Sink>\n\t\tstruct filter_sink {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tusing guaranteed_break_or_continue = std::conditional_t<\n\t\t\t\tstd::is_same<tc::constant<tc::continue_>, guaranteed_break_or_continue_t<Sink>>::value,\n\t\t\t\ttc::constant<tc::continue_>,\n\t\t\t\ttc::break_or_continue\n\t\t\t>;\n\t\t\tPred const& m_pred;\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename T> requires tc::runtime_predicate<Pred, T> && tc::sinkable<Sink, T>\n\t\t\tconstexpr auto operator()(T&& t) const& noexcept(tc::nothrow_predicate<Pred, T> && tc::nothrow_sinkable<Sink, T>) {\n\t\t\t\treturn tc::explicit_cast<bool>(tc_invoke(m_pred, tc::as_const(t)))\n\t\t\t\t\t\t\t? tc::continue_if_not_break(m_sink, tc_move_if_owned(t))\n\t\t\t\t\t\t\t: tc::constant<tc::continue_>();\n\t\t\t}\n\n\t\t\ttemplate<typename T> requires tc::constant_predicate_true<Pred, T>  && tc::sinkable<Sink, T>\n\t\t\tconstexpr auto operator()(T&& t) const& noexcept(tc::nothrow_predicate<Pred, T> && tc::nothrow_sinkable<Sink, T>) {\n\t\t\t\ttc::discard(tc_invoke(m_pred, tc::as_const(t)));\n\t\t\t\treturn tc::continue_if_not_break(m_sink, tc_move_if_owned(t));\n\t\t\t}\n\t\t\ttemplate<typename T> requires tc::constant_predicate_false<Pred, T>\n\t\t\tconstexpr auto operator()(T&& t) const& noexcept(tc::nothrow_predicate<Pred, T>) {\n\t\t\t\ttc::discard(tc_invoke(m_pred, tc::as_const(t)));\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Pred, typename Rng, bool HasIterator=tc::range_with_iterators< Rng > >\n\t\tstruct filter_adaptor;\n\n\t\ttemplate< typename Pred, typename Rng >\n\t\tstruct [[nodiscard]] filter_adaptor<Pred, Rng, false> : tc::generator_range_adaptor<Rng> {\n\t\tprotected:\n\t\t\tstatic_assert(tc::decayed<Pred>);\n\t\t\tPred m_pred;\n\n\t\tpublic:\n\t\t\tconstexpr filter_adaptor() = default;\n\t\t\ttemplate< typename RngRef, typename PredRef >\n\t\t\tconstexpr filter_adaptor(RngRef&& rng, PredRef&& pred) noexcept\n\t\t\t\t: filter_adaptor::generator_range_adaptor(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_pred(tc_move_if_owned(pred))\n\t\t\t{}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tconstexpr auto adapted_sink(Sink&& sink, bool /*bReverse*/) const& noexcept {\n\t\t\t\treturn filter_sink<Pred, tc::decay_t<Sink>>{m_pred, tc_move_if_owned(sink)};\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<typename T>\n\t\t\tusing is_not_constant_predicate_false = tc::constant<!tc::constant_predicate_false<Pred, T>>;\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, filter_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_filter<\n\t\t\t\tis_not_constant_predicate_false,\n\t\t\t\ttc::range_output_t<decltype(std::declval<Self>().base_range())>\n\t\t\t> {} // unevaluated\n\t\t};\n\n\t\ttemplate< typename Pred, typename Rng >\n\t\tstruct [[nodiscard]] filter_adaptor<Pred, Rng, true>\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\tfilter_adaptor<Pred, Rng, true>,\n\t\t\t\tRng, tc::index_range_adaptor_flags::inherit_end | tc::index_range_adaptor_flags::inherit_dereference,\n\t\t\t\tfilter_adaptor<Pred, Rng, false>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = filter_adaptor;\n\t\t\tusing base_ = typename filter_adaptor::index_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\t\tconstexpr filter_adaptor() = default;\n\t\t\tusing base_::base_;\n\n\t\tprivate:\n\t\t\tvoid increment_until_kept(tc_index& idx) const& MAYTHROW {\n\t\t\t\t// always call operator() const, which is assumed to be thread-safe\n\t\t\t\twhile(!this->at_end_index(idx) && !tc::explicit_cast<bool>(tc_invoke(this->m_pred, tc::as_const(this->dereference_index(idx))))) {\n\t\t\t\t\ttc::increment_index(this->base_range(), idx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(begin_index)() const& MAYTHROW -> tc_index {\n\t\t\t\ttc_index idx=this->base_begin_index();\n\t\t\t\tincrement_until_kept(idx);\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& MAYTHROW -> void {\n\t\t\t\ttc::increment_index(this->base_range(), idx);\n\t\t\t\tincrement_until_kept(idx);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(decrement_index)(tc_index& idx) const& MAYTHROW -> void\n\t\t\t\trequires tc::has_decrement_index<Rng>\n\t\t\t{\n\t\t\t\tdo {\n\t\t\t\t\ttc::decrement_index(this->base_range(), idx);\n\t\t\t\t\t// always call operator() const, which is assumed to be thread-safe\n\t\t\t\t} while(!tc::explicit_cast<bool>(tc_invoke(this->m_pred, tc::as_const(this->dereference_index(idx)))));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(middle_point)( tc_index & idx, tc_index const& idxEnd ) const& MAYTHROW -> void\n\t\t\t\trequires tc::has_middle_point<Rng> && tc::has_decrement_index<Rng>\n\t\t\t{\n\t\t\t\ttc_index const idxBegin = idx;\n\t\t\t\ttc::middle_point(this->base_range(), idx, idxEnd);\n\t\t\t\n\t\t\t\t// always call operator() const, which is assumed to be thread-safe\n\t\t\t\twhile(idxBegin != idx && !tc::explicit_cast<bool>(tc_invoke(this->m_pred, tc::as_const(this->dereference_index(idx))))) {\n\t\t\t\t\ttc::decrement_index(this->base_range(), idx);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::filter_adaptor;\n\n\ttemplate<typename Pred, typename Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::filter_adaptor<Pred, Rng, true>> = tc::stable_index_on_move<Rng>;\n\n\ttemplate<typename Rng, typename Pred = tc::identity>\n\tconstexpr auto filter(Rng&& rng, Pred&& pred = Pred())\n\t\treturn_ctor_noexcept( TC_FWD(tc::filter_adaptor<tc::decay_t<Pred>, Rng>), (tc_move_if_owned(rng),tc_move_if_owned(pred)) )\n}\n\n"
  },
  {
    "path": "tc/range/index_iterator.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"../base/assert_defs.h\"\n#include \"index_range.h\"\n#include \"iterator_facade.h\"\n#include \"../optional.h\"\n\n#include <boost/iterator/detail/facade_iterator_category.hpp>\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename It>\n\t\tstruct nullable_iterator {\n\t\t\tstatic_assert(tc::decayed<It>);\n\t\t\ttemplate<typename Derived>\n\t\t\tstruct base : It {\n\t\t\t\tusing difference_type = typename std::iterator_traits<It>::difference_type;\n\t\t\t\tusing value_type = typename std::iterator_traits<It>::value_type;\n\t\t\t\tusing pointer = typename std::iterator_traits<It>::pointer;\n\t\t\t\tusing reference = typename std::iterator_traits<It>::reference;\n\t\t\t\tusing iterator_category = typename std::iterator_traits<It>::iterator_category;\n\n\t\t\tprivate:\n\t\t\t\tconstexpr Derived& derived() noexcept {return tc::derived_cast<Derived>(*MSVC_WORKAROUND_THIS);}\n\t\t\tpublic:\n\t\t\t\tconstexpr base() noexcept : m_bValid(false) {}\n\n\t\t\t\t// no implicit conversion from It; we must ensure that It has the semantics of element rather than border before allowing the construction\n\t\t\t\tconstexpr explicit base(It const& it) noexcept : It(it), m_bValid(true) {}\n\t\t\t\tconstexpr explicit base(It && it) noexcept : It(tc_move(it)), m_bValid(true) {}\n\n\t\t\t\tconstexpr Derived& operator=(It const& it) & noexcept {\n\t\t\t\t\tIt::operator=(it);\n\t\t\t\t\tm_bValid = true;\n\t\t\t\t\treturn derived();\n\t\t\t\t}\n\t\t\t\tconstexpr Derived& operator=(It && it) & noexcept {\n\t\t\t\t\tIt::operator=(tc_move(it));\n\t\t\t\t\tm_bValid = true;\n\t\t\t\t\treturn derived();\n\t\t\t\t}\n\n\t\t\t\tconstexpr explicit operator bool() const& noexcept {\n\t\t\t\t\treturn m_bValid;\n\t\t\t\t}\n\n\t\t\t\tconstexpr Derived& operator++() & noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\t++tc::base_cast<It>(*this);\n\t\t\t\t\treturn derived();\n\t\t\t\t}\n\n\t\t\t\tconstexpr Derived& operator--() & noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\t--tc::base_cast<It>(*this);\n\t\t\t\t\treturn derived();\n\t\t\t\t}\n\n\t\t\t\tconstexpr decltype(auto) operator*() const& noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\treturn *tc::base_cast<It>(*this);\n\t\t\t\t}\n\t\t\t\tconstexpr decltype(auto) operator*() const&& noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\treturn *tc::base_cast<It>(tc_move_always_even_const(*this));\n\t\t\t\t}\n\t\t\t\tconstexpr decltype(auto) operator*() && noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\treturn *tc::base_cast<It>(tc_move_always(*this));\n\t\t\t\t}\n\n\t\t\t\tconstexpr pointer operator->() const& noexcept {\n\t\t\t\t\t_ASSERT(m_bValid);\n\t\t\t\t\treturn tc::base_cast<It>(*this).operator->();\n\t\t\t\t}\n\n\t\t\tprotected:\n\t\t\t\tbool m_bValid;\n\t\t\t};\n\n\t\t\tstruct element_type final : base<element_type> {\n\t\t\t\tusing base_ = base<element_type>;\n\t\t\t\tusing base_::base_;\n\t\t\t\tusing base_::operator=;\n\n\t\t\t\tconstexpr auto element_base() const& noexcept requires requires(It const& it) { it.element_base(); } {\n\t\t\t\t\tusing ItBase = typename nullable_iterator<decltype(tc::base_cast<It>(*this).element_base())>::element_type;\n\t\t\t\t\treturn this->m_bValid ? ItBase{ tc::base_cast<It>(*this).element_base() } : ItBase{};\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tstruct border_type final : base<border_type> {\n\t\t\t\tusing base_ = base<border_type>;\n\t\t\t\tusing base_::base_;\n\t\t\t\tusing base_::operator=;\n\n\t\t\t\tconstexpr auto border_base() const& noexcept requires requires(It const& it) { it.border_base(); } {\n\t\t\t\t\tusing ItBase = typename nullable_iterator<decltype(tc::base_cast<It>(*this).border_base())>::border_type;\n\t\t\t\t\treturn this->m_bValid ? ItBase{ tc::base_cast<It>(*this).border_base() } : ItBase{};\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\n\t\ttemplate<typename It> requires tc::explicit_castable_from<bool, It>\n\t\tstruct nullable_iterator<It> {\n\t\t\tstatic_assert(tc::decayed<It>);\n\t\t\tusing element_type = It;\n\t\t\tusing border_type = It;\n\t\t};\n\t}\n\n\ttemplate< typename It >\n\tusing element_t = typename no_adl::nullable_iterator<It>::element_type;\n\t\n\ttemplate< typename It >\n\tusing border_t = typename no_adl::nullable_iterator<It>::border_type;\n\n\ttemplate< typename It >\n\tconstexpr auto make_element(It&& it) noexcept {\n\t\treturn element_t<tc::decay_t<It>>(tc_move_if_owned(it));\n\t}\n\n\t// Regarding constness:\n\t// const_iterators point to const ranges; non-const iterators point to non-const ranges.\n\t// The index type, traversal, and difference_type must be the same regardless of whether the range is const.\n\t// The reference type, and pointer type may be different.\n\t// The value_type should be the same but there is nothing preventing it from being different.\n\t\t\n\t// Other than dereference_index, base_range and creating subranges, all range functions are called on const references.\n\n\ttemplate< typename T, bool bConst >\n\tusing conditional_const_t=std::conditional_t< bConst, T const, T >;\n\n\tnamespace index_iterator_impl {\n\t\ttemplate<typename IndexRange, bool bConst>\n\t\tstruct index_iterator;\n\t}\n\tusing index_iterator_impl::index_iterator;\n\n\tnamespace index_iterator_traits_no_adl {\n\t\ttemplate< typename IndexRange>\n\t\tstruct difference_type_base {\n\t\t\tusing difference_type = std::ptrdiff_t; // needed to compile interfaces relying on difference_type\n\t\t};\n\n\t\ttemplate< has_mem_fn_distance_to_index IndexRange>\n\t\tstruct difference_type_base<IndexRange> {\n\t\t\tusing difference_type = decltype(std::declval<IndexRange const&>().distance_to_index(std::declval<typename IndexRange::tc_index const&>(), std::declval<typename IndexRange::tc_index const&>()));\n\t\t};\n\n\t\ttemplate< typename IndexRange>\n\t\tstruct value_type_base {\n\t\t\tusing value_type = void;\n\t\t};\n\n\t\ttemplate< typename IndexRange > requires requires { typename tc::range_value_t<IndexRange>; }\n\t\tstruct value_type_base<IndexRange> {\n\t\t\tusing value_type = tc::range_value_t<IndexRange>;\n\t\t};\n\t}\n}\n\nnamespace std {\n\ttemplate<typename IndexRange, bool bConst>\n\tstruct iterator_traits<tc::index_iterator<IndexRange, bConst>>\n\t\t: tc::index_iterator_traits_no_adl::difference_type_base<IndexRange> // should not be different for const and non-const\n\t\t, tc::index_iterator_traits_no_adl::value_type_base<tc::conditional_const_t<IndexRange, bConst>&>\n\t{\n\t\tstatic_assert(tc::has_index<IndexRange>);\n\n\t\t// IndexRange::dereference_index does not take an argument of type Index. Did you write tc::transform(Rng, Fn) and Fn takes the wrong argument?\n\t\tusing reference = std::iter_reference_t<tc::index_iterator<IndexRange, bConst>>;\n\n\t\t// Since C++20, iterator_traits<It>::pointer is synthesized in this way by default, if typename It::pointer does not exist.\n\t\tusing pointer = decltype(std::declval<tc::index_iterator<IndexRange, bConst>&>().operator->());\n\n\t\t// Some of our ranges, may not even conform to LecayInputIterator concept.\n\t\t// We ignore the requirements on value_type and reference, because library implementors do not rely on them anyway.\n\t\tstatic auto compute_iterator_concept() {\n\t\t\tif constexpr (!tc::has_mem_fn_decrement_index<IndexRange>) {\n\t\t\t\treturn std::forward_iterator_tag();\n\t\t\t} else if constexpr (!tc::has_mem_fn_distance_to_index<IndexRange>) {\n\t\t\t\treturn std::bidirectional_iterator_tag();\n\t\t\t} else if constexpr (!tc::has_mem_fn_index_to_address<IndexRange>) {\n\t\t\t\treturn std::random_access_iterator_tag();\n\t\t\t} else {\n\t\t\t\treturn std::contiguous_iterator_tag();\n\t\t\t}\n\t\t}\n\t\tusing iterator_concept = decltype(compute_iterator_concept());\n\n\t\t// Note that iterator_category must not be std::contiguous_iterator_tag, as code may not expect it.\n\t\tusing iterator_category = std::conditional_t<std::is_same_v<iterator_concept, std::contiguous_iterator_tag>, std::random_access_iterator_tag, iterator_concept>;\n\t};\n\n\ttemplate<typename IndexRange, bool bConst>\n\t\trequires std::same_as<typename iterator_traits<tc::index_iterator<IndexRange, bConst>>::iterator_concept, std::contiguous_iterator_tag>\n\tstruct pointer_traits<tc::index_iterator<IndexRange, bConst>>\n\t{\n\t\tusing pointer = tc::index_iterator<IndexRange, bConst>;\n\n\t\t// Note that it is *not* the value_type! We want to preserve a const, while the value type strips it.\n\t\tusing element_type = std::remove_reference_t<typename iterator_traits<pointer>::reference>;\n\n\t\tusing difference_type = typename iterator_traits<pointer>::difference_type;\n\n\t\t// Note that we cannot provide rebind or pointer_to, but don't need that for our use cases either.\n\n\t\tstatic constexpr element_type* to_address(pointer const& ptr) noexcept\n\t\t{\n\t\t\treturn ptr.get_range().index_to_address(ptr.get_index());\n\t\t}\n\t};\t\n}\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct end_sentinel final {};\n\t}\n\tusing no_adl::end_sentinel;\n\n\tnamespace index_iterator_impl {\n\t\ttemplate<typename IndexRange, bool bConst>\n\t\tstruct index_iterator : tc::iterator_facade<index_iterator<IndexRange, bConst>>\n\t\t{\n\t\t\tstatic_assert(tc::decayed<IndexRange>);\n\n\t\t\tstatic constexpr bool c_bHasStashingElement = IndexRange::c_bHasStashingIndex;\n\n\t\tprivate:\n\t\t\tfriend class boost::iterator_core_access;\n\t\t\tfriend struct index_iterator<IndexRange,!bConst>;\n\n\t\t\ttc::optional_reference_or_value<tc::conditional_const_t<IndexRange, bConst>&> m_oidxrng;\n\n\t\tpublic: // TODO private\n\t\t\tusing tc_index = index_t<IndexRange>;\n\t\t\ttc_index m_idx;\n\n\t\tprivate:\n\t\t\tusing this_type = index_iterator<IndexRange, bConst>;\n\n\t\tpublic:\n\t\t\tconstexpr index_iterator() noexcept\n\t\t\t\t: m_oidxrng()\n\t\t\t\t, m_idx()\n\t\t\t{}\n\n\t\t\ttemplate<bool bConstOther> requires bConst || (!bConstOther)\n\t\t\tconstexpr index_iterator(index_iterator<IndexRange,bConstOther> const& other) noexcept\n\t\t\t\t: m_oidxrng(other.m_oidxrng)\n\t\t\t\t, m_idx(other.m_idx)\n\t\t\t{}\n\n\t\t\tconstexpr index_iterator(conditional_const_t<IndexRange, bConst>& idxrng, tc_index idx) noexcept\n\t\t\t\t: m_oidxrng(tc::make_optional_reference_or_value(idxrng))\n\t\t\t\t, m_idx(tc_move(idx))\n\t\t\t{}\n\n\t\t\tconstexpr decltype(auto) get_range() const& noexcept {\n\t\t\t\treturn *m_oidxrng;\n\t\t\t}\n\t\t\tconstexpr tc_index const& get_index() const& noexcept {\n\t\t\t\treturn m_idx;\n\t\t\t}\n\t\t\tconstexpr tc_index&& get_index() && noexcept {\n\t\t\t\treturn tc_move(m_idx);\n\t\t\t}\n\n\t\t\tfriend index_iterator middle_point( index_iterator const& itBegin, index_iterator const& itEnd ) noexcept requires tc::has_mem_fn_middle_point<IndexRange> {\n\t\t\t\tindex_iterator it=itBegin;\n\t\t\t\t_ASSERTE(itBegin.m_oidxrng);\n\t\t\t\tif constexpr (!tc::empty_type<IndexRange>) _ASSERTE(std::addressof(*itBegin.m_oidxrng) == std::addressof(*itEnd.m_oidxrng));\n\t\t\t\ttc::as_const(*itBegin.m_oidxrng).middle_point(it.m_idx,itEnd.m_idx);\n\t\t\t\treturn it;\n\t\t\t}\n\n\t\t\tconstexpr auto border_base() const& noexcept requires\n\t\t\t\ttc::has_mem_fn_base_range<IndexRange> && tc::has_mem_fn_border_base_index<IndexRange>\n\t\t\t{\n\t\t\t\treturn tc::make_iterator( m_oidxrng->base_range(), tc::as_const(*m_oidxrng).border_base_index(m_idx));\n\t\t\t}\n\n\t\t\tconstexpr auto element_base() const& noexcept requires\n\t\t\t\ttc::has_mem_fn_base_range<IndexRange> && tc::has_mem_fn_element_base_index<IndexRange>\n\t\t\t{\n\t\t\t\tusing It = tc::element_t<tc::decay_t<decltype(tc::make_iterator(m_oidxrng->base_range(), tc::as_const(*m_oidxrng).element_base_index(m_idx)))>>;\n\t\t\t\tif(m_oidxrng) {\n\t\t\t\t\treturn It(tc::make_iterator(m_oidxrng->base_range(), tc::as_const(*m_oidxrng).element_base_index(m_idx)));\n\t\t\t\t} else {\n\t\t\t\t\treturn It();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconstexpr decltype(auto) operator*() const& return_MAYTHROW(\n\t\t\t\tm_oidxrng->dereference_index(m_idx)\n\t\t\t)\n\t\t\tconstexpr decltype(auto) operator*() const&& return_MAYTHROW(\n\t\t\t\t(*tc_move_always_even_const(m_oidxrng)).dereference_index(tc_move_always_even_const(m_idx))\n\t\t\t)\n\t\t\tconstexpr decltype(auto) operator*() && return_MAYTHROW(\n\t\t\t\t(*tc_move_always(m_oidxrng)).dereference_index(tc_move_always(m_idx))\n\t\t\t)\n\n\t\t\tconstexpr this_type& operator++() noexcept(noexcept(m_oidxrng->increment_index(m_idx))) {\n\t\t\t\ttc::as_const(*m_oidxrng).increment_index(m_idx);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr this_type& operator--() noexcept(noexcept(m_oidxrng->decrement_index(m_idx))) requires tc::has_mem_fn_decrement_index<IndexRange> {\n\t\t\t\ttc::as_const(*m_oidxrng).decrement_index(m_idx);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\texplicit constexpr operator bool() const& noexcept {\n\t\t\t\ttc_return_cast(m_oidxrng);\n\t\t\t}\n\n\t\t\tconstexpr bool operator==(end_sentinel) const& noexcept {\n\t\t\t\treturn tc::as_const(*m_oidxrng).at_end_index(m_idx);\n\t\t\t}\n\t\t\ttemplate <bool OtherConst> requires tc::is_equality_comparable<tc_index>::value\n\t\t\tconstexpr bool operator==(index_iterator<IndexRange, OtherConst> const& rhs) const& noexcept {\n\t\t\t\tif constexpr (!tc::empty_type<IndexRange>) _ASSERTE(std::addressof(*m_oidxrng) == std::addressof(*rhs.m_oidxrng));\n\t\t\t\t_ASSERTDEBUG( m_oidxrng || m_idx == rhs.m_idx );\n\t\t\t\treturn m_idx == rhs.m_idx;\n\t\t\t}\n\n\t\t\t// For iterator_facade.\n\t\t\ttemplate<typename N> requires tc::has_mem_fn_advance_index<IndexRange>\n\t\t\tconstexpr void advance(N&& n) noexcept(noexcept(m_oidxrng->advance_index(m_idx, n))) {\n\t\t\t\ttc::as_const(*m_oidxrng).advance_index(m_idx, tc_move_if_owned(n));\n\t\t\t}\n\t\t};\n\n\t\ttemplate< tc::has_mem_fn_distance_to_index IndexRange_, bool bConst1, bool bConst2>\n\t\tconstexpr auto operator -( index_iterator<IndexRange_, bConst1> const& itLhs, index_iterator<IndexRange_, bConst2> const& itRhs) noexcept {\n\t\t\tif constexpr (!tc::empty_type<IndexRange_>) _ASSERTE(std::addressof(itLhs.get_range()) == std::addressof(itRhs.get_range()));\n\t\t\treturn tc::as_const(itLhs.get_range()).distance_to_index(itRhs.get_index(), itLhs.get_index());\n\t\t}\n\t}\n\tusing index_iterator_impl::index_iterator;\n\n\ttemplate <typename It>\n\tconstexpr auto is_index_iterator = false;\n\ttemplate<typename IndexRange, bool bConst>\n\tconstexpr auto is_index_iterator<index_iterator<IndexRange, bConst>> = true;\n\n\ttemplate <typename Rng> requires tc::empty_type<Rng> && is_index_iterator<tc::iterator_t<Rng>>\n\tconstexpr auto enable_borrowed_range<Rng> = true;\n\n\tnamespace iterator2index_detail {\n\t\ttemplate<typename It, typename Rng>\n\t\tconcept iterator_of = tc::decayed_derived_from<It, tc::iterator_t<std::remove_cvref_t<Rng>>>\n\t\t\t|| tc::decayed_derived_from<It, tc::iterator_t<std::remove_cvref_t<Rng> const>>;\n\t}\n\n\ttemplate<typename Rng, typename It>\n\tconstexpr decltype(auto) iterator2index(It&& it) noexcept {\n\t\tif constexpr(tc::has_index<std::remove_reference_t<Rng>>) {\n\t\t\treturn std::remove_reference_t<Rng>::iterator2index(tc_move_if_owned(it));\n\t\t} else {\n\t\t\tstatic_assert(iterator2index_detail::iterator_of<It, Rng>);\n\t\t\treturn tc_move_if_owned(it);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/range/index_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/type_traits_fwd.h\"\n#include \"../base/as_lvalue.h\"\n#include \"../base/reference_or_value.h\"\n#include \"../base/static_polymorphism.h\"\n#include \"../algorithm/break_or_continue.h\"\n#include \"../algorithm/size.h\"\n#include \"meta.h\"\n\n\nMODIFY_WARNINGS_BEGIN(((disable)(4018)))\n#include <boost/range/difference_type.hpp>\n#include <boost/range/category.hpp>\nMODIFY_WARNINGS_END\n\n#include <boost/range/iterator_range.hpp>\n\n#include <boost/mpl/has_xxx.hpp>\n\n#include <type_traits>\n\nnamespace tc {\n\n\t/////////////////////////////////////////////\n\t// required for all index ranges\n\tTC_HAS_EXPR(index, (Rng), std::declval<typename std::decay_t<Rng>::tc_index>())\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct index final {\n\t\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\t\tusing type=tc::iterator_t<Rng>;\n\t\t};\n\n\t\ttemplate<tc::has_index Rng>\n\t\tstruct index<Rng> final  {\n\t\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\t\tusing type=typename Rng::tc_index;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tusing index_t=typename index<std::remove_reference_t<Rng>>::type;\n\t\t\n\t}\n\tusing no_adl::index_t;\n\n\ttemplate<typename Rng>\n\t\trequires (!tc::has_index<Rng>) && tc::borrowed_range<Rng>\n\tconstexpr auto begin_index(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::begin(rng)\n\t)\n\n\ttemplate<tc::has_index Rng>\n\tconstexpr auto begin_index(Rng&& rng) return_decltype_MAYTHROW(\n\t\trng.begin_index()\n\t)\n\n\ttemplate <typename Rng>\n\tconcept index_range\n\t\t= tc::range_with_iterators<Rng> || (tc::has_index<Rng> && requires(Rng&& rng) { tc::begin_index(tc_move_if_owned(rng)); });\n\n\ttemplate<tc::common_range Rng>\n\t\trequires (!tc::has_index<Rng>) && tc::borrowed_range<Rng>\n\tconstexpr auto end_index(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::end(rng)\n\t)\n\n\ttemplate<tc::has_index Rng>\n\tconstexpr auto end_index(Rng&& rng) return_decltype_MAYTHROW(\n\t\trng.end_index()\n\t)\n\n\ttemplate<typename Rng, typename It>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr bool at_end_index(Rng const& rng, It const& it) return_MAYTHROW(\n\t\tit == tc::end(rng)\n\t)\n\n\ttemplate<tc::has_index Rng, typename Index>\n\tconstexpr bool at_end_index(Rng const& rng, Index const& idx) return_MAYTHROW(\n\t\trng.at_end_index(idx)\n\t)\n\n\ttemplate<typename Rng, typename It>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr auto dereference_index(Rng&& /*rng*/, It&& it) noexcept(noexcept(*tc_move_if_owned(it)))\n\t\t-> typename std::conditional_t<\n\t\t\ttc::safely_convertible_to<decltype(*std::declval<It>()), std::iter_reference_t<tc::iterator_t<Rng>>>,\n\t\t\tstd::type_identity<std::iter_reference_t<tc::iterator_t<Rng>>>,\n\t\t\ttc::decay<std::iter_reference_t<tc::iterator_t<Rng>>>\n\t\t>::type\n\t{\n\t\treturn *tc_move_if_owned(it);\n\t}\n\n\ttemplate<tc::has_index Rng, typename Index>\n\tconstexpr auto dereference_index(Rng&& rng, Index&& idx) return_decltype_allow_xvalue_MAYTHROW(\n\t\ttc_move_if_owned(rng).dereference_index(tc_move_if_owned(idx))\n\t)\n\n\ttemplate<typename Rng, typename It>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr void increment_index(Rng const&, It& it) noexcept(noexcept(++it)) {\n\t\t++it;\n\t}\n\n\ttemplate<tc::has_index Rng, typename Index>\n\tconstexpr void increment_index(Rng const& rng, Index& idx) return_MAYTHROW(\n\t\trng.increment_index(idx)\n\t)\n\n\tTC_HAS_EXPR(end_index, (Rng), tc::end_index(std::declval<Rng const&>()));\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(base_range, &)\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(border_base_index, const&, std::declval<typename T::tc_index &>())\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(element_base_index, const&, std::declval<typename T::tc_index &>())\n\n\tnamespace no_adl {\n\t\t// By standard, the lifetime of a reference may be limited to the lifetime of the iterator (\"stashing iterators\").\n\t\t// Stashing is forbidden for C++17 iterators that fulfill the ForwardIterator/BidirectionalIterator concept.\n\t\t// This essentially follows from the multipass guarantee: a==b <--> *a points to the same object as *b.\n\t\t// The C++17 STL still comes with some stashing iterators (LegacyForwardIterator/LegacyBidirectionalIterator concept).\n\t\t// A notable example is std::filesystem::path::iterator. Unfortunately, neither std:: nor boost::iterator_traits allows\n\t\t// us to tell apart legacy from non-stashing iterators.\n\t\t// tc::counting_iterator are stashing, as well as the iterators of all ranges adapted from a counting range.\n\t\ttemplate <typename Element>\n\t\tstruct is_stashing_element : tc::constant<false> {};\n\n\t\ttemplate <typename Element> requires Element::c_bHasStashingElement\n\t\tstruct is_stashing_element<Element> : tc::constant<Element::c_bHasStashingElement> {};\n\n\t\ttemplate<typename Rng>\n\t\tstruct has_stashing_index : is_stashing_element<index_t<Rng>> {\n\t\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\t};\n\n\t\ttemplate<tc::has_index Rng>\n\t\tstruct has_stashing_index<Rng> : tc::constant<Rng::c_bHasStashingIndex>  {\n\t\t\tstatic_assert( !std::is_reference<Rng>::value );\n\t\t};\n\t}\n\tusing no_adl::is_stashing_element;\n\tusing no_adl::has_stashing_index;\n\n\t/////////////////////////////////////////////\n\t// stable index range\n\t// If `tc::stable_index_on_move<Rng>`, `Rng` has indices and an index is not invalidated when the `Rng` object is moved.\n\t// This is true for:\n\t// * borrowed ranges, where the iterator indices are completely decoupled from `Rng` anyway\n\t// * `std::vector` (but not `std::string` due to SSO)\n\t// * ...\n\ttemplate <typename Rng>\n\tconstexpr auto enable_stable_index_on_move = false;\n\n\ttemplate <typename Rng>\n\tconcept stable_index_on_move\n\t\t= tc::index_range<Rng> && (std::is_lvalue_reference<Rng>::value || enable_stable_index_on_move<std::remove_cvref_t<Rng>>);\n\n\ttemplate <typename Rng> requires tc::borrowed_range<Rng>\n\tconstexpr auto enable_stable_index_on_move<Rng> = true;\n\ttemplate <typename T, typename Alloc>\n\tconstexpr auto enable_stable_index_on_move<std::vector<T, Alloc>> = true; // end iterator is not guaranteed by the standard but we assume it's still valid\n\n\t/////////////////////////////////////////////\n\t// bidirectional index ranges\n\n\ttemplate<typename Rng, typename It>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr auto decrement_index(Rng const&, It& it) return_decltype_MAYTHROW(\n\t\tvoid(--it)\n\t)\n\n\ttemplate<tc::has_index Rng, typename Index>\n\tconstexpr auto decrement_index(Rng const& rng, Index& idx) return_decltype_MAYTHROW(\n\t\trng.decrement_index(idx)\n\t)\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(decrement_index, const&, std::declval<typename T::tc_index &>())\n\tTC_HAS_EXPR(decrement_index, (Rng), tc::decrement_index(std::declval<Rng const&>(), std::declval<index_t<Rng>&>()))\n\n\t/////////////////////////////////////////////\n\t// index ranges with distance\n\n\ttemplate<typename Rng, typename ItLhs, typename ItRhs>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr auto distance_to_index(Rng const&, ItLhs const& itLhs, ItRhs const& itRhs) return_decltype_MAYTHROW(\n\t\titRhs - itLhs\n\t)\n\n\ttemplate<tc::has_index Rng, typename IndexLhs, typename IndexRhs>\n\tconstexpr auto distance_to_index(Rng const& rng, IndexLhs const& idxLhs, IndexRhs const& idxRhs) return_decltype_MAYTHROW(\n\t\trng.distance_to_index(idxLhs,idxRhs)\n\t)\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(distance_to_index, const&, std::declval<typename T::tc_index const&>(), std::declval<typename T::tc_index const&>())\n\tTC_HAS_EXPR(distance_to_index, (Rng), tc::distance_to_index(std::declval<Rng const&>(), std::declval<index_t<Rng> const&>(), std::declval<index_t<Rng> const&>()));\n\n\t/////////////////////////////////////////////\n\t// random access index ranges\n\n\ttemplate<typename Rng, typename It, typename Difference>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr void advance_index(Rng const&, It& it, Difference&& d) MAYTHROW {\n\t\tit += tc_move_if_owned(d);\n\t}\n\n\ttemplate<tc::has_index Rng, typename Index, typename Difference>\n\tconstexpr auto advance_index(Rng const& rng, Index& idx, Difference&& d) return_decltype_MAYTHROW(\n\t\trng.advance_index(idx, tc_move_if_owned(d))\n\t)\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(advance_index, const&, std::declval<typename T::tc_index &>(), std::declval<T const&>().distance_to_index(std::declval<typename T::tc_index const&>(), std::declval<typename T::tc_index const&>()))\n\tTC_HAS_EXPR(advance_index, (Rng), tc::advance_index(std::declval<Rng const&>(), std::declval<index_t<Rng> &>(), tc::distance_to_index(std::declval<Rng const&>(), std::declval<index_t<Rng> const&>(), std::declval<index_t<Rng> const&>())));\n\n\n\t/////////////////////////////////////////////\n\t// contiguous index ranges\n\n\ttemplate<typename Rng, typename It>\n#ifdef _LIBCPP_VERSION\n\t\trequires (!tc::has_index<Rng>) && tc::contiguous_range_detail::contiguous_iterator<std::decay_t<It>>\n#else\n\t\trequires (!tc::has_index<Rng>) && std::contiguous_iterator<std::decay_t<It>>\n#endif\n\tconstexpr auto index_to_address(Rng&&, It&& it) noexcept {\n\t\treturn std::to_address(tc_move_if_owned(it));\n\t}\n\n\ttemplate<tc::has_index Rng, typename Index>\n\tconstexpr auto index_to_address(Rng&& rng, Index&& idx) return_decltype_noexcept(\n\t\ttc_move_if_owned(rng).index_to_address(tc_move_if_owned(idx))\n\t)\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(index_to_address, &&, std::declval<typename T::tc_index>())\n\tTC_HAS_EXPR(index_to_address, (Rng), tc::index_to_address(std::declval<Rng&&>(), std::declval<index_t<Rng>&&>()))\n\n\t/////////////////////////////////////////////\n\t// index ranges with middle point\n\tnamespace iterator {\n\t\t#ifdef __clang__\n\t\t\t#pragma clang diagnostic push\n\t\t\t#pragma clang diagnostic ignored \"-Wundefined-inline\"\n\t\t\t#pragma clang diagnostic ignored \"-Wundefined-internal\"\n\t\t#endif\n\t\ttemplate<typename It> constexpr It middle_point(It const&, It const&) noexcept;\n\t\t#ifdef __clang__\n\t\t\t#pragma clang diagnostic pop\n\t\t#endif\n\t}\n\n\ttemplate<typename Rng, std::forward_iterator ItLhs, std::forward_iterator ItRhs>\n\t\trequires (!tc::has_index<Rng>)\n\tconstexpr void middle_point(Rng const&, ItLhs& itLhs, ItRhs const& itRhs) MAYTHROW {\n\t\titLhs = tc::iterator::middle_point(tc::as_const(itLhs), itRhs);\n\t}\n\n\ttemplate<tc::has_index Rng, typename IndexLhs, typename IndexRhs >\n\tconstexpr auto middle_point(Rng const& rng, IndexLhs& idxLhs, IndexRhs const& idxRhs) return_decltype_MAYTHROW(\n\t\trng.middle_point(idxLhs,idxRhs)\n\t)\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(middle_point, const&, std::declval<typename T::tc_index &>(), std::declval<typename T::tc_index const&>());\n\tTC_HAS_EXPR(middle_point, (Rng), tc::middle_point(std::declval<Rng const&>(), std::declval<index_t<Rng> &>(), std::declval<index_t<Rng> const&>()));\n\n\t/////////////////////////////////////////////\n\t// make_iterator\n\ttemplate<typename Rng, typename It > requires (!tc::has_index< std::remove_reference_t<Rng> >)\n\tconstexpr decltype(auto) make_iterator(Rng&&, It&& it) noexcept {\n\t\treturn tc_move_if_owned(it);\n\t}\n\n\ttemplate<typename Rng, typename Index > requires tc::has_index< std::remove_reference_t<Rng> >\n\tconstexpr decltype(auto) make_iterator(Rng&& rng, Index&& idx) noexcept {\n\t\treturn tc_move_if_owned(rng).make_iterator(tc_move_if_owned(idx));\n\t}\n}\n"
  },
  {
    "path": "tc/range/intersection_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../algorithm/compare.h\"\n#include \"../algorithm/algorithm.h\"\n#include \"filter_adaptor.h\"\n\nnamespace tc {\n\tnamespace intersection_difference_adaptor_detail::no_adl {\n\t\ttemplate<typename Sink, bool bIntersection, bool bSubset>\n\t\tstruct intersection_difference_sink {\n\t\t\tSink const m_sink;\n\n\t\t\tconstexpr auto operator()(interleave_2_detail::lhs_tag_t, auto&& lhs) const& noexcept {\n\t\t\t\tif constexpr(!bIntersection) {\n\t\t\t\t\treturn tc_invoke(m_sink, tc_move_if_owned(lhs));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconstexpr void operator()(interleave_2_detail::rhs_tag_t, tc::unused) const& noexcept {\n\t\t\t\tif constexpr(bSubset) {\n\t\t\t\t\t_ASSERTFALSE;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconstexpr auto operator()(interleave_2_detail::lhsrhs_tag_t, auto&& lhs, tc::unused) const& noexcept {\n\t\t\t\tif constexpr(bIntersection) {\n\t\t\t\t\treturn tc_invoke(m_sink, tc_move_if_owned(lhs));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace intersection_difference_adaptor_adl {\n\t\ttemplate<\n\t\t\tbool bIntersection,\n\t\t\tbool bSubset,\n\t\t\ttypename Comp,\n\t\t\ttypename Rng0,\n\t\t\ttypename Rng1\n\t\t>\n\t\tstruct [[nodiscard]] intersection_difference_adaptor final\n\t\t{\n\t\tprivate:\n\t\t\ttc::tuple<\n\t\t\t\ttc::reference_or_value< Rng0 >,\n\t\t\t\ttc::reference_or_value< Rng1 >\n\t\t\t> m_tplbaserng;\n\n\t\t\tComp m_comp;\n\n\t\tpublic:\n\t\t\ttemplate<typename Rhs0, typename Rhs1, typename Comp2>\n\t\t\texplicit intersection_difference_adaptor(Rhs0&& rhs0, Rhs1&& rhs1, Comp2&& comp) noexcept\n\t\t\t\t: m_tplbaserng{{\n\t\t\t\t\t{{aggregate_tag, tc_move_if_owned(rhs0)}},\n\t\t\t\t\t{{aggregate_tag, tc_move_if_owned(rhs1)}}\n\t\t\t\t}},\n\t\t\t\tm_comp(tc_move_if_owned(comp))\n\t\t\t{\n\t\t\t\t// For non-strictly sorted ranges, performs multiset intersect/difference, but the\n\t\t\t\t// meaning when the ranges are not sorted at all is unclear, though well-defined.\n\t\t\t\t// m_comp not always applicable on a single range:\n\t\t\t\t//\t_ASSERTDEBUG(tc::is_sorted(*tc::get<0>(m_tplbaserng), tc::lessfrom3way(comp)));\n\t\t\t\t//\t_ASSERTDEBUG(tc::is_sorted(*tc::get<1>(m_tplbaserng), tc::lessfrom3way(comp)));\n\t\t\t}\n\n\t\t\ttemplate<tc::decayed_derived_from<intersection_difference_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn interleave_2_detail::internal_interleave_2(\n\t\t\t\t\t*tc::get<0>(tc_move_if_owned(self).m_tplbaserng),\n\t\t\t\t\t*tc::get<1>(tc_move_if_owned(self).m_tplbaserng),\n\t\t\t\t\ttc_move_if_owned(self).m_comp,\n\t\t\t\t\tintersection_difference_adaptor_detail::no_adl::intersection_difference_sink<tc::decay_t<Sink>, bIntersection, bSubset>{tc_move_if_owned(sink)}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, intersection_difference_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> tc::range_output_t<decltype(*tc::get<0>(std::declval<Self>().m_tplbaserng))> {} // unevaluated\n\t\t};\n\t}\n\tusing intersection_difference_adaptor_adl::intersection_difference_adaptor;\n\n\ttemplate<bool bIntersection, typename Rng0, typename Rng1>\n\tauto set_intersect_or_difference(Rng0&& rng0, Rng1&& rng1) noexcept {\n\t\tstatic_assert(tc::instance<std::remove_reference_t<Rng1>, std::unordered_set>);\n\t\treturn tc::filter(\n\t\t\ttc_move_if_owned(rng0),\n\t\t\t[rng1_ = tc::reference_or_value< Rng1 >(tc::aggregate_tag, tc_move_if_owned(rng1))](auto const& element) noexcept {\n\t\t\t\tif constexpr(bIntersection) {\n\t\t\t\t\treturn tc::cont_find<tc::return_bool>(*rng1_, element);\n\t\t\t\t} else {\n\t\t\t\t\treturn !tc::cont_find<tc::return_bool>(*rng1_, element);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n\ttemplate<typename Rng0, typename Rng1>\n\tauto set_intersect(Rng0&& rng0, Rng1&& rng1) noexcept {\n\t\treturn set_intersect_or_difference<true>(tc_move_if_owned(rng0), tc_move_if_owned(rng1));\n\t}\n\n\ttemplate<typename Rng0, typename Rng1>\n\tauto set_difference(Rng0&& rng0, Rng1&& rng1) noexcept {\n\t\treturn set_intersect_or_difference<false>(tc_move_if_owned(rng0), tc_move_if_owned(rng1));\n\t}\n\n#pragma push_macro(\"DEFINE_INTERSECT_DIFFERENCE\")\n#define DEFINE_INTERSECT_DIFFERENCE(name, bIntersect, bSubset) \\\n\ttemplate<typename Rng0, typename Rng1, typename Comp = tc::fn_compare> \\\n\tauto name(Rng0&& rng0, Rng1&& rng1, Comp&& comp = Comp()) return_ctor_noexcept( \\\n\t\tTC_FWD(intersection_difference_adaptor<bIntersect, bSubset, tc::decay_t<Comp>, Rng0, Rng1>), \\\n\t\t(tc_move_if_owned(rng0), tc_move_if_owned(rng1), tc_move_if_owned(comp)) \\\n\t)\n\n\tDEFINE_INTERSECT_DIFFERENCE(intersect, true, false)\n\tDEFINE_INTERSECT_DIFFERENCE(subset_intersect, true, true)\n\tDEFINE_INTERSECT_DIFFERENCE(difference, false, false)\n\tDEFINE_INTERSECT_DIFFERENCE(subset_difference, false, true)\n#pragma pop_macro(\"DEFINE_INTERSECT_DIFFERENCE\")\n}\n"
  },
  {
    "path": "tc/range/intersection_adaptor.t.cpp",
    "content": "// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"intersection_adaptor.h\"\n\nUNITTESTDEF(intersection_difference) {\n\tint rngn[] = {2,3,5,7};\n\tdouble rngf[] = {1,3,5};\n\tauto rngnDifference = tc::difference(rngn, rngf);\n\tauto rngnIntersection = tc::intersect(rngn, rngf);\n\tSTATICASSERTSAME(tc::range_value_t<decltype(rngnDifference)>, int);\n\tSTATICASSERTSAME(tc::range_value_t<decltype(rngnIntersection)>, int);\n\t_ASSERT(tc::equal(rngnDifference, tc::make_array(tc::aggregate_tag, 2, 7)));\n\t_ASSERT(tc::equal(rngnIntersection, tc::make_array(tc::aggregate_tag, 3, 5)));\n\n\tauto rngndiff2 = tc::difference(\n\t\ttc::generator_range_output<int>([](auto sink) noexcept {\n\t\t\tif (tc::break_ == sink(1)) return tc::break_;\n\t\t\tif (tc::break_ == sink(2)) return tc::break_;\n\t\t\tif (tc::break_ == sink(3)) return tc::break_;\n\t\t\treturn tc::continue_;\n\t\t}),\n\t\ttc::single(2)\n\t);\n\n\t_ASSERT(tc::equal(rngndiff2, tc::make_array(tc::aggregate_tag,1,3)));\n\n\tauto rngndiff3 = tc::difference(\n\t\ttc::make_array(tc::aggregate_tag,0,1,3,5),\n\t\ttc::generator_range_output<int>([](auto sink) noexcept {\n\t\t\tif (tc::break_ == sink(1)) return tc::break_;\n\t\t\tif (tc::break_ == sink(2)) return tc::break_;\n\t\t\tif (tc::break_ == sink(3)) return tc::break_;\n\t\t\treturn tc::continue_;\n\t\t})\n\t);\n\n\ttc::for_each(rngndiff3, [](auto const n) noexcept {\n\t});\n\t_ASSERT(tc::equal(rngndiff3, tc::make_array(tc::aggregate_tag,0,5)));\n\n\n}\n"
  },
  {
    "path": "tc/range/iota_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../algorithm/element.h\"\n\n// By default, boost uses long long as counting_iterator<int>::difference_type,\n// which generates C4244 level 1 compiler warnings when cast back to int.\n// Most pragmatically, difference_type should reflect the type of a-b, thus counting_iterator<int>::difference_type is int,\n// and counting_iterator<unsigned short (or anything else shorter than int)>::difference_type is int.\n\nnamespace tc {\n\n\tnamespace counting_iterator_adl {\n\t\t\n\t\ttemplate<typename T>\n\t\tstruct delayed_iterator_difference_type {\n\t\t\tusing type = std::make_signed_t<decltype(std::declval<T>() - std::declval<T>())>;\n\t\t};\n\n\t\tTC_HAS_EXPR(decrement, (T), --std::declval<T&>());\n\t\tTC_HAS_EXPR(subtract, (T), std::declval<T const&>() - std::declval<T const&>());\n\n\t\ttemplate<typename T>\n\t\tstruct counting_iterator\n\t\t\t: iterator_facade<counting_iterator<T>>\n\t\t{\n\t\t\tstatic_assert(tc::decayed<T>);\n\n\t\tprivate:\n\t\t\tusing traversal = std::conditional_t<has_decrement<T>,\n\t\t\t\tstd::conditional_t<has_subtract<T>,\n\t\t\t\t\tboost::iterators::random_access_traversal_tag,\n\t\t\t\t\tboost::iterators::bidirectional_traversal_tag\n\t\t\t\t>,\n\t\t\t\tboost::iterators::forward_traversal_tag\n\t\t\t>;\n\n\t\t\tT value;\n\n\t\tpublic:\n\n\t\t\t// Non-random-access iterators might not be subtractable, but they still need a default difference_type, which is unrelated to subtraction.\n\t\t\tusing difference_type = typename std::conditional_t<\n\t\t\t\thas_subtract<T>,\n\t\t\t\tdelayed_iterator_difference_type<T>,\n\t\t\t\tstd::type_identity<std::ptrdiff_t>\n\t\t\t>::type;\n\n\t\t\tusing value_type = T;\n\t\t\tusing pointer = T const*;\n\t\t\tusing reference = T const&;\n\t\t\tusing iterator_category = typename boost::iterators::detail::iterator_facade_default_category<traversal, value_type, reference>::type;\n\n\t\t\tconstexpr counting_iterator(T value)\n\t\t\t\tnoexcept(std::is_nothrow_move_constructible<T>::value)\n\t\t\t\t: value(tc_move(value)) {}\n\n\t\t\tconstexpr counting_iterator() = default;\n\n\t\t\tconstexpr T const* operator->() const& noexcept { return std::addressof(value); }\n\t\t\tconstexpr T const* operator->() const&& = delete; // && not required yet. Could return a tc::no_adl::iterator_facade_value_wrapper\n\n\t\t\tconstexpr T && operator*() && noexcept { return tc_move(value); }\n\t\t\tconstexpr T const& operator*() const& noexcept { return value; }\n\t\t\tconstexpr T const&& operator*() const&& noexcept { return tc_move_always_even_const(value); }\n\n\t\t\ttemplate<typename U>\n\t\t\tfriend constexpr bool operator ==(counting_iterator<T> const& a, counting_iterator<U> const& b) return_MAYTHROW(\n\t\t\t\t*a == *b\n\t\t\t)\n\n\t\t\tconstexpr counting_iterator& operator++() noexcept(noexcept(\n\t\t\t\t++value\n\t\t\t)) requires requires { ++std::declval<T&>(); } {\n\t\t\t\t++value;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr counting_iterator& operator--() noexcept(noexcept(\n\t\t\t\t--value\n\t\t\t)) requires requires { --std::declval<T&>(); } {\n\t\t\t\t--value;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\t// For iterator_facade.\nMODIFY_WARNINGS_BEGIN(((disable)(4244))) // conversion possibly loses data; e.g. if T is an integral type smaller than int (so difference_type is int).\n\t\t\ttemplate < ENABLE_SFINAE, tc::decay_t<decltype(std::declval<SFINAE_TYPE(T&)>() += std::declval<difference_type&>())>* = nullptr >\n\t\t\tconstexpr void advance(difference_type n) noexcept(noexcept(\n\t\t\t\tvalue += n\n\t\t\t\t)) {\n\t\t\t\tvalue += n;\n\t\t\t}\nMODIFY_WARNINGS_END\n\n\t\t\t// iterator_facade's operator[] will not work for counting_iterator - it tries to return a dangling rvalue reference. This function returns by value.\n\t\t\ttemplate < ENABLE_SFINAE, tc::decay_t<decltype(std::declval<SFINAE_TYPE(counting_iterator &)>() += std::declval<difference_type &>())>* = nullptr >\n\t\t\tconstexpr auto operator[](SFINAE_TYPE(difference_type) index) const noexcept(\n\t\t\t\tnoexcept(std::declval<counting_iterator&>() += index)\n\t\t\t\t&& std::is_nothrow_copy_constructible<counting_iterator>::value\n\t\t\t\t&& std::is_nothrow_copy_constructible<T>::value\n\t\t\t) {\n\t\t\t\tauto it = *this;\n\t\t\t\tit += index;\n\t\t\t\treturn *it;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename T, std::enable_if_t<!std::is_unsigned<T>::value>* = nullptr>\n\t\tconstexpr auto operator -(counting_iterator<T> const& a, counting_iterator<T> const& b) return_decltype_NOEXCEPT( // NOEXCEPT() for e.g. counting_iterator<tc::iterator_t<tc::vector<T>>>\n\t\t\ttc::as_signed(*a - *b)\n\t\t)\n\n\t\ttemplate<typename T, std::enable_if_t<std::is_unsigned<T>::value>* = nullptr>\n\t\tconstexpr auto operator -(counting_iterator<T> const& a, counting_iterator<T> const& b) return_decltype_noexcept(\n\t\t\ttc::as_signed(*a) - tc::as_signed(*b)\n\t\t)\n\t}\n\n\tusing counting_iterator_adl::counting_iterator;\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct is_stashing_element<tc::counting_iterator<T>> : tc::constant<true> {};\n\t}\n\n\ttemplate <typename Rng> requires tc::instance<tc::iterator_t<Rng>, tc::counting_iterator>\n\tconstexpr auto enable_borrowed_range<Rng> = true;\n\n\ttemplate<typename TBegin, typename TEnd>\n\t[[nodiscard]] constexpr auto iota(TBegin const& tBegin, TEnd const& tEnd) noexcept {\n\t\tusing T = tc::counting_iterator<tc::common_type_t<TBegin, TEnd> >;\n\t\tif constexpr (std::convertible_to<typename boost::iterator_traversal<T>::type, boost::iterators::random_access_traversal_tag>) {\n\t\t\t_ASSERTE(!(static_cast<T>(tEnd) < static_cast<T>(tBegin)));\n\t\t}\n\t\treturn tc::make_iterator_range(static_cast<T>(tBegin), static_cast<T>(tEnd));\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct is_iota_range_impl final: tc::constant<false> {};\n\n\t\ttemplate<typename T>\n\t\tstruct is_iota_range_impl<subrange<universal_range<tc::counting_iterator<T>>>> final: tc::constant<true> {\n\t\t\tSTATICASSERTSAME(decltype(tc::iota(std::declval<T>(), std::declval<T>())), subrange<universal_range<tc::counting_iterator<T>>>);\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\tusing is_iota_range = tc::no_adl::is_iota_range_impl<std::remove_cvref_t<Rng>>;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] range_of_elements {\n\t\t\ttemplate<typename Rhs>\n\t\t\tconstexpr range_of_elements(aggregate_tag_t, Rhs&& rhs) noexcept\n\t\t\t\t: m_rng(aggregate_tag, tc_move_if_owned(rhs))\n\t\t\t{}\n\n\t\t\tconstexpr auto begin() const&\n\t\t\t\treturn_MAYTHROW(tc::counting_iterator<tc::decay_t<decltype(tc::begin(*m_rng))>>(tc::begin(*m_rng)))\n\t\t\t\n\t\t\tconstexpr auto end() const&\n\t\t\t\treturn_MAYTHROW(tc::counting_iterator<tc::decay_t<decltype(tc::end(*m_rng))>>(tc::end(*m_rng)))\n\t\t\t\n\t\t\tconstexpr auto begin() &\n\t\t\t\treturn_MAYTHROW(tc::counting_iterator<tc::decay_t<decltype(tc::begin(*m_rng))>>(tc::begin(*m_rng)))\n\n\t\t\tconstexpr auto end() &\n\t\t\t\treturn_MAYTHROW(tc::counting_iterator<tc::decay_t<decltype(tc::end(*m_rng))>>(tc::end(*m_rng)))\n\n\t\tprivate:\n\t\t\ttc::reference_or_value<Rng> m_rng;\n\t\t};\n\t}\n\ttemplate<typename Rng>\n\tconstexpr auto make_range_of_iterators(Rng&& rng)\n\t\treturn_ctor_noexcept( no_adl::range_of_elements< Rng >, (aggregate_tag, tc_move_if_owned(rng)) )\n\n\tnamespace no_adl {\n\t\ttemplate<auto Begin, decltype(Begin) End\n#ifdef _MSC_VER // MSVC 19.31 sometimes incorrectly folds iota_range_constant<EnumUnrelated(0), EnumUnrelated(7)> and iota_range_constant<Enum(0), Enum(7)>. I don't have a concise repro for this behavior.\n\t\t\t, typename MsvcWorkaround = decltype(Begin)\n#endif\n\t\t>\n\t\tstruct [[nodiscard]] iota_range_constant {\n\t\t\tstatic constexpr auto begin() noexcept {\n\t\t\t\treturn tc::counting_iterator(Begin);\n\t\t\t}\n\t\t\tstatic constexpr auto end() noexcept {\n\t\t\t\treturn tc::counting_iterator(End);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<tc::as_unsigned(End - Begin)>{};\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Enum>\n\t\tstruct [[nodiscard]] all_values final : iota_range_constant<tc::contiguous_enum<Enum>::begin(), tc::contiguous_enum<Enum>::end()> {\n\t\t\tstatic constexpr std::size_t index_of(Enum e) noexcept {\n\t\t\t\treturn e - tc::contiguous_enum<Enum>::begin();\n\t\t\t}\n#ifdef _MSC_VER\n\t\tprivate:\n\t\t\tstatic auto constexpr _natvis_begin = tc::contiguous_enum<Enum>::begin(); // natvis visualizations cannot call functions even if they are constexpr.\n\t\t\tstatic_assert( _natvis_begin == _natvis_begin ); // Make sure it is ODR-used.\n#endif\n\t\t};\n\n\t\ttemplate <typename RangeReturn, IF_TC_CHECKS(typename CheckUnique,) typename Enum>\n\t\t[[nodiscard]] constexpr decltype(auto) find_first_or_unique_impl(std::type_identity<RangeReturn>, IF_TC_CHECKS(CheckUnique bCheckUnique,) all_values<Enum> rng, Enum e) MAYTHROW {\n\t\t\tif constexpr( RangeReturn::requires_iterator ) {\n\t\t\t\treturn RangeReturn::pack_element(tc::begin(rng) + tc::explicit_cast<decltype(tc::end(rng) - tc::begin(rng))>(rng.index_of(e)), rng);\n\t\t\t} else {\n\t\t\t\treturn RangeReturn::template pack_element<all_values>(e);\n\t\t\t}\n\t\t}\n\t}\n\tusing no_adl::iota_range_constant;\n\tusing no_adl::all_values;\n\n\ttemplate <typename Enum>\n\tconstexpr auto enable_borrowed_range<tc::all_values<Enum>> = true;\n\n\ttemplate<typename Enum>\n\tinline auto constexpr all_constants = tc::tuple_transform(\n\t\ttc::index_sequence_as_tuple(std::make_index_sequence<tc::size(tc::all_values<Enum>())>()),\n\t\t[](auto const constn) constexpr {\n\t\t\treturn tc::constant<static_cast<Enum>(tc_at_nodebug(tc::all_values<Enum>(), constn()))>();\n\t\t}\n\t);\n\n\ttemplate<typename Derived, typename Counter>\n\tusing iota_range_adaptor = tc::index_range_adaptor<Derived, tc::no_adl::universal_range</*It*/tc::counting_iterator<Counter>>, tc::index_range_adaptor_flags::inherit_traversal>;\n}\n"
  },
  {
    "path": "tc/range/iterator_cache.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/accessors.h\"\n#include \"../base/noncopyable.h\"\n#include \"../base/reference_or_value.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename It>\n\t\tstruct iterator_cache final : tc::nonmovable /*m_ref may contain pointer into m_it*/ {\n\t\tprivate:\n\t\t\tPRIVATE_MEMBER_PUBLIC_ACCESSOR(It, m_it)\n\t\t\ttc::reference_or_value< typename std::iterator_traits<It>::reference > m_ref;\n\n\t\tpublic:\n\t\t\tconstexpr iterator_cache(It it) noexcept\n\t\t\t\t: m_it(tc_move(it))\n\t\t\t\t, m_ref(aggregate_tag, *m_it)\n\t\t\t{}\n\n\t\t\tconstexpr iterator_cache& operator=(It it) & noexcept {\n\t\t\t\tm_it=tc_move(it);\n\t\t\t\tm_ref = tc::reference_or_value<typename std::iterator_traits<It>::reference>(tc::aggregate_tag, *m_it);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr auto operator*() const& return_decltype_noexcept( *m_ref )\n\t\t\tconstexpr auto operator*() && return_decltype_allow_xvalue_noexcept( *tc_move(m_ref) )\n\t\t\tconstexpr auto operator*() const&& noexcept = delete;\n\t\t};\n\t}\n\tusing no_adl::iterator_cache;\n}\n"
  },
  {
    "path": "tc/range/iterator_facade.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/return_decltype.h\"\n#include \"../base/explicit_cast.h\"\n#include \"../base/as_lvalue.h\"\n\nnamespace tc\n{\n\tnamespace iterator_facade_detail\n\t{\n\t\ttemplate<typename T>\n\t\tstruct value_wrapper final {\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr value_wrapper(It const& it) noexcept(noexcept(*it))\n\t\t\t\t: m_value(*it)\n\t\t\t{}\n\n\t\t\t// This must return a non-const pointer, so that it can be moved from.\n\t\t\tconstexpr T* operator->() noexcept { return std::addressof(m_value); }\n\n\t\tprivate:\n\t\t\tT m_value;\n\t\t};\n\n#ifdef _MSC_VER\n\t\t// Due to a bug in the MSVC standard library, we need to allow std::ptrdiff_t as distance type as well.\n\t\t// Note that this is only the type in the interface of the operators, not the actual one as reported by the traits.\n\t\t// https://github.com/microsoft/STL/issues/3663\n\t\ttemplate <typename It>\n\t\tusing difference_type = std::ptrdiff_t;\n#else\n\t\ttemplate <typename It>\n\t\tusing difference_type = typename std::iterator_traits<std::decay_t<It>>::difference_type;\n#endif\n\t\n\t\ttemplate <typename It>\t\n\t\tconstexpr auto as_difference_type(difference_type<It> value) noexcept {\n\t\t\tusing actual_difference_type = typename std::iterator_traits<std::decay_t<It>>::difference_type;\n\t\t\treturn tc::explicit_cast<actual_difference_type>(value);\n\t\t}\n\n\t\tstruct TC_EMPTY_BASES iterator_facade_base{};\n\n\t\ttemplate <typename T>\n\t\tconcept iterator_facade = std::is_base_of<iterator_facade_base, std::decay_t<T>>::value;\n\t}\n\n\tnamespace iterator_facade_adl\n\t{\n\t\t// This base class implements several iterator operators in terms of other operators.\n\t\t//\n\t\t// iterator_facade relies on the following members being implemented in the derived class:\n\t\t// Always:\n\t\t//   using difference_type = ...;\n\t\t//   bool operator==(iterator const&, iterator const&)\n\t\t//   iterator& operator++()\n\t\t//   any_type operator*() const&  // may return a reference or a value\n\t\t//\n\t\t// For bidirectional or random access traversal:\n\t\t//   iterator& operator--()\n\t\t//\n\t\t// For random access traversal:\n\t\t//   void iterator::advance(difference_type)\n\t\t//   difference_type operator-(iterator const&, iterator const&)\n\t\ttemplate<typename Derived>\n\t\tstruct TC_EMPTY_BASES iterator_facade : iterator_facade_detail::iterator_facade_base {\n\t\t\ttemplate<typename It = Derived>\n\t\t\tconstexpr decltype(auto) operator->() const& noexcept(noexcept(*std::declval<It const&>())) {\n\t\t\t\tauto& self = tc::derived_cast<Derived>(*MSVC_WORKAROUND_THIS);\n\n\t\t\t\tusing reference = decltype(*std::declval<It const&>());\n\t\t\t\tif constexpr (std::is_reference<reference>::value) {\n\t\t\t\t\t// There are no rvalue pointers; return a pointer even if operator* returns an rvalue reference.\n\t\t\t\t\t// std::addressof will not accept an rvalue reference argument\n\t\t\t\t\treturn std::addressof(tc::as_lvalue(*self));\n\t\t\t\t} else {\n\t\t\t\t\t// If operator* returns a const or volatile object by value, it's not clear whether we should keep that qualifier\n\t\t\t\t\tstatic_assert(std::is_same<reference, std::remove_cv_t<reference>>::value, \"Iterator dereferencing should not result in a const or volatile value type\");\n\n\t\t\t\t\t// If operator* returns a value type (e.g. for transform_adaptor iterators) then operator-> returns a proxy instead of a pointer\n\t\t\t\t\treturn iterator_facade_detail::value_wrapper<reference>(self);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename It = Derived>\n\t\t\tconstexpr auto operator[](iterator_facade_detail::difference_type<It> index) const& return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\t*(tc::derived_cast<It>(*MSVC_WORKAROUND_THIS) + iterator_facade_detail::as_difference_type<It>(index))\n\t\t\t)\n\t\t\ttemplate<typename It = Derived>\n\t\t\tconstexpr auto operator[](iterator_facade_detail::difference_type<It> index) && return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\t*(tc::derived_cast<It>(*MSVC_WORKAROUND_THIS) += iterator_facade_detail::as_difference_type<It>(index))\n\t\t\t)\n\t\t};\n\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr It operator++(It &it, int) noexcept(std::is_nothrow_copy_constructible<It>::value && noexcept(++std::declval<It&>())) {\n\t\t\tauto result = it;\n\t\t\t++it;\n\t\t\treturn result;\n\t\t}\n\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\t\trequires requires(It& it) { --it; }\n\t\tconstexpr It operator--(It& it, int) noexcept(std::is_nothrow_copy_constructible<It>::value && noexcept(--std::declval<It&>())) {\n\t\t\tauto result = it;\n\t\t\t--it;\n\t\t\treturn result;\n\t\t}\n\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr auto operator+=(It& it, iterator_facade_detail::difference_type<It> n) return_decltype_MAYTHROW(\n\t\t\tit.advance(iterator_facade_detail::as_difference_type<It>(n)), it\n\t\t)\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr auto operator-=(It& it, iterator_facade_detail::difference_type<It> n) return_decltype_MAYTHROW(\n\t\t\tit.advance(iterator_facade_detail::as_difference_type<It>(-n)), it\n\t\t)\n\n\t\t// clang bug: We cannot use only requires to constrain the operator overload, need at least one enable_if.\n\t\t// (Otherwise, it complains about overloading it for non-class types.)\n\t\ttemplate<typename It, typename ItDecay = std::decay_t<It>,\n\t\t\t\t std::enable_if_t<iterator_facade_detail::iterator_facade<ItDecay>>* = nullptr>\n\t\t\trequires requires (ItDecay& it) { it += 1; }\n\t\tconstexpr auto operator+(It&& lhs, iterator_facade_detail::difference_type<It> rhs) noexcept(std::is_nothrow_constructible<std::decay_t<It>, It&&>::value && noexcept(std::declval<ItDecay&>() += 1)) {\n\t\t\tauto result = tc_move_if_owned(lhs);\n\t\t\tresult += iterator_facade_detail::as_difference_type<It>(rhs);\n\t\t\treturn result;\n\t\t}\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr auto operator+(iterator_facade_detail::difference_type<It> lhs, It&& rhs) return_decltype_MAYTHROW(\n\t\t\ttc_move_if_owned(rhs) + lhs\n\t\t)\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr auto operator-(It&& lhs, iterator_facade_detail::difference_type<It> rhs) return_decltype_MAYTHROW(\n\t\t\ttc_move_if_owned(lhs) + iterator_facade_detail::as_difference_type<It>(-rhs)\n\t\t)\n\n\t\ttemplate<iterator_facade_detail::iterator_facade It>\n\t\tconstexpr auto operator<=>(const It& lhs, const It& rhs) return_decltype_noexcept(\n\t\t\t(lhs - rhs) <=> 0\n\t\t)\n\t}\n\tusing iterator_facade_adl::iterator_facade;\n}\n"
  },
  {
    "path": "tc/range/join_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/modified.h\"\n#include \"../algorithm/accumulate.h\"\n#include \"../algorithm/size_linear.h\"\n#include \"range_adaptor.h\"\n#include \"transform_adaptor.h\"\n#include \"reverse_adaptor.h\"\n\nnamespace tc {\n\tDECLARE_TMPL_FUNC_WITH_CUSTOMIZATIONS(join)\n\t\n\ttc_define_fn(size_linear_raw)\n\n\tnamespace no_adl {\n\t\tnamespace join_adaptor_detail {\n\t\t\ttemplate<typename RngRng>\n\t\t\tconcept joinable_with_iterators = tc::range_with_iterators<RngRng>\n\t\t\t\t&& !tc::has_stashing_index<std::remove_reference_t<RngRng>>::value // RngRgn must not have \"stashing\" index/iterator: copying the composite index would invalidate the inner index/iterator.\n\t\t\t\t&& tc::borrowed_range<std::iter_reference_t<tc::iterator_t<RngRng>>>;\n\n\t\t\ttemplate <typename RngRng, typename CommonOutput = boost::mp11::mp_apply<\n\t\t\t\ttc::common_reference_t,\n\t\t\t\ttc::mp_transform<\n\t\t\t\t\tstd::add_rvalue_reference_t,\n\t\t\t\t\ttc::range_output_t<RngRng>\n\t\t\t\t>>\n\t\t\t>\n\t\t\t\trequires tc::has_constexpr_size<CommonOutput>\n\t\t\tauto constexpr rng_constexpr_size = tc::constexpr_size<CommonOutput>;\n\t\t}\n\n\t\ttemplate<typename RngRng, bool bHasIterator = join_adaptor_detail::joinable_with_iterators<RngRng>>\n\t\tstruct join_adaptor;\n\n\t\ttemplate<typename Sink, bool bReverse>\n\t\tstruct join_sink;\n\n\t\ttemplate<typename Sink>\n\t\tstruct join_sink<Sink, /*bReverse*/false> {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tconstexpr auto operator()(Rng&& rng) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::for_each(tc_move_if_owned(rng), m_sink)\n\t\t\t)\n\n\t\t\ttemplate<typename SubRngRng, ENABLE_SFINAE>\n\t\t\tauto chunk(SubRngRng&& rngrng) const& return_decltype_MAYTHROW(\n\t\t\t\tSFINAE_VALUE(m_sink).chunk(tc::join(tc_move_if_owned(rngrng)))\n\t\t\t)\n\t\t};\n\n\t\ttemplate<typename Sink>\n\t\tstruct join_sink<Sink, /*bReverse*/true> {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tauto operator()(Rng&& rng) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::for_each(tc::reverse(tc_move_if_owned(rng)), m_sink)\n\t\t\t)\n\t\t};\n\n\t\ttemplate<typename RngRng>\n\t\tstruct [[nodiscard]] join_adaptor<RngRng, false> : tc::generator_range_adaptor<RngRng> {\n\t\t\tconstexpr join_adaptor() = default;\n\t\t\tusing tc::generator_range_adaptor<RngRng>::generator_range_adaptor;\n\n\t\t\ttemplate<typename Sink, bool bReverse>\n\t\t\tstatic constexpr auto adapted_sink(Sink&& sink, tc::constant<bReverse>) noexcept {\n\t\t\t\treturn join_sink<tc::decay_t<Sink>, bReverse>{tc_move_if_owned(sink)};\n\t\t\t}\n\n\t\t\tconstexpr auto size() const& MAYTHROW\n\t\t\t\trequires tc::has_size<RngRng> && requires(join_adaptor const& join) { join_adaptor_detail::rng_constexpr_size<decltype(join.base_range())>; } {\n\t\t\t\treturn tc::compute_range_adaptor_size<[](auto const n) noexcept {\n\t\t\t\t\treturn tc::as_unsigned(n * join_adaptor_detail::rng_constexpr_size<decltype(std::declval<join_adaptor>().base_range())>());\n\t\t\t\t}>(this->base_range());\n\t\t\t}\n\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr auto size_linear() const& return_decltype_noexcept(\n\t\t\t\ttc::accumulate(tc::transform(SFINAE_VALUE(this)->base_range(), tc::fn_size_linear_raw(), tc::explicit_cast<std::size_t>(0), tc::fn_assign_plus()))\n\t\t\t)\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, join_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<boost::mp11::mp_flatten<tc::mp_transform<tc::range_output_t, tc::range_output_t<decltype(std::declval<Self>().base_range())>>>> {} // unevaluated\n\t\t\t\n\t\t};\n\n\t\ttemplate<typename RngRng>\n\t\tstruct [[nodiscard]] join_adaptor<RngRng, true> :\n\t\t\tjoin_adaptor<RngRng, false>,\n\t\t\ttc::range_iterator_from_index<\n\t\t\t\tjoin_adaptor<RngRng>,\n\t\t\t\ttc::tuple<\n\t\t\t\t\ttc::index_t<std::remove_reference_t<RngRng>>,\n\t\t\t\t\ttc::index_t<std::remove_reference_t<std::iter_reference_t<tc::iterator_t<RngRng>>>>\n\t\t\t\t>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = join_adaptor;\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<std::iter_reference_t<tc::iterator_t<RngRng>>>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\t\tprivate:\n\t\t\ttc::index_t<std::remove_reference_t<std::iter_reference_t<tc::iterator_t<RngRng>>>> find_valid_index(tc::index_t<std::remove_reference_t<RngRng>>& idxFirst) const& noexcept {\n\t\t\t\twhile (!tc::at_end_index(this->base_range(), idxFirst)) {\n\t\t\t\t\tdecltype(auto) rngSecond = tc::dereference_index(this->base_range_best_access(), idxFirst);\n\t\t\t\t\tauto idxSecond = tc::begin_index(rngSecond);\n\t\t\t\t\tif (tc::at_end_index(rngSecond, idxSecond)) {\n\t\t\t\t\t\ttc::increment_index(this->base_range(), idxFirst);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn idxSecond;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {};\n\t\t\t}\n\t\tpublic:\n\t\t\tconstexpr join_adaptor() = default;\n\t\t\tusing join_adaptor<RngRng, false>::join_adaptor;\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\tauto idxFirst = this->base_begin_index();\n\t\t\t\tauto idxSecond = find_valid_index(idxFirst);\n\t\t\t\treturn { tc_move(idxFirst), tc_move(idxSecond) };\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn { this->base_end_index(), {} };\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn tc::at_end_index(this->base_range(), tc::get<0>(idx));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERT(!tc::at_end_index(this->base_range(), tc::get<0>(idx)));\n\t\t\t\ttc_auto_cref(rngSecond, tc::dereference_index(this->base_range(), tc::get<0>(idx)));\n\t\t\t\ttc::increment_index(rngSecond, tc::get<1>(idx));\n\t\t\t\tif (tc::at_end_index(rngSecond, tc::get<1>(idx))) {\n\t\t\t\t\ttc::increment_index(this->base_range(), tc::get<0>(idx));\n\t\t\t\t\ttc::get<1>(idx) = find_valid_index(tc::get<0>(idx));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& noexcept -> void\n\t\t\t\trequires tc::has_decrement_index<std::remove_reference_t<RngRng>>\n\t\t\t\t\t&& tc::has_end_index<std::remove_reference_t<std::iter_reference_t<tc::iterator_t<RngRng>>>>\n\t\t\t\t\t&& tc::has_decrement_index<std::remove_reference_t<std::iter_reference_t<tc::iterator_t<RngRng>>>>\n\t\t\t{\n\t\t\t\tauto const funcReverseFindValidIndex = [&]() noexcept {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\ttc::decrement_index(this->base_range(), tc::get<0>(idx));\n\t\t\t\t\t\tdecltype(auto) rngSecond = tc::dereference_index(this->base_range_best_access(), tc::get<0>(idx));\n\t\t\t\t\t\ttc::get<1>(idx) = tc::end_index(rngSecond);\n\t\t\t\t\t\tif (tc::begin_index(rngSecond) != tc::get<1>(idx)) {\n\t\t\t\t\t\t\ttc::decrement_index(rngSecond, tc::get<1>(idx));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tif(tc::at_end_index(this->base_range(), tc::get<0>(idx))) {\n\t\t\t\t\tfuncReverseFindValidIndex();\n\t\t\t\t} else {\n\t\t\t\t\ttc_auto_cref(rngSecond, tc::dereference_index(this->base_range(), tc::get<0>(idx)));\n\t\t\t\t\tif(tc::begin_index(rngSecond) == tc::get<1>(idx)) {\n\t\t\t\t\t\tfuncReverseFindValidIndex();\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttc::decrement_index(rngSecond, tc::get<1>(idx));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc::dereference_index(\n\t\t\t\t\ttc::dereference_index(this->base_range(), tc::get<0>(tc_move_if_owned(idx))),\n\t\t\t\t\ttc::get<1>(tc_move_if_owned(idx))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(auto&& idx) & MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc::dereference_index(\n\t\t\t\t\ttc::dereference_index(this->base_range(), tc::get<0>(tc_move_if_owned(idx))),\n\t\t\t\t\ttc::get<1>(tc_move_if_owned(idx))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tstatic constexpr auto element_base_index(tc_index const& idx) noexcept {\n\t\t\t\treturn tc::get<0>(idx);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::join_adaptor;\n\n\ttemplate<typename RngRng>\n\tconstexpr auto enable_stable_index_on_move<join_adaptor<RngRng, true>> = tc::stable_index_on_move<RngRng>;\n\n\tnamespace join_default {\n\t\ttemplate<typename RngRng>\n\t\tconstexpr join_adaptor<RngRng> join_impl(RngRng&& rngrng) noexcept {\n\t\t\treturn {aggregate_tag, tc_move_if_owned(rngrng)};\n\t\t}\n\t}\n\n\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(join)\n}\n"
  },
  {
    "path": "tc/range/join_framed_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"empty_range.h\"\n#include \"../algorithm/for_each.h\"\n#include \"../algorithm/empty.h\"\n#include \"../base/reference_or_value.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename FuncBegin, typename FuncElem, typename FuncSeparator>\n\t\tstruct framed_for_each_sink { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tFuncBegin const& m_funcBegin;\n\t\t\tFuncElem const& m_funcElement;\n\t\t\tFuncSeparator const& m_funcSeparator;\n\t\t\tbool& m_bEmpty;\n\n\t\t\tconstexpr auto operator()(auto&& t) const& MAYTHROW {\n\t\t\t\ttc_return_break_or_continue(\n\t\t\t\t\t(tc_conditional_prvalue_as_val(tc::change(m_bEmpty, false),\n\t\t\t\t\t\ttc_internal_continue_if_not_break(m_funcBegin()),\n\t\t\t\t\t\ttc_internal_continue_if_not_break(m_funcSeparator())\n\t\t\t\t\t))\n\t\t\t\t\t(tc::continue_if_not_break(m_funcElement, tc_move_if_owned(t)))\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Rng, typename FuncBegin, typename FuncElem, typename FuncSeparator, typename FuncEnd>\n\tconstexpr auto framed_for_each(Rng&& rng, FuncBegin funcBegin, FuncElem funcElement, FuncSeparator funcSeparator, FuncEnd funcEnd) MAYTHROW {\n\t\tbool bEmpty = true;\n\n\t\ttc_return_break_or_continue(\n\t\t\t(tc::for_each(tc_move_if_owned(rng), no_adl::framed_for_each_sink<FuncBegin, FuncElem, FuncSeparator>{funcBegin, funcElement, funcSeparator, bEmpty}))\n\t\t\t(tc_conditional_prvalue_as_val(!bEmpty,\n\t\t\t\ttc_internal_continue_if_not_break(funcEnd()),\n\t\t\t\ttc::constant<tc::continue_>()\n\t\t\t))\n\t\t);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename RngBegin, typename RngRng, typename RngSep, typename RngEnd>\n\t\tstruct [[nodiscard]] join_framed_adaptor {\n\t\t\ttemplate<typename RngBegin2, typename RngRng2, typename RngSep2, typename RngEnd2>\n\t\t\texplicit join_framed_adaptor(aggregate_tag_t, RngBegin2&& rngBegin, RngRng2&& baserng, RngSep2&& rngSep, RngEnd2&& rngEnd) noexcept\n\t\t\t\t: m_rngBegin(aggregate_tag, tc_move_if_owned(rngBegin))\n\t\t\t\t, m_baserng(aggregate_tag, tc_move_if_owned(baserng))\n\t\t\t\t, m_rngSep(aggregate_tag, tc_move_if_owned(rngSep))\n\t\t\t\t, m_rngEnd(aggregate_tag, tc_move_if_owned(rngEnd))\n\t\t\t{}\n\n\t\t\ttemplate<tc::decayed_derived_from<join_framed_adaptor> Self, typename Sink>\n\t\t\tfriend auto for_each_impl(Self&& self, Sink sink) MAYTHROW {\n\t\t\t\treturn tc::framed_for_each(*tc_move_if_owned(self).m_baserng,\n\t\t\t\t\t[&]() MAYTHROW {\n\t\t\t\t\t\treturn tc::for_each(*tc_move_if_owned(self).m_rngBegin, sink);\n\t\t\t\t\t},\n\t\t\t\t\t[&](auto&& rng) MAYTHROW {\n\t\t\t\t\t\treturn tc::for_each(tc_move_if_owned(rng), sink);\n\t\t\t\t\t},\n\t\t\t\t\t[&]() MAYTHROW {\n\t\t\t\t\t\treturn tc::for_each(*tc_move_if_owned(self).m_rngSep, sink);\n\t\t\t\t\t},\n\t\t\t\t\t[&]() MAYTHROW {\n\t\t\t\t\t\treturn tc::for_each(*tc_move_if_owned(self).m_rngEnd, tc_move(sink));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, join_framed_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&& self) -> boost::mp11::mp_unique<boost::mp11::mp_append<\n\t\t\t\ttc::range_output_t<decltype(*tc_move_if_owned(self).m_rngBegin)>,\n\t\t\t\tboost::mp11::mp_flatten<tc::mp_transform<tc::range_output_t, tc::range_output_t<decltype(*tc_move_if_owned(self).m_baserng)>>>,\n\t\t\t\ttc::range_output_t<decltype(*tc_move_if_owned(self).m_rngSep)>,\n\t\t\t\ttc::range_output_t<decltype(*tc_move_if_owned(self).m_rngEnd)>\n\t\t\t>> {} // unevaluated\n\n\t\t\tbool empty() const& noexcept {\n\t\t\t\treturn\n\t\t\t\t\ttc::empty(*m_baserng)\n\t\t\t\t\t|| (\n\t\t\t\t\t\ttc::empty(*m_rngBegin) && tc::empty(*m_rngEnd) && [&]() noexcept {\n\t\t\t\t\t\t\tbool const bEmptySep = tc::empty(*m_rngSep);\n\t\t\t\t\t\t\tbool bFirst = false;\n\t\t\t\t\t\t\treturn tc::continue_==tc::for_each(*m_baserng, [&](auto const& rng) noexcept {\n\t\t\t\t\t\t\t\treturn tc::continue_if(tc::empty(rng) && (tc::change(bFirst, true) || bEmptySep));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}()\n\t\t\t\t\t);\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttc::reference_or_value<RngBegin> m_rngBegin;\n\t\t\ttc::reference_or_value<RngRng> m_baserng;\n\t\t\ttc::reference_or_value<RngSep> m_rngSep;\n\t\t\ttc::reference_or_value<RngEnd> m_rngEnd;\n\t\t};\n\t}\n\tusing no_adl::join_framed_adaptor;\n\n\ttemplate<typename RngBegin, typename RngRng, typename RngSep, typename RngEnd>\n\tauto join_framed(RngBegin&& rngBegin, RngRng&& rngrng, RngSep&& rngSep, RngEnd&& rngEnd) return_ctor_noexcept(\n\t\tTC_FWD(join_framed_adaptor<RngBegin, RngRng, RngSep, RngEnd>),\n\t\t(aggregate_tag, tc_move_if_owned(rngBegin), tc_move_if_owned(rngrng), tc_move_if_owned(rngSep), tc_move_if_owned(rngEnd))\n\t)\n\n\ttemplate<typename RngBegin, typename RngRng, typename RngEnd>\n\tauto join_framed(RngBegin&& rngBegin, RngRng&& rngrng, RngEnd&& rngEnd) return_ctor_noexcept(\n\t\tTC_FWD(join_framed_adaptor<RngBegin, RngRng, tc::empty_range, RngEnd>),\n\t\t(aggregate_tag, tc_move_if_owned(rngBegin), tc_move_if_owned(rngrng), tc::empty_range(), tc_move_if_owned(rngEnd))\n\t)\n\n\ttemplate<typename RngSep, typename RngRng>\n\tauto join_with_separator(RngSep&& rngSep, RngRng&& rngrng) return_ctor_noexcept(\n\t\tTC_FWD(join_framed_adaptor<tc::empty_range, RngRng, RngSep, tc::empty_range>),\n\t\t(aggregate_tag, tc::empty_range(), tc_move_if_owned(rngrng), tc_move_if_owned(rngSep), tc::empty_range())\n\t)\n}\n"
  },
  {
    "path": "tc/range/literal_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"meta.h\"\n#include \"../base/casts.h\"\n\nnamespace tc {\n\tnamespace literal_range_detail {\n\t\ttemplate <typename T, auto ... Ts>\n\t\tinline constexpr T const array[] = {T(Ts)...};\n\n\t\ttemplate <tc::char_like T, auto ... Ts>\n#if defined(__clang__) && !defined(_DEBUG)\n\t\t// We make it static, so it matches a string literal.\n\t\t// That way, compilers are able to de-duplicate it: https://godbolt.org/z/9hjjxrTnx\n\t\t// This de-duplicate only works with clang release build\n\t\tstatic\n#else\n\t\tinline\n#endif\n\t\tconstexpr T const str[] = {T(Ts)..., T()};\n\t}\n\n\tnamespace literal_range_adl {\n\t\t// Note that Ts... does not have the type of T but can be some other type, that can be used to construct T in the array initializer.\n\t\t// This keeps the instantiated name of the type small - for example, a value of tc::char_ascii is something like `tc::char_ascii<template-params>{tc::additive<>{}, value}`,\n\t\t// but if passed as `char` it is just `value`.\n\t\ttemplate <typename T, auto... Ts>\n\t\tstruct literal_range final {\n\t\t\t// The return type should be an array reference so we don't lose type information.\n\t\t\t// However, there is a bug in the current MSVC version, that doesn't allow decltype(auto): https://developercommunity.visualstudio.com/t/decltypeauto-strips-reference-of-array-types/218527\n\t\t\tstatic constexpr auto as_array() noexcept -> T const (&)[sizeof...(Ts) + (tc::char_like<T> ? 1 : 0)]{\n\t\t\t\tif constexpr (tc::char_like<T>) {\n\t\t\t\t\treturn literal_range_detail::str<T, Ts...>;\n\t\t\t\t} else {\n\t\t\t\t\treturn literal_range_detail::array<T, Ts...>;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Implicit conversion to C string, if it's a C string.\n\t\t\ttemplate <std::same_as<T const*> Target>\n\t\t\tconstexpr operator Target() const& noexcept\n\t\t\t\trequires tc::char_like<T> && (tc::strlen(literal_range::as_array()) == sizeof...(Ts))\n\t\t\t{\n\t\t\t\treturn as_array(); // decays to pointer\n\t\t\t}\n\n\t\t\tconstexpr T const* begin() const& noexcept {\n\t\t\t\treturn as_array();\n\t\t\t}\n\t\t\tconstexpr T const* end() const& noexcept {\n\t\t\t\treturn as_array() + sizeof...(Ts);\n\t\t\t}\n\n\t\t\tstatic constexpr auto size() noexcept {\n\t\t\t\treturn tc::least_uint_constant<sizeof...(Ts)>{};\n\t\t\t}\n\t\t};\n\n\t\ttemplate <tc::char_like T, auto ... Ts>\n\t\t[[nodiscard]] constexpr auto as_c_str_impl(literal_range<T, Ts...> rng) return_decltype_noexcept(\n\t\t\ttc::implicit_cast<T const*>(rng)\n\t\t)\n\t}\n\tusing literal_range_adl::literal_range;\n\n\ttemplate <typename T, auto ... Ts>\n\tinline constexpr auto enable_borrowed_range<tc::literal_range<T, Ts...>> = true;\n\n\ttemplate <auto ... Ts>\n\tconstexpr literal_range<tc::common_type_t<decltype(Ts)...>, Ts...> literal_range_of = {};\n\n\tnamespace literal_range_detail {\n\t\ttemplate <typename T>\n\t\tconstexpr auto is_literal_range = false;\n\t\ttemplate <typename T, auto ... Ts>\n\t\tconstexpr auto is_literal_range<literal_range<T, Ts...>> = true;\n\t}\n\ttemplate <typename T>\n\tconcept is_literal_range = literal_range_detail::is_literal_range<tc::decay_t<T>>;\n}\n"
  },
  {
    "path": "tc/range/literal_range.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"literal_range.h\"\n#include \"../string/make_c_str.h\"\n#include \"../array.h\"\n\nUNITTESTDEF(literal_range) {\n\tstd::same_as<tc::literal_range<int, 1, 2, 3>> auto rng = tc::literal_range_of<1, 2, 3>;\n\tTEST_RANGE_EQUAL(rng, (std::array<int, 3>{1, 2, 3}));\n\t_ASSERTEQUAL(tc::make_array(rng), (std::array<int, 3>{1, 2, 3}));\n}\n\nUNITTESTDEF(literal_range_string) {\n\tstd::same_as<tc::literal_range<char, 'a', 'b', 'c'>> auto rng = tc::literal_range_of<'a', 'b', 'c'>;\n\tTEST_RANGE_EQUAL(rng, (std::array<char, 3>{'a', 'b', 'c'}));\n\t_ASSERTEQUAL(tc::make_array(rng), (std::array<char, 3>{'a', 'b', 'c'}));\n\n\tchar const* implicit_str = rng;\n\t_ASSERTEQUAL(implicit_str[0], 'a');\n\t_ASSERTEQUAL(implicit_str[1], 'b');\n\t_ASSERTEQUAL(implicit_str[2], 'c');\n\t_ASSERTEQUAL(implicit_str[3], '\\0');\n\n\t_ASSERTEQUAL(tc::as_c_str(rng), implicit_str);\n\t// GCC doesn't like it without the implicit cast.\n\t_ASSERTEQUAL(tc::implicit_cast<char const*>(tc::make_c_str(rng)), implicit_str);\n\t_ASSERTEQUAL(tc::make_str(rng), \"abc\");\n}\n"
  },
  {
    "path": "tc/range/make_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../array.h\"\n\nnamespace tc {\n\ttemplate<typename T0, typename... T>\n\tconstexpr decltype(auto) make_range(T0&& t0, T&&... t) noexcept {\n\t\tif constexpr( (std::is_same<T0, T>::value && ...) ) {\n\t\t\treturn tc::make_array<std::conditional_t<std::is_reference<T0>::value, T0, std::remove_cv_t<T0>>>(tc::aggregate_tag,\n\t\t\t\ttc_move_if_owned(t0), tc_move_if_owned(t)...\n\t\t\t);\n\t\t} else {\n\t\t\treturn tc::transform(\n\t\t\t\ttc::make_tuple(\n\t\t\t\t\ttc::make_reference_or_value(tc_move_if_owned(t0)),\n\t\t\t\t\ttc::make_reference_or_value(tc_move_if_owned(t))...\n\t\t\t\t),\n\t\t\t\ttc::fn_indirection()\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/range/merge_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"union_adaptor.h\"\n\nnamespace tc {\n\ttemplate<typename Rng0, typename Rng1, typename Less = tc::fn_less>\n\t[[nodiscard]] auto merge_range(Rng0&& rng0, Rng1&& rng1, Less&& less = Less()) noexcept {\n\t\treturn tc::disjoint_union_range(\n\t\t\ttc_move_if_owned(rng0),\n\t\t\ttc_move_if_owned(rng1),\n\t\t\t[less=tc::decay_copy(tc_move_if_owned(less))](auto const& lhs, auto const& rhs) noexcept {\n\t\t\t\treturn less(rhs, lhs) ? std::weak_ordering::greater : std::weak_ordering::less;\n\t\t\t}\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "tc/range/merge_ranges.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../algorithm/algorithm.h\"\n#include \"../algorithm/sort_streaming.h\"\n\nnamespace tc {\n\ttemplate<typename RngRng, typename Less = tc::fn_less>\n\tauto merge_many(RngRng&& rngrng, Less&& less = Less()) noexcept {\n\t\treturn tc::transform(\n\t\t\ttc::sort_streaming(\n\t\t\t\ttc::filter(\n\t\t\t\t\ttc::transform(\n\t\t\t\t\t\ttc_move_if_owned(rngrng),\n\t\t\t\t\t\ttc_fn(tc::all)\n\t\t\t\t\t),\n\t\t\t\t\ttc_fn(!tc::empty)\n\t\t\t\t),\n\t\t\t\ttc::projected(tc_move_if_owned(less), tc::fn_front()),\n\t\t\t\t[](auto& rng) noexcept {\n\t\t\t\t\ttc::drop_first_inplace(rng);\n\t\t\t\t\treturn !tc::empty(rng);\n\t\t\t\t}\n\t\t\t),\n\t\t\ttc::fn_front()\n\t\t);\n\t}\n\n\ttemplate<typename RngRng, typename Less = tc::fn_less>\n\tauto merge_many_unique(RngRng&& rngrng, Less&& less = Less()) noexcept {\n\t\treturn tc::ordered_unique(tc::merge_many(tc_move_if_owned(rngrng), less), less);\n\t}\n}\n"
  },
  {
    "path": "tc/range/merge_ranges.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/compare.h\"\n\n#include \"merge_ranges.h\"\n#include \"zip_range.h\"\n\nUNITTESTDEF(merge_ranges_with_simple_usecase) {\n\n\ttc::vector<tc::vector<int>> vecvecn;\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,1,3,5));\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,2,4));\n\n\tint N=0;\n\ttc::for_each(\n\t\ttc::merge_many(vecvecn),\n\t\t[&](int const n) noexcept {\n\t\t\t_ASSERTEQUAL(n, ++N);\n\t\t}\n\t);\n\t_ASSERTEQUAL(5, N);\n}\n\n\nUNITTESTDEF(zip_range_adaptor_test) {\n\t{\n\t\ttc::vector<int> vecn{1,3,5};\n\t\ttc::vector<int> vecn2{2,6,10};\n\n\t\tauto rng = tc::zip(vecn,vecn2);\n\n\t\t_ASSERTEQUAL(tc::get<0>(*tc::begin(rng)), 1);\n\t\t_ASSERTEQUAL(std::addressof(tc::get<1>(*tc::begin(rng))),std::addressof(vecn2[0]));\n\n\t\tauto it = tc::begin(vecn);\n\t\tauto it2 = tc::begin(vecn2);\n\t\ttc::for_each(\n\t\t\trng,\n\t\t\t[&](int const& n, int const& n2) noexcept {\n\t\t\t\t_ASSERTEQUAL(*it, n);\n\t\t\t\t_ASSERTEQUAL(*it2, n2);\n\t\t\t\t_ASSERTEQUAL(std::addressof(*it), std::addressof(n));\n\t\t\t\t_ASSERTEQUAL(std::addressof(*it2), std::addressof(n2));\n\t\t\t\t++it; ++it2;\n\t\t\t}\n\t\t);\n\t\t_ASSERTEQUAL(tc::end(vecn), it);\n\t}\n\n\tauto rng = tc::zip(\n\t\ttc::vector<int>{4,2,1},\n\t\ttc::iota(0,3)\n\t);\n\n\tint N=4;\n\tint N2=0;\n\ttc::for_each(\n\t\trng,\n\t\t[&](int const n, int const n2) noexcept {\n\t\t\tVERIFYEQUAL(N, n) /= 2;\n\t\t\t++VERIFYEQUAL(N2, n2);\n\t\t}\n\t);\n\t_ASSERTEQUAL(N2,3);\n}\n\nUNITTESTDEF(merge_ranges_with_unique_range_2) {\n\ttc::vector<tc::vector<int>> vecvecn;\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,10));\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,1,1,3,3,3,5,5,5,5,11));\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,6,9));\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,2,2,4,12));\n\ttc::cont_emplace_back(vecvecn, tc::make_array(tc::aggregate_tag,7,8));\n\n\ttc::vector<tc::vector<int>> vecvecn2;\n\ttc::cont_emplace_back(vecvecn2, tc::make_array(tc::aggregate_tag,100));\n\ttc::cont_emplace_back(vecvecn2, tc::make_array(tc::aggregate_tag,101,102,103,104,105,106,107,108,109,110));\n\ttc::cont_emplace_back(vecvecn2, tc::make_array(tc::aggregate_tag,111,112));\n\ttc::cont_emplace_back(vecvecn2, tc::make_array(tc::aggregate_tag,113,114,115,116));\n\ttc::cont_emplace_back(vecvecn2, tc::make_array(tc::aggregate_tag,117,118));\n\n\tauto lesspred = tc::projected(tc::fn_less(), tc_fn(tc::get<0>));\n\n\tint n=0;\n\tint nTotal=0;\n\tint nCompares = 0;\n\ttc::for_each(\n\t\ttc::merge_many(\n\t\t\ttc::transform(\n\t\t\t\ttc::iota(0,5),\n\t\t\t\t[&](int const n) noexcept {\n\t\t\t\t\treturn tc::ordered_unique_range(\n\t\t\t\t\t\ttc::zip(\n\t\t\t\t\t\t\ttc::all(vecvecn[n]),\n\t\t\t\t\t\t\ttc::all(vecvecn2[n])\n\t\t\t\t\t\t),\n\t\t\t\t\t\tlesspred\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t),\n\t\t\t[&](auto const& lhs, auto const& rhs) {\n\t\t\t\t++nCompares;\n\t\t\t\treturn tc::projected(lesspred, tc::fn_front())(lhs, rhs);\n\t\t\t}\n\t\t),\n\t\t[&](auto rng) noexcept {\n\t\t\ttc::for_each(\n\t\t\t\trng,\n\t\t\t\t[&](int const first, int& second) noexcept {\n\t\t\t\t\tsecond = n;\n\t\t\t\t\t_ASSERTEQUAL(first, n+1);\n\t\t\t\t\t++nTotal;\n\t\t\t\t}\n\t\t\t);\n\t\t\t++n;\n\t\t}\n\t);\n\t_ASSERTEQUAL(n,12);\n\t_ASSERTEQUAL(nTotal, 19);\n\t_ASSERTEQUAL(vecvecn2[0][0],9);\n\t_ASSERTEQUAL(vecvecn2[1][0],0);\n\t_ASSERTEQUAL(vecvecn2[1][1],0);\n\t_ASSERTEQUAL(vecvecn2[1][2],2);\n\t_ASSERTEQUAL(vecvecn2[1][5],4);\n\t_ASSERTEQUAL(vecvecn2[1][9],10);\n\t_ASSERTEQUAL(vecvecn2[2][0],5);\n\t_ASSERTEQUAL(vecvecn2[2][1],8);\n\t_ASSERTEQUAL(vecvecn2[3][0],1);\n\t_ASSERTEQUAL(vecvecn2[3][1],1);\n\t_ASSERTEQUAL(vecvecn2[3][2],3);\n\t_ASSERTEQUAL(vecvecn2[3][3],11);\n\t_ASSERTEQUAL(vecvecn2[4][0],6);\n\t_ASSERTEQUAL(vecvecn2[4][1],7);\n}\n"
  },
  {
    "path": "tc/range/meta.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/type_traits_fwd.h\"\n#include \"../base/functors.h\"\n#include \"../base/tag_type.h\"\n#include \"../base/casts.h\"\n#include \"../container/string.h\"\n#include \"../tuple.h\"\n\n#include <boost/range/has_range_iterator.hpp>\n#include <type_traits>\n#include <iterator>\n#include <ranges>\n#include <boost/range/traversal.hpp>\n\nnamespace tc {\n\tnamespace begin_end_adl {\n\t\tDEFINE_ADL_TAG_TYPE(begin_end_tag);\n\t}\n\n\ttemplate <typename Rng>\n\tconcept borrowed_range_impl = (std::is_lvalue_reference<Rng>::value || std::ranges::enable_borrowed_range<std::remove_cvref_t<Rng>>);\n\n\ttemplate<tc::borrowed_range_impl Rng>\n\t[[nodiscard]] constexpr auto begin(Rng&& rng) return_decltype_MAYTHROW(\n\t\t// Rng has member begin\n\t\trng.begin()\n\t)\n\n\ttemplate<tc::borrowed_range_impl Rng>\n\t[[nodiscard]] constexpr auto begin(Rng&& rng) return_decltype_MAYTHROW(\n\t\t// Rng has free begin found by tag\n\t\tbegin(begin_end_adl::begin_end_tag, rng)\n\t)\n\n\ttemplate<tc::borrowed_range_impl Rng>\n\t[[nodiscard]] constexpr auto end(Rng&& rng) return_decltype_MAYTHROW(\n\t\t// Rng has member end\n\t\trng.end()\n\t)\n\n\ttemplate<tc::borrowed_range_impl Rng>\n\t[[nodiscard]] constexpr auto end(Rng&& rng) return_decltype_MAYTHROW(\n\t\t// Rng has free end found by tag\n\t\tend(begin_end_adl::begin_end_tag, rng)\n\t)\n\n\ttemplate<typename Rng>\n\tusing iterator_t = decltype(tc::begin(std::declval<Rng&>()));\n\ttemplate<typename Rng>\n\tusing sentinel_t = decltype(tc::end(std::declval<Rng&>()));\n\n\ttemplate<typename Rng>\n\tconcept range_with_iterators = requires {\n\t\ttypename tc::iterator_t<Rng>;\n\t\ttypename tc::sentinel_t<Rng>;\n\t};\n\n\ttemplate<typename Rng>\n\tconcept common_range = tc::range_with_iterators<Rng> && std::same_as<tc::iterator_t<Rng>, tc::sentinel_t<Rng>>;\n\n\t// `Rng` models `tc::borrowed_range` iff the validity of iterators of `Rng` is not tied to the lifetime of the `Rng` object:\n\t// * references to containers (not containers themselves)\n\t// * tc::span\n\t// * ...\n\ttemplate<typename Rng>\n\tconcept borrowed_range = tc::range_with_iterators<Rng> && tc::borrowed_range_impl<Rng>;\n\n\t// For convenience, you can specialize `tc::enable_borrowed_range` instead of `std::ranges::enable_borrowed_range` which doesn't require opening up a separate namespace.\n\t// (There is a specialization of `std::ranges::enable_borrowed_range` at the end of the file.)\n\ttemplate<typename Rng>\n\tconstexpr auto enable_borrowed_range = nullptr; // primary is \"disabled\"\n\n\tnamespace detail {\n\t\ttemplate<typename Rng, typename Required>\n\t\tconcept has_traversal = tc::range_with_iterators<Rng> && std::convertible_to<typename boost::range_traversal<Rng>::type, Required>;\n\t}\n\n\ttemplate<typename Rng>\n\tconcept bidirectional_range = detail::has_traversal<Rng, boost::iterators::bidirectional_traversal_tag>;\n\ttemplate<typename Rng>\n\tconcept random_access_range = detail::has_traversal<Rng, boost::iterators::random_access_traversal_tag>;\n\n\t// Note that we cannot use std::contiguous_iterator yet as it is broken on our version of libcxx.\n\t// So instead we just check the iterator category as a proxy.\n#ifdef _LIBCPP_VERSION\n\tnamespace contiguous_range_detail {\n\t\ttemplate <typename It>\n\t\tconstexpr auto compute_iterator_concept() {\n\t\t\tusing traits = std::iterator_traits<It>;\n\n\t\t\t// This algorithm isn't precisely the one specified for ITER_CONCEPT in the standard,\n\t\t\t// but that requires detecting whether or not traits have been specialized, which a non-standard library cannot do.\n\t\t\t// So instead we approximate it.\n\t\t\tif constexpr (requires { typename It::iterator_concept; }) {\n\t\t\t\treturn typename It::iterator_concept();\n\t\t\t} else if constexpr (requires { typename traits::iterator_concept; }) {\n\t\t\t\treturn typename traits::iterator_concept();\n\t\t\t} else if constexpr (requires { typename It::iterator_category; }) {\n\t\t\t\treturn typename It::iterator_category();\n\t\t\t} else {\n\t\t\t\treturn typename traits::iterator_category();\n\t\t\t}\n\t\t}\n\t\ttemplate <typename It>\n\t\tusing iterator_concept = decltype(compute_iterator_concept<It>());\n\n\t\ttemplate <typename It>\n\t\tconcept contiguous_iterator = std::is_pointer_v<It> || std::is_base_of_v<std::contiguous_iterator_tag, iterator_concept<It>>;\n\t}\n\ttemplate <typename Rng>\n\tconcept contiguous_range = tc::range_with_iterators<Rng> && contiguous_range_detail::contiguous_iterator<tc::iterator_t<Rng>>;\n#else\n\ttemplate <typename Rng>\n\tconcept contiguous_range = tc::range_with_iterators<Rng> && std::contiguous_iterator<tc::iterator_t<Rng>>;\n#endif\n\n\ttemplate <typename Rng>\n\tconcept prefers_for_each = !tc::range_with_iterators<Rng> || Rng::c_bPrefersForEach;\n\n\ttemplate <typename ... Rng>\n\tconcept ranges_with_common_reference\n\t\t= (... && tc::range_with_iterators<Rng>) && requires { typename tc::common_reference_t<std::iter_reference_t<tc::iterator_t<Rng>>...>; };\n\n\tnamespace range_output_t_adl {\n\t\tDEFINE_ADL_TAG_TYPE(adl_tag);\n\n\t\ttemplate<typename T, T... t>\n\t\tauto range_output_t_impl(adl_tag_t, std::integer_sequence<T, t...> const&) -> boost::mp11::mp_list<T>; // declaration only\n\t}\n\n\tnamespace range_output_no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct from_iter_reference {};\n\n\t\ttemplate<typename Rng> requires (!std::is_void<std::iter_reference_t<tc::iterator_t<Rng>>>::value)\n\t\tstruct from_iter_reference<Rng> {\n\t\t\tusing type = boost::mp11::mp_list<tc::remove_rvalue_reference_t<std::iter_reference_t<tc::iterator_t<Rng>>>>;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct from_adl_with_tag : from_iter_reference<Rng> {};\n\n\t\ttemplate<typename Rng> requires requires { /*adl*/range_output_t_impl(tc::range_output_t_adl::adl_tag, std::declval<Rng>()); }\n\t\tstruct from_adl_with_tag<Rng> {\n\t\t\tusing type = decltype(/*adl*/range_output_t_impl(tc::range_output_t_adl::adl_tag, std::declval<Rng>()));\n\t\t\tstatic_assert(tc::decayed<type> && tc::instance<type, boost::mp11::mp_list>);\n\t\t\tstatic_assert(!boost::mp11::mp_any_of<type, std::is_rvalue_reference>::value);\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct from_adl final : from_adl_with_tag<Rng> {};\n\n\t\ttemplate<typename Rng> requires requires { /*adl*/range_output_t_impl(std::declval<Rng>()); }\n\t\tstruct from_adl<Rng> {\n\t\t\tusing type = decltype(/*adl*/range_output_t_impl(std::declval<Rng>()));\n\t\t\tstatic_assert(tc::decayed<type> && tc::instance<type, boost::mp11::mp_list>);\n\t\t\tstatic_assert(!boost::mp11::mp_any_of<type, std::is_rvalue_reference>::value);\n\t\t};\n\t}\n\ttemplate<typename Rng>\n\tusing range_output_t = typename range_output_no_adl::from_adl<Rng>::type;\n\n\tnamespace make_lazy_adl {\n\t\ttemplate<typename Func>\n\t\tauto range_output_t_impl(make_lazy<Func> const&) noexcept -> tc::range_output_t<decltype(std::declval<Func const&>()())>; // declaration only\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct value_type_impl {\n\t\t\tusing type = T;\n\t\t};\n\t}\n\ttemplate<typename T>\n\tusing value_t = typename tc::no_adl::value_type_impl<tc::decay_t<T>>::type;\n\n\tnamespace range_value_no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct from_range_output final { using type = void; };\n\n\t\ttemplate<typename Rng> requires requires { typename boost::mp11::mp_apply<tc::common_type_t, tc::mp_transform<tc::value_t, tc::range_output_t<Rng>>>; }\n\t\tstruct from_range_output<Rng> final {\n\t\t\tusing type = boost::mp11::mp_apply<tc::common_type_t, tc::mp_transform<tc::value_t, tc::range_output_t<Rng>>>;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct from_cont final { using type = void; };\n\n\t\ttemplate<typename Cont> requires requires { typename std::remove_reference_t<Cont>::value_type; }\n\t\tstruct from_cont<Cont> final {\n\t\t\tusing type = typename std::remove_reference_t<Cont>::value_type;\n\t\t};\n\n\t\ttemplate<typename Rng, typename ValueTypeFromOutput = typename from_range_output<Rng>::type, typename ValueTypeFromCont = typename from_cont<Rng>::type>\n\t\tstruct range_value final {\n\t\t\t// STATICASSERTSAME(ValueTypeFromOutput, ValueTypeFromCont); fires for Rng=std::array<tc::tuple<int&>, 1> (tuple<int> or tuple<int&>) or Rng=boost::filesystem::path (path or wchar_t?).\n\t\t\t// In both cases, not defining range_value_t is sensible.\n\t\t};\n\n\t\ttemplate<typename Rng, typename ValueType>\n\t\tstruct range_value<Rng, ValueType, ValueType> final {\n\t\t\tusing type = ValueType;\n\t\t};\n\n\t\ttemplate<typename Rng, typename ValueTypeFromOutput>\n\t\tstruct range_value<Rng, ValueTypeFromOutput, void> final {\n\t\t\tusing type = ValueTypeFromOutput;\n\t\t};\n\n\t\ttemplate<typename Rng, typename ValueTypeFromCont>\n\t\tstruct range_value<Rng, void, ValueTypeFromCont> final {\n\t\t\tusing type = ValueTypeFromCont;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct range_value<Rng, void, void> final {}; // range_value_t is not void\n\t}\n\ttemplate<typename Rng>\n\tusing range_value_t = typename tc::range_value_no_adl::range_value<Rng>::type;\n\n\ttemplate<typename Rng>\n\tconcept has_range_value = requires { typename tc::range_value_t<Rng>; };\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct constexpr_size_impl;\n\t}\n\ttemplate<typename Rng>\n\tconcept has_constexpr_size = requires { no_adl::constexpr_size_impl<std::remove_cvref_t<Rng>>::value; };\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr std::size_t strlen( T const* pt ) noexcept {\n\t\t_ASSERTNORETURN(pt);\n\t\treturn std::char_traits<T>::length(pt);\n\t}\n\n\tnamespace zero_termination_sentinel_adl {\n\t\tstruct zero_termination_sentinel final {};\n\n\t\ttemplate<typename T>\n\t\tconstexpr bool operator==(zero_termination_sentinel, T* p) noexcept {\n\t\t\treturn !*VERIFY(p);\n\t\t}\n\t}\n\tusing zero_termination_sentinel_adl::zero_termination_sentinel;\n\n\tnamespace nullptr_or_zero_termination_sentinel_adl {\n\t\tstruct nullptr_or_zero_termination_sentinel final {};\n\n\t\ttemplate<tc::char_type Char>\n\t\tconstexpr bool operator==(nullptr_or_zero_termination_sentinel, Char const* psz) noexcept {\n\t\t\treturn !psz || static_cast<Char>(0) == *psz;\n\t\t}\n\t}\n\tusing nullptr_or_zero_termination_sentinel_adl::nullptr_or_zero_termination_sentinel;\n\n\tnamespace begin_end_adl {\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr T* begin(begin_end_tag_t, T (&at)[N]) noexcept {\n\t\t\treturn at;\n\t\t}\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr T const* begin(begin_end_tag_t, T const (&at)[N]) noexcept {\n\t\t\treturn at;\n\t\t}\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr T* end_array_impl(T (&at)[N]) noexcept {\n\t\t\tif constexpr (tc::char_type<T>) {\n\t\t\t\t_ASSERTE( tc::strlen(at) == N - 1 );\n\t\t\t\treturn at + N - 1;\n\t\t\t} else {\n\t\t\t\treturn at + N;\n\t\t\t}\n\t\t}\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr T* end(begin_end_tag_t, T (&at)[N]) noexcept {\n\t\t\treturn end_array_impl(at);\n\t\t}\n\t\ttemplate<typename T, std::size_t N>\n\t\tconstexpr T const* end(begin_end_tag_t, T const (&at)[N]) noexcept {\n\t\t\treturn end_array_impl(at);\n\t\t}\n\n\t\ttemplate<typename It, typename Enable = decltype(*++std::declval<It&>())>\n\t\tconstexpr It begin(begin_end_tag_t, std::pair<It,It> const& pairit) noexcept {\n\t\t\treturn pairit.first;\n\t\t}\n\t\ttemplate<typename It>\n\t\tconstexpr It end(begin_end_tag_t, std::pair<It,It> const& pairit) noexcept {\n\t\t\treturn pairit.second;\n\t\t}\n\t}\n\n\ttemplate <typename It>\n\tconstexpr auto enable_borrowed_range<std::pair<It, It>> = true;\n}\n\nnamespace boost {\n\ttemplate<typename Rng> requires std::same_as<Rng, std::remove_cvref_t<Rng>> && requires { typename tc::iterator_t<Rng>; }\n\tstruct range_mutable_iterator<Rng> {\n\t\tusing type = tc::iterator_t<Rng>;\n\t};\n\n\ttemplate<typename Rng> requires std::same_as<Rng, std::remove_cvref_t<Rng>> && requires { typename tc::iterator_t<std::add_const_t<Rng>>; }\n\tstruct range_const_iterator<Rng> {\n\t\tusing type = tc::iterator_t<std::add_const_t<Rng>>;\n\t};\n}\n\n#pragma push_macro(\"CHAR_RANGE\")\n#define CHAR_RANGE( xchar ) \\\nnamespace tc { \\\n\tnamespace begin_end_adl { \\\n\t\t/* Note: We cannot use overloading to differentiate xchar* and xchar(&)[N]. */ \\\n\t\ttemplate<typename CharPtrConvertible> requires \\\n\t\t\ttc::safely_convertible_to<CharPtrConvertible, xchar*> \\\n\t\t\t\t&& (!tc::has_constexpr_size<CharPtrConvertible>) \\\n\t\tconstexpr xchar* begin(begin_end_tag_t, CharPtrConvertible& pchc) noexcept { \\\n\t\t\treturn pchc; \\\n\t\t} \\\n\t\ttemplate<typename CharPtrConvertible> requires \\\n\t\t\ttc::safely_convertible_to<CharPtrConvertible, xchar const*> \\\n\t\t\t\t&& (!tc::safely_convertible_to<CharPtrConvertible, xchar*>) \\\n\t\t\t\t&& (!tc::has_constexpr_size<CharPtrConvertible>) \\\n\t\tconstexpr xchar const* begin(begin_end_tag_t, CharPtrConvertible& pchc) noexcept { \\\n\t\t\treturn pchc; \\\n\t\t} \\\n\t\ttemplate<typename CharPtrConvertible> requires \\\n\t\t\ttc::safely_convertible_to<CharPtrConvertible, xchar const*> \\\n\t\t\t\t&& (!tc::has_constexpr_size<CharPtrConvertible>) \\\n\t\tconstexpr tc::zero_termination_sentinel end(begin_end_tag_t, CharPtrConvertible& pchc) noexcept { \\\n\t\t\t_ASSERT( tc::implicit_cast<xchar const*>(pchc) ); \\\n\t\t\treturn {}; \\\n\t\t} \\\n\t} \\\n\ttemplate <> \\\n\tinline constexpr auto enable_borrowed_range<xchar*> = true; \\\n\ttemplate <> \\\n\tinline constexpr auto enable_borrowed_range<xchar const*> = true; \\\n}\n\nCHAR_RANGE(char)\nCHAR_RANGE(wchar_t)\nCHAR_RANGE(char8_t)\nCHAR_RANGE(char16_t)\nCHAR_RANGE(char32_t)\n\n#pragma pop_macro(\"CHAR_RANGE\")\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename TTarget>\n\t\tstruct curried_safely_convertible_to {\n\t\t\ttemplate<typename TSource>\n\t\t\tusing fn = tc::constant<tc::safely_convertible_to<TSource, TTarget>>;\n\t\t};\n\t}\n\n\ttemplate<typename Rng, typename T>\n\tconcept range_of = boost::mp11::mp_all_of<tc::range_output_t<Rng>, no_adl::curried_safely_convertible_to<T>::template fn>::value;\n}\n\nnamespace tc_begin_end_no_adl {\n\ttemplate< typename Rng >\n\tauto adl_begin(Rng& rng) return_decltype_MAYTHROW(\n\t\t// Rng has free begin found by ADL\n\t\tbegin( rng )\n\t)\n\n\ttemplate< typename Rng >\n\tauto adl_end(Rng& rng) return_decltype_MAYTHROW(\n\t\t// Rng has free end found by ADL\n\t\tend( rng )\n\t)\n}\n\nnamespace tc {\n\ttemplate <typename Rng>\n\tauto cyclic_next(tc::iterator_t<Rng> it, Rng& rng) noexcept {\n\t\t++it;\n\t\treturn tc::end(rng)==it ? tc::begin(rng) : it;\n\t}\n}\n\n//////////////////////////////////////////////\n// Boost.Range compatiblity\n\n#ifdef BOOST_RANGE_BEGIN_HPP\n#error\n#endif\n#ifdef BOOST_RANGE_END_HPP\n#error\n#endif\n#define BOOST_RANGE_BEGIN_HPP\n#define BOOST_RANGE_END_HPP\n\nnamespace boost {\n\ttemplate< typename Rng >\n\tauto begin(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::begin( rng )\n\t)\n\n\ttemplate< typename Rng >\n\tauto end(Rng&& rng) return_decltype_MAYTHROW(\n\t\ttc::end( rng )\n\t)\n\n\ttemplate< typename Rng >\n\tauto const_begin(Rng const& rng) return_decltype_MAYTHROW(\n\t\ttc::begin( rng )\n\t)\n\n\ttemplate< typename Rng >\n\tauto const_end(Rng const& rng) return_decltype_MAYTHROW(\n\t\ttc::end( rng )\n\t)\n}\n\n//////////////////////////////////////////////\n// std.range compatiblity\nnamespace std::ranges {\n\ttemplate <typename Rng> requires (std::same_as<decltype(tc::enable_borrowed_range<Rng>), const bool>)\n\tconstexpr bool enable_borrowed_range<Rng> = tc::enable_borrowed_range<Rng>;\n}\n\n//////////////////////////////////////////////\n// range customizations for tuple_like types\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<tuple_like Tuple> requires (!requires { tc::begin(std::declval<Tuple>()); })\n\t\tstruct constexpr_size_impl<Tuple>: tc::least_uint_constant<std::tuple_size<Tuple>::value> {};\n\t}\n\n\tnamespace tuple_detail {\n\t\ttemplate<std::size_t I, tuple_like... Tuple>\n\t\tconstexpr auto zip_get(Tuple&&... tuple) noexcept {\n\t\t\t// Tuple elements are tc::apply_cvref_t<std::tuple_element_t<I, std::remove_cvref_t<Tuple>>, Tuple>... unless tuple is tc::tuple and element types is empty.\n\t\t\treturn tc::tuple<std::conditional_t<\n\t\t\t\tstd::is_rvalue_reference<std::tuple_element_t<I, std::remove_cvref_t<Tuple>>>::value,\n\t\t\t\tdecltype(tc::get<I>(std::declval<Tuple>())),\n\t\t\t\ttc::remove_rvalue_reference_t<decltype(tc::get<I>(std::declval<Tuple>()))>\n\t\t\t>...>{{\n\t\t\t\t{tc::get<I>(tc_move_if_owned(tuple))}...\n\t\t\t}};\n\t\t}\n\n\t\ttemplate<std::size_t... I, tuple_like... Tuple>\n\t\tconstexpr auto zip_impl(std::index_sequence<I...>, Tuple&&... tuple) noexcept {\n\t\t\treturn tc::tuple<decltype(tuple_detail::zip_get<I>(tc_move_if_owned(tuple)...))...>{{ // tc::make_tuple without extra copy\n\t\t\t\t{tuple_detail::zip_get<I>(tc_move_if_owned(tuple)...)}...\n\t\t\t}};\n\t\t}\n\t}\n\n\ttemplate<tuple_like Tuple0, tuple_like... Tuple>\n\t\trequires (!tc::range_with_iterators<Tuple0> || ... || !tc::range_with_iterators<Tuple>) // Prefer zip_adaptor for zip(std::array...)\n\t[[nodiscard]] constexpr auto zip(Tuple0&& tuple0, Tuple&&... tuple) noexcept {\n\t\tstatic_assert( ((std::tuple_size<std::remove_reference_t<Tuple0>>::value == std::tuple_size<std::remove_reference_t<Tuple>>::value) && ...) );\n\t\treturn tuple_detail::zip_impl(\n\t\t\tstd::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple0>>::value>(),\n\t\t\ttc_move_if_owned(tuple0),\n\t\t\ttc_move_if_owned(tuple)...\n\t\t);\n\t}\n\n\ttemplate<typename TIndex, TIndex... Is>\n\t[[nodiscard]] consteval tc::tuple<tc::constant<Is>...> index_sequence_as_tuple(std::integer_sequence<TIndex, Is...>) {\n\t\treturn {};\n\t}\n\n\ttemplate<tuple_like Tuple> requires (!tc::range_with_iterators<Tuple>)\n\t[[nodiscard]] constexpr auto enumerate(Tuple&& tuple) noexcept {\n\t\treturn tc::zip(\n\t\t\ttc::index_sequence_as_tuple(std::make_integer_sequence<int, std::tuple_size<std::remove_reference_t<Tuple>>::value>()),\n\t\t\ttc_move_if_owned(tuple)\n\t\t);\n\t}\n}\n\n//////////////////////////////////////////////\n// range customizations for boost::mp11::mp_list\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename ... T>\n\t\tstruct constexpr_size_impl<boost::mp11::mp_list<T...>>: tc::least_uint_constant<sizeof...(T)> {};\n\t}\n\n\t// Returns an mp_list<mp_list<...>, ...>, tc::for_each turns it into a range of tc::tuple<std::type_identity<...>, ...>.\n\ttemplate<typename ... Lists> requires (tc::instance<std::remove_reference_t<Lists>, boost::mp11::mp_list> && ...)\n\t[[nodiscard]] constexpr auto zip(Lists&&...) noexcept {\n\t\treturn tc::mp_zip<Lists...>{};\n\t}\n\n\t// Returns an mp_list<mp_list<tc::constant<0>, ...>, ...>, tc::for_each turns it into a range of tc::tuple<tc::constant<N>, std::type_identity<...>>.\n\ttemplate<typename List> requires tc::instance<std::remove_reference_t<List>, boost::mp11::mp_list>\n\t[[nodiscard]] constexpr auto enumerate(List&&) noexcept {\n\t\treturn tc::mp_enumerate<List>{};\n\t}\n}\n\n"
  },
  {
    "path": "tc/range/ordered_pairs.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"range_adaptor.h\"\n\nnamespace tc {\n\tnamespace ordered_pairs_adaptor_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] ordered_pairs_adaptor : tc::range_adaptor_base_range<Rng> {\n\t\tprivate:\n\t\t\tusing base_ = typename ordered_pairs_adaptor::range_adaptor_base_range;\n\t\tpublic:\n\t\t\tconstexpr ordered_pairs_adaptor() = default;\n\t\t\tusing base_::base_;\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, ordered_pairs_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_list<tc::tuple<\n\t\t\t\tstd::iter_reference_t<tc::iterator_t<decltype(std::declval<Self&>().base_range())>>&&,\n\t\t\t\tstd::iter_reference_t<tc::iterator_t<decltype(std::declval<Self&>().base_range())>>&&\n\t\t\t>> {} // unevaluated\n\n\t\t\ttemplate<tc::decayed_derived_from<ordered_pairs_adaptor> Self, typename Sink> \n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink sink) MAYTHROW -> tc::common_type_t<decltype(tc::continue_if_not_break(sink, std::declval<tc::mp_only<tc::range_output_t<Self>>>())), tc::constant<tc::continue_>> {\n\t\t\t\tauto idx1st = self.base_begin_index();\n\t\t\t\t// tc::ordered_pairs(rng) is a subsequence of tc::cartesian_product(rng, rng).\n\t\t\t\tif(!tc::at_end_index(self.base_range(), idx1st)) {\n\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\tauto idx2nd = idx1st;\n\t\t\t\t\t\ttc::increment_index(self.base_range(), idx2nd);\n\t\t\t\t\t\tif(tc::at_end_index(self.base_range(), idx2nd)) break;\n\t\t\t\t\t\tdecltype(auto) ref1st = tc::dereference_index(self.base_range(), idx1st);\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc::tie(ref1st, tc::dereference_index(self.base_range(), idx2nd))))\n\t\t\t\t\t\t\ttc::increment_index(self.base_range(), idx2nd);\n\t\t\t\t\t\t} while(!tc::at_end_index(self.base_range(), idx2nd));\n\t\t\t\t\t\ttc::increment_index(self.base_range(), idx1st);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\n\t\t\tconstexpr auto size() const& MAYTHROW requires tc::has_size<Rng> {\n\t\t\t\treturn tc::compute_range_adaptor_size<[](auto const n) noexcept {\n\t\t\t\t\treturn tc::as_unsigned(n * (n - 1) / 2);\n\t\t\t\t}>(this->base_range());\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\tauto ordered_pairs(Rng&& rng) return_ctor_noexcept(\n\t\tordered_pairs_adaptor_adl::ordered_pairs_adaptor<Rng>,\n\t\t(tc::aggregate_tag, tc_move_if_owned(rng))\n\t)\n}\n"
  },
  {
    "path": "tc/range/partial_sum.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../algorithm/for_each.h\"\n#include \"../base/modified.h\"\n#include \"range_adaptor.h\"\n\nnamespace tc {\n\t/////////////////////////////////////////////////////\n\t// partial_sum\n\tnamespace no_adl {\n\t\ttemplate<typename Sink, typename Accu, typename AccuOp>\n\t\tstruct partial_sum_sink { // MSVC workaround: not a lambda for shorter symbol names. clang workaround: not a lambda to avoid ICE.\n\t\t\tSink const& m_sink;\n\t\t\tAccu& m_accu;\n\t\t\tAccuOp const& m_accuop;\n\n\t\t\tconstexpr auto operator()(auto&& arg) const& MAYTHROW {\n\t\t\t\ttc_invoke(m_accuop, m_accu, tc_move_if_owned(arg));\n\t\t\t\treturn tc::continue_if_not_break(m_sink, tc::as_const(m_accu));\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename Rng, typename T, typename AccuOp, bool c_bIncludeInit>\n\t\tstruct [[nodiscard]] partial_sum_adaptor : private tc::range_adaptor_base_range<Rng> {\n\t\tprivate:\n\t\t\ttc::reference_or_value<T> m_init;\n\t\t\ttc::decay_t<AccuOp> m_accuop;\n\t\tpublic:\n\t\t\tfriend auto range_output_t_impl(partial_sum_adaptor const&) -> boost::mp11::mp_list<tc::decay_t<T> const&>; // declaration only\n\n\t\t\ttemplate <typename RngRef, typename TRef, typename AccuOpRef>\n\t\t\tconstexpr partial_sum_adaptor(RngRef&& rng, TRef&& init, AccuOpRef&& accuop) noexcept\n\t\t\t\t: tc::range_adaptor_base_range<Rng>(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_init(aggregate_tag, tc_move_if_owned(init))\n\t\t\t\t, m_accuop(tc_move_if_owned(accuop))\n\t\t\t{}\n\n\t\t\ttemplate <typename Sink>\n\t\t\tconstexpr auto operator()(Sink sink) const& MAYTHROW {\n\t\t\t\ttc::decay_t<T> accu = *m_init;\n\t\t\t\ttc_return_break_or_continue(\n\t\t\t\t\t(tc_conditional_prvalue_as_val(\n\t\t\t\t\t\tc_bIncludeInit,\n\t\t\t\t\t\ttc::continue_if_not_break(sink, tc::as_const(accu)),\n\t\t\t\t\t\ttc::constant<tc::continue_>()\n\t\t\t\t\t))\n\t\t\t\t\t(tc::for_each(this->base_range(), no_adl::partial_sum_sink<decltype(sink), decltype(accu), decltype(m_accuop)>{sink, accu, m_accuop}))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconstexpr auto size() const& MAYTHROW requires tc::has_size<Rng> {\n\t\t\t\treturn tc::compute_range_adaptor_size<[](auto n) noexcept {\n\t\t\t\t\tif constexpr (c_bIncludeInit) ++n;\n\t\t\t\t\treturn n;\n\t\t\t\t}>(this->base_range());\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::partial_sum_adaptor;\n\n\ttemplate <typename Rng, typename T, typename AccuOp = tc::fn_assign_plus>\n\tconstexpr auto partial_sum_excluding_init(Rng&& rng, T&& init, AccuOp&& accuop = AccuOp()) noexcept {\n\t\treturn partial_sum_adaptor<Rng, T, AccuOp, /*c_bIncludeInit*/false>(tc_move_if_owned(rng), tc_move_if_owned(init), tc_move_if_owned(accuop));\n\t}\n\n\ttemplate <typename Rng, typename T, typename AccuOp = tc::fn_assign_plus>\n\tconstexpr auto partial_sum_including_init(Rng&& rng, T&& init, AccuOp&& accuop = AccuOp()) noexcept {\n\t\treturn partial_sum_adaptor<Rng, T, AccuOp, /*c_bIncludeInit*/true>(tc_move_if_owned(rng), tc_move_if_owned(init), tc_move_if_owned(accuop));\n\t}\n}\n"
  },
  {
    "path": "tc/range/range.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../unittest.h\"\n\n#include \"../array.h\"\n#include \"../container/container.h\" // tc::vector\n#include \"../algorithm/append.h\"\n#include \"../algorithm/best_element.h\"\n#include \"../algorithm/algorithm.h\"\n\n#include \"adjacent_adaptor.h\"\n#include \"cartesian_product_adaptor.h\"\n#include \"concat_adaptor.h\"\n#include \"filter_adaptor.h\"\n#include \"join_adaptor.h\"\n#include \"sparse_adaptor.h\"\n\n\nnamespace {\n\n//---- Basic ------------------------------------------------------------------------------------------------------------------\nUNITTESTDEF( basic ) {\n\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20});\n\n\tauto evenvr = tc::filter(v, [](int const v) noexcept { return v%2==0;});\n\n\tTEST_init_hack(tc::vector, int, vexp, {2, 4, 6, 8, 10, 12, 14, 16, 18, 20});\n\tTEST_RANGE_EQUAL(vexp, evenvr);\n}\n\n\ttemplate<typename Func>\n\tstruct WrapVoidFunc final {\n\t\tstatic_assert(\n\t\t\tstd::is_reference<Func>::value,\n\t\t\t\"type must be a reference type\"\n\t\t);\n\n\t\tWrapVoidFunc(Func func, tc::break_or_continue& boc) noexcept :\n\t\t\tm_func(tc_move(func)), m_boc(boc)\n\t\t{}\n\n\t\ttemplate<typename Arg>\n\t\tvoid operator()(Arg&& arg) & noexcept {\n\t\t\tif (tc::continue_ == m_boc) {\n\t\t\t\tif constexpr( std::is_same<decltype(std::declval<std::remove_reference_t<Func> >()(std::declval<Arg>())), tc::break_or_continue>::value ) {\n\t\t\t\t\tm_boc = m_func(tc_move_if_owned(arg));\n\t\t\t\t} else {\n\t\t\t\t\tm_func(tc_move_if_owned(arg));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate:\n\t\t\tFunc m_func;\n\t\t\ttc::break_or_continue& m_boc;\n\t};\n\n\ttemplate<typename Rng>\n\tstruct void_range_struct final : std::remove_reference_t<Rng> {\n\n\t\tusing base_ = std::remove_reference_t<Rng>;\n\n\t\ttemplate< typename Func>\n\t\ttc::break_or_continue operator()(Func&& func) & noexcept {\n\t\t\tif constexpr( std::is_same<decltype(std::declval<base_>()(std::declval<Func>())), tc::break_or_continue>::value ) {\n\t\t\t\treturn base_::operator()(tc_move_if_owned(func));\n\t\t\t} else {\n\t\t\t\ttc::break_or_continue boc = tc::continue_;\n\t\t\t\tbase_::operator()(WrapVoidFunc<Func&&>(tc_move_if_owned(func), boc));\n\t\t\t\treturn boc;\n\t\t\t}\n\t\t}\n\n\t\ttemplate< typename Func>\n\t\ttc::break_or_continue operator()(Func&& func) const& noexcept {\n\t\t\tif constexpr( std::is_same<decltype(std::declval<base_>()(std::declval<Func>())), tc::break_or_continue>::value ) {\n\t\t\t\treturn base_::operator()(tc_move_if_owned(func));\n\t\t\t} else {\n\t\t\t\ttc::break_or_continue boc = tc::continue_;\n\t\t\t\tbase_::operator()(WrapVoidFunc<Func&&>(tc_move_if_owned(func), boc));\n\t\t\t\treturn boc;\n\t\t\t}\n\t\t}\n\t};\n\n\ttemplate<typename Rng>\n\tauto void_range(Rng&& rng) return_decltype_allow_xvalue_MAYTHROW(\n\t\ttc::derived_cast<void_range_struct<Rng&&>>(tc_move_if_owned(rng))\n\t)\n\n\n//---- Generator Range --------------------------------------------------------------------------------------------------------\nnamespace {\n\tstruct generator_range {\n\t\ttemplate< typename Func >\n\t\tvoid operator()(Func func) const& noexcept {\n\t\t\tfor(int i=0;i<50;++i) {\n\t\t\t\tfunc(i);\n\t\t\t}\n\t\t}\n\t};\n}\n\nUNITTESTDEF( generator_range ) {\n   TEST_init_hack(tc::vector, int, vexp, {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48});\n\n   TEST_RANGE_EQUAL(vexp, tc::filter( void_range(generator_range()), [](int const i) noexcept { return i%2==0; } ));\n   TEST_RANGE_EQUAL(tc::filter( void_range(generator_range()), [](int const i) noexcept { return i%2==0; } ), vexp);\n}\n\n//---- Generator Range (with break) -------------------------------------------------------------------------------------------\nnamespace {\n\tstruct generator_range_break final {\n\t\ttemplate< typename Func >\n\t\ttc::break_or_continue operator()(Func func) {\n\t\t\tfor(int i=0;i<5000;++i) {\n\t\t\t\tif (func(i)==tc::break_) { return tc::break_; }\n\t\t\t}\n\t\t\treturn tc::continue_;\n\t\t}\n\t};\n}\n\n//---- N3752 filters examples  ------------------------------------------------------------------------------------------------\nUNITTESTDEF( N3752 ) {\n   TEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20});\n\n   auto r =  tc::filter( tc::filter( tc::filter(\n                                v,\n                                [](int const i) noexcept { return i%2!=0; } ),\n                                [](int const i) noexcept { return i%3!=0; } ),\n                                [](int const i) noexcept { return i%5!=0; } );\n\n   TEST_init_hack(tc::vector, int, vexp, {1, 7, 11, 13, 17, 19});\n   TEST_RANGE_EQUAL(vexp, r);\n\n   auto ir = tc::make_iterator_range(std::begin(r), std::end(r));    // you shouldn't do this in real code! \n   TEST_RANGE_EQUAL(vexp, ir);\n\n   auto bir = boost::make_iterator_range(tc::begin(r), tc::end(r));    // you shouldn't do this in real code! \n   TEST_RANGE_EQUAL(vexp, bir);\n}\n\nUNITTESTDEF( zero_termination ) {\n\t// only char is treated as zero-terminated character array.\n\t// signed/unsigned char is treated as a regular array\n\t{\n\t\tchar const ach[]={ 0x20, 0 };\n\t\t_ASSERTEQUAL( tc::size(ach), 1 );\n\t\tchar const* pch=ach;\n\t\t_ASSERTEQUAL( tc::size_linear(pch), 1 );\n\t}\n\t{\n\t\tsigned char const ach[]={ 0x20, 0 };\n\t\t_ASSERTEQUAL( tc::size(ach), 2 );\n\t\t// signed char const* pch=ach;\n\t\t// _ASSERTEQUAL( tc::size(pch), 2 ); // correctly refuses to compile\n\t}\n\t{\n\t\tunsigned char const ach[]={ 0x20, 0 };\n\t\t_ASSERTEQUAL( tc::size(ach), 2 );\n\t\t// unsigned char const* pch=ach;\n\t\t// _ASSERTEQUAL( tc::size(pch), 2 ); // correctly refuses to compile\n\t}\n}\n\nUNITTESTDEF( ensure_index_range_on_chars ) {\n\tstatic_assert( tc::range_with_iterators<char*> );\n\tstatic_assert( tc::range_with_iterators<char const*> );\n\tstatic_assert( tc::range_with_iterators<char* &> );\n\tstatic_assert( tc::range_with_iterators<char* const&> );\n\n\tstruct check_5_chars final {\n\t\tvoid operator()( char ) {\n\t\t\t++m_cch;\n\t\t}\n\t\t~check_5_chars() {\n\t\t\t_ASSERTEQUAL(m_cch,5u);\n\t\t}\n\tprivate:\n\t\tstd::size_t m_cch = 0;\n\t};\n\n\t{\n\t\tchar ach[] = \"Hello\";\n\t\tchar * str=ach;\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(str, std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc::as_const(str), std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc_move(str), std::ref(chk));\n\t\t}\n\t}\n\t{\n\t\tchar str[]=\"Hello\";\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(str, std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc::as_const(str), std::ref(chk));\n\t\t}\n\t}\n\t{\n\t\tchar const* str=\"Hello\";\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(str, std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc::as_const(str), std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc_move(str), std::ref(chk));\n\t\t}\n\t}\n\t{\n\t\tchar const str[]=\"Hello\";\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(str, std::ref(chk));\n\t\t}\n\t\t{\n\t\t\tcheck_5_chars chk;\n\t\t\ttc::for_each(tc::as_const(str), std::ref(chk));\n\t\t}\n\t}\n}\n\nUNITTESTDEF( construct_array_from_range ) {\n\tauto rng=tc::iota(0, 10);\n\tauto an=tc::explicit_cast<std::array<int, 10>>(rng);\n\tauto anCopy=an;\n\ttc::array<int&, 10> anRef(an);\n\ttc::for_each(rng, [&](int const n) {\n\t\t_ASSERTEQUAL(tc::at(an, n), n);\n\t\t_ASSERTEQUAL(tc::at(anCopy, n), n);\n\t\t_ASSERTEQUAL(tc::at(anRef, n), n);\n\t});\n}\n\nstruct GeneratorInt {\n\tfriend auto range_output_t_impl(GeneratorInt const&) -> boost::mp11::mp_list<int>; // declaration only\n\ttemplate<typename Func>\n\ttc::break_or_continue operator()(Func func) const& {\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 1))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 6))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 3))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 4))\n\t\treturn tc::continue_;\n\t}\n};\n\nstruct GeneratorLong {\n\tfriend auto range_output_t_impl(GeneratorLong const&) -> boost::mp11::mp_list<long>; // declaration only\n\ttemplate<typename Func>\n\ttc::break_or_continue operator()(Func func) const& {\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 1l))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 6l))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 3l))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, 4l))\n\t\treturn tc::continue_;\n\t}\n\n};\n\nstruct GeneratorGeneratorInt {\n\tfriend auto range_output_t_impl(GeneratorGeneratorInt const&) -> boost::mp11::mp_list<GeneratorInt>; // declaration only\n\ttemplate<typename Func>\n\ttc::break_or_continue operator()(Func func) const& {\n\t\ttc_return_if_break(tc::continue_if_not_break(func, GeneratorInt()))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, GeneratorInt()))\n\t\treturn tc::continue_;\n\t}\n};\n\nstruct GeneratorMutableInt {\n\tint m_an[3] = {1,2,3};\n\n\tfriend auto range_output_t_impl(GeneratorMutableInt&) -> boost::mp11::mp_list<int&>; // declaration only\n\n\ttemplate<typename Func>\n\ttc::break_or_continue operator()(Func func) & {\n\t\ttc_return_if_break(tc::continue_if_not_break(func, m_an[0]))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, m_an[1]))\n\t\ttc_return_if_break(tc::continue_if_not_break(func, m_an[2]))\n\t\treturn tc::continue_;\n\t}\n};\n\n} // end anonymous namespace\n\nnamespace {\n\nstruct dummy_pred {\n\tbool operator()(tc::unused) noexcept;\n};\n\nstatic_assert(\n\t!tc::has_range_value<decltype(\n\t\t\ttc::filter(\n\t\t\t\tstd::declval<GeneratorMutableInt>(),\n\t\t\t\tdummy_pred()\n\t\t\t)\n\t)>\n);\n\nstatic_assert(\n\t!tc::has_range_value<std::add_const_t<decltype(\n\t\ttc::filter(\n\t\t\tstd::declval<GeneratorMutableInt>(),\n\t\t\tdummy_pred()\n\t\t)\n\t)>>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::range_value_t<\n\t\t\tdecltype(\n\t\t\t\ttc::filter(\n\t\t\t\t\tstd::declval<GeneratorMutableInt&>(),\n\t\t\t\t\tdummy_pred()\n\t\t\t\t)\n\t\t\t)\n\t\t>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::range_value_t<\n\t\t\tstd::add_const_t<decltype(\n\t\t\t\ttc::filter(\n\t\t\t\t\tstd::declval<GeneratorMutableInt&>(),\n\t\t\t\t\tdummy_pred()\n\t\t\t\t)\n\t\t\t)>\n\t\t>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\t!tc::has_range_value<\n\t\tdecltype(\n\t\t\ttc::filter(\n\t\t\t\tstd::declval<GeneratorMutableInt const&>(),\n\t\t\t\tdummy_pred()\n\t\t\t)\n\t\t)\n\t>\n);\n\nstatic_assert(\n\t!tc::has_range_value<\n\t\tstd::add_const_t<decltype(\n\t\t\ttc::filter(\n\t\t\t\tstd::declval<GeneratorMutableInt const&>(),\n\t\t\t\tdummy_pred()\n\t\t\t)\n\t\t)>\n\t>\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::range_value_t<\n\t\t\tstd::add_const_t<decltype(\n\t\t\t\ttc::concat(\n\t\t\t\t\tstd::declval<GeneratorMutableInt&>(),\n\t\t\t\t\tstd::declval<GeneratorMutableInt&>()\n\t\t\t\t)\n\t\t\t)>\n\t\t>,\n\t\tint\n\t>::value\n);\n\nstatic_assert(\n\tstd::is_same<\n\t\ttc::range_value_t<\n\t\t\tdecltype(\n\t\t\t\ttc::concat(\n\t\t\t\t\tstd::declval<GeneratorInt&>(),\n\t\t\t\t\tstd::declval<GeneratorMutableInt&>()\n\t\t\t\t)\n\t\t\t)\n\t\t>,\n\t\tint\n\t>::value\n);\n\nUNITTESTDEF(filter_with_generator_range) {\n\t_ASSERTEQUAL(\n\t\ttc::max_element<tc::return_value>(\n\t\t\tGeneratorInt()\n\t\t),\n\t\t6\n\t);\n\t\n\t_ASSERTEQUAL(\n\t\ttc::max_element<tc::return_value>(\n\t\t\ttc::filter(\n\t\t\t\tGeneratorInt(),\n\t\t\t\t[](int const n) noexcept {return 1==n%2;}\n\t\t\t)\n\t\t),\n\t\t3\n\t);\n\n\ttc::for_each(\n\t\tGeneratorInt(),\n\t\t[](int&& n) noexcept {\n\t\t\tn += 1;\n\t\t}\n\t);\n\n\t_ASSERTEQUAL(\n\t\ttc::max_element<tc::return_value>(\n\t\t\ttc::transform(\n\t\t\t\tGeneratorInt(),\n\t\t\t\t[](int const n) noexcept {return -n;}\n\t\t\t)\n\t\t),\n\t\t-1\n\t);\n\n\tauto const tr1 = tc::transform(\n\t\tGeneratorInt(),\n\t\t[](int const n) noexcept {return -n;}\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::range_value_t<decltype(tr1)>,\n\t\t\tint\n\t\t>::value\n\t);\n\n\tauto const filtered = tc::filter(\n\t\tGeneratorInt(),\n\t\t[](int const n) noexcept {return n>0;}\n\t);\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::range_value_t<decltype(filtered)>,\n\t\t\tint\n\t\t>::value\n\t);\n\n\n\tauto vecn = tc::make_vector(GeneratorInt());\n\n\t{\n\t\tauto vecn2 = tc::make_vector(tc::join(GeneratorGeneratorInt()));\n\t\t_ASSERTEQUAL(\n\t\t\ttc::size(vecn2),\n\t\t\t8\n\t\t);\n\t}\n\n\tauto vecgenint = tc::make_vector(GeneratorGeneratorInt());\n\t{\n\t\tauto vecn2 = tc::make_vector(tc::join(vecgenint));\n\t\t_ASSERTEQUAL(\n\t\t\ttc::size(vecn2),\n\t\t\t8\n\t\t);\n\t}\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::range_value_t<\n\t\t\t\tdecltype(tc::join(vecgenint))\n\t\t\t>,\n\t\t\tint\n\t\t>::value\n\t);\n\tauto vecnx = tc::make_vector(GeneratorInt(), GeneratorInt());\n\t_ASSERTEQUAL(tc::size(vecnx), 8);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::range_value_t<\n\t\t\t\tdecltype(tc::concat(GeneratorInt(), GeneratorLong()))\n\t\t\t>,\n\t\t\tlong\n\t\t>::value\n\t);\n\n\tstatic_assert(\n\t\tstd::is_same<\n\t\t\ttc::range_value_t<\n\t\t\t\tdecltype(tc::concat(GeneratorLong(), GeneratorLong()))\n\t\t\t>,\n\t\t\tlong\n\t\t>::value\n\t);\n}\n\nUNITTESTDEF(make_constexpr_array_test) {\n\tconstexpr auto const& an = tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1, 2, 3));\n\tstatic_assert(tc::at(an, 0) == 1);\n\tstatic_assert(tc::at(an, 1) == 2);\n\tstatic_assert(tc::at(an, 2) == 3);\n\tstatic_assert(tc::size(an) == 3);\n\t_ASSERT(tc::equal(an, tc::iota(1, 4)));\n}\n\nUNITTESTDEF(join_repeat) {\n\t_ASSERTEQUAL(tc::make_str(tc::join(tc::repeat_n(3, \"ab\"))), \"ababab\");\n}\n\n}\n\n//---- Cartesian product ------------------------------------------------------------------------------------------------------\n\nnamespace {\n\t// cannot be local to workaround MSVC compiler bugs\n\tauto constexpr an1 = std::array<int, 5>{ 0, 1, 2, 3, 4 };\n\tauto constexpr an2 = std::array<int, 3>{ 0, 1, 2 };\n\t[[maybe_unused]] void cartesian_product_test(std::array<int, 2>& an) {\n\t\ttc::for_each(tc::cartesian_product(an, an), [](auto&& x){\n\t\t\tSTATICASSERTSAME(decltype(x), TC_FWD(tc::tuple<int&, int&>&&));\n\t\t});\n\t\ttc::for_each(tc::cartesian_product(tc::as_const(an), tc::as_const(an)), [](auto&& x){\n\t\t\tSTATICASSERTSAME(decltype(x), TC_FWD(tc::tuple<int const&, const int&>&&));\n\t\t});\n\t\ttc_static_auto_constexpr_lambda(rvaluerng) = [](auto sink) { sink(1); };\n\t\ttc::for_each(tc::cartesian_product(rvaluerng, rvaluerng), [](auto&& x){\n\t\t\tSTATICASSERTSAME(decltype(x), TC_FWD(tc::tuple<int const&&, int&&>&&));\n\t\t});\n\n\t\ttc_static_auto_constexpr(rng, tc::cartesian_product(an1, an2));\n\n\t\tGCC_WORKAROUND_STATIC_ASSERT( *++tc::begin(rng) == tc::make_tuple(0, 1) );\n\t\tGCC_WORKAROUND_STATIC_ASSERT( *--tc::end(rng) == tc::make_tuple(4, 2) );\n\t\tGCC_WORKAROUND_STATIC_ASSERT( tc::at(rng, 7) == tc::make_tuple(2, 1) );\n\t\tGCC_WORKAROUND_STATIC_ASSERT( int(tc::begin(rng) - tc::end(rng)) == -15 );\n\t\tGCC_WORKAROUND_STATIC_ASSERT( int(++tc::begin(rng) - --tc::end(rng)) == -13 );\n\n\t\tGCC_WORKAROUND_STATIC_ASSERT( tc::find_unique<tc::return_element_index>(rng, tc::make_tuple(2, 1)) == 7 );\n\t\tGCC_WORKAROUND_STATIC_ASSERT( tc::find_unique<tc::return_element>(rng, tc::make_tuple(2, 1)) - tc::begin(rng) == 7 );\n\t}\n}\n\n//---- Adjacent tuples ------------------------------------------------------------------------------------------------------\n\nnamespace {\n\tnamespace adjacent_tuples_iterator_test {\n\t\tauto constexpr an = std::array<int, 5>{ 1, 2, 3, 4, 5 };\n\t\tnamespace non_empty {\n\t\t\tauto constexpr rng = tc::adjacent<3>(an);\n\n\t\t\tstatic_assert( 3 == tc::size(rng) );\n\t\t\tstatic_assert( *tc::begin(rng) == tc::make_tuple(1, 2, 3) );\n\t\t\tauto constexpr it = []() { auto _ = tc::begin(rng); ++_; return _; }();\n\t\t\tstatic_assert( *it == tc::make_tuple(2,3,4) );\n\t\t\tauto constexpr it2 = []() { auto _ = tc::end(rng); --_; return _; }();\n\t\t\tstatic_assert( *it2 == tc::make_tuple(3,4,5) );\n\t\t\tstatic_assert( it + 1 == it2 );\n\t\t\tstatic_assert( *(tc::begin(rng) + 2) == tc::make_tuple(3, 4, 5) );\n\t\t\tauto constexpr it3 = []() { auto _ = tc::begin(rng); ++_; ++_; ++_; return _; }();\n\t\t\tstatic_assert( tc::begin(rng) + 3 == it3 );\n\t\t\tstatic_assert( tc::begin(rng) + 3 == tc::end(rng) );\n\t\t\tstatic_assert( tc::begin(rng) + 3 == tc::end_sentinel() );\n\t\t\tstatic_assert( tc::end(rng) == tc::end_sentinel() );\n\t\t\tstatic_assert( tc::end(rng) - tc::begin(rng) == 3 );\n\t\t\tstatic_assert( *tc::middle_point(tc::begin(rng), tc::end(rng)) == tc::make_tuple(2,3,4) );\n\t\t}\n\t\tnamespace empty {\n\t\t\tauto constexpr rng = tc::adjacent<6>(an);\n\t\t\tstatic_assert( tc::empty(rng) );\n\t\t\tstatic_assert( tc::begin(rng) == tc::end(rng) );\n\t\t\tstatic_assert( tc::begin(rng) == tc::end_sentinel() );\n\t\t\tstatic_assert( tc::end(rng) == tc::end_sentinel() );\n\t\t\tstatic_assert( tc::begin(rng) + 0 == tc::begin(rng) );\n\t\t\tstatic_assert( tc::end(rng) - tc::begin(rng) == 0 );\n\t\t}\n\t}\n}\n\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<tc::tuple<int, double, int, double const&>>), TC_FWD(boost::mp11::mp_list<int, double, double const&>));\n#ifndef TC_PRIVATE\nSTATICASSERTSAME(TC_FWD(tc::range_output_t<std::tuple<int, double, int, double const&>>), TC_FWD(boost::mp11::mp_list<int, double, double const&>));\n#endif\nSTATICASSERTSAME(tc::range_value_t<decltype(tc::concat_nonempty_with_separator(\"-\", \"1\", \"2\"))>, char);\nSTATICASSERTSAME(tc::range_value_t<decltype(tc::concat_nonempty_with_separator(\"-\", \"1\", tc::string<char>(\"2\")))>, char);\nSTATICASSERTSAME(tc::range_value_t<decltype(tc::concat_nonempty_with_separator(\"-\", \"1\", tc::empty_range()))>, char);\n\n//---- Adjacent tuples ------------------------------------------------------------------------------------------------------\n\nnamespace {\n\tUNITTESTDEF(range_of_elements__dereference_index) {\n\t\ttc::discard(tc::make_vector(tc::transform(\n\t\t\ttc::make_range_of_iterators(tc::filter(tc::vector<void*>())),\n\t\t\t[&](auto&& it) noexcept {\n\t\t\t\t_ASSERT( std::is_same<decltype(it), decltype(tc::begin(tc::as_const(tc::as_lvalue(tc::filter(tc::vector<void*>()))))) &&>::value );\n\t\t\t\treturn 7;\n\t\t\t}\n\t\t)));\n\t}\n}\n"
  },
  {
    "path": "tc/range/range_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"index_iterator.h\"\n#include \"meta.h\"\n#include \"../base/assert_defs.h\"\n#include \"../base/casts.h\"\n#include \"../base/static_polymorphism.h\"\n#include \"../algorithm/for_each.h\"\n\n#include <boost/range/detail/demote_iterator_traversal_tag.hpp>\n#include <boost/mpl/has_xxx.hpp>\n\n#include <type_traits>\n\nnamespace tc {\n\n\tTC_HAS_MEM_FN_XXX_CONCEPT_DEF(end_index, const&);\n\n\t//////////////////////////////////////////////////////////\n\t// range adaptors\n\t//\n\t// Basic building block for all ranges.\n\t// Comes in two variations, one for generator ranges, one for iterator ranges. \n\t//\n\tnamespace no_adl {\n\t\ttemplate <typename Derived, typename Index>\n\t\tstruct TC_EMPTY_BASES index_range_interface {\n\t\tprivate:\n\t\t\tusing this_type = index_range_interface;\n\t\tpublic:\n\t\t\tusing tc_index = Index;\n\n\t\t\tSTATIC_VIRTUAL(begin_index)\n\t\t\tSTATIC_VIRTUAL(end_index)\n\t\t\tSTATIC_VIRTUAL(increment_index)\n\t\t\tSTATIC_VIRTUAL(decrement_index)\n\t\t\tSTATIC_VIRTUAL(dereference_index)\n\t\t\tSTATIC_VIRTUAL(advance_index)\n\t\t\tSTATIC_VIRTUAL(index_to_address)\n\t\t\tSTATIC_VIRTUAL(distance_to_index)\n\t\t\tSTATIC_VIRTUAL(middle_point)\n\n\t\t\tSTATIC_VIRTUAL_WITH_FALLBACK_MOD(\n\t\t\t\tTC_FWD(\n\t\t\t\t\ttemplate<typename Derived_ = Derived> requires has_mem_fn_end_index<Derived_> && tc::is_equality_comparable<Index>::value\n\t\t\t\t\tconstexpr\n\t\t\t\t),\n\t\t\tat_end_index)(tc_index const& idx) const&\n\t\t\t\treturn_MAYTHROW(end_index() == idx)\n\n\t\t};\n\t}\n\tusing no_adl::index_range_interface;\n\n\tnamespace no_adl {\n\t\t// simulate iterator interface on top of index interface\n\t\ttemplate <typename Derived, typename Index>\n\t\tstruct TC_EMPTY_BASES range_iterator_from_index : index_range_interface<Derived, Index> {\n\t\tprivate:\n\t\t\tusing iterator = index_iterator<Derived, false>;\n\t\t\tusing const_iterator = index_iterator<Derived, true>;\n\n\t\tpublic:\n\t\t\tconstexpr iterator make_iterator(auto&& idx) & noexcept {\n\t\t\t\treturn iterator(*tc::derived_cast<Derived>(MSVC_WORKAROUND_THIS),tc_move_if_owned(idx));\n\t\t\t}\n\t\t\tconstexpr const_iterator make_iterator(auto&& idx) const& noexcept {\n\t\t\t\treturn const_iterator(*tc::derived_cast<Derived>(MSVC_WORKAROUND_THIS), tc_move_if_owned(idx));\n\t\t\t}\n\n\t\t\tconstexpr iterator begin() &\n\t\t\t\treturn_MAYTHROW(make_iterator(this->begin_index()))\n\t\t\tconstexpr const_iterator begin() const&\n\t\t\t\treturn_MAYTHROW(make_iterator(this->begin_index()))\n\n\n\t\t\ttemplate<typename Derived_ = Derived>\n\t\t\t\trequires tc::has_mem_fn_end_index<Derived_> && tc::is_equality_comparable<Index>::value\n\t\t\tconstexpr iterator end() &\n\t\t\t\treturn_MAYTHROW(make_iterator(this->end_index()))\n\t\t\ttemplate<typename Derived_ = Derived>\n\t\t\t\trequires tc::has_mem_fn_end_index<Derived_> && tc::is_equality_comparable<Index>::value\n\t\t\tconstexpr const_iterator end() const&\n\t\t\t\treturn_MAYTHROW(make_iterator(this->end_index()))\n\n\t\t\ttemplate<typename Derived_ = Derived> // no requires, so lower priority\n\t\t\tconstexpr end_sentinel end() const& noexcept {\n\t\t\t\treturn {};\n\t\t\t}\n\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr static decltype(auto) iterator2index(It&& it) noexcept {\n\t\t\t\tif constexpr(std::same_as<Index, tc::decay_t<It>>) {\n\t\t\t\t\treturn tc_move_if_owned(it);\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert(std::same_as<Index, tc::decay_t<decltype(tc_unwrap_temporary(tc_move_if_owned(it)).m_idx)>>);\n\t\t\t\t\treturn tc_rewrap_temporary(It, tc_unwrap_temporary(tc_move_if_owned(it)).m_idx);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::range_iterator_from_index;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct TC_EMPTY_BASES range_adaptor_base_range : /*not private to enable use as non-type template parameter*/ tc::reference_or_value<Rng, /*bBestAccess*/true> {\n\t\tprivate:\n\t\t\tstatic_assert(!std::is_rvalue_reference<Rng>::value);\n\t\t\tusing base_= tc::reference_or_value<Rng, true>;\n\t\t\tusing base_::operator->;\n\t\t\tusing base_::operator*;\n\t\t\tusing base_::best_access;\n\n\t\tpublic:\n\t\t\tconstexpr range_adaptor_base_range()=default;\n\t\t\ttemplate<typename Rhs>\n\t\t\tconstexpr range_adaptor_base_range(tc::aggregate_tag_t, Rhs&& rhs) noexcept\n\t\t\t\t: tc::reference_or_value<Rng, /*bBestAccess*/true>(tc::aggregate_tag, tc_move_if_owned(rhs))\n\t\t\t{}\n\n\t\t\tconstexpr decltype(auto) base_range() & noexcept { return **this; }\n\t\t\tconstexpr decltype(auto) base_range() const& noexcept { return **this; }\n\t\t\tconstexpr decltype(auto) base_range() && noexcept { return *tc_move_always(*this); }\n\t\t\tconstexpr decltype(auto) base_range() const&& noexcept { return *tc_move_always_even_const(*this); }\n\t\t\tconstexpr decltype(auto) base_range_best_access() const& noexcept { return this->best_access(); }\n\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr auto base_begin_index() const& return_decltype_MAYTHROW(\n\t\t\t\ttc::begin_index(SFINAE_VALUE(this)->base_range_best_access())\n\t\t\t)\n\t\t\ttemplate<ENABLE_SFINAE>\n\t\t\tconstexpr auto base_end_index() const& return_decltype_MAYTHROW(\n\t\t\t\ttc::end_index(SFINAE_VALUE(this)->base_range_best_access())\n\t\t\t)\n\t\t};\n\t}\n\tusing no_adl::range_adaptor_base_range;\n\n\tnamespace generator_range_adl {\n\t\t//-------------------------------------------------------------------------------------------------------------------------\n\t\t// First generator ranges\n\t\t//\n\t\t// a generator range is any type that supports an operator() with a template parameter that is a Function that can be \n\t\t// called with the element type of the range. \n\t\t// The generator range should support the break_or_continue protocol\n\n\t\ttemplate<typename Rng>\n\t\tstruct TC_EMPTY_BASES generator_range_adaptor : tc::range_adaptor_base_range<Rng> {\n\t\t\tconstexpr generator_range_adaptor()=default;\n\t\t\tusing range_adaptor_base_range<Rng>::range_adaptor_base_range;\n\t\t\tusing is_generator_range_adaptor = void;\n\t\t};\n\n\t\ttemplate<typename Self, typename Sink, typename std::remove_reference_t<Self>::is_generator_range_adaptor* = nullptr>\n\t\tconstexpr auto for_each_impl(Self&& self, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\ttc::for_each(\n\t\t\t\ttc_move_if_owned(self).base_range(),\n\t\t\t\ttc_move_if_owned(self).adapted_sink(tc_move_if_owned(sink), /*bReverse*/tc::constant<false>())\n\t\t\t)\n\t\t)\n\t}\n\tusing generator_range_adl::generator_range_adaptor;\n\n\tnamespace generator_range_output_detail::no_adl {\n\t\ttemplate<typename Derived, typename T>\n\t\tstruct generator_range_output_sink_base {\n\t\t\tSTATICASSERTSAME( T, std::remove_cv_t<T>, \"range output must be a reference or cv-unqualified object type\" );\n\n\t\t\ttemplate<typename Derived_ = Derived>\n\t\t\tconstexpr auto operator()(T t) const& return_decltype_MAYTHROW(\n\t\t\t\ttc_invoke(tc::derived_cast<Derived_>(this)->m_sink, tc_move_if_owned(t))\n\t\t\t)\n\t\t};\n\n\t\ttemplate<typename Sink, typename... T>\n\t\tstruct generator_range_output_sink : generator_range_output_sink_base<generator_range_output_sink<Sink, T...>, T>... {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tusing guaranteed_break_or_continue = guaranteed_break_or_continue_t<Sink>;\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename Sink_>\n\t\t\tconstexpr generator_range_output_sink(tc::aggregate_tag_t, Sink_&& sink) noexcept : m_sink(tc_move_if_owned(sink)) {}\n\n\t\t\tusing generator_range_output_sink_base<generator_range_output_sink<Sink, T...>, T>::operator()...;\n\n\t\t\t// generator_range_output_sink forwards chunks without modifications.\n\t\t\t// This is relevant when m_sink is a tc::contiguous_chunk_appender or tc::no_adl::with_iterator_range.\n\t\t\t// To enforce consistency with operator(), we enforce all output types of a chunk to be similar to\n\t\t\t// one of the declared output types.\n\t\t\ttemplate<typename U>\n\t\t\tusing is_valid_chunk_output = tc::constant<\n\t\t\t\t((\n\t\t\t\t\tstd::is_reference<T>::value && !std::is_const<std::remove_reference_t<T>>::value\n\t\t\t\t\t\t? std::same_as<T, U&&> // require exact match for mutable references\n\t\t\t\t\t\t: std::same_as< // bind immutable references and prvalues from any reference to same underlying object type\n\t\t\t\t\t\t\tstd::remove_const_t<std::remove_reference_t<T>>,\n\t\t\t\t\t\t\tstd::remove_const_t<std::remove_reference_t<U>>\n\t\t\t\t\t\t>\n\t\t\t\t) || ...)\n\t\t\t>;\n\n\t\t\ttemplate<typename Rng> requires tc::has_mem_fn_chunk<Sink const&, Rng> && boost::mp11::mp_all_of<tc::range_output_t<Rng>, is_valid_chunk_output>::value\n\t\t\tconstexpr auto chunk(Rng&& rng) const& noexcept(noexcept(m_sink.chunk(std::declval<Rng>()))) {\n\t\t\t\treturn m_sink.chunk(tc_move_if_owned(rng));\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace generator_range_output_adaptor_adl {\n\t\ttemplate<typename Rng, typename... T>\n\t\tstruct [[nodiscard]] TC_EMPTY_BASES generator_range_output_adaptor : generator_range_output_adaptor<Rng, boost::mp11::mp_list<T...>> {\n\t\t\tusing generator_range_output_adaptor<Rng, boost::mp11::mp_list<T...>>::generator_range_output_adaptor;\n\t\t};\n\n\t\ttemplate<typename Rng, typename... T>\n\t\tstruct [[nodiscard]] TC_EMPTY_BASES generator_range_output_adaptor<Rng, boost::mp11::mp_list<T...>> : tc::generator_range_adaptor<Rng> {\n\t\t\tusing generator_range_adaptor<Rng>::generator_range_adaptor;\n\t\t\tfriend auto range_output_t_impl(generator_range_output_adaptor const&)\n\t\t\t\t-> boost::mp11::mp_unique<boost::mp11::mp_list<tc::remove_rvalue_reference_t<T>...>>; // declaration only\n\n\t\t\ttemplate<typename Sink>\n\t\t\tconstexpr auto adapted_sink(Sink&& sink, bool /*bReverse*/) const& noexcept {\n\t\t\t\treturn generator_range_output_detail::no_adl::generator_range_output_sink<tc::decay_t<Sink>, T...>(tc::aggregate_tag, tc_move_if_owned(sink));\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename... TypeListOrTs, typename Rng>\n\tconstexpr auto generator_range_output(Rng&& rng) noexcept {\n\t\treturn generator_range_output_adaptor_adl::generator_range_output_adaptor<Rng, TypeListOrTs...>(tc::aggregate_tag, tc_move_if_owned(rng));\n\t}\n\n\tnamespace range_output_from_base_range_adl {\n\t\tstruct TC_EMPTY_BASES range_output_from_base_range {\n\t\t\ttemplate<typename Derived, std::enable_if_t<tc::decayed_derived_from<Derived, range_output_from_base_range>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Derived&&) -> tc::range_output_t<decltype(std::declval<Derived>().base_range())> {} // unevaluated\n\t\t};\n\t}\n\tusing range_output_from_base_range_adl::range_output_from_base_range;\n\n#ifdef _CHECKS\n\tnamespace no_adl {\n\t\ttemplate< typename Rng >\n\t\tstruct SSinglePassRange : tc::noncopyable {\n\t\t\texplicit SSinglePassRange(Rng&& rng) noexcept\n\t\t\t: m_rng(tc_move(rng)) {}\n\t\t\ttemplate< typename Sink >\n\t\t\tconstexpr auto operator()(Sink&& sink) && MAYTHROW {\n\t\t\t\t_ASSERTE( tc::change(m_bFirstPass, false) );\n\t\t\t\treturn tc::for_each(tc_move(m_rng), tc_move_if_owned(sink));\n\t\t\t}\n\n\t\t\tRng m_rng;\n\t\t\tbool mutable m_bFirstPass = true;\n\t\t};\n\t}\n\n\ttemplate< typename Rng >\n\tauto assert_single_pass(Rng&& rng) noexcept {\n\t\treturn no_adl::SSinglePassRange<Rng>(tc_move(rng)); // Disallow lvalue references.\n\t}\n#else\n\ttemplate< typename Rng >\n\tdecltype(auto) assert_single_pass(Rng&& rng) noexcept {\n\t\treturn tc_move_if_owned(rng);\n\t}\n#endif\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// iterator/index based ranges\n\t//\n\t// they derive from the generator case, because the generator interface can transparently and efficiently be added\n\t// to any iterator or index based range.\n\t//\n\tnamespace index_range_adaptor_flags_adl {\n\t\t// Cannot use tc::enumset due to cyclic dependency.\n\t\tenum class index_range_adaptor_flags {\n\t\t\tinherit_none = 0,\n\n\t\t\tinherit_begin = 1 << 0,\n\t\t\tinherit_end = 1 << 1,\n\t\t\tinherit_begin_end = inherit_begin | inherit_end,\n\n\t\t\tinherit_dereference = 1 << 2,\n\t\t\tinherit_traversal = 1 << 3,\n\t\t\tinherit_behavior = inherit_dereference | inherit_traversal,\n\n\t\t\tinherit_all = inherit_begin_end | inherit_behavior,\n\t\t};\n\t\tTC_BITMASK_OPS(index_range_adaptor_flags)\n\t}\n\tusing index_range_adaptor_flags_adl::index_range_adaptor_flags;\n\n\tnamespace no_adl {\n\t\tnamespace index_range_adaptor_detail {\n\t\t\ttemplate <typename Derived, typename Rng, bool InheritBehavior>\n\t\t\tstruct iterator_range_interface : tc::range_iterator_from_index<Derived, tc::index_t<Rng>> {};\n\n\t\t\ttemplate <typename Derived, typename Rng>\n\t\t\t\trequires tc::range_with_iterators<Rng>\n\t\t\tstruct iterator_range_interface<Derived, Rng, true> : tc::index_range_interface<Derived, tc::index_t<Rng>> {\n\t\t\tprivate:\n\t\t\t\tusing iterator = tc::iterator_t<decltype(*std::declval<tc::reference_or_value<Rng>&>())>;\n\t\t\t\tusing const_iterator = tc::iterator_t<decltype(*std::declval<tc::reference_or_value<Rng> const&>())>;\n\t\t\t\t\n\t\t\t\tstruct sentinel {\n\t\t\t\t\tDerived const* self;\n\n\t\t\t\t\tconstexpr bool operator==(auto const& it) const MAYTHROW {\n\t\t\t\t\t\treturn tc::at_end_index(*self, tc::iterator2index<Rng>(it));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\tpublic:\n\t\t\t\tconstexpr iterator make_iterator(auto&& idx) & return_MAYTHROW(\n\t\t\t\t\ttc::make_iterator(tc::derived_cast<Derived>(MSVC_WORKAROUND_THIS)->base_range(), tc_move_if_owned(idx))\n\t\t\t\t)\n\t\t\t\tconstexpr const_iterator make_iterator(auto&& idx) const& return_MAYTHROW(\n\t\t\t\t\ttc::make_iterator(tc::derived_cast<Derived>(MSVC_WORKAROUND_THIS)->base_range(), tc_move_if_owned(idx))\n\t\t\t\t)\n\n\t\t\t\tconstexpr iterator begin() &\n\t\t\t\t\treturn_MAYTHROW(make_iterator(this->begin_index()))\n\t\t\t\tconstexpr const_iterator begin() const&\n\t\t\t\t\treturn_MAYTHROW(make_iterator(this->begin_index()))\n\n\t\t\t\ttemplate<typename Derived_ = Derived>\n\t\t\t\t\trequires tc::has_mem_fn_end_index<Derived_>\n\t\t\t\tconstexpr iterator end() &\n\t\t\t\t\treturn_MAYTHROW(make_iterator(this->end_index()))\n\t\t\t\ttemplate<typename Derived_ = Derived>\n\t\t\t\t\trequires tc::has_mem_fn_end_index<Derived_>\n\t\t\t\tconstexpr const_iterator end() const&\n\t\t\t\t\treturn_MAYTHROW(make_iterator(this->end_index()))\n\n\t\t\t\ttemplate<typename Derived_ = Derived> // no requires, so lower priority\n\t\t\t\tconstexpr auto end() const& noexcept {\n\t\t\t\t\treturn sentinel{tc::derived_cast<Derived>(MSVC_WORKAROUND_THIS)};\n\t\t\t\t}\n\n\t\t\t\ttemplate<typename It>\n\t\t\t\tconstexpr static decltype(auto) iterator2index(It&& it) noexcept {\n\t\t\t\t\treturn tc::iterator2index<Rng>(tc_move_if_owned(it));\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\ttemplate<\n\t\t\ttypename Derived,\n\t\t\ttypename Rng, index_range_adaptor_flags Flags,\n\t\t\ttypename Base = tc::range_adaptor_base_range<Rng>\n\t\t>\n\t\tstruct TC_EMPTY_BASES index_range_adaptor\n\t\t\t: Base\n\t\t\t, index_range_adaptor_detail::iterator_range_interface<\n\t\t\t\tDerived, Rng,\n\t\t\t\t(Flags & index_range_adaptor_flags::inherit_behavior) == index_range_adaptor_flags::inherit_behavior\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = index_range_adaptor;\n\n\t\tpublic:\n\t\t\tconstexpr index_range_adaptor() = default;\n\t\t\tusing Base::Base;\n\n\t\t\tusing tc_index = tc::index_t<Rng>;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\n\t\tprivate:\n\t\t\tstatic constexpr auto inherit_begin = static_cast<bool>(Flags & index_range_adaptor_flags::inherit_begin);\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr,begin_index)() const& MAYTHROW\n\t\t\t\trequires inherit_begin\n\t\t\t{\n\t\t\t\treturn this->base_begin_index();\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstatic constexpr auto inherit_end = static_cast<bool>(Flags & index_range_adaptor_flags::inherit_end);\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr,end_index)() const& MAYTHROW\n\t\t\t\trequires inherit_end && tc::has_end_index<Rng>\n\t\t\t{\n\t\t\t\treturn this->base_end_index();\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr,at_end_index)(tc_index const& idx) const& MAYTHROW\n\t\t\t\trequires inherit_end\n\t\t\t{\n\t\t\t\treturn tc::at_end_index(this->base_range(),idx);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstatic constexpr auto inherit_dereference = static_cast<bool>(Flags & index_range_adaptor_flags::inherit_dereference);\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, dereference_index)(auto&& idx) & MAYTHROW -> decltype(auto)\n\t\t\t\trequires inherit_dereference\n\t\t\t{\n\t\t\t\treturn tc::dereference_index(this->base_range(), tc_move_if_owned(idx));\n\t\t\t}\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto)\n\t\t\t\trequires inherit_dereference\n\t\t\t{\n\t\t\t\treturn tc::dereference_index(this->base_range(), tc_move_if_owned(idx));\n\t\t\t}\n\n\t\tpublic:\n\t\t\tconstexpr decltype(auto) dereference_untransform(auto&& idx) const& noexcept\n\t\t\t\trequires inherit_dereference\n\t\t\t{\n\t\t\t\treturn this->base_range().dereference_untransform(tc_move_if_owned(idx));\n\t\t\t}\n\n\t\t\tstatic constexpr decltype(auto) element_base_index(auto&& idx) noexcept\n\t\t\t\trequires inherit_dereference\n\t\t\t{\n\t\t\t\treturn tc_move_if_owned(idx);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstatic constexpr auto inherit_traversal = static_cast<bool>(Flags & index_range_adaptor_flags::inherit_traversal);\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr,increment_index)(tc_index& idx) const& MAYTHROW\n\t\t\t\trequires inherit_traversal\n\t\t\t{\n\t\t\t\ttc::increment_index(this->base_range(),idx);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, decrement_index)(tc_index& idx) const& MAYTHROW\n\t\t\t\trequires inherit_traversal && tc::has_decrement_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\ttc::decrement_index(this->base_range(),idx);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, advance_index)(tc_index& idx, typename boost::range_difference<Rng>::type d) const& MAYTHROW\n\t\t\t\trequires inherit_traversal && tc::has_advance_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\ttc::advance_index(this->base_range(),idx,d);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& MAYTHROW\n\t\t\t\trequires inherit_traversal && tc::has_distance_to_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\treturn tc::distance_to_index(this->base_range(),idxLhs,idxRhs);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, middle_point)( tc_index & idxBegin, tc_index const& idxEnd ) const& MAYTHROW\n\t\t\t\trequires inherit_traversal && tc::has_middle_point<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\ttc::middle_point(this->base_range(),idxBegin,idxEnd);\n\t\t\t}\n\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, index_to_address)(tc_index const& idx) & noexcept\n\t\t\t\trequires inherit_dereference && inherit_traversal && tc::has_index_to_address<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\treturn tc::index_to_address(this->base_range(), idx);\n\t\t\t}\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, index_to_address)(tc_index const& idx) const& noexcept\n\t\t\t\trequires inherit_dereference && inherit_traversal && tc::has_index_to_address<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\treturn tc::index_to_address(this->base_range(), idx);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::index_range_adaptor;\n\n\tnamespace no_adl {\n\t\ttemplate<template<bool, typename...> typename AdaptorTemplate, template<typename...> typename IndexTemplate, typename... Rng>\n\t\tstruct product_index_range_adaptor\n\t\t\t: AdaptorTemplate<false, Rng...>\n\t\t\t, range_iterator_from_index<\n\t\t\t\tAdaptorTemplate<true, Rng...>,\n\t\t\t\tIndexTemplate<tc::index_t<std::remove_reference_t<Rng>>...>\n\t\t\t>\n\t\t{\n\t\t\tstatic constexpr bool c_bHasStashingIndex=std::disjunction<tc::has_stashing_index<std::remove_reference_t<Rng>>...>::value;\n\n\t\t\tusing AdaptorTemplate<false, Rng...>::AdaptorTemplate;\n\t\t\tusing typename product_index_range_adaptor::range_iterator_from_index::tc_index;\n\n\t\t\ttemplate<typename Self>\n\t\t\tstatic constexpr auto base_ranges(Self&& self) noexcept { // TODO C++23 deducing *this\n\t\t\t\treturn tc::tuple_transform(\n\t\t\t\t\ttc_move_if_owned(self).m_tupleadaptbaserng,\n\t\t\t\t\ttc_mem_fn(.base_range)\n\t\t\t\t);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tusing Derived = AdaptorTemplate<true, Rng...>;\n\t\t\tusing this_type = product_index_range_adaptor;\n\n\t\t\tSTATIC_OVERRIDE_MOD(template<typename Index> constexpr, dereference_index)(Index&& idx) const& MAYTHROW {\n\t\t\t\treturn tc::tuple_transform(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx),\n\t\t\t\t\t[](auto&& adaptbaserng, auto&& baseidx) MAYTHROW -> decltype(auto) {\n\t\t\t\t\t\treturn tc::dereference_index(adaptbaserng.base_range(), tc::forward_like<Index>(baseidx));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(template<typename Index> constexpr, dereference_index)(Index&& idx) & MAYTHROW {\n\t\t\t\treturn tc::tuple_transform(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx),\n\t\t\t\t\t[](auto&& adaptbaserng, auto&& baseidx) MAYTHROW -> decltype(auto) {\n\t\t\t\t\t\treturn tc::dereference_index(adaptbaserng.base_range(), tc::forward_like<Index>(baseidx));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::product_index_range_adaptor;\n}\n\nnamespace tc::no_adl {\n\ttemplate<typename... T> requires (requires { typename tc::value_t<T>; } && ...)\n\tstruct value_type_impl<tc::tuple<T...>> final {\n\t\tusing type = tc::tuple<tc::value_t<T>...>;\n\t};\n}\n"
  },
  {
    "path": "tc/range/range_return.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"subrange.h\"\n\nnamespace tc {\n\tnamespace return_detail {\n\t\ttemplate<typename Rng>\n\t\tconstexpr decltype(auto) empty_slice(Rng&& rng) noexcept {\n\t\t\tauto it = tc::begin(rng);\n\t\t\tauto it2 = it;\n\t\t\treturn tc::slice(tc_move_if_owned(rng), tc_move(it), tc_move(it2));\n\t\t}\n\n\t\tnamespace no_adl {\n\t\t\t// Pack border as subrange\n\n\t\t\tstruct return_take_base {\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr auto pack_border(It&& it, Rng&& rng) return_decltype_allow_xvalue_noexcept(\n\t\t\t\t\ttc::take(tc_move_if_owned(rng), tc_move_if_owned(it))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\tstruct return_drop_base {\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr auto pack_border(It&& it, Rng&& rng) return_decltype_allow_xvalue_noexcept(\n\t\t\t\t\ttc::drop(tc_move_if_owned(rng), tc_move_if_owned(it))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnSubrange>\n\t\t\tstruct return_subrange_or_assert final : ReturnSubrange {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\n\t\t\t\ttemplate<typename... Args>\n\t\t\t\tstatic decltype(auto) pack_no_border(Args&&... args) noexcept {\n\t\t\t\t\t_ASSERTFALSE;\n\t\t\t\t\treturn ReturnSubrange::pack_no_border(tc_move_if_owned(args)...);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnSubrange>\n\t\t\tstruct return_subrange_or_none final {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr auto pack_border(It&& it, Rng&& rng) noexcept {\n\t\t\t\t\treturn std::optional(ReturnSubrange::pack_border(tc_move_if_owned(it), tc_move_if_owned(rng)));\n\t\t\t\t}\n\n\t\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\t\tstatic constexpr decltype(std::optional(ReturnSubrange::pack_border(tc::begin(std::declval<Rng&>()), std::declval<Rng>()))) pack_no_border(Rng&&, OptEndIt&&...) noexcept {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnSubrange>\n\t\t\tstruct return_subrange_or_all final : ReturnSubrange {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\t\tstatic constexpr decltype(ReturnSubrange::pack_border(tc::begin(std::declval<Rng&>()), std::declval<Rng>())) pack_no_border(Rng&& rng, OptEndIt&&...) noexcept {\n\t\t\t\t\treturn tc_move_if_owned(rng);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Pack element as border before/after\n\n\t\t\ttemplate<typename ReturnBorder, bool bSupportsNoElement>\n\t\t\tstruct pack_as_border_base {\n\t\t\t\tstatic_assert( !ReturnBorder::allowed_if_always_has_border, \"Specify what to return in the no_element case. Use bSupportsNoElement=false to _ASSERT it does not occur.\" );\n\t\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\t\ttemplate<typename Rng>\n\t\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) noexcept code_return_decltype_allow_xvalue(\n\t\t\t\t\tif constexpr( !bSupportsNoElement ) _ASSERTFALSE;,\n\t\t\t\t\tReturnBorder::pack_no_border(tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnBorder, bool bSupportsNoElement = true>\n\t\t\tstruct pack_as_border_before : pack_as_border_base<ReturnBorder, bSupportsNoElement> {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr auto pack_element(It&& it, Rng&& rng, tc::unused /*ref*/={}) return_decltype_allow_xvalue_noexcept(\n\t\t\t\t\tReturnBorder::pack_border(tc_move_if_owned(it), tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr decltype(auto) pack_border(It it, Rng&& rng) noexcept(noexcept(--it)) {\n\t\t\t\t\tif( tc::begin(rng) != it ) {\n\t\t\t\t\t\t--it;\n\t\t\t\t\t\treturn ReturnBorder::pack_border(tc_move(it), tc_move_if_owned(rng));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ReturnBorder::pack_no_border(tc_move_if_owned(rng));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\t\tstatic constexpr auto pack_view(Rng&& rng, Begin&& begin, End&& end) return_decltype_allow_xvalue_noexcept(\n\t\t\t\t\tReturnBorder::pack_border(tc_move_if_owned(begin), tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnBorder, bool bSupportsNoElement = true>\n\t\t\tstruct pack_as_border_after : pack_as_border_base<ReturnBorder, bSupportsNoElement> {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr auto pack_element(It it, Rng&& rng, tc::unused /*ref*/={}) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\t\t++it, // MAYTHROW\n\t\t\t\t\tReturnBorder::pack_border(tc_move(it), tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr decltype(auto) pack_border(It it, Rng&& rng) noexcept(noexcept(--it)) {\n\t\t\t\t\tif( tc::end(rng) != it ) {\n\t\t\t\t\t\t++it;\n\t\t\t\t\t\treturn ReturnBorder::pack_border(tc_move(it), tc_move_if_owned(rng));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ReturnBorder::pack_no_border(tc_move_if_owned(rng));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\t\tstatic constexpr auto pack_view(Rng&& rng, Begin&&, End&& end) return_decltype_allow_xvalue_noexcept(\n\t\t\t\t\tReturnBorder::pack_border(tc_move_if_owned(end), tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\t// Pack border as element before/after\n\n\t\t\ttemplate<typename ReturnElement>\n\t\t\tstruct pack_as_element_base {\n\t\t\t\tstatic constexpr bool allowed_if_always_has_border = true; // element before/after may not exist, even if we have a border.\n\t\t\t\tstatic_assert( ReturnElement::requires_iterator );\n\n\t\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\t\tstatic constexpr auto pack_no_border(Rng&& rng, OptEndIt&&...) return_decltype_noexcept(\n\t\t\t\t\tReturnElement::pack_no_element(tc_move_if_owned(rng))\n\t\t\t\t)\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnElement>\n\t\t\tstruct pack_as_element_before final : pack_as_element_base<ReturnElement> {\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr decltype(auto) pack_border(It&& it, Rng&& rng) noexcept(noexcept(--it)) {\n\t\t\t\t\tif( tc::begin(rng) != it ) {\n\t\t\t\t\t\t--it;\n\t\t\t\t\t\treturn ReturnElement::pack_element(tc_move_if_owned(it), tc_move_if_owned(rng));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ReturnElement::pack_no_element(tc_move_if_owned(rng));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttemplate<typename ReturnElement>\n\t\t\tstruct pack_as_element_after final : pack_as_element_base<ReturnElement> {\n\t\t\t\ttemplate<typename It, typename Rng>\n\t\t\t\tstatic constexpr decltype(auto) pack_border(It&& it, Rng&& rng) noexcept {\n\t\t\t\t\tif( tc::end(rng) != it ) {\n\t\t\t\t\t\treturn ReturnElement::pack_element(tc_move_if_owned(it), tc_move_if_owned(rng));\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ReturnElement::pack_no_element(tc_move_if_owned(rng));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\t/////////////////////////////////////\n\t\t// return void\n\n\t\tstruct return_void final {\n\t\t\tstatic constexpr bool requires_iterator = false;\n\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\n\t\t\tstatic constexpr void pack_border(tc::unused /*it*/, tc::unused /*rng*/) noexcept {}\n\t\t\tstatic constexpr void pack_no_border(tc::unused /*rng*/) noexcept {}\n\t\t\tstatic constexpr void pack_no_border(tc::unused /*rng*/, tc::unused /*itEnd*/) noexcept {}\n\t\t\tstatic constexpr void pack_element(tc::unused /*it*/, tc::unused /*rng*/) noexcept {}\n\t\t\tstatic constexpr void pack_element(tc::unused /*it*/, tc::unused /*rng*/, tc::unused /*ref*/) noexcept {}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr void pack_element(tc::unused /*ref*/) noexcept {}\n\t\t\tstatic constexpr void pack_no_element(tc::unused) noexcept {}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr void pack_no_element() noexcept {}\n\t\t\tstatic constexpr void pack_view(tc::unused /*rng*/, tc::unused /*itBegin*/, tc::unused /*itEnd*/) noexcept {}\n\t\t};\n\n\t\t/////////////////////////////////////\n\t\t// return bool\n\n\t\tstruct return_bool {\n\t\t\tstatic constexpr bool requires_iterator = false;\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\tstatic constexpr bool pack_border(tc::unused /*it*/, tc::unused /*rng*/) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tstatic constexpr bool pack_no_border(tc::unused /*rng*/) noexcept {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tstatic constexpr bool pack_no_border(tc::unused /*rng*/, tc::unused /*itEnd*/) noexcept {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tstatic constexpr bool pack_element(tc::unused /*it*/, tc::unused /*rng*/) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tstatic constexpr bool pack_element(tc::unused /*it*/, tc::unused /*rng*/, tc::unused /*ref*/) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr bool pack_element(tc::unused /*ref*/) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tstatic constexpr bool pack_no_element(tc::unused) noexcept {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr bool pack_no_element() noexcept {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tstatic constexpr bool pack_view(tc::unused /*rng*/, tc::unused /*itBegin*/, tc::unused /*itEnd*/) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t};\n\n\t\t/////////////////////////////////////\n\t\t// controlling bound return\n\n\t\t// returning bound\n\n\t\tstruct return_border {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\n\t\t\ttemplate<typename It>\n\t\t\tstatic constexpr tc::decay_t<It> pack_border(It&& it, tc::unused /*rng*/) noexcept {\n\t\t\t\treturn tc_move_if_owned(it);\n\t\t\t}\n\n\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\tstatic auto pack_no_border(Rng&& rng, OptEndIt&&...) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::begin(rng);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_border_or_begin final : return_border {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng, OptEndIt&&...) noexcept {\n\t\t\t\treturn tc::begin(rng);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_border_or_end final : return_border {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng) noexcept {\n\t\t\t\treturn tc::end(rng);\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng, tc::iterator_t<Rng>&& itEnd) noexcept {\n\t\t\t\treturn tc_move(itEnd);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_border_or_null final {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr auto pack_border(It&& it, Rng&&) noexcept {\n\t\t\t\treturn tc::border_t<tc::decay_t<It>>(tc_move_if_owned(it));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\tstatic constexpr auto pack_no_border(Rng&&, OptEndIt&&...) noexcept {\n\t\t\t\treturn tc::border_t<tc::decay_t<decltype(tc::begin(std::declval<Rng&>()))>>{};\n\t\t\t}\n\t\t};\n\n\t\tstruct return_border_index final {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = true;\n\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr auto pack_border(It&& it, Rng&& rng) noexcept {\n\t\t\t\treturn tc::make_size_proxy(it - tc::begin(rng));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\tstatic auto pack_no_border(Rng&&, OptEndIt&&...) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(0);\n\t\t\t}\n\t\t};\n\n\t\t// returning range\n\n\t\tstruct return_take_or_empty : return_detail::no_adl::return_take_base {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\ttemplate<typename Rng, typename... OptEndIt>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng, OptEndIt&&...) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\ttc::take(tc_move_if_owned(rng), tc::begin(rng))\n\t\t\t)\n\t\t};\n\n\t\tstruct return_drop_or_empty : return_detail::no_adl::return_drop_base {\n\t\t\tstatic constexpr bool allowed_if_always_has_border = false;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\ttc::drop(tc_move_if_owned(rng), tc::end(rng))\n\t\t\t)\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_border(Rng&& rng, tc::iterator_t<Rng>&& itEnd) return_decltype_allow_xvalue_MAYTHROW(\n\t\t\t\ttc::drop(tc_move_if_owned(rng), tc_move(itEnd))\n\t\t\t)\n\t\t};\n\n\t\t/////////////////////////////////////\n\t\t// controlling element return\n\n\t\t// returning element\n\n\t\tstruct return_element {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename It>\n\t\t\tstatic constexpr tc::decay_t<It> pack_element(It&& it, tc::unused /*rng*/, tc::unused /*ref*/={}) noexcept {\n\t\t\t\treturn tc_move_if_owned(it);\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic auto pack_no_element(Rng&& rng) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::begin(rng);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_or_null final {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename It>\n\t\t\tstatic constexpr auto pack_element(It&& it, tc::unused /*rng*/, tc::unused /*ref*/={}) noexcept {\n\t\t\t\treturn tc::make_element(tc_move_if_owned(it));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn tc::element_t<tc::decay_t<decltype(tc::begin(std::declval<Rng&>()))>>{}; // value initialization to initialize pointers to nullptr\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_or_front final : return_element {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) noexcept {\n\t\t\t\treturn tc::begin(rng);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_or_back final : return_element {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) noexcept {\n\t\t\t\treturn tc::end_prev<tc::return_border>(tc_move_if_owned(rng));\n\t\t\t}\n\t\t};\n\n\t\tstruct return_value {\n\t\t\tstatic constexpr bool requires_iterator = false;\n\n\t\t\t// Don't take it by value, or ref may be invalidated\n\t\t\ttemplate<typename Rng, typename Ref>\n\t\t\tstatic constexpr tc::range_value_t<Rng> pack_element(tc::unused /*it*/, Rng&&, Ref&& ref) noexcept {\n\t\t\t\treturn tc_move_if_owned(ref);\n\t\t\t}\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr tc::range_value_t<Rng> pack_element(It&& it, Rng&&) noexcept {\n\t\t\t\treturn *tc_move_if_owned(it);\n\t\t\t}\n\t\t\ttemplate<typename Rng, typename Ref>\n\t\t\tstatic constexpr tc::range_value_t<Rng> pack_element(Ref&& ref) noexcept {\n\t\t\t\treturn tc_move_if_owned(ref);\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic auto pack_no_element(Rng&&) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::construct_default_or_terminate<tc::range_value_t<Rng>>();\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic auto pack_no_element() noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::construct_default_or_terminate<tc::range_value_t<Rng>>();\n\t\t\t}\n\t\t};\n\n\t\tstruct return_value_or_default final : return_value {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr tc::range_value_t<Rng> pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn {};\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr tc::range_value_t<Rng> pack_no_element() noexcept {\n\t\t\t\treturn {};\n\t\t\t}\n\t\t};\n\n\t\tstruct return_value_or_none final {\n\t\t\tstatic constexpr bool requires_iterator = false;\n\n\t\t\t// Don't take it by value, or ref may be invalidated\n\t\t\ttemplate<typename Rng, typename Ref>\n\t\t\tstatic constexpr std::optional<tc::range_value_t<Rng>> pack_element(tc::unused /*it*/, Rng&&, Ref&& ref) noexcept {\n\t\t\t\treturn tc_move_if_owned(ref);\n\t\t\t}\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr std::optional<tc::range_value_t<Rng>> pack_element(It&& it, Rng&&) noexcept {\n\t\t\t\treturn *tc_move_if_owned(it);\n\t\t\t}\n\t\t\ttemplate<typename Rng, typename Ref>\n\t\t\tstatic constexpr std::optional<tc::range_value_t<Rng>> pack_element(Ref&& ref) noexcept {\n\t\t\t\treturn tc_move_if_owned(ref);\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr std::optional<tc::range_value_t<Rng>> pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr std::optional<tc::range_value_t<Rng>> pack_no_element() noexcept {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t};\n\n\t\tstruct return_reference_or_none final {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tusing optional_t = tc::optional<std::iter_reference_t<tc::iterator_t<Rng>>>; // may be optional value\n\n\t\t\ttemplate<typename It, typename Rng, typename Ref>\n\t\t\tstatic constexpr optional_t<Rng> pack_element(It&&, Rng&&, Ref&& ref) noexcept {\n\t\t\t\tstatic_assert(!tc::is_stashing_element<std::remove_cvref_t<It>>::value);\n\t\t\t\treturn tc_move_if_owned(ref);\n\t\t\t}\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr optional_t<Rng> pack_element(It&& it, Rng&&) noexcept {\n\t\t\t\tstatic_assert(!tc::is_stashing_element<std::remove_cvref_t<It>>::value);\n\t\t\t\treturn *tc_move_if_owned(it);\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr optional_t<Rng> pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_index {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr auto pack_element(It&& it, Rng&& rng, tc::unused /*ref*/={}) noexcept {\n\t\t\t\treturn tc::make_size_proxy(it - tc::begin(rng));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic auto pack_no_element(Rng&&) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(0);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_index_or_none final {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr auto pack_element(It&& it, Rng&& rng, tc::unused /*ref*/={}) noexcept {\n\t\t\t\treturn std::optional(tc::make_size_proxy(it - tc::begin(rng)));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr decltype(std::optional(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))) pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_index_or_npos final : return_element_index {\n\t\t\t// Note: prefer return_element_index_or_none\n\t\t\t// static_cast<int>(npos) must be -1. Anything else is error-prone. So use range_difference instead of range_size.\n\t\t\t// Alternatively, we could return a special type that casts npos to -1.\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(-1);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_element_index_or_size final : return_element_index {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) noexcept {\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(tc::size(rng));\n\t\t\t}\n\t\t};\n\n\t\tstruct return_singleton_range {\n\t\t\tstatic constexpr bool requires_iterator = true;\n\n\t\t\ttemplate<typename It, typename Rng>\n\t\t\tstatic constexpr decltype(auto) pack_element(It&& it, Rng&& rng, tc::unused /*ref*/={}) noexcept(noexcept(++tc::as_lvalue(tc::decay_copy(it)))) {\n\t\t\t\treturn tc::slice(tc_move_if_owned(rng), it, tc_modified(it, ++_));\n\t\t\t}\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic decltype(auto) pack_no_element(Rng&& rng) noexcept {\n\t\t\t\t// safe choice is empty because result may be empty\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::return_detail::empty_slice(tc_move_if_owned(rng));\n\t\t\t}\n\t\t};\n\n\t\tstruct return_singleton_range_or_empty final : return_singleton_range {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) return_decltype_noexcept(\n\t\t\t\ttc::return_detail::empty_slice(tc_move_if_owned(rng))\n\t\t\t)\n\t\t};\n\n\t\t/////////////////////////////////////\n\t\t// controlling view return\n\n\t\tstruct return_view {\n\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\tstatic constexpr auto pack_view(Rng&& rng, Begin&& begin, End&& end) return_decltype_noexcept(\n\t\t\t\ttc::slice(tc_move_if_owned(rng), tc_move_if_owned(begin), tc_move_if_owned(end))\n\t\t\t)\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic decltype(auto) pack_no_element(Rng&& rng) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn tc::slice(tc_move_if_owned(rng), tc::begin(rng), tc::end(rng));\n\t\t\t}\n\t\t};\n\n\t\tstruct return_view_or_none final {\n\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\tstatic constexpr auto pack_view(Rng&& rng, Begin&& begin, End&& end) noexcept {\n\t\t\t\treturn std::optional(return_view::pack_view(tc_move_if_owned(rng), tc_move_if_owned(begin), tc_move_if_owned(end)));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic decltype(std::optional(return_view::pack_no_element(std::declval<Rng>()))) pack_no_element(Rng&&) noexcept {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\t\t};\n\n\t\tstruct return_view_or_empty final : return_view {\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic constexpr auto pack_no_element(Rng&& rng) return_decltype_noexcept(\n\t\t\t\ttc::return_detail::empty_slice(tc_move_if_owned(rng))\n\t\t\t)\n\t\t};\n\n\t\tstruct return_begin_index final {\n\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\tstatic constexpr decltype(auto) pack_view(Rng&& rng, Begin&& begin, End&& end) noexcept {\n\t\t\t\treturn tc::make_size_proxy(begin - tc::begin(rng));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic decltype(auto) pack_no_element(Rng&& rng) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(0);\n\t\t\t}\n\t\t};\n\n\t\tstruct return_end_index final {\n\t\t\ttemplate<typename Rng, typename Begin, typename End>\n\t\t\tstatic constexpr decltype(auto) pack_view(Rng&& rng, Begin&& begin, End&& end) noexcept {\n\t\t\t\treturn tc::make_size_proxy(end - tc::begin(rng));\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tstatic decltype(auto) pack_no_element(Rng&& rng) noexcept {\n\t\t\t\t_ASSERTFALSE;\n\t\t\t\treturn decltype(tc::make_size_proxy(tc::begin(std::declval<Rng&>()) - tc::begin(std::declval<Rng&>())))(0);\n\t\t\t}\n\t\t};\n\t} // namespace no_adl\n\tusing no_adl::return_void;\n\tusing no_adl::return_bool;\n\n\t// return border\n\tusing no_adl::return_border;\n\tusing no_adl::return_border_or_begin;\n\tusing no_adl::return_border_or_end;\n\tusing no_adl::return_border_or_null;\n\tusing no_adl::return_border_index;\n\n\tusing no_adl::return_take_or_empty;\n\tusing return_take = return_detail::no_adl::return_subrange_or_assert<tc::return_take_or_empty>;\n\tusing return_take_or_none = return_detail::no_adl::return_subrange_or_none<return_detail::no_adl::return_take_base>;\n\tusing return_take_or_all = return_detail::no_adl::return_subrange_or_all<return_detail::no_adl::return_take_base>;\n\n\tusing no_adl::return_drop_or_empty;\n\tusing return_drop = return_detail::no_adl::return_subrange_or_assert<tc::return_drop_or_empty>;\n\tusing return_drop_or_none = return_detail::no_adl::return_subrange_or_none<return_detail::no_adl::return_drop_base>;\n\tusing return_drop_or_all = return_detail::no_adl::return_subrange_or_all<return_detail::no_adl::return_drop_base>;\n\n\t// return element\n\tusing no_adl::return_element;\n\tusing no_adl::return_element_or_null;\n\tusing no_adl::return_element_or_front;\n\tusing no_adl::return_element_or_back;\n\tusing no_adl::return_value;\n\tusing no_adl::return_value_or_default;\n\tusing no_adl::return_value_or_none;\n\tusing no_adl::return_reference_or_none;\n\tusing no_adl::return_element_index;\n\tusing no_adl::return_element_index_or_none;\n\tusing no_adl::return_element_index_or_npos;\n\tusing no_adl::return_element_index_or_size;\n\tusing no_adl::return_singleton_range;\n\tusing no_adl::return_singleton_range_or_empty;\n\n\ttemplate< tc::actual_integer T >\n\t[[nodiscard]] constexpr bool is_npos(T t) noexcept {\n\t\tif constexpr( std::is_signed<T>::value ) {\n\t\t\treturn -1 == t;\n\t\t} else {\n\t\t\treturn std::numeric_limits<T>::max() == t;\n\t\t}\n\t}\n\n\t// return border element\n\tusing return_element_before = return_detail::no_adl::pack_as_element_before<tc::return_element>;\n\tusing return_element_before_or_null = return_detail::no_adl::pack_as_element_before<tc::return_element_or_null>;\n\tusing return_element_before_or_front = return_detail::no_adl::pack_as_element_before<tc::return_element_or_front>;\n\tusing return_element_after = return_detail::no_adl::pack_as_element_after<tc::return_element>;\n\tusing return_element_after_or_null = return_detail::no_adl::pack_as_element_after<tc::return_element_or_null>;\n\tusing return_element_after_or_back = return_detail::no_adl::pack_as_element_after<tc::return_element_or_back>;\n\n\t// return element border\n\tusing return_border_after = return_detail::no_adl::pack_as_border_after<tc::return_border_or_end, false>;\n\tusing return_border_after_or_begin = return_detail::no_adl::pack_as_border_after<tc::return_border_or_begin>;\n\tusing return_border_before = return_detail::no_adl::pack_as_border_before<tc::return_border_or_begin, false>;\n\tusing return_border_before_or_end = return_detail::no_adl::pack_as_border_before<tc::return_border_or_end>;\n\n\t// return element border or border element\n\tusing return_border_before_or_begin = return_detail::no_adl::pack_as_border_before<tc::return_border_or_begin>;\n\tusing return_border_after_or_end = return_detail::no_adl::pack_as_border_after<tc::return_border_or_end>;\n\n\tusing return_take_before = return_detail::no_adl::pack_as_border_before<tc::return_take_or_empty, false>; // safe choice is empty because result may be empty\n\tusing return_take_before_or_empty = return_detail::no_adl::pack_as_border_before<tc::return_take_or_empty>;\n\tusing return_take_before_or_all = return_detail::no_adl::pack_as_border_before<tc::return_take_or_all>;\n\tusing return_take_before_or_none = return_detail::no_adl::pack_as_border_before<tc::return_take_or_none>;\n\tusing return_take_after = return_detail::no_adl::pack_as_border_after<tc::return_take_or_all, false>; // safe choice is all because result is never empty\n\tusing return_take_after_or_empty = return_detail::no_adl::pack_as_border_after<tc::return_take_or_empty>;\n\tusing return_take_after_or_all = return_detail::no_adl::pack_as_border_after<tc::return_take_or_all>;\n\tusing return_take_after_or_none = return_detail::no_adl::pack_as_border_after<tc::return_take_or_none>;\n\n\tusing return_drop_before = return_detail::no_adl::pack_as_border_before<tc::return_drop_or_all, false>; // safe choice is all because result is never empty\n\tusing return_drop_before_or_empty = return_detail::no_adl::pack_as_border_before<tc::return_drop_or_empty>;\n\tusing return_drop_before_or_all = return_detail::no_adl::pack_as_border_before<tc::return_drop_or_all>;\n\tusing return_drop_before_or_none = return_detail::no_adl::pack_as_border_before<tc::return_drop_or_none>;\n\tusing return_drop_after = return_detail::no_adl::pack_as_border_after<tc::return_drop_or_empty, false>; // safe choice is empty because result may be empty\n\tusing return_drop_after_or_empty = return_detail::no_adl::pack_as_border_after<tc::return_drop_or_empty>;\n\tusing return_drop_after_or_all = return_detail::no_adl::pack_as_border_after<tc::return_drop_or_all>;\n\tusing return_drop_after_or_none = return_detail::no_adl::pack_as_border_after<tc::return_drop_or_none>;\n\n\t// return view\n\tusing no_adl::return_view;\n\tusing no_adl::return_view_or_none;\n\tusing no_adl::return_view_or_empty;\n\tusing no_adl::return_begin_index;\n\tusing no_adl::return_end_index;\n}\n"
  },
  {
    "path": "tc/range/repeat_n.h",
    "content": "// \n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"iota_range.h\"\n\nnamespace tc {\n\t////////////////////////\n\t// repeat_range\n\n\tnamespace no_adl {\n\t\ttemplate <typename T>\n\t\tstruct [[nodiscard]] TC_EMPTY_BASES repeat_range : tc::iota_range_adaptor<repeat_range<T>, std::size_t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = repeat_range;\n\t\t\tstd::size_t m_ct;\n\t\t\ttc::reference_or_value< T > m_t;\n\t\tpublic:\n\t\t\tusing typename this_type::index_range_adaptor::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=false;\n\n\t\t\texplicit constexpr repeat_range(std::size_t ct, T&& t) noexcept\n\t\t\t\t: m_ct(ct)\n\t\t\t\t, m_t(aggregate_tag, tc_move_if_owned(t))\n\t\t\t{}\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr static, begin_index)() noexcept -> tc_index {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn m_ct;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(tc::unused /*idx*/) const& return_decltype_noexcept(\n\t\t\t\t*m_t\n\t\t\t)\n\t\t};\n\t}\n\tusing no_adl::repeat_range;\n\n\ttemplate<typename T>\n\tconstexpr auto enable_stable_index_on_move<repeat_range<T>> = true;\n\n\ttemplate<typename TSize, typename T>\n\tconstexpr auto repeat_n( TSize&& ct, T && t ) return_ctor_noexcept(\n\t\tno_adl::repeat_range<T>, ( tc::explicit_cast<std::size_t>(tc_move_if_owned(ct)), tc_move_if_owned(t) )\n\t)\n}\n"
  },
  {
    "path": "tc/range/reverse_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/modified.h\"\n#include \"../algorithm/size.h\"\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n#include \"subrange.h\"\n\nnamespace tc {\n\tnamespace reverse_adaptor_detail {\n\t\tnamespace for_each_reverse_default {\n\t\t\ttemplate<typename Rng, typename Sink>\n\t\t\tconstexpr auto for_each_reverse_impl(Rng&& rng, Sink const sink) MAYTHROW\n\t\t\t\t-> tc::common_type_t<decltype(tc::continue_if_not_break(sink, tc::dereference_index(std::declval<Rng&>(), tc::as_lvalue(tc::begin_index(std::declval<Rng&>()))))), tc::constant<tc::continue_>>\n\t\t\t{\n\t\t\t\tauto const idxBegin = tc::begin_index(rng);\n\t\t\t\tauto idxEnd = tc::end_index(rng);\n\t\t\t\twhile( idxBegin != idxEnd ) {\n\t\t\t\t\ttc::decrement_index(rng, idxEnd);\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc::dereference_index(rng, idxEnd)))\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t}\n\n\t\tDEFINE_TMPL_FUNC_WITH_CUSTOMIZATIONS(for_each_reverse)\n\n\t\tnamespace for_each_reverse_adl {\n\t\t\ttemplate<tc::tuple_like Tuple, typename Sink,\n\t\t\t\ttypename ReverseIndexList = tc::mp_integer_list<tc::make_reverse_integer_sequence<std::size_t, 0, std::tuple_size<std::remove_reference_t<Tuple>>::value>>\n\t\t\t\tTC_REQUIRES_CWG2369_WORKAROUND(!tc::range_with_iterators<Tuple>)\n\t\t\tconstexpr auto for_each_reverse_impl(adl_tag_t, Tuple&& tuple, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\t\tfor_each_detail::for_each_parameter_pack(ReverseIndexList(), for_each_detail::tuple_index_sink<Tuple, tc::decay_t<Sink>>{tc_move_if_owned(tuple), tc_move_if_owned(sink)})\n\t\t\t)\n\t\t}\n\t}\n\n\tnamespace reverse_adaptor_adl {\n\t\ttemplate<typename Rng, bool HasIterators = tc::range_with_iterators<Rng>>\n\t\tstruct reverse_adaptor;\n\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] reverse_adaptor<Rng, false> : tc::range_adaptor_base_range<Rng>, tc::range_output_from_base_range {\n\t\t\tusing tc::range_adaptor_base_range<Rng>::range_adaptor_base_range;\n\n\t\t\ttemplate<tc::decayed_derived_from<reverse_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) return_MAYTHROW(\n\t\t\t\treverse_adaptor_detail::for_each_reverse(tc_move_if_owned(self).base_range(), tc_move_if_owned(sink))\n\t\t\t)\n\n\t\t\ttemplate<tc::decayed_derived_from<reverse_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_reverse_impl(Self&& self, Sink&& sink) return_MAYTHROW(\n\t\t\t\ttc::for_each(tc_move_if_owned(self).base_range(), tc_move_if_owned(sink))\n\t\t\t)\n\n\t\t\tconstexpr auto size() const& MAYTHROW requires tc::has_size<Rng> {\n\t\t\t\treturn tc::compute_range_adaptor_size<tc::identity{}>(this->base_range());\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] reverse_adaptor<Rng, true>\n\t\t\t: reverse_adaptor<Rng, false>\n\t\t\t, tc::range_iterator_from_index<\n\t\t\t\treverse_adaptor<Rng>,\n\t\t\t\tstd::optional<\n\t\t\t\t\ttc::index_t<std::remove_reference_t<\n\t\t\t\t\t\tRng\n\t\t\t\t\t>>\n\t\t\t\t>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = reverse_adaptor;\n\n\t\t\tstatic_assert(tc::has_decrement_index<std::remove_reference_t<Rng>>, \"Base range must have bidirectional traversal or it cannot be reversed\");\n\n\t\tpublic:\n\t\t\tusing typename reverse_adaptor::range_iterator_from_index::tc_index;\n\t\t\tusing reverse_adaptor<Rng, false>::reverse_adaptor;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL(begin_index)() const& noexcept -> tc_index {\n\t\t\t\tauto idx = this->base_end_index();\n\t\t\t\tif( this->base_begin_index() == idx ) {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t} else {\n\t\t\t\t\ttc::decrement_index(this->base_range(),idx);\n\t\t\t\t\treturn idx;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn !tc::explicit_cast<bool>(idx);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\tif (this->base_begin_index() == *idx) {\n\t\t\t\t\tidx = std::nullopt;\n\t\t\t\t} else {\n\t\t\t\t\ttc::decrement_index(this->base_range(),*idx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(decrement_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\tif (idx) {\n\t\t\t\t\ttc::increment_index(this->base_range(),*idx);\n\t\t\t\t} else {\n\t\t\t\t\tidx = this->base_begin_index();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto) { // return_decltype_MAYTHROW causes ICE on MSVC 19.39\n\t\t\t\treturn tc::dereference_index(this->base_range(), *tc_move_if_owned(idx));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(dereference_index)(auto&& idx) & MAYTHROW -> decltype(auto) { // return_decltype_MAYTHROW causes ICE on MSVC 19.39\n\t\t\t\treturn tc::dereference_index(this->base_range(), *tc_move_if_owned(idx));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& noexcept\n\t\t\t\trequires tc::has_distance_to_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\treturn tc_modified(\n\t\t\t\t\ttc::distance_to_index(this->base_range(), idxRhs ? *idxRhs : this->base_begin_index(), idxLhs ? *idxLhs : this->base_begin_index()),\n\t\t\t\t\tif(!idxRhs) ++_;\n\t\t\t\t\tif(!idxLhs) --_;\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(advance_index)(tc_index& idx, typename boost::range_difference<Rng>::type d) const& noexcept -> void\n\t\t\t\trequires\n\t\t\t\t\ttc::has_advance_index<std::remove_reference_t<Rng>> &&\n\t\t\t\t\ttc::has_decrement_index<std::remove_reference_t<Rng>> &&\n\t\t\t\t\ttc::is_equality_comparable<tc_index>::value\n\t\t\t{\n\t\t\t\tusing difference_type = typename boost::range_difference<Rng>::type;\n\t\t\t\tif (idx) {\n\t\t\t\t\ttc::advance_index(this->base_range(),*idx, tc::explicit_cast<difference_type>(-(d-1)));\n\t\t\t\t\tif (this->base_begin_index() == *idx) {\n\t\t\t\t\t\tidx = std::nullopt;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttc::decrement_index(this->base_range(),*idx);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (0 != d) {\n\t\t\t\t\t\t_ASSERT(d < 0);\n\t\t\t\t\t\tidx = this->base_begin_index();\n\t\t\t\t\t\ttc::advance_index(this->base_range(),*idx, tc::explicit_cast<difference_type>(-(d+1)));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tpublic:\n\t\t\tauto border_base_index(tc_index const& idx) const& noexcept {\n\t\t\t\treturn idx ? tc_modified(*idx, tc::increment_index(this->base_range(),_)) : this->base_begin_index();\n\t\t\t}\n\n\t\t\tauto element_base_index(tc_index const& idx) const& noexcept {\n\t\t\t\t_ASSERT(!this->at_end_index(idx));\n\t\t\t\treturn *idx;\n\t\t\t}\n\t\tprivate:\n\t\t\tSTATIC_FINAL(middle_point)(tc_index & idx, tc_index const& idxEnd ) const& noexcept -> void requires tc::has_middle_point<Rng> {\n\t\t\t\tauto idxBeginBase = border_base_index(idxEnd);\n\t\t\t\ttc::middle_point(this->base_range(), idxBeginBase, border_base_index(idx));\n\t\t\t\tidx = idxBeginBase;\n\t\t\t}\n\t\tpublic:\n\t\t\ttemplate <typename It>\n\t\t\tvoid take_inplace(It&& it) & noexcept {\n\t\t\t\ttc::drop_inplace(this->base_range(), it.border_base());\n\t\t\t}\n\n\t\t\ttemplate <typename It>\n\t\t\tvoid drop_inplace(It&& it) & noexcept {\n\t\t\t\ttc::take_inplace(this->base_range(), it.border_base());\n\t\t\t}\n\t\t};\n\t}\n\tusing reverse_adaptor_adl::reverse_adaptor;\n\n\ttemplate<typename Rng>\n\tconstexpr auto reverse(Rng&& rng) return_ctor_noexcept(\n\t\ttc::reverse_adaptor< Rng >,\n\t\t(aggregate_tag, tc_move_if_owned(rng))\n\t)\n\t\n\ttemplate<typename Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::reverse_adaptor<Rng, true>> = tc::stable_index_on_move<Rng>;\n\n\tnamespace generator_range_adl {\n\t\ttemplate<typename Self, typename Sink, typename std::remove_reference_t<Self>::is_generator_range_adaptor* = nullptr>\n\t\tconstexpr auto for_each_reverse_impl(Self&& self, Sink&& sink) return_decltype_MAYTHROW(\n\t\t\ttc::for_each(\n\t\t\t\ttc::reverse(tc_move_if_owned(self).base_range()),\n\t\t\t\ttc_move_if_owned(self).adapted_sink(tc_move_if_owned(sink), /*bReverse*/tc::constant<true>())\n\t\t\t)\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "tc/range/reverse_adaptor.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/algorithm.h\"\n#include \"reverse_adaptor.h\"\n\n#include <list>\n\nUNITTESTDEF(tc_reverse_random_access) {\n\tTEST_RANGE_EQUAL(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)), tc::reverse(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 3,2,1))));\n\n\t// test iterators:\n\tauto rng = tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3));\n\tauto revrng = tc::reverse(rng);\n\tauto it = tc::begin(revrng);\n\t_ASSERTEQUAL(*it++, 3);\n\t_ASSERTEQUAL(*it++, 2);\n\t_ASSERTEQUAL(*it++, 1);\n\t_ASSERTEQUAL(tc::end(revrng), it);\n\n\t--it;\n\t_ASSERTEQUAL(*it,1);\n\n\t// Test random access\n\tit -= 2;\n\t_ASSERTEQUAL(*it,3);\n\n\tit += 3;\n\t_ASSERTEQUAL(tc::end(revrng), it);\n}\n\n#include <numeric>\n\nUNITTESTDEF(tc_reverse_binary_search) {\n\ttc::vector<int> vecn(64);\n\tstd::iota(tc::begin(vecn), tc::end(vecn), 0);\n\n\t// random access:\n\t_ASSERT(tc::binary_find_unique<tc::return_bool>(tc::reverse(vecn),32, tc::fn_greater()));\n\n\t// bidirectional:\n\t_ASSERT(\n\t\ttc::binary_find_unique<tc::return_bool>(\n\t\t\ttc::reverse(\n\t\t\t\ttc::filter(vecn,[](auto) noexcept {return true;})\n\t\t\t),\n\t\t\t32,\n\t\t\ttc::fn_greater()\n\t\t)\n\t);\n}\n\nUNITTESTDEF(tc_reverse_bidirectional) {\n\tstd::list<int> rng{1,2,3};\n\tauto rngrev = tc::reverse(rng);\n\tauto it = tc::begin(rngrev);\n\t_ASSERTEQUAL(*it++, 3);\n\t_ASSERTEQUAL(*it++, 2);\n\t_ASSERTEQUAL(*it++, 1);\n\t_ASSERTEQUAL(tc::end(rngrev), it);\n\n\tTEST_RANGE_EQUAL(tc::reverse(rng), tc_as_constexpr(tc::make_array(tc::aggregate_tag, 3,2,1)));\n\tTEST_RANGE_EQUAL(tc::reverse(tc::reverse(rng)), rng);\n}\n\nUNITTESTDEF(tc_reverse_base_bound) {\n\tstd::list<int> rng{1,2,3,4};\n\tauto rngreverse = tc::reverse(rng);\n\tauto it = tc_modified(tc_modified(tc::begin(rngreverse), ++_), ++_);\n\tTEST_RANGE_EQUAL(\n\t\ttc::reverse(tc::take(rngreverse,it)),\n\t\ttc::drop(rng, it.border_base())\n\t);\n\n\t_ASSERTEQUAL(*it,*it.element_base());\n}\n\nUNITTESTDEF(tc_reverse_drop_first_last_inplace) {\n\ttc::vector<int> vecn{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };\n\tauto&& rngnReverse = tc::reverse(tc::all(vecn));\n\n\ttc::drop_first_inplace(rngnReverse, 0);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}));\n\n\ttc::drop_first_inplace(rngnReverse, 1);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{8, 7, 6, 5, 4, 3, 2, 1, 0}));\n\n\ttc::drop_first_inplace(rngnReverse, 2);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{6, 5, 4, 3, 2, 1, 0}));\n\n\ttc::drop_last_inplace(rngnReverse, 0);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{6, 5, 4, 3, 2, 1, 0}));\n\n\ttc::drop_last_inplace(rngnReverse, 1);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{6, 5, 4, 3, 2, 1}));\n\n\ttc::drop_last_inplace(rngnReverse, 2);\n\tTEST_RANGE_EQUAL(rngnReverse, (tc::vector<int>{6, 5, 4, 3}));\n}\n"
  },
  {
    "path": "tc/range/sparse_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../algorithm/compare.h\"\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n#include \"repeat_n.h\"\n\n\nnamespace tc {\n\n\tnamespace no_adl {\n\t\ttemplate<typename Sink, typename TValue>\n\t\tstruct sparse_adaptor_sink { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tSink const m_sink;\n\t\t\tstd::size_t const m_nEnd;\n\t\t\tTValue const m_default;\n\t\t\tstd::size_t m_n=0;\n\n\t\t\tauto GenerateDefaultUpTo(std::size_t const nEnd) & MAYTHROW {\n\t\t\t\t_ASSERT( m_n <= nEnd );\n\t\t\t\tauto const bc=tc::for_each(tc::repeat_n(nEnd - m_n, m_default), m_sink); // MAYTHROW\n\t\t\t\tm_n = nEnd;\n\t\t\t\treturn bc;\n\t\t\t}\n\n\t\t\tauto operator()(std::size_t const nIndex, auto&& value) & MAYTHROW {\n\t\t\t\ttc_return_if_break(GenerateDefaultUpTo(nIndex)); // MAYTHROW\n\t\t\t\t++m_n;\n\t\t\t\treturn tc::continue_if_not_break(m_sink, tc_move_if_owned(value)); // MAYTHROW\n\t\t\t}\n\t\t};\n\n\t\ttemplate<\n\t\t\ttypename RngPairIndexValue,\n\t\t\ttypename TValue,\n\t\t\tbool HasIterator = tc::range_with_iterators< RngPairIndexValue >\n\t\t>\n\t\tstruct [[nodiscard]] sparse_adaptor;\n\n\t\ttemplate<\n\t\t\ttypename RngPairIndexValue,\n\t\t\ttypename TValue\n\t\t>\n\t\tstruct [[nodiscard]] sparse_adaptor<RngPairIndexValue, TValue, false> : tc::range_adaptor_base_range<RngPairIndexValue> {\n\t\tprotected:\n\t\t\tstd::size_t m_nEnd;\n\t\t\ttc::reference_or_value<TValue> m_default;\n\n\t\tpublic:\n\t\t\ttemplate<typename Rhs, typename RHSValue>\n\t\t\texplicit sparse_adaptor(Rhs&& rngpairIndexValue, std::size_t nEnd, RHSValue&& defaultValue) noexcept\n\t\t\t\t: tc::range_adaptor_base_range<RngPairIndexValue>(aggregate_tag, tc_move_if_owned(rngpairIndexValue))\n\t\t\t\t, m_nEnd(nEnd)\n\t\t\t\t, m_default(aggregate_tag, tc_move_if_owned(defaultValue))\n\t\t\t{}\n\n\t\t\tauto operator()(auto&& sink) const& MAYTHROW {\n\t\t\t\tsparse_adaptor_sink<tc::decay_t<decltype(sink)>, decltype(*m_default)> adaptedsink{tc_move_if_owned(sink), m_nEnd, *m_default};\n\t\t\t\ttc_return_if_break(tc::for_each(this->base_range(), std::ref(adaptedsink))); // MAYTHROW\n\t\t\t\treturn adaptedsink.GenerateDefaultUpTo(m_nEnd); // MAYTHROW\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Index>\n\t\tstruct sparse_adaptor_index {\n\t\t\tstd::size_t m_n;\n\t\t\tIndex m_idxBase;\n\n\t\t\tfriend bool operator==(sparse_adaptor_index const& lhs, sparse_adaptor_index const& rhs) noexcept {\n\t\t\t\treturn EQUAL_MEMBERS(m_n);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<\n\t\t\ttypename RngPairIndexValue,\n\t\t\ttypename TValue\n\t\t>\n\t\tstruct [[nodiscard]] sparse_adaptor<RngPairIndexValue, TValue, true> :\n\t\t\tsparse_adaptor<RngPairIndexValue, TValue, false>,\n\t\t\trange_iterator_from_index<\n\t\t\t\tsparse_adaptor<RngPairIndexValue, TValue>,\n\t\t\t\tsparse_adaptor_index<tc::index_t<std::remove_reference_t<RngPairIndexValue>>>\n\t\t\t>\n\t\t{\n\t\t\tusing typename sparse_adaptor::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<RngPairIndexValue>>::value;\n\n\t\t\ttemplate<typename RhsRngPairIndexValue, typename RHSValue>\n\t\t\texplicit sparse_adaptor(RhsRngPairIndexValue&& rngpairIndexValue, std::size_t nEnd, RHSValue&& defaultValue) noexcept :\n\t\t\t\tsparse_adaptor<RngPairIndexValue, TValue, false>(tc_move_if_owned(rngpairIndexValue), nEnd, tc_move_if_owned(defaultValue))\n\t\t\t{}\n\n\t\tprivate:\n\t\t\tusing this_type = sparse_adaptor;\n\t\t\tbool IndexIsDefault(tc_index const& idx) const& noexcept {\n\t\t\t\t_ASSERT(idx.m_n < this->m_nEnd);\n\t\t\t\treturn tc::at_end_index(this->base_range(),idx.m_idxBase) ||\n\t\t\t\t\tidx.m_n != tc::as_unsigned(tc::get<0>(tc::dereference_index(this->base_range(),idx.m_idxBase)));\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn {0, this->base_begin_index()};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn {this->m_nEnd, this->base_end_index()};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\tif (!IndexIsDefault(idx)) {\n\t\t\t\t\ttc::increment_index(this->base_range(),idx.m_idxBase);\n\t\t\t\t}\n\t\t\t\t++idx.m_n;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn idx.m_n == this->m_nEnd;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto) { // MSVC 19.39 gets confused when using return_decltype_MAYTHROW\n\t\t\t\treturn IndexIsDefault(idx)\n\t\t\t\t\t? *(this->m_default)\n\t\t\t\t\t: tc::get<1>(tc::dereference_index(this->base_range(), tc_move_if_owned(idx).m_idxBase));\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<\n\t\ttypename RngPairIndexValue,\n\t\ttypename TValue = typename std::tuple_element<1, tc::range_value_t<RngPairIndexValue>>::type\n\t>\n\tauto sparse_range(RngPairIndexValue&& rngpairindexvalue, std::size_t nsizerng, TValue&& valueDefault = TValue()) return_ctor_noexcept(\n\t\tTC_FWD(no_adl::sparse_adaptor< RngPairIndexValue, TValue >),\n\t\t(tc_move_if_owned(rngpairindexvalue), nsizerng, tc_move_if_owned(valueDefault))\n\t)\n}\n"
  },
  {
    "path": "tc/range/sparse_adaptor.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../array.h\"\n#include \"sparse_adaptor.h\"\n\nUNITTESTDEF(sparse_range) {\n\tbool const abVals[] = {true, false, false, true, false, false};\n\tauto const rngb = tc::sparse_range(tc::make_array(tc::aggregate_tag, std::make_pair(0u, true), std::make_pair(3u, true)), 6, false);\n\t_ASSERT(tc::equal(rngb, abVals));\n\tint iVal = 0;\n\ttc::for_each(rngb, [&](bool const b) noexcept { _ASSERTEQUAL(b, abVals[iVal++]); });\n}\n"
  },
  {
    "path": "tc/range/subrange.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/move.h\"\n#include \"../base/trivial_functors.h\"\n#include \"../base/modified.h\"\n#include \"../base/invoke.h\"\n#include \"../container/container_traits.h\"\n#include \"../algorithm/size.h\"\n#include \"../algorithm/size_linear.h\"\n#include \"../algorithm/size_bounded.h\"\n#include \"../base/change.h\"\n#include \"../base/rvalue_property.h\"\n#include \"../optional.h\"\n#include \"../storage_for.h\"\n#include \"../base/scope.h\"\n\n#include \"empty_range.h\"\n#include \"index_range.h\"\n#include \"meta.h\"\n#include \"range_adaptor.h\"\n\n#include <type_traits>\n#include <memory>\n#include <deque>\n\nnamespace tc {\n\tnamespace return_detail::no_adl {\n\t\ttemplate<typename ReturnSubrange>\n\t\tstruct return_subrange_or_assert;\n\t}\n\tnamespace no_adl {\n\t\tstruct return_border;\n\t\tstruct return_take_or_empty;\n\t\tstruct return_drop_or_empty;\n\t}\n\tusing no_adl::return_border;\n\tusing return_take = return_detail::no_adl::return_subrange_or_assert<no_adl::return_take_or_empty>;\n\tusing return_drop = return_detail::no_adl::return_subrange_or_assert<no_adl::return_drop_or_empty>;\n\n\tnamespace no_adl {\n\t\ttemplate<typename It>\n\t\tstruct universal_range;\n\t\ttemplate<typename Rng>\n\t\tstruct subrange;\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// ptr_iterator_t/ptr_begin/ptr_end\n#if !defined(_MSC_VER)\n\t// On libc++ and libstdc++, std::pointer_trait is broken.\n\t// E.g. on libc++, it is missing a specialization for std::__wrap_iter (aka std::vector::iterator).\n\ttemplate <tc::contiguous_range Rng>\n\tusing ptr_iterator_t = decltype(std::to_address(std::declval<tc::iterator_t<Rng>>()));\n#else\n\t// On MSVC, std::to_address isn't SFINAE friendly, so we have to use std::pointer_traits.\n\ttemplate <tc::contiguous_range Rng>\n\tusing ptr_iterator_t = typename std::pointer_traits<tc::iterator_t<Rng>>::element_type*;\n#endif\n\n\ttemplate<tc::contiguous_range Rng> requires tc::borrowed_range<Rng>\n\t[[nodiscard]] constexpr ptr_iterator_t<Rng> ptr_begin(Rng&& rng) noexcept {\n\t\treturn std::to_address(tc::begin(rng));\n\t}\n\n\ttemplate<tc::contiguous_range Rng> requires tc::borrowed_range<Rng>\n\t[[nodiscard]] constexpr ptr_iterator_t<Rng> ptr_end(Rng&& rng) noexcept {\n\t\tif constexpr (tc::common_range<Rng>) {\n\t\t\treturn std::to_address(tc::end(rng));\n\t\t} else {\n\t\t\treturn tc::ptr_begin(rng) + tc::size_linear_raw(rng);\n\t\t}\n\t}\n\t\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// subrange\n\n\tnamespace subrange_detail {\n\t\ttemplate<typename Rng>\n\t\tstatic constexpr decltype(auto) whole_range(Rng&& rng) noexcept {\n\t\t\tif constexpr( tc::instance<std::remove_reference_t<Rng>, no_adl::subrange> ) {\n\t\t\t\treturn tc_move_if_owned(rng).base_range();\n\t\t\t} else {\n\t\t\t\treturn tc_move_if_owned(rng);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<typename Rng>\n\t\tusing whole_range_t = tc::remove_rvalue_reference_t<decltype(subrange_detail::whole_range(std::declval<Rng>()))>;\n\n\t\t// It may not be tc::safely_constructible_from because of slicing (e.g. tc::iterator_t<std::vector (const)> on Windows, or tc::element_t)\n\t\ttemplate <typename TTarget, typename TSource> constexpr auto is_index_safely_constructible = std::is_constructible<TTarget, TSource>::value;\n\n\t\t// Unlike tc::safely_constructible_from, we want to prevent pointer slicing here, as we're dealing with arrays, not single values.\n\t\ttemplate<typename TTarget, typename TSource> constexpr auto is_ptr_safely_constructible = false;\n\t\ttemplate<typename T> constexpr auto is_ptr_safely_constructible<T*, T*> = true;\n\t\ttemplate<typename T> constexpr auto is_ptr_safely_constructible<T const*, T*> = true;\n\t\ttemplate<typename T> constexpr auto is_ptr_safely_constructible<T volatile*, T*> = true;\n\t\ttemplate<typename T> constexpr auto is_ptr_safely_constructible<T const volatile*, T*> = true;\n\n\t\t// When forwarding `Rhs` into `Rng`, do we first need to translate existing indices of `Rhs` because they might be invalidated?\n\t\ttemplate <typename Rng, typename Rhs>\n\t\tconstexpr auto require_index_translation = true;\n\t\ttemplate <typename Rng, typename Rhs>\n\t\t\trequires tc::borrowed_range<Rng>\n\t\tconstexpr auto require_index_translation<Rng, Rhs> = false; // Forwarding `Rhs` doesn't affect indices at all.\n\t\ttemplate <typename Rng, typename Rhs>\n\t\t\trequires (!tc::borrowed_range<Rng>) && tc::stable_index_on_move<Rng>\n\t\t\t\t&& (!std::is_lvalue_reference<Rhs>::value && !std::is_const<std::remove_reference_t<Rhs>>::value)\n\t\tconstexpr auto require_index_translation<Rng, Rhs> = false; // We perform a move but have a stable index.\n\n\t\tnamespace no_adl {\n\t\t\ttemplate <typename Rng>\n\t\t\tstruct get_index {\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto begin(Rhs& rng) return_decltype_MAYTHROW(tc::begin_index(rng));\n\t\t\t\ttemplate <typename BaseRng, typename Rhs>\n\t\t\t\tstatic constexpr auto begin(BaseRng&& baserng, Rhs&) return_decltype_MAYTHROW(tc::begin_index(baserng));\n\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto end(Rhs& rng) return_decltype_MAYTHROW(tc::end_index(rng));\n\t\t\t\ttemplate <typename BaseRng, typename Rhs>\n\t\t\t\tstatic constexpr auto end(BaseRng&& baserng, Rhs&) return_decltype_MAYTHROW(tc::end_index(baserng));\n\t\t\t};\n\n\t\t\ttemplate <typename It>\n\t\t\tstruct get_index<tc::no_adl::universal_range<It>> {\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto begin(Rhs& rng) return_decltype_MAYTHROW(tc::begin(rng));\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto begin(tc::no_adl::universal_range<It>, Rhs& rng) return_decltype_MAYTHROW(tc::begin(rng));\n\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto end(Rhs& rng) return_decltype_MAYTHROW(tc::end(rng));\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto end(tc::no_adl::universal_range<It>, Rhs& rng) return_decltype_MAYTHROW(tc::end(rng));\n\t\t\t};\n\n\t\t\ttemplate <typename T>\n\t\t\tstruct get_index<tc::no_adl::universal_range<T*>> {\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto begin(Rhs& rng) return_decltype_MAYTHROW(tc::ptr_begin(rng));\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto begin(tc::no_adl::universal_range<T*>, Rhs& rng) return_decltype_MAYTHROW(tc::ptr_begin(rng));\n\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto end(Rhs& rng) return_decltype_MAYTHROW(tc::ptr_end(rng));\n\t\t\t\ttemplate <typename Rhs>\n\t\t\t\tstatic constexpr auto end(tc::no_adl::universal_range<T*>, Rhs& rng) return_decltype_MAYTHROW(tc::ptr_end(rng));\n\t\t\t};\n\t\t}\n\t\tusing no_adl::get_index;\n\t}\n\n\tnamespace no_adl {\n\t\t// The universal range is the superset of all possible ranges build from iterator pairs It.\n\t\t// It is used as Rng type of subrange when the range isn't known.\n\t\ttemplate <typename It>\n\t\tstruct universal_range {\n\t\t\tconstexpr universal_range() noexcept = default;\n\n\t\t\ttemplate <tc::common_range Rhs> requires\n\t\t\t\t(!std::is_pointer<It>::value) &&\n\t\t\t\tsubrange_detail::is_index_safely_constructible<It, tc::iterator_t<Rhs>>\n\t\t\tconstexpr universal_range(Rhs&&) noexcept {}\n\n\t\t\ttemplate <tc::contiguous_range Rhs> requires\n\t\t\t\tstd::is_pointer<It>::value &&\n\t\t\t\tsubrange_detail::is_ptr_safely_constructible<It, tc::ptr_iterator_t<Rhs>>\n\t\t\tconstexpr universal_range(Rhs&&) noexcept {}\n\n\t\t\t// subrange constructors assume that \"universal_range constructible from Rhs\" <=> \"can call subrange_detail::get_index\".\n\t\t\t// Without deleting construction from non-ranges, this assumption breaks for tc_return_cast.\n\t\t\ttemplate <typename Rhs> requires (!tc::range_with_iterators<Rhs>)\n\t\t\tuniversal_range(Rhs&&) = delete;\n\n\t\t\ttemplate <typename It_ = It>\n\t\t\tconstexpr It begin() const& noexcept {\n\t\t\t\tstatic_assert(tc::dependent_false<It_>::value, \"universal_range::begin() does not exist\");\n\t\t\t\treturn std::declval<It>();\n\t\t\t}\n\t\t\ttemplate <typename It_ = It>\n\t\t\tconstexpr It end() const& noexcept {\n\t\t\t\tstatic_assert(tc::dependent_false<It_>::value, \"universal_range::end() does not exist\");\n\t\t\t\treturn std::declval<It>();\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate <typename It>\n\tconstexpr auto enable_borrowed_range<no_adl::universal_range<It>> = true;\n\n\tnamespace no_adl {\n\t\ttemplate< typename Rng >\n\t\tstruct subrange\n\t\t\t: tc::index_range_adaptor<subrange<Rng>, Rng, tc::index_range_adaptor_flags::inherit_behavior>\n\t\t\t// Disable compiler generated special member functions.\n\t\t\t// Implicit construction from another subrange of the same type may still be possible via the user-defined constructor below.\n\t\t\t, std::conditional_t<tc::borrowed_range<Rng>,\n\t\t\t\ttc::copyable,\n\t\t\t\tstd::conditional_t<tc::stable_index_on_move<Rng>,\n\t\t\t\t\ttc::noncopyable,\n\t\t\t\t\ttc::nonmovable\n\t\t\t\t>\n\t\t\t>\n\t\t{\n\t\t\tstatic_assert(!tc::instance<Rng, no_adl::subrange>, \"Don't write the type directly.\");\n\n\t\tprivate:\n\t\t\tusing this_type = subrange;\n\t\t\tusing base_ = typename subrange::index_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\n\t\tprivate:\n\t\t\ttc_index m_idxBegin;\n\t\t\ttc_index m_idxEnd;\n\n\t\tprivate:\n\t\t\tDEFINE_NESTED_TAG_TYPE(integer_tag)\n\t\t\tDEFINE_NESTED_TAG_TYPE(index_tag)\n\n\t\t\t// ctor from rng/numeric begin/numeric end\n\t\t\ttemplate<typename Rhs, typename N>\n\t\t\tconstexpr subrange(integer_tag_t, Rhs&& wholerng, N nFrom, N nTo) noexcept\n\t\t\t\t: subrange(tc_move_if_owned(wholerng))\n\t\t\t{\n\t\t\t\ttake_inplace(tc_modified(this->begin_index(), this->advance_index(_, nTo)));\n\t\t\t\tdrop_inplace(tc_modified(this->begin_index(), this->advance_index(_, nFrom)));\n\t\t\t}\n\n\t\t\t// ctor from baserng/begin/end (with translation)\n\t\t\ttemplate<typename Rhs, typename IndexBegin, typename IndexEnd> requires subrange_detail::require_index_translation<Rng, Rhs>\n\t\t\tconstexpr subrange(index_tag_t, Rhs&& wholerng, IndexBegin&& idxBegin, IndexEnd&& idxEnd) noexcept\n\t\t\t\t: subrange(integer_tag,\n\t\t\t\t\ttc_move_if_owned(wholerng),\n\t\t\t\t\ttc::distance_to_index(wholerng, tc::begin_index(wholerng), tc_move_if_owned(idxBegin)),\n\t\t\t\t\ttc::distance_to_index(wholerng, tc::begin_index(wholerng), tc_move_if_owned(idxEnd))\n\t\t\t\t)\n\t\t\t{}\n\t\t\t// ctor from baserng/begin/end (no index translation)\n\t\t\ttemplate<typename Rhs, typename IndexBegin, typename IndexEnd> requires (!subrange_detail::require_index_translation<Rng, Rhs>)\n\t\t\tconstexpr subrange(index_tag_t, Rhs&& wholerng, IndexBegin&& idxBegin, IndexEnd&& idxEnd) noexcept\n\t\t\t\t: base_(aggregate_tag, tc_move_if_owned(wholerng))\n\t\t\t\t, m_idxBegin(tc_move_if_owned(idxBegin))\n\t\t\t\t, m_idxEnd(tc_move_if_owned(idxEnd))\n\t\t\t{}\n\n\t\tpublic:\n\t\t\t// default ctor (for deferred initialization)\n\t\t\tconstexpr subrange() = default;\n\n\t\t\t// ctor from empty range\n\t\t\tconstexpr subrange(tc::empty_range) noexcept(std::is_nothrow_default_constructible<base_>::value) requires std::is_default_constructible<base_>::value\n\t\t\t\t: base_()\n\t\t\t\t, m_idxBegin()\n\t\t\t\t, m_idxEnd()\n\t\t\t{}\n\n\t\t\t// ctor from whole range\n\t\t\ttemplate<typename Rhs> requires\n\t\t\t\t(!tc::instance<std::remove_cvref_t<Rhs>, no_adl::subrange>) && (!tc::instance<std::remove_cvref_t<Rhs>, no_adl::universal_range>) && tc::safely_constructible_from<Rng, Rhs>\n\t\t\tconstexpr subrange(Rhs&& rng) noexcept(\n\t\t\t\tstd::is_nothrow_constructible<base_, aggregate_tag_t, Rhs>::value &&\n\t\t\t\tnoexcept(subrange_detail::get_index<Rng>::begin(rng)) &&\n\t\t\t\tnoexcept(subrange_detail::get_index<Rng>::end(rng))\n\t\t\t)\n\t\t\t\t: base_(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_idxBegin(subrange_detail::get_index<Rng>::begin(this->base_range_best_access(), rng))\n\t\t\t\t, m_idxEnd(subrange_detail::get_index<Rng>::end(this->base_range_best_access(), rng))\n\t\t\t{}\n\n\t\t\t// ctor from other subrange\n\t\t\ttemplate <typename Rhs> requires\n\t\t\t\ttc::instance<std::remove_cvref_t<Rhs>, no_adl::subrange> && tc::safely_constructible_from<Rng, subrange_detail::whole_range_t<Rhs>> &&\n\t\t\t\t// If Rhs is the same subrange, we must not have a copy constructor we could have used instead.\n\t\t\t\t(!std::same_as<std::remove_cvref_t<Rhs>, subrange> || !tc::borrowed_range<Rhs>) &&\n\t\t\t\t// If we require index translation, we must have a random access range.\n\t\t\t\t(!subrange_detail::require_index_translation<Rng, Rhs> || tc::random_access_range<Rng>)\n\t\t\tconstexpr subrange(Rhs&& rng) noexcept(noexcept(tc::begin_index(rng)) && noexcept(tc::end_index(rng)))\n\t\t\t\t: subrange(index_tag,\n\t\t\t\t\tsubrange_detail::whole_range(tc_move_if_owned(rng)),\n\t\t\t\t\tsubrange_detail::get_index<Rng>::begin(rng),\n\t\t\t\t\tsubrange_detail::get_index<Rng>::end(rng)\n\t\t\t\t)\n\t\t\t{}\n\n\t\t\t// ctor for tc::slice\n\t\t\ttemplate<typename Rhs, typename Begin, typename End> requires\n\t\t\t\ttc::safely_constructible_from<Rng, subrange_detail::whole_range_t<Rhs>> &&\n\t\t\t\tsubrange_detail::is_index_safely_constructible<tc_index, decltype(tc::iterator2index<Rhs>(std::declval<Begin>()))> &&\n\t\t\t\tsubrange_detail::is_index_safely_constructible<tc_index, decltype(tc::iterator2index<Rhs>(std::declval<End>()))>\n\t\t\tconstexpr explicit subrange(Rhs&& rng, Begin&& begin, End&& end) noexcept\n\t\t\t\t: subrange(index_tag,\n\t\t\t\t\tsubrange_detail::whole_range(tc_move_if_owned(rng)),\n\t\t\t\t\ttc::iterator2index<Rhs>(tc_move_if_owned(begin)),\n\t\t\t\t\ttc::iterator2index<Rhs>(tc_move_if_owned(end))\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tstatic_assert(!subrange_detail::require_index_translation<Rng, subrange_detail::whole_range_t<Rhs>> || tc::random_access_range<Rng>,\n\t\t\t\t\t\"We require index translation but do not have a random access range. Potential fixes: make Rng a random access range, specialize tc::enable_stable_index_on_move for Rng and move Rhs in, or specialize tc::enable_borrowed_range\");\n\t\t\t}\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn m_idxBegin;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index {\n\t\t\t\treturn m_idxEnd;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn idx == m_idxEnd;\n\t\t\t}\n\n\t\tpublic:\n\t\t\ttemplate< typename It >\n\t\t\tconstexpr void take_inplace( It&& it ) & noexcept {\n\t\t\t\tm_idxEnd=tc::iterator2index<Rng>( tc_move_if_owned(it) );\n\t\t\t}\n\n\t\t\ttemplate< typename It >\n\t\t\tconstexpr void drop_inplace( It&& it ) & noexcept {\n\t\t\t\tm_idxBegin=tc::iterator2index<Rng>( tc_move_if_owned(it) );\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\tconstexpr auto enable_stable_index_on_move<no_adl::subrange<Rng>> = tc::stable_index_on_move<Rng>;\n\ttemplate <typename Rng>\n\tconstexpr auto enable_borrowed_range<no_adl::subrange<Rng>> = tc::borrowed_range<Rng>;\n\n\ttemplate<typename Rng>\n\tusing subrange_arg_t = tc::mp_only<typename tc::is_instance<std::remove_reference_t<Rng>, no_adl::subrange>::arguments>;\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// subrange creation\n\ttemplate<tc::range_with_iterators Rng, typename Begin, typename End>\n\t[[nodiscard]] constexpr auto slice(Rng&& rng, Begin&& begin, End&& end) noexcept {\n\t\t// If we have a common borrowed range, we don't need to store rng.\n\t\t// However, if we have index iteratores, storing two index_iterators is worse then storing the reference + two indices.\n\t\tif constexpr (tc::borrowed_range<Rng> && tc::common_range<Rng> && !tc::is_index_iterator<tc::iterator_t<Rng>>) {\n\t\t\treturn no_adl::subrange<no_adl::universal_range<tc::iterator_t<Rng>>>(tc_move_if_owned(rng), tc_move_if_owned(begin), tc_move_if_owned(end));\n\t\t} else {\n\t\t\treturn no_adl::subrange<subrange_detail::whole_range_t<Rng>>(tc_move_if_owned(rng), tc_move_if_owned(begin), tc_move_if_owned(end));\n\t\t}\n\t}\n\ttemplate<typename Rng>\n\tusing slice_t = decltype(slice(std::declval<Rng>(), std::declval<tc::iterator_t<Rng>>(), std::declval<tc::iterator_t<Rng>>()));\n\n\ttemplate<tc::range_with_iterators Rng>\n\t[[nodiscard]] constexpr auto all(Rng&& rng) return_ctor_MAYTHROW(tc::slice_t<Rng>, (tc_move_if_owned(rng)))\n\n\ttemplate<typename It>\n\t[[nodiscard]] constexpr auto make_iterator_range(It itBegin, It itEnd) noexcept {\n\t\tif constexpr (tc::is_index_iterator<It>) {\n\t\t\tif constexpr (!tc::empty_type<std::remove_reference_t<decltype(itBegin.get_range())>>) {\n\t\t\t\t_ASSERTEQUAL(std::addressof(itBegin.get_range()), std::addressof(itEnd.get_range()));\n\t\t\t}\n\t\t\treturn slice(itBegin.get_range(), tc_move(itBegin).get_index(), tc_move(itEnd).get_index());\n\t\t} else {\n\t\t\treturn no_adl::subrange<no_adl::universal_range<It>>(no_adl::universal_range<It>(), tc_move(itBegin), tc_move(itEnd));\n\t\t}\n\t}\n\n\ttemplate<typename It>\n\tusing iterator_range = decltype(tc::make_iterator_range(std::declval<It>(), std::declval<It>()));\n\ttemplate<typename Rng>\n\t\trequires tc::safely_convertible_to<Rng&&, tc::iterator_range<tc::iterator_t<Rng>>>\n\tusing iterator_range_t = tc::iterator_range<tc::iterator_t<Rng>>;\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr auto make_empty_range() noexcept {\n\t\treturn tc::make_iterator_range(std::add_pointer_t<T>(), std::add_pointer_t<T>());\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// make counted range\n\n\ttemplate< typename It, typename Count >\n\t[[nodiscard]] constexpr auto counted( It const& it, Count&& count ) noexcept {\n\t\treturn tc::make_iterator_range( it, it+tc_move_if_owned(count) );\n\t}\n\n\ttemplate< tc::char_type T, std::size_t N >\n\t[[nodiscard]] constexpr auto as_array(T (&at)[N] ) return_decltype_noexcept(\n\t\ttc::counted( std::addressof(at[0]), N )\n\t)\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// take/drop\n\tnamespace detail {\n\t\ttemplate<typename Cont, typename It>\n\t\tconcept has_mem_fn_erase_from_begin = requires { std::declval<Cont&>().erase(tc::begin(std::declval<Cont&>()),std::declval<It&&>()); };\n\n\t\ttemplate<typename Cont, typename It>\n\t\tconcept has_mem_fn_take_inplace = requires { std::declval<Cont&>().take_inplace(std::declval<It&&>()); };\n\n\t\ttemplate<typename Cont, typename It>\n\t\tconcept has_mem_fn_drop_inplace = requires { std::declval<Cont&>().drop_inplace(std::declval<It&&>()); };\n\t}\n\n\ttemplate< typename Cont, typename It >\n\tconstexpr void take_inplace( Cont& cont, It&& it ) noexcept {\n\t\tif constexpr( detail::has_mem_fn_take_inplace<Cont,It> ) {\n\t\t\tcont.take_inplace(tc_move_if_owned(it));\n\t\t} else if constexpr( (tc::instance<Cont, std::vector> || tc::instance<Cont, std::deque>) && !std::is_move_assignable<tc::range_value_t<Cont&>>::value ) {\n\t\t\tif (tc::begin(cont) == it) {\n\t\t\t\tcont.clear();\n\t\t\t} else {\n\t\t\t\t--it;\n\t\t\t\twhile (tc_modified(tc::end(cont), --_) != it) {\n\t\t\t\t\tcont.pop_back();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tcont.erase(tc_move_if_owned(it),tc::end(cont));\n\t\t}\n\t}\n\n\ttemplate< typename Rng, typename End >\n\t[[nodiscard]] constexpr auto take(Rng&& rng, End&& end) return_ctor_NOEXCEPT( // boost::iterator_range doesn't have a noexcept constructor\n\t\ttc::slice_t<Rng>,\n\t\t(tc_move_if_owned(rng), tc::begin(rng), tc_move_if_owned(end))\n\t)\n\n\ttemplate< typename C, typename T, typename A, typename It >\n\t[[nodiscard]] std::basic_string<C,T,A> && take( std::basic_string<C,T,A>&& rng, It&& it ) noexcept {\n\t\ttc::take_inplace(rng,tc_move_if_owned(it));\n\t\treturn tc_move(rng);\n\t}\n\ttemplate< typename Rng, typename It >\n\t[[nodiscard]] constexpr no_adl::subrange<Rng>&& take( no_adl::subrange<Rng>&& rng, It&& it ) noexcept {\n\t\trng.take_inplace(tc_move_if_owned(it));\n\t\treturn tc_move(rng);\n\t}\n\n\ttemplate< typename Cont, typename It> requires detail::has_mem_fn_erase_from_begin<Cont,It>\n\tconstexpr void drop_inplace( Cont & cont, It&& it ) noexcept {\n\t\tcont.erase(tc::begin(cont),tc_move_if_owned(it));\n\t}\n\n\ttemplate< typename Cont, typename It> requires detail::has_mem_fn_drop_inplace<Cont,It>\n\tconstexpr void drop_inplace( Cont & cont, It&& it ) noexcept {\n\t\tcont.drop_inplace(tc_move_if_owned(it));\n\t}\n\n\ttemplate< tc::char_ptr CharPtr, typename It>\n\tconstexpr void drop_inplace( CharPtr& pch, It&& it ) noexcept {\n\t\tpch=tc_move_if_owned(it);\n\t}\n\n\tnamespace detail {\n\t\ttemplate< typename Rng, typename It>\n\t\tconstexpr auto drop_impl( Rng&& rng, It&& itBegin ) noexcept {\n\t\t\treturn tc::slice_t<Rng>( tc_move_if_owned(rng), tc_move_if_owned(itBegin), tc::end(rng) );\n\t\t}\n\n\t\t// C strings have efficient in-place drop\n\t\ttemplate< typename CharPtr, typename It> requires tc::char_ptr<std::remove_reference_t<CharPtr>>\n\t\tconstexpr std::decay_t<CharPtr> drop_impl( CharPtr&& pch, It&& it ) noexcept {\n\t\t\treturn tc_modified(pch, tc::drop_inplace(_, tc_move_if_owned(it)));\n\t\t}\n\t}\n\n\ttemplate< typename Rng, typename It >\n\t[[nodiscard]] constexpr auto drop(Rng&& rng, It&& it) return_decltype_NOEXCEPT(\n\t\tdetail::drop_impl( tc_move_if_owned(rng), tc_move_if_owned(it) )\n\t)\n\ttemplate< typename Rng, typename It >\n\t[[nodiscard]] constexpr no_adl::subrange<Rng>&& drop( no_adl::subrange<Rng>&& rng, It&& it ) noexcept {\n\t\trng.drop_inplace(tc_move_if_owned(it));\n\t\treturn tc_move(rng);\n\t}\n\n\t////////////////////////////////\n\t// begin_next/end_prev\n\n\tnamespace begin_next_detail {\n\t\ttemplate< typename RangeReturn, bool bLinear, typename Rng >\n\t\tconstexpr auto begin_next(\n\t\t\tRng&& rng,\n\t\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n,\n\t\t\tboost::iterators::forward_traversal_tag\n\t\t) noexcept {\n\t\t\t_ASSERTDEBUG(0 <= n);\n\t\t\tif constexpr(!bLinear) {\n\t\t\t\t_ASSERTENOTIFY(n <= 2);\n\t\t\t}\n\t\t\tauto it=tc::begin(rng);\n\t\t\tauto const itBound=tc::end(rng);\n\t\t\twhile (0<n) {\n\t\t\t\tif(it==itBound) {\n\t\t\t\t\treturn RangeReturn::pack_no_border(tc_move_if_owned(rng), tc_move(it));\n\t\t\t\t}\n\t\t\t\t--n;\n\t\t\t\t++it;\n\t\t\t}\n\t\t\treturn RangeReturn::pack_border(tc_move(it), tc_move_if_owned(rng));\n\t\t}\n\n\t\ttemplate< typename RangeReturn, bool bLinear, typename Rng >\n\t\tconstexpr auto begin_next(\n\t\t\tRng&& rng,\n\t\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n,\n\t\t\tboost::iterators::random_access_traversal_tag\n\t\t) noexcept {\n\t\t\t_ASSERTDEBUG(0<=n);\n\t\t\tif constexpr( tc::common_range<Rng> ) {\n\t\t\t\tif(n<=tc::size_raw(rng)) {\n\t\t\t\t\treturn RangeReturn::pack_border(tc::begin(rng)+n, tc_move_if_owned(rng));\n\t\t\t\t} else {\n\t\t\t\t\treturn RangeReturn::pack_no_border(tc_move_if_owned(rng));\n\t\t\t\t}\n\t\t\t} else if constexpr( RangeReturn::allowed_if_always_has_border ) {\n#ifdef _DEBUG\n\t\t\t\treturn begin_next_detail::begin_next<RangeReturn, /*bLinear*/true>(tc_move_if_owned(rng), n, boost::iterators::forward_traversal_tag());\n#else\n\t\t\t\treturn RangeReturn::pack_border(tc::begin(rng)+n, tc_move_if_owned(rng));\n#endif\n\t\t\t} else {\n\t\t\t\treturn begin_next_detail::begin_next<RangeReturn, bLinear>(tc_move_if_owned(rng), n, boost::iterators::forward_traversal_tag());\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, tc::range_with_iterators Rng>\n\t[[nodiscard]] constexpr auto begin_next(\n\t\tRng&& rng,\n\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n=1\n\t) noexcept {\n\t\treturn begin_next_detail::begin_next<RangeReturn, /*bLinear*/false>(tc_move_if_owned(rng), n, typename boost::range_traversal<Rng>::type());\n\t}\n\n\ttemplate< typename RangeReturn, tc::range_with_iterators Rng>\n\t[[nodiscard]] auto linear_begin_next(\n\t\tRng&& rng,\n\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n=1\n\t) noexcept {\n\t\treturn begin_next_detail::begin_next<RangeReturn, /*bLinear*/true>(tc_move_if_owned(rng), n, typename boost::range_traversal<Rng>::type());\n\t}\n\n\tnamespace end_prev_detail {\n\t\ttemplate< typename RangeReturn, typename Rng >\n\t\tconstexpr auto end_prev(\n\t\t\tRng&& rng,\n\t\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n,\n\t\t\tboost::iterators::bidirectional_traversal_tag\n\t\t) noexcept {\n\t\t\t_ASSERT(0 <= n);\n\t\t\t_ASSERTNOTIFY(n <= 2);\n\t\t\tauto it=tc::end(rng);\n\t\t\tauto const itBound=tc::begin(rng);\n\t\t\twhile (0<n) {\n\t\t\t\tif(it==itBound) {\n\t\t\t\t\treturn RangeReturn::pack_no_border(tc_move_if_owned(rng));\n\t\t\t\t}\n\t\t\t\t--n;\n\t\t\t\t--it;\n\t\t\t}\n\t\t\treturn RangeReturn::pack_border(it, tc_move_if_owned(rng));\n\t\t}\n\n\t\ttemplate< typename RangeReturn, typename Rng >\n\t\tconstexpr auto end_prev(\n\t\t\tRng&& rng,\n\t\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n,\n\t\t\tboost::iterators::random_access_traversal_tag\n\t\t) noexcept {\n\t\t\t_ASSERTDEBUG(0 <= n);\n\t\t\tif(n<=tc::size_raw(rng)) {\n\t\t\t\treturn RangeReturn::pack_border(tc::end(rng)-n, tc_move_if_owned(rng));\n\t\t\t} else {\n\t\t\t\treturn RangeReturn::pack_no_border(tc_move_if_owned(rng));\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate< typename RangeReturn, typename Rng >\n\t[[nodiscard]] constexpr auto end_prev(\n\t\tRng&& rng,\n\t\ttypename boost::range_size< std::remove_reference_t<Rng> >::type n=1\n\t) noexcept {\n\t\treturn end_prev_detail::end_prev<RangeReturn>(tc_move_if_owned(rng), n, typename boost::range_traversal<Rng>::type());\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////////////\n\t// take/drop_*_first/last_n\n\n\ttemplate< typename Cont >\n\tvoid take_first_inplace(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n=1) noexcept {\n\t\ttc::take_inplace(cont, tc::begin_next<tc::return_border>(cont,n));\n\t}\n\n\tnamespace take_first_detail {\n\t\tTC_DEFINE_ENUM(ETakePred, etakepred,\n\t\t\t(TAKEANDCONTINUE)\n\t\t\t(TAKEANDBREAK)\n\t\t\t(DONTTAKE)\n\t\t)\n\t\tnamespace no_adl {\n\t\t\ttemplate< typename Sink, typename TakePred >\n\t\t\tstruct take_first_sink /*final*/ {\n\t\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\t\tstatic_assert(tc::decayed<TakePred>);\n\n\t\t\t\ttemplate<typename Sink2>\n\t\t\t\ttake_first_sink(Sink2&& sink, TakePred& takepred, tc::break_or_continue& boc) noexcept\n\t\t\t\t\t: m_sink(tc_move_if_owned(sink))\n\t\t\t\t\t, m_takepred(takepred)\n\t\t\t\t\t, m_boc(boc)\n\t\t\t\t{}\n\n\t\t\t\ttemplate< typename T >\n\t\t\t\tauto operator()(T&& t) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\t\tdecltype(tc::continue_if_not_break(std::declval<Sink const&>(), std::declval<T>())),\n\t\t\t\t\ttc::constant<tc::break_>\n\t\t\t\t> {\n\t\t\t\t\tauto const Take=[&]() MAYTHROW { return tc::continue_if_not_break(m_sink, tc_move_if_owned(t)); };\n\t\t\t\t\tswitch_no_default(m_takepred.take(t)) {\n\t\t\t\t\t\tcase etakepredTAKEANDCONTINUE: {\n\t\t\t\t\t\t\tauto boc=Take(); // MAYTHROW\n\t\t\t\t\t\t\tm_boc=boc;\n\t\t\t\t\t\t\treturn boc; // allow return type to be tc::constant<tc::break_> if possible\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase etakepredTAKEANDBREAK:\n\t\t\t\t\t\t\tm_boc=Take(); // MAYTHROW\n\t\t\t\t\t\t\treturn tc::constant<tc::break_>();\n\t\t\t\t\t\tcase etakepredDONTTAKE:\n\t\t\t\t\t\t\tm_boc=tc::continue_;\n\t\t\t\t\t\t\treturn tc::constant<tc::break_>();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttemplate< typename Rng >\n\t\t\t\tauto chunk(Rng&& rng) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\t\tdecltype(tc::continue_if_not_break(tc::mem_fn_chunk(), std::declval<Sink const&>(), tc::take(std::declval<Rng>(), tc::begin(std::declval<Rng&>())))),\n\t\t\t\t\ttc::constant<tc::break_>\n\t\t\t\t> {\n\t\t\t\t\ttc_auto_cref(pairitetakepred, m_takepred.take_range(rng)); // MAYTHROW\n\t\t\t\t\tauto boc=tc::continue_if_not_break(tc::mem_fn_chunk(), m_sink, tc::take(tc_move_if_owned(rng), pairitetakepred.first)); // MAYTHROW\n\t\t\t\t\tm_boc=boc;\n\t\t\t\t\tswitch_no_default(pairitetakepred.second) {\n\t\t\t\t\t\tcase etakepredTAKEANDCONTINUE: return boc;\n\t\t\t\t\t\tcase etakepredTAKEANDBREAK: return tc::constant<tc::break_>();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tprivate:\n\t\t\t\tSink m_sink;\n\t\t\t\tTakePred& m_takepred;\n\t\t\t\ttc::break_or_continue& m_boc;\n\t\t\t};\n\n\t\t\tstruct take_first_pred {\n\t\t\t\texplicit take_first_pred(std::size_t nCount) noexcept\n\t\t\t\t\t: m_nCount(VERIFYPRED(nCount, 0<_))\n\t\t\t\t{}\n\n\t\t\t\tETakePred take(tc::unused) & noexcept {\n\t\t\t\t\t--VERIFYPRED(m_nCount, 0<_);\n\t\t\t\t\treturn may_continue();\n\t\t\t\t}\n\n\t\t\t\ttemplate<typename Rng>\n\t\t\t\tauto take_range(Rng /*const*/& rng) & MAYTHROW {\n\t\t\t\t\tauto it=tc::begin(rng); // MAYTHROW\n\t\t\t\t\tm_nCount-=tc::advance_forward_bounded(it, m_nCount, tc::end(rng)); // MAYTHROW\n\t\t\t\t\treturn std::make_pair(it, may_continue());\n\t\t\t\t}\n\n\t\t\tprotected:\n\t\t\t\tETakePred may_continue() const& noexcept {\n\t\t\t\t\treturn 0<m_nCount ? etakepredTAKEANDCONTINUE : etakepredTAKEANDBREAK;\n\t\t\t\t}\n\n\t\t\t\tstd::size_t m_nCount;\n\t\t\t};\n\t\t}\n\t}\n\n\tnamespace take_first_adaptor_adl {\n\t\ttemplate< typename TakePred, bool bTruncate, typename Rng >\n\t\tstruct take_first_adaptor : tc::range_adaptor_base_range<Rng>, tc::range_output_from_base_range {\n\t\t\ttake_first_adaptor(Rng&& rng, std::size_t const n) noexcept\n\t\t\t\t: take_first_adaptor::range_adaptor_base_range(aggregate_tag, tc_move_if_owned(rng)), m_n(n)\n\t\t\t{\n\t\t\t\tstatic_assert(!tc::range_with_iterators<Rng>);\n\t\t\t}\n\n\t\t\ttemplate<tc::decayed_derived_from<take_first_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tif(0<self.m_n) {\n\t\t\t\t\tTakePred takepred(self.m_n);\n\t\t\t\t\ttc::break_or_continue boc;\n\t\t\t\t\tif(tc::break_==tc::for_each(\n\t\t\t\t\t\ttc_move_if_owned(self).base_range(),\n\t\t\t\t\t\ttc::take_first_detail::no_adl::take_first_sink<tc::decay_t<decltype(sink)>, TakePred>(tc_move_if_owned(sink), takepred, boc)\n\t\t\t\t\t)) { // MAYTHROW\n\t\t\t\t\t\treturn VERIFYINITIALIZED(boc);\n\t\t\t\t\t} else { // boc won't be initialized if rng is empty\n\t\t\t\t\t\t_ASSERT(bTruncate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tc::continue_;\n\t\t\t}\n\t\tprivate:\n\t\t\tstd::size_t m_n;\n\t\t};\n\t}\n\n\ttemplate< std::same_as<tc::return_take> RangeReturn, typename Rng> requires (!tc::range_with_iterators<Rng>)\n\t[[nodiscard]] auto begin_next(Rng&& rng, std::size_t n=1) noexcept {\n\t\treturn tc::take_first_adaptor_adl::take_first_adaptor<take_first_detail::no_adl::take_first_pred, /*bTruncate*/ false, Rng>(tc_move_if_owned(rng), n);\n\t}\n\n\ttemplate< typename Cont >\n\tvoid drop_first_inplace(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n) noexcept {\n\t\ttc::drop_inplace(cont, tc::begin_next<tc::return_border>(cont, n));\n\t}\n\n\ttemplate< typename Cont >\n\tvoid drop_first_inplace(Cont& cont) noexcept {\n\t\tif constexpr( has_mem_fn_pop_front<Cont> ) {\n\t\t\tcont.pop_front();\n\t\t} else {\n\t\t\ttc::drop_inplace(cont, tc::begin_next<tc::return_border>(cont));\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate< typename Sink >\n\t\tstruct drop_first_sink /*final*/ {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\n\t\t\ttemplate<typename Sink2>\n\t\t\tdrop_first_sink(Sink2&& sink, std::size_t& nCount) noexcept\n\t\t\t\t: m_sink(tc_move_if_owned(sink))\n\t\t\t\t, m_nCount(nCount)\n\t\t\t{}\n\n\t\t\ttemplate< typename T >\n\t\t\tauto operator()(T&& t) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\ttc::constant<tc::continue_>,\n\t\t\t\tdecltype(tc::continue_if_not_break(std::declval<Sink const&>(), std::declval<T>()))\n\t\t\t> {\n\t\t\t\tif(0<m_nCount) {\n\t\t\t\t\t--m_nCount;\n\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::continue_if_not_break(m_sink, tc_move_if_owned(t)); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate< typename Rng >\n\t\t\tauto chunk(Rng&& rng) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\ttc::constant<tc::continue_>,\n\t\t\t\tdecltype(tc::continue_if_not_break(tc::mem_fn_chunk(), std::declval<Sink const&>(), tc::drop(std::declval<Rng>(), tc::begin(std::declval<Rng&>()))))\n\t\t\t> {\n\t\t\t\tauto it=tc::begin(rng);\n\t\t\t\tm_nCount-=tc::advance_forward_bounded(it, m_nCount, tc::end(rng));\n\t\t\t\tif(0<m_nCount) {\n\t\t\t\t\t_ASSERT(tc::end(rng)==it);\n\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::continue_if_not_break(tc::mem_fn_chunk(), m_sink, tc::drop(tc_move_if_owned(rng), tc_move(it))); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\tprivate:\n\t\t\tSink m_sink;\n\t\t\tstd::size_t& m_nCount;\n\t\t};\n\t}\n\n\tnamespace drop_first_adaptor_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct drop_first_adaptor : tc::range_adaptor_base_range<Rng>, tc::range_output_from_base_range {\n\t\t\tdrop_first_adaptor(Rng&& rng, std::size_t const n) noexcept\n\t\t\t\t: drop_first_adaptor::range_adaptor_base_range(aggregate_tag, tc_move_if_owned(rng)), m_n(n) {}\n\n\t\t\ttemplate<tc::decayed_derived_from<drop_first_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tauto nCount=self.m_n;\n\t\t\t\tauto boc=tc::for_each(tc_move_if_owned(self).base_range(), no_adl::drop_first_sink<tc::decay_t<decltype(sink)>>(tc_move_if_owned(sink), nCount)); // MAYTHROW\n\t\t\t\t_ASSERTEQUAL(nCount, 0);\n\t\t\t\treturn boc;\n\t\t\t}\n\t\tprivate:\n\t\t\tstd::size_t m_n;\n\t\t};\n\t}\n\n\ttemplate< std::same_as<tc::return_drop> RangeReturn, typename Rng> requires (!tc::range_with_iterators<Rng>)\n\t[[nodiscard]] auto begin_next(Rng&& rng, std::size_t const n=1) noexcept {\n\t\treturn tc::drop_first_adaptor_adl::drop_first_adaptor<Rng>(tc_move_if_owned(rng), n);\n\t}\n\n\ttemplate< typename Cont >\n\tvoid take_last_inplace(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n=1) noexcept {\n\t\ttc::drop_inplace(cont, tc::end_prev<tc::return_border>(cont, n));\n\t}\n\n\ttemplate< typename Cont >\n\tvoid drop_last_inplace(Cont& cont, typename boost::range_size< std::remove_reference_t<Cont> >::type n) noexcept {\n\t\ttc::take_inplace(cont, tc::end_prev<tc::return_border>(cont, n));\n\t}\n\n\ttemplate< typename Cont>\n\tvoid drop_last_inplace(Cont& cont) noexcept {\n\t\tif constexpr( has_mem_fn_pop_back<Cont> ) {\n\t\t\tcont.pop_back();\n\t\t} else {\n\t\t\ttc::take_inplace(cont, tc::end_prev<tc::return_border>(cont));\n\t\t}\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// take_first_truncate...\n\n\ttemplate< typename Cont >\n\tvoid take_first_truncate_inplace( Cont& rng, typename boost::range_size< std::remove_reference_t<Cont> >::type n ) noexcept {\n\t\tauto it=tc::begin(rng);\n\t\ttc::advance_forward_bounded( it, n, tc::end(rng) );\n\t\ttc::take_inplace( rng, tc_move(it) );\n\t}\n\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// span\n\ttemplate<typename T>\n\tusing span = no_adl::subrange<no_adl::universal_range<T*>>;\n\n\tnamespace span_detail {\n\t\ttemplate <typename Rng>\n\t\tusing unchecked_span_t = span<std::remove_pointer_t<tc::ptr_iterator_t<Rng>>>;\n\t}\n\n\ttemplate<tc::contiguous_range Rng>\n\t\trequires tc::safely_convertible_to<Rng&&, span_detail::unchecked_span_t<Rng>>\n\tusing span_t = span_detail::unchecked_span_t<Rng>;\n\n\t// get a consecutive block of memory from range and return an iterator_range of pointers\n\ttemplate<tc::contiguous_range Rng>\n\t[[nodiscard]] constexpr auto as_span(Rng&& rng) noexcept \n\t\t-> tc::span_t<Rng&&>\n\t{\n\t\treturn tc_move_if_owned(rng);\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// range common reference\n\tnamespace no_adl {\n\t\ttemplate <typename It, typename TSource>\n\t\tstruct is_class_safely_constructible<subrange<universal_range<It>>, TSource> final\n\t\t\t: tc::constant<\n\t\t\t\tstd::is_same<tc::decay_t<TSource>, tc::empty_range>::value ||\n\t\t\t\ttc::borrowed_range<TSource>\n\t\t\t>\n\t\t{};\n\n\t\ttemplate <typename Rng1, typename Rng2>\n\t\tstruct common_iterator_range\n\t\t    : std::conditional_t<\n\t\t            std::same_as<std::remove_cvref_t<Rng1>, tc::empty_range>, boost::mp11::mp_defer<tc::iterator_range_t, Rng2>,\n\t\t            std::conditional_t<\n                        std::same_as<std::remove_cvref_t<Rng2>, tc::empty_range>, boost::mp11::mp_defer<tc::iterator_range_t, Rng1>,\n                        boost::mp11::mp_list<> // no common iterator range in the primary specialization\n                    >\n            >\n\t\t{};\n\n\t\t// Rng have common iterator\n\t\ttemplate <typename Rng1, typename Rng2>\n\t\t\trequires tc::safely_constructible_from<tc::iterator_range<tc::common_type_t<tc::iterator_t<Rng1>, tc::iterator_t<Rng2>>>, Rng1>\n\t\t\t\t&& tc::safely_constructible_from<tc::iterator_range<tc::common_type_t<tc::iterator_t<Rng1>, tc::iterator_t<Rng2>>>, Rng2>\n\t\tstruct common_iterator_range<Rng1, Rng2> {\n\t\t\tusing type = tc::iterator_range<tc::common_type_t<tc::iterator_t<Rng1>, tc::iterator_t<Rng2>>>;\n\t\t};\n\t\t// Rng have common pointer iterator\n\t\ttemplate <typename Rng1, typename Rng2>\n\t\t\trequires (!requires { typename tc::common_type_t<tc::iterator_t<Rng1>, tc::iterator_t<Rng2>>; })\n\t\t\t\t&& tc::safely_constructible_from<tc::iterator_range<tc::common_type_t<tc::ptr_iterator_t<Rng1>, tc::ptr_iterator_t<Rng2>>>, Rng1>\n\t\t\t\t&& tc::safely_constructible_from<tc::iterator_range<tc::common_type_t<tc::ptr_iterator_t<Rng1>, tc::ptr_iterator_t<Rng2>>>, Rng2>\n\t\tstruct common_iterator_range<Rng1, Rng2> {\n\t\t\tusing type = tc::iterator_range<tc::common_type_t<tc::ptr_iterator_t<Rng1>, tc::ptr_iterator_t<Rng2>>>;\n\t\t};\n\n\t\t// If T0 and T1 have a common iterator range, that is their common reference.\n\t\ttemplate <typename T0, typename T1> requires requires { typename common_iterator_range<T0, T1>::type; }\n\t\tstruct common_reference_impl<T0, T1> : common_iterator_range<T0, T1> {};\n\t}\n}\n"
  },
  {
    "path": "tc/range/subrange.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../container/container.h\" // tc::vector\n#include \"../interval.h\"\n#include \"subrange.h\"\n#include \"range_return.h\"\n#include \"union_adaptor.h\"\n#include \"unique_range_adaptor.h\"\n#include \"intersection_adaptor.h\"\n\n#include <type_traits>\n#include <string_view> // for test only\n\nnamespace {\n\t// non-borrowed ranges are subranges\n\tSTATICASSERTSAME(tc::slice_t<std::string>, tc::no_adl::subrange<std::string>);\n\t// borrowed range are iterator_ranges\n\tSTATICASSERTSAME(tc::slice_t<std::string&>, tc::iterator_range_t<std::string&>);\n\tSTATICASSERTSAME(tc::slice_t<std::string_view>, tc::iterator_range_t<std::string_view>);\n\tSTATICASSERTSAME(tc::slice_t<std::string_view&>, tc::iterator_range_t<std::string_view>);\n\t// unwrapping\n\tSTATICASSERTSAME(tc::slice_t<tc::no_adl::subrange<std::string>>, tc::no_adl::subrange<std::string>);\n\tSTATICASSERTSAME(tc::slice_t<tc::no_adl::subrange<std::string>&>, tc::iterator_range_t<std::string&>);\n\tSTATICASSERTSAME(tc::slice_t<tc::span<char const>>, tc::span<char const>);\n\tSTATICASSERTSAME(tc::slice_t<tc::span<char const>&>, tc::span<char const>);\n\n\n\tUNITTESTDEF( subrange_array ) {\n\n\t\tint arr[4] = {1,2,3,4};\n\t\tauto arr_rng = tc::slice_by_interval(arr, tc::make_interval(1, 3));\n\n\t\tvoid(tc::implicit_cast<tc::no_adl::subrange<tc::no_adl::universal_range<int *>>>(arr_rng));\n\t\tvoid(tc::implicit_cast<tc::no_adl::subrange<tc::no_adl::universal_range<int const*>>>(arr_rng));\n\t}\n\n\n\tUNITTESTDEF( const_subrange_char_ptr ) {\n\t\ttc::no_adl::subrange<tc::no_adl::universal_range<char const*>>{\"test\"};\n\t}\n\n\t//-------------------------------------------------------------------------------------------------------------------------\n\n\tusing SRVI = tc::slice_t<tc::vector<int>&>;\n\tusing CSRVI = tc::slice_t<tc::vector<int> const&>;\n\n\tusing SSRVI = tc::slice_t<tc::slice_t<tc::vector<int>&>>;\n\tusing CSSRVI = tc::slice_t<tc::slice_t<tc::vector<int> const&>>;\n\n\t[[maybe_unused]] void ref_test(SRVI & rng) noexcept {\n\t\tCSRVI const_rng(rng);\n\t\tSRVI non_const_rng(rng);\n\t\tUNUSED_TEST_VARIABLE(const_rng);\n\t\tUNUSED_TEST_VARIABLE(non_const_rng);\n\t}\n\n\tUNITTESTDEF( const_subrange ) {\n\t\ttc::vector<int> v;\n\t\tauto srvi = tc::all(v);\n\t\tauto csrvi = tc::all(tc::as_const(v));\n\n\t\t(void) srvi;\n\t\t(void) csrvi;\n\n\t\tSRVI non_const_rng(srvi);\n\t\tUNUSED_TEST_VARIABLE(non_const_rng);\n\t\tCSRVI const_rng(srvi);\n\t\tUNUSED_TEST_VARIABLE(const_rng);\n\t}\n\n\tUNITTESTDEF( sub_subrange_rvalue ) {\n\n\t\ttc::vector<int> v;\n\n\t\tauto srvi = tc::all(v);\n\t\tauto csrvi = tc::all(tc::as_const(v));\n\n\t\tauto ssrvi = tc::all(tc::all(v));\n\t\tauto cssrvi = tc::all(tc::all(tc::as_const(v)));\n\n\t\tSTATICASSERTSAME(decltype(ssrvi), decltype(srvi), \"Sub-sub-range does not flatten to sub-range (decltype)\");\n\t\tSTATICASSERTSAME(decltype(cssrvi), decltype(csrvi), \"const sub-sub-range does not flatten to const sub-range (decltype)\");\n\t}\n\n\tUNITTESTDEF( sub_subrange_lvalue ) {\n\n\t\ttc::vector<int> v;\n\n\t\tauto srvi = tc::all(v);\n\t\tauto csrvi = tc::all(tc::as_const(v));\n\n\t\tauto ssrvi = tc::all(srvi);\n\t\tauto cssrvi = tc::all(csrvi);\n\n\t\t// sanity checks\n\t\tSTATICASSERTSAME(decltype(srvi), SRVI, \"make_subrange_result gives wrong result\");\n\t\tSTATICASSERTSAME(decltype(csrvi), CSRVI, \"make_subrange_result gives wrong result\");\n\t\tSTATICASSERTSAME(decltype(ssrvi), SSRVI, \"make_subrange_result gives wrong result\");\n\t\tSTATICASSERTSAME(decltype(cssrvi), CSSRVI, \"make_subrange_result gives wrong result\");\n\n\t\t// the actual test\n\t\tSTATICASSERTSAME(decltype(ssrvi), decltype(srvi), \"Sub-sub-range does not flatten to sub-range\");\n\t\tSTATICASSERTSAME(decltype(cssrvi), decltype(csrvi), \"const sub-sub-range does not flatten to const sub-range\");\n\t}\n\n\tUNITTESTDEF( sub_subrange_index ) {\n\n\t\tTEST_init_hack(tc::vector, int, v, {1,2,3,4,5,6,7,8,9});\n\t\tTEST_init_hack(tc::vector, int, exp36, {4,5,6});\n\n\t\tauto sr = tc::all(v);\n\t\tauto csr = tc::all(tc::as_const(v));\n\n\t\t// use range_difference to specify bounds\n\t\tauto ssr1 = tc::slice_by_interval(sr, tc::make_interval(3, 6));\n\t\tauto cssr1 = tc::slice_by_interval(csr, tc::make_interval(3, 6));\n\n\t\tSTATICASSERTSAME(decltype(ssr1), decltype(sr), \"Sub-sub-range does not flatten to sub-range\");\n\t\tSTATICASSERTSAME(decltype(cssr1), decltype(csr), \"const sub-sub-range does not flatten to const sub-range\");\n\n\t}\n\n\tUNITTESTDEF(union_range_tests) {\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,4)),\n\t\t\ttc::union_range(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,4)),\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 2,3))\n\t\t\t)\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 4,3,2,1,0)),\n\t\t\ttc::union_range(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 4,2,0)),\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 3,2,1)),\n\t\t\t\t[](int const lhs, int const rhs) noexcept {return tc::compare(rhs,lhs);}\n\t\t\t)\n\t\t);\n\n\t\t_ASSERTEQUAL(\n\t\t\t*tc::upper_bound<tc::return_border>(\n\t\t\t\ttc::union_range(\n\t\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,4)),\n\t\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 2,3))\n\t\t\t\t),\n\t\t\t\t2\n\t\t\t),\n\t\t\t3\n\t\t);\n\n\t\t{\n\t\t\tauto rng = tc::union_range(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,3,4,4,5)),\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,1,1,3,4,4,4))\n\t\t\t);\n\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\trng,\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,1,1,2,3,3,4,4,4,5))\n\t\t\t);\n\n\t\t\t{\n\t\t\t\tauto it = tc::lower_bound<tc::return_border>(rng,3);\n\t\t\t\t_ASSERTEQUAL(*it,3);\n\t\t\t\t_ASSERTEQUAL(*tc_modified(it, --_), 2);\n\t\t\t\t_ASSERTEQUAL(*tc_modified(it, ++_), 3);\n\t\t\t}\n\t\t\t{\n\t\t\t\tauto it = tc::upper_bound<tc::return_border>(rng,1);\n\t\t\t\t_ASSERTEQUAL(*it,2);\n\t\t\t\t_ASSERTEQUAL(*--it, 1);\n\t\t\t\t_ASSERTEQUAL(*--it, 1);\n\t\t\t\t_ASSERTEQUAL(*--it, 1);\n\t\t\t}\n\t\t}\n\t\t{\n\t\t\tauto rng = tc::union_range(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,1,1,1,1,1,1,1,1)),\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,1))\n\t\t\t);\n\t\t\tauto it = tc::lower_bound<tc::return_border>(rng,1);\n\t\t\t_ASSERTEQUAL(*it,1);\n\t\t}\n\t}\n\n\tUNITTESTDEF(union_range_generator) {\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,5,6)),\n\t\t\ttc::union_range(\n\t\t\t\t[](auto sink) noexcept -> tc::break_or_continue {\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, 1))\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, 3))\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, 5))\n\t\t\t\t\treturn tc::continue_;\n\t\t\t\t},\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 2,6))\n\t\t\t)\n\t\t);\n\n\t\ttc::vector<double> vecf = {1,3,5};\n\t\ttc::for_each(\n\t\t\ttc::union_range(\n\t\t\t\ttc::make_generator_range(vecf),\n\t\t\t\tvecf\n\t\t\t),\n\t\t\t[](double& d) noexcept {d += 0.1;}\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1.1,3.1,5.1)),\n\t\t\tvecf\n\t\t);\n\t}\n\n\tUNITTESTDEF(subrange_with_tranform) {\n\n\t\ttc::vector<int> vecn{1,2,3};\n\t\tauto rgntrnsfn = tc::transform(vecn, [](int const n) noexcept {return n*n;});\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::slice(rgntrnsfn, tc::begin(rgntrnsfn), tc::end(rgntrnsfn)),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,4,9))\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag,  1, 2, 3 )),\n\t\t\ttc::untransform(tc::slice(rgntrnsfn, tc::begin(rgntrnsfn), tc::end(rgntrnsfn)))\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::single(2),\n\t\t\ttc::untransform(tc::equal_range(tc::transform(vecn, [](int const n) noexcept {return n*n; }), 4))\n\t\t);\n\n\t\t{\n\t\t\tauto rng = tc::transform(tc::filter(vecn, [](int const n) noexcept {return n<3;}), [](int const n) noexcept {return n*n; });\n\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc::single(2),\n\t\t\t\ttc::untransform(tc::equal_range(rng, 4))\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// r-value transform with l-value range\n\t\t\tauto&& rng = tc::untransform(tc::transform(vecn, [](int const n) noexcept {return n*n;}));\n\t\t\t_ASSERTEQUAL(tc::size(vecn), 3);\n\t\t\t_ASSERTEQUAL(std::addressof(*tc::begin(rng)), std::addressof(*tc::begin(vecn)));\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(!std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// r-value transform with l-value const range\n\t\t\tauto&& rng = tc::untransform(tc::transform(tc::as_const(vecn), [](int const n) noexcept {return n*n;}));\n\t\t\t_ASSERTEQUAL(tc::size(vecn), 3);\n\t\t\t_ASSERTEQUAL(std::addressof(*tc::begin(rng)), std::addressof(*tc::begin(vecn)));\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype((rng))>::value);\n\t\t\tstatic_assert(std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// r-value transform with r-value range\n\t\t\tauto rng = tc::untransform(tc::transform(tc::vector<int>{1, 2, 3}, [](int const n) noexcept {return n*n;}));\n\t\t\tSTATICASSERTSAME(decltype(rng),tc::vector<int>);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// l-value transform of l-value-range\n\t\t\tauto trnsfrng = tc::transform(vecn, [](int const n) noexcept {return n*n;});\n\n\t\t\tauto&& rng = tc::untransform(trnsfrng);\n\t\t\t_ASSERTEQUAL(tc::size(vecn), 3);\n\t\t\t_ASSERTEQUAL(std::addressof(*tc::begin(rng)), std::addressof(*tc::begin(vecn)));\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(!std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// l-value transform of const l-value-range\n\t\t\tauto const trnsfrng = tc::transform(tc::as_const(vecn), [](int const n) noexcept {return n*n;});\n\n\t\t\tauto&& rng = tc::untransform(trnsfrng);\n\t\t\t_ASSERTEQUAL(tc::size(vecn), 3);\n\t\t\t_ASSERTEQUAL(std::addressof(*tc::begin(rng)), std::addressof(*tc::begin(vecn)));\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// l-value transform of const l-value-range\n\t\t\tauto trnsfrng = tc::transform(tc::as_const(vecn), [](int const n) noexcept {return n*n;});\n\n\t\t\tauto&& rng = tc::untransform(trnsfrng);\n\t\t\t_ASSERTEQUAL(tc::size(vecn), 3);\n\t\t\t_ASSERTEQUAL(std::addressof(*tc::begin(rng)), std::addressof(*tc::begin(vecn)));\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\n\t\t{\n\t\t\t// l-value transform of r-value range\n\t\t\tauto trnsfrng = tc::transform(tc::vector<int>{1, 2, 3}, [](int const n) noexcept {return n*n; });\n\t\t\tauto&& rng = tc::untransform(trnsfrng);\n\t\t\t_ASSERTEQUAL(\n\t\t\t\tstd::addressof(*tc::begin(trnsfrng).element_base()),\n\t\t\t\tstd::addressof(*tc::begin(rng))\n\t\t\t);\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(!std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\t\t{\n\t\t\t// const l-value transform of r-value range\n\t\t\tauto const trnsfrng = tc::transform(tc::vector<int>{1, 2, 3}, [](int const n) noexcept {return n*n; });\n\t\t\tauto&& rng = tc::untransform(trnsfrng);\n\t\t\t_ASSERTEQUAL(\n\t\t\t\tstd::addressof(*tc::begin(trnsfrng).element_base()),\n\t\t\t\tstd::addressof(*tc::begin(rng))\n\t\t\t);\n\t\t\tstatic_assert(std::is_lvalue_reference<decltype(rng)>::value);\n\t\t\tstatic_assert(std::is_const<std::remove_reference_t<decltype(rng)>>::value);\n\t\t\tTEST_RANGE_EQUAL(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3)),\n\t\t\t\trng\n\t\t\t);\n\t\t}\n\t}\n\n\tUNITTESTDEF(Unique_Ranges) {\n\t\ttc::vector<int> vecn{1,2,3,3,5,5,7};\n\n\t\t{\n\t\t\tstd::initializer_list<int> const rngExpected[] = { // extends life-time of underlying arrays\n\t\t\t\t{1},\n\t\t\t\t{2},\n\t\t\t\t{3,3},\n\t\t\t\t{5,5},\n\t\t\t\t{7}\n\t\t\t};\n\n\t\t\t{\n\t\t\t\tauto it = tc::begin(rngExpected);\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::adjacent_unique_range(vecn),\n\t\t\t\t\t[&](auto const& subrng) noexcept {\n\t\t\t\t\t\tTEST_RANGE_EQUAL(subrng, *it);\n\t\t\t\t\t\t++it;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\t_ASSERTEQUAL(tc::end(rngExpected), it);\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tauto it = tc::begin(rngExpected);\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::adjacent_unique_range(tc::as_const(vecn)),\n\t\t\t\t\t[&](auto const& subrng) noexcept {\n\t\t\t\t\t\tTEST_RANGE_EQUAL(subrng, *it);\n\t\t\t\t\t\t++it;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\t_ASSERTEQUAL(tc::end(rngExpected), it);\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tauto it = tc::begin(rngExpected);\n\t\t\t\ttc::for_each(\n\t\t\t\ttc::adjacent_unique_range(vecn),\n\t\t\t\t\t[&](auto const& subrng) noexcept {\n\t\t\t\t\t\tTEST_RANGE_EQUAL(subrng, *it);\n\t\t\t\t\t\t++it;\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\t_ASSERTEQUAL(tc::end(rngExpected), it);\n\t\t\t}\n\n\t\t}\n\n\t\ttc_static_auto_constexpr_lambda(Pred) = [](int const lhs, int const rhs) noexcept {\n\t\t\treturn std::abs(lhs-rhs) <=1;\n\t\t};\n\n\t\t{\n\t\t\tstd::initializer_list<int> const rngExpected[] = { // extends life-time of underlying arrays\n\t\t\t\t{1,2},\n\t\t\t\t{3,3},\n\t\t\t\t{5,5},\n\t\t\t\t{7}\n\t\t\t};\n\t\t\tauto it = tc::begin(rngExpected);\n\t\t\ttc::for_each(\n\t\t\t\ttc::front_unique_range(vecn, Pred),\n\t\t\t\t[&](auto const& subrng) noexcept {\n\t\t\t\t\tTEST_RANGE_EQUAL(subrng, *it);\n\t\t\t\t\t++it;\n\t\t\t\t}\n\t\t\t);\n\t\t\t_ASSERTEQUAL(tc::end(rngExpected), it);\n\t\t}\n\n\t\t{\n\t\t\tstd::initializer_list<int> const rngExpected[] = { // extends life-time of underlying arrays\n\t\t\t\t{1,2,3,3},\n\t\t\t\t{5,5},\n\t\t\t\t{7}\n\t\t\t};\n\t\t\tauto it = tc::begin(rngExpected);\n\t\t\ttc::for_each(\n\t\t\t\ttc::adjacent_unique_range(vecn, Pred),\n\t\t\t\t[&](auto const& subrng) noexcept {\n\t\t\t\t\tTEST_RANGE_EQUAL(subrng, *it);\n\t\t\t\t\t++it;\n\t\t\t\t}\n\t\t\t);\n\t\t\t_ASSERTEQUAL(tc::end(rngExpected), it);\n\t\t}\n\t}\n\n\tUNITTESTDEF(difference_range) {\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::difference(\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,2,4,7,8,8,11,11)),\n\t\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 2,3,4,8,8))\n\t\t\t),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,7,11,11))\n\t\t);\n\t}\n\n\tUNITTESTDEF(difference_unordered_set) {\n\t\ttc::unordered_set<int> setn1;\n\t\ttc::cont_assign(setn1, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,4,5,6,7,8,9,10,11)));\n\n\t\ttc::unordered_set<int> setn2;\n\t\ttc::cont_assign(setn2, tc_as_constexpr(tc::make_array(tc::aggregate_tag, 10,9,8,7,6,5,4,3,2,1)));\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::set_difference(setn1, setn2),\n\t\t\ttc::single(11)\n\t\t);\n\n\t\ttc::vector<int> vecn;\n\t\ttc::for_each(tc::set_intersect(setn1, setn2), [&](int const n) noexcept {\n\t\t\tvecn.emplace_back(n);\n\t\t});\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::sort(vecn),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,4,5,6,7,8,9,10))\n\t\t);\n\t}\n\n\tUNITTESTDEF(tc_unique) {\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::adjacent_unique(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,2,4,7,8,8,11,11))),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,4,7,8,11))\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::reverse(tc::adjacent_unique(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,2,4,7,8,8,11,11)))),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 11,8,7,4,2,1))\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::transform(\n\t\t\t\ttc::adjacent_unique(\n\t\t\t\t\ttc::make_range_of_iterators(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,2,3,3,3,4,7,8,8,11,11))),\n\t\t\t\t\ttc::projected(tc::equal_to, tc::fn_indirection())\n\t\t\t\t),\n\t\t\t\ttc::fn_indirection()\n\t\t\t),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,4,7,8,11))\n\t\t);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\ttc::transform(\n\t\t\t\ttc::reverse(tc::adjacent_unique(\n\t\t\t\t\ttc::make_range_of_iterators(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,2,3,3,3,4,7,8,8,11,11))),\n\t\t\t\t\ttc::projected(tc::equal_to, tc::fn_indirection())\n\t\t\t\t)),\n\t\t\t\ttc::fn_indirection()\n\t\t\t),\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 11,8,7,4,3,2,1))\n\t\t);\n\n\t\ttc::vector<int> vecn{1,1,2,2};\n\t\tauto rngunique = tc::adjacent_unique(vecn);\n\t\tauto it = tc::begin(rngunique);\n\t\tauto itvec = it.element_base();\n\t\t_ASSERT(1==*itvec);\n\t\t_ASSERT(1 == *(++itvec));\n\t\t_ASSERT(2 == *(++itvec));\n\n\t\t_ASSERT(1 == *it);\n\t\t_ASSERT(2 == *(++it));\n\t\t_ASSERT(1 == *(--it));\n\t\t_ASSERTEQUAL(tc::begin(rngunique), it);\n\n\t}\n\n#ifdef _CHECKS\n\tstruct MovingInt final {\n\t\tint m_n;\n\n\t\tMovingInt(int n) noexcept : m_n(n)\n\t\t{}\n\n\t\tMovingInt(MovingInt&& other) noexcept : m_n(other.m_n)\n\t\t{\n\t\t\tother.m_n = 0;\n\t\t}\n\n\t\tMovingInt(MovingInt const&) = delete;\n\t\tMovingInt& operator=(MovingInt& other) = delete;\n\n\t\tMovingInt& operator=(MovingInt&& other) & noexcept {\n\t\t\tm_n = other.m_n;\n\t\t\tif (&other.m_n != &m_n) {\n\t\t\t\tother.m_n = 0;\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\toperator int() const& noexcept {return m_n;}\n\t};\n#endif\n\n\tUNITTESTDEF(tc_unique_inplace) {\n\t\ttc::vector<MovingInt> vecmn; // list initializtion not possible with move-only element type\n\t\ttc::cont_emplace_back(vecmn, 1);\n\t\ttc::cont_emplace_back(vecmn, 1);\n\t\ttc::cont_emplace_back(vecmn, 1);\n\t\ttc::cont_emplace_back(vecmn, 2);\n\t\ttc::cont_emplace_back(vecmn, 2);\n\t\ttc::cont_emplace_back(vecmn, 2);\n\t\ttc::cont_emplace_back(vecmn, 3);\n\t\ttc::cont_emplace_back(vecmn, 4);\n\t\ttc::cont_emplace_back(vecmn, 4);\n\t\ttc::adjacent_unique_inplace(vecmn);\n\n\t\tTEST_RANGE_EQUAL(\n\t\t\tvecmn,\n\t\t\ttc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2,3,4))\n\t\t);\n\t}\n\n\tUNITTESTDEF( take_first_sink ) {\n\t\ttc_static_auto_constexpr_lambda(rngn) = [](auto sink) noexcept {\n\t\t\tfor(int i=0;;++i) { tc_return_if_break(tc::continue_if_not_break(sink, i)) }\n\t\t};\n\n\t\t_ASSERTEQUAL(tc::for_each(tc::begin_next<tc::return_take>(rngn), [](int) noexcept {}), tc::continue_);\n\t\t_ASSERTEQUAL(tc::for_each(tc::begin_next<tc::return_take>(rngn), [](int) noexcept { return tc::break_; }), tc::break_);\n\t\t_ASSERT(tc::equal(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 0,1,2,3)), tc::begin_next<tc::return_take>(rngn, 4)));\n\n\t\tauto rngch = tc::concat(\"123\", [](auto&& sink) noexcept { return tc::for_each(\"456\", tc_move_if_owned(sink)); });\n\n\t\tstruct assert_no_single_char_sink /*final*/ {\n\t\t\tauto operator()(char) const& noexcept { _ASSERTFALSE; return tc::construct_default_or_terminate<tc::break_or_continue>(); }\n\t\t\tauto chunk(tc::span<char const> str) const& noexcept { return tc::constant<tc::continue_>(); }\n\t\t};\n\t\t_ASSERTEQUAL(tc::for_each(tc::begin_next<tc::return_take>(rngch, 4), assert_no_single_char_sink()), tc::continue_);\n\t\t_ASSERT(tc::equal(\"1234\", tc::begin_next<tc::return_take>(rngch, 4)));\n\t}\n\n\tUNITTESTDEF( drop_first_sink ) {\n\t\ttc_static_auto_constexpr_lambda(rngn) = [](auto sink) noexcept {\n\t\t\tfor(int i=0; i < 7;++i) { tc_return_if_break(tc::continue_if_not_break(sink, i)) }\n\t\t\treturn tc::continue_;\n\t\t};\n\n\t\t_ASSERTEQUAL(tc::for_each(tc::begin_next<tc::return_drop>(rngn), [](int) noexcept {}), tc::continue_);\n\t\t_ASSERTEQUAL(tc::for_each(tc::begin_next<tc::return_drop>(rngn), [](int) noexcept { return tc::break_; }), tc::break_);\n\t\t_ASSERT(tc::equal(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 4,5,6)), tc::begin_next<tc::return_drop>(rngn, 4)));\n\n\t\tauto rngch = tc::begin_next<tc::return_drop>(tc::concat(\"123\", [](auto&& sink) noexcept { return tc::for_each(\"456\", tc_move_if_owned(sink)); }), 2);\n\n\t\tstruct assert_no_single_char_sink /*final*/ {\n\t\t\tauto operator()(char) const& noexcept { _ASSERTFALSE; return tc::construct_default_or_terminate<tc::break_or_continue>(); }\n\t\t\tauto chunk(tc::span<char const> str) const& noexcept { return tc::constant<tc::continue_>(); }\n\t\t};\n\t\t_ASSERTEQUAL(tc::for_each(rngch, assert_no_single_char_sink()), tc::continue_);\n\t\t_ASSERT(tc::equal(\"3456\", rngch));\n\t}\n\n\tUNITTESTDEF( span_from_subrange ) {\n\t\ttc::string<char> str(\"1234\");\n\t\t_ASSERTEQUAL( tc::begin(tc::as_span(tc::begin_next<tc::return_drop>(str, 2))), tc::begin(tc::begin_next<tc::return_drop>(tc::as_span(str), 2)) );\n\t\t_ASSERTEQUAL( tc::end(tc::as_span(tc::begin_next<tc::return_take>(str, 2))), tc::end(tc::begin_next<tc::return_take>(tc::as_span(str), 2)) );\n\t}\n#ifndef __clang__\n\tnamespace {\n\t\tstruct STestPtrs {\n\t\t\tconstexpr STestPtrs(char const* itBegin,char const* itEnd): m_itBegin(itBegin),m_itEnd(itEnd) {}\n\n\t\t\tchar const* m_itBegin;\n\t\t\tchar const* m_itEnd;\n\t\t};\n\t}\n\n\tUNITTESTDEF( constexpr_ptr_to_string_literal_runtime_bug ) {\n\t\t// https://developercommunity.visualstudio.com/content/problem/900648/codegen-constexpr-pointer-to-trailing-zero-on-stri.html\n\t\t// Visual Studio 2017/2019 will fire at run time if we disable string pooling by setting /GF-.\n\t\tconstexpr char const* str = \"abcde\";\n\t\tconstexpr STestPtrs ptrs(tc::ptr_begin(str), tc::ptr_end(str));\n\t\tstatic_assert(tc::begin(str)==ptrs.m_itBegin);\n\t\tstatic_assert(tc::end(str)==ptrs.m_itEnd);\n\t\t_ASSERTEQUAL(tc::begin(str), ptrs.m_itBegin); // run time compare\n\t\t_ASSERTEQUAL(tc::end(str), ptrs.m_itEnd);  // run time compare\n\t}\n#endif\n\n\tUNITTESTDEF(and_then) {\n\t\ttc_static_auto_constexpr_lambda(fn) = [](auto const n) noexcept {return n+1;};\n\t\tstd::optional<int> on(12);\n\n\t\tauto n1=tc::and_then(on, fn);\n\t\tstatic_assert(std::is_same<decltype(n1), int>::value);\n\t\t_ASSERTEQUAL(n1, 13);\n\n\t\tauto on1=tc::and_then(on, tc::chained(tc::fn_make_optional{}, fn));\n\t\tstatic_assert(std::is_same<decltype(on1), std::optional<int>>::value);\n\t\t_ASSERTEQUAL(*VERIFY(on1), 13);\n\n\t\ton=std::nullopt;\n\t\tauto n2=tc::and_then(on, fn);\n\t\tstatic_assert(std::is_same<decltype(n2), int>::value);\n\t\t_ASSERTEQUAL(n2,0);\n\n\t\tauto on2=tc::and_then(on, tc::chained(tc::fn_make_optional{}, fn));\n\t\tstatic_assert(std::is_same<decltype(on1), std::optional<int>>::value);\n\t\t_ASSERT(!on2);\n\n\t\tstruct X{ int const n; };\n\t\tstruct Y{ X const* px; };\n\t\tstruct Z{ Y const* py; };\n\n\t\tX const x{ 23 };\n\t\tY const y{ &x };\n\t\tZ const z{ &y };\n\n\t\tauto n3=tc::and_then(&z, tc_member(.py), tc_member(.px), tc_member(.n));\n\t\tstatic_assert(std::is_same<decltype(n3), int>::value);\n\t\t_ASSERTEQUAL(n3, 23);\n\n\t\tZ const* pz=nullptr;\n\t\tauto n4=tc::and_then(pz, tc_member(.py), tc_member(.px), tc_member(.n));\n\t\tstatic_assert(std::is_same<decltype(n4), int>::value);\n\t\t_ASSERTEQUAL(n4, 0);\n\t}\n\n}\n\nSTATICASSERTEQUAL( sizeof(tc::span<int>), 2 * sizeof(int*) );\nstatic_assert( std::is_nothrow_default_constructible<tc::span<int>>::value );\nstatic_assert( std::is_trivially_destructible<tc::span<int>>::value );\nstatic_assert( std::is_trivially_copy_constructible<tc::span<int>>::value );\nstatic_assert( std::is_trivially_move_constructible<tc::span<int>>::value );\nstatic_assert( std::is_trivially_copy_assignable<tc::span<int>>::value );\nstatic_assert( std::is_trivially_move_assignable<tc::span<int>>::value );\nstatic_assert( std::is_trivially_copyable<tc::span<int>>::value );\n\nnamespace {\n\tUNITTESTDEF( subrange_index_translation ) {\n\t\tTEST_RANGE_EQUAL(\"est\", []() noexcept {\n\t\t\ttc::string<char> str = \"Test\";\n\t\t\treturn tc::begin_next<tc::return_drop>(tc_move(str));\n\t\t}());\n\t}\n}\n"
  },
  {
    "path": "tc/range/take_while.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/move.h\"\n#include \"../base/conditional.h\"\n#include \"../base/invoke.h\"\n#include \"../base/trivial_functors.h\"\n\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate< typename Pred, typename Rng, bool HasIterator=tc::range_with_iterators< Rng > >\n\t\tstruct take_while_adaptor;\n\n\t\ttemplate< typename Pred, typename Rng >\n\t\tstruct [[nodiscard]] take_while_adaptor<Pred, Rng, false> : tc::range_adaptor_base_range<Rng>, tc::range_output_from_base_range {\n\t\tprotected:\n\t\t\tstatic_assert(tc::decayed<Pred>);\n\t\t\tPred m_pred;\n\n\t\tpublic:\n\t\t\tconstexpr take_while_adaptor() = default;\n\t\t\ttemplate< typename RngRef, typename PredRef >\n\t\t\tconstexpr take_while_adaptor(RngRef&& rng, PredRef&& pred) noexcept\n\t\t\t\t: take_while_adaptor::range_adaptor_base_range(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_pred(tc_move_if_owned(pred))\n\t\t\t{}\n\n\t\t\ttemplate<tc::decayed_derived_from<take_while_adaptor> Self, typename Sink> \n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\ttc::common_type_t<decltype(tc::for_each(tc_move_if_owned(self).base_range(), sink)),tc::constant<tc::continue_>> boc = tc::constant<tc::continue_>();\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc_move_if_owned(self).base_range(),\n\t\t\t\t\t[&](auto&& t) MAYTHROW -> tc::break_or_continue {\n\t\t\t\t\t\tif (tc_invoke(self.m_pred, tc::as_const(t))) {\n\t\t\t\t\t\t\tboc = tc::continue_if_not_break(sink, tc_move_if_owned(t));\n\t\t\t\t\t\t\treturn boc;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\treturn boc;\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Pred, typename Rng >\n\t\tstruct [[nodiscard]] take_while_adaptor<Pred, Rng, true>\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\ttake_while_adaptor<Pred, Rng, true>,\n\t\t\t\tRng, tc::index_range_adaptor_flags::inherit_begin | tc::index_range_adaptor_flags::inherit_behavior,\n\t\t\t\ttake_while_adaptor<Pred, Rng, false>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = take_while_adaptor;\n\t\t\tusing base_ = typename take_while_adaptor::index_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = tc::prefers_for_each<std::remove_reference_t<Rng>>;\n\n\t\t\tconstexpr take_while_adaptor() = default;\n\t\t\tusing base_::base_;\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& = delete;  // let range_iterator_from_index::end return end_sentinel\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& return_MAYTHROW(\n\t\t\t\ttc::at_end_index(this->base_range(), idx) || !tc_invoke(this->m_pred, tc::as_const(this->dereference_index(idx)))\n\t\t\t)\n\t\t};\n\t}\n\tusing no_adl::take_while_adaptor;\n\n\ttemplate<typename Pred, typename Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::take_while_adaptor<Pred, Rng, true>> = tc::stable_index_on_move<Rng>;\n\n\ttemplate<typename Rng, typename Pred = tc::identity>\n\tconstexpr auto take_while(Rng&& rng, Pred&& pred = Pred())\n\t\treturn_ctor_noexcept( TC_FWD( tc::take_while_adaptor<tc::decay_t<Pred>, Rng>), (tc_move_if_owned(rng),tc_move_if_owned(pred)) )\n}\n"
  },
  {
    "path": "tc/range/take_while.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"take_while.h\"\n#include \"make_range.h\"\n#include \"../algorithm/for_each_xxx.h\"\n#include \"../algorithm/append.h\"\n\nUNITTESTDEF(GeneratorRangeTakeWhile) {\n\tauto GeneratorRange = tc::generator_range_output<int>([](auto const& sink) noexcept -> tc::break_or_continue {\n\t\ttc_return_if_break(tc::continue_if_not_break(sink, 1))\n\t\ttc_return_if_break(tc::continue_if_not_break(sink, 2))\n\t\t_ASSERTFALSE;\n\t\ttc_return_if_break(tc::continue_if_not_break(sink, 3))\n\t\treturn tc::continue_;\n\t});\n\n\tstatic_assert(std::is_same<int, tc::range_value_t<decltype(tc::take_while(GeneratorRange))>>::value);\n\n\ttc::for_each(\n\t\ttc::take_while(\n\t\t\tGeneratorRange,\n\t\t\t[](auto const n) noexcept {\n\t\t\t\treturn n<2;\n\t\t\t}\n\t\t),\n\t\t[](auto const n) noexcept {\n\t\t\t_ASSERTEQUAL(n, 1);\n\t\t\treturn tc::constant<tc::continue_>();\n\t\t}\n\t);\n\n\tauto vecn = tc::explicit_cast<tc::vector<int>>(tc::make_range(1,2,3,4));\n\tstatic_assert(std::is_same<\n\t\tdecltype(tc::for_each(vecn,tc::noop())),\n\t\ttc::constant<tc::continue_>\n\t>::value);\n\n\tauto rng = tc::take_while(vecn,[](auto const n) noexcept { return n<3; });\n\tstatic_assert(std::is_same<tc::vector<int>&, decltype(rng.base_range())>::value);\n\n\ttc::for_each(rng, [](auto const n) noexcept {\n\t\t_ASSERT(1==n || 2==n);\n\t});\n\n\tauto itBegin = tc::begin(rng);\n\tauto const itEnd = tc::end(rng);\n\t_ASSERT(itBegin != itEnd);\n\t_ASSERTEQUAL(1, *itBegin);\n\t++itBegin;\n\t_ASSERT(itBegin != itEnd);\n\t_ASSERTEQUAL(2, *itBegin);\n\t++itBegin;\n\t_ASSERT(itBegin == itEnd);\n}\n"
  },
  {
    "path": "tc/range/transform.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/generic_macros.h\"\n#include \"../base/move.h\"\n#include \"../base/invoke.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename Func, typename Src>\n\t\tstruct transform_value final {};\n\n\t\ttemplate<typename Func, typename Src> requires tc::invocable<tc::decay_t<Func> const&, Src>\n\t\tstruct transform_value<Func, Src> final {\n\t\t\tusing type = tc::decay_t<decltype(tc_invoke(std::declval<tc::decay_t<Func> const&>(), std::declval<Src>()))>;\n\t\t};\n\n\t\ttemplate<typename Func, typename Src>\n\t\tstruct transform_output final {};\n\n\t\ttemplate<typename Func, typename Src> requires tc::invocable<tc::decay_t<Func> const&, Src>\n\t\tstruct transform_output<Func, Src> final {\n\t\t\tusing type = tc::remove_rvalue_reference_t<decltype(tc_invoke(std::declval<tc::decay_t<Func> const&>(), std::declval<Src>()))>;\n\t\t};\n\t}\n\n\ttemplate<typename Func, typename Src>\n\tusing transform_value_t = typename no_adl::transform_value<Func, Src>::type;\n\n\ttemplate<typename Func, typename Src>\n\tusing transform_output_t = typename no_adl::transform_output<Func, Src>::type;\n\n\tDEFINE_TAG_TYPE(transform_tag)\n}\n\n#define DEFINE_MEMBER_TRANSFORM_3(class_template, value_template, T) TC_FWD( \\\n\tprivate: \\\n\t\ttemplate<typename, typename /*=void gives warning on MSVC*/> \\\n\t\tstruct transform_result; \\\n\t\ttemplate<typename U> \\\n\t\tstruct transform_result<value_template<U>, void> : std::type_identity<class_template<U>> {}; \\\n\tpublic: \\\n\t\ttemplate<std::size_t nDepth=0, typename Func, std::enable_if_t<0==nDepth>* = nullptr> \\\n\t\t[[nodiscard]] constexpr auto transform(Func&& func) const& return_decltype_MAYTHROW( \\\n\t\t\ttypename transform_result<tc::transform_value_t<Func, value_template<T> const&>, void>::type(tc::transform_tag, *this, tc_move_if_owned(func)) \\\n\t\t) \\\n\t\ttemplate<std::size_t nDepth=0, typename Func, std::enable_if_t<0==nDepth>* = nullptr> \\\n\t\t[[nodiscard]] constexpr auto transform(Func&& func) && return_decltype_MAYTHROW( \\\n\t\t\ttypename transform_result<tc::transform_value_t<Func, value_template<T>>, void>::type(tc::transform_tag, tc_move_always(*this), tc_move_if_owned(func)) \\\n\t\t) \\\n\t\ttemplate<std::size_t nDepth, typename Func, std::enable_if_t<0<nDepth>* = nullptr> \\\n\t\t[[nodiscard]] constexpr auto transform(Func&& func) const& MAYTHROW { \\\n\t\t\treturn transform([&](auto const& val) MAYTHROW { return val.template transform<nDepth-1>(tc_move_if_owned(func)); }); \\\n\t\t} \\\n\t\ttemplate<std::size_t nDepth, typename Func, std::enable_if_t<0<nDepth>* = nullptr> \\\n\t\t[[nodiscard]] constexpr auto transform(Func&& func) && MAYTHROW { \\\n\t\t\treturn transform([&](auto&& val) MAYTHROW { return tc_move_if_owned(val).template transform<nDepth-1>(tc_move_if_owned(func)); }); \\\n\t\t} \\\n\t)\n\n#define DEFINE_MEMBER_TRANSFORM_2(class_template, value_template) \\\n\tDEFINE_MEMBER_TRANSFORM_3(class_template, value_template, T)\n\n#define DEFINE_MEMBER_TRANSFORM_1(class_template) \\\n\tDEFINE_MEMBER_TRANSFORM_2(class_template, tc::mp_identity)\n\n#define DEFINE_MEMBER_TRANSFORM(...) \\\n\tBOOST_PP_OVERLOAD(DEFINE_MEMBER_TRANSFORM_, __VA_ARGS__)(__VA_ARGS__)\n"
  },
  {
    "path": "tc/range/transform.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/element.h\"\n#include \"../algorithm/size.h\"\n#include \"../array.h\"\n#include \"filter_adaptor.h\"\n#include \"transform_adaptor.h\"\n\nnamespace {\n\t[[maybe_unused]] void static_tests() noexcept {\n\t\tauto rngSize = tc::transform(tc::vector<int>(), [](int) noexcept { return 0; });\n\t\tstatic_assert(tc::has_size<decltype(rngSize)>);\n\n\t\tauto rngNoSize = tc::transform(tc::filter(tc::vector<int>(), [](int) noexcept { return false; }), [](int) noexcept { return 0; });\n\t\tstatic_assert(!tc::has_size<decltype(rngNoSize)>);\n\n\t\tint anNative[] = {1,2,3,4,5};\n\t\tauto anTc = tc::make_array(anNative);\n\t\tauto anTc2 = tc::make_array(anTc);\n\t\tauto anNativeTrans = tc::make_array(tc::transform(anNative, tc::identity()));\n\t\tauto anTcTrans = tc::make_array(tc::transform(anTc, tc::identity()));\n\n\t\tstatic_assert( tc::constexpr_size<decltype(anTc)>() == tc::constexpr_size<decltype(anNative)>() );\n\t\tstatic_assert( tc::constexpr_size<decltype(anTc2)>() == tc::constexpr_size<decltype(anNative)>() );\n\t\tstatic_assert( tc::constexpr_size<decltype(anNativeTrans)>() == tc::constexpr_size<decltype(anNative)>() );\n\t\tstatic_assert( tc::constexpr_size<decltype(anTcTrans)>() == tc::constexpr_size<decltype(anNative)>() );\n\n\t\tauto rngnoncopy = tc::transform(tc_as_constexpr(tc::make_array(tc::aggregate_tag, 1,2)), [](int) noexcept {\n\t\t\tstruct NonCopyNonMoveable final {\n\t\t\t\tNonCopyNonMoveable(NonCopyNonMoveable const&) = delete;\n\t\t\t\tNonCopyNonMoveable(NonCopyNonMoveable&&) = delete;\n\n\t\t\t\tNonCopyNonMoveable() {}\n\t\t\t};\n\t\t\treturn NonCopyNonMoveable();\n\t\t});\n\t\ttc::for_each(\n\t\t\trngnoncopy,\n\t\t\t[](auto&& noncopy) noexcept {}\n\t\t);\n\t\t[[maybe_unused]] auto noncopy = tc::front(rngnoncopy);\n\t}\n}\n\nUNITTESTDEF(vector_int_ref_need_sfinae_transform) {\n\ttc::vector<int> vecn{1,2,3};\n\tauto rgntrnsfn = tc::transform(vecn, [](int& n) noexcept {return n*n;});\n\tauto it = tc::begin(rgntrnsfn);\n\t_ASSERTEQUAL(*it++,1);\n\t_ASSERTEQUAL(*it++,4);\n\t_ASSERTEQUAL(*it++,9);\n}\n"
  },
  {
    "path": "tc/range/transform_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/move.h\"\n\n#include \"range_adaptor.h\"\n#include \"subrange.h\"\n#include \"meta.h\"\n\n#include \"transform.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename Func, typename Sink>\n\t\tstruct transform_sink /*final*/ {\n\t\t\tstatic_assert(tc::decayed<Sink>);\n\t\t\tusing guaranteed_break_or_continue = guaranteed_break_or_continue_t<Sink>;\n\t\t\tFunc const& m_func;\n\t\t\tSink m_sink;\n\n\t\t\ttemplate<typename T>\n\t\t\tconstexpr auto operator()(T&& t) const& return_decltype_MAYTHROW(\n\t\t\t\ttc_invoke(m_sink, tc_invoke(m_func, tc_move_if_owned(t)))\n\t\t\t)\n\t\t};\n\t}\n\n\tnamespace transform_adaptor_adl {\n\t\ttemplate< typename Func, typename Rng, bool HasIterator=tc::range_with_iterators< Rng > >\n\t\tstruct transform_adaptor;\n\n\t\ttemplate< typename Func, typename Rng >\n\t\tstruct [[nodiscard]] transform_adaptor<Func,Rng,false> : tc::generator_range_adaptor<Rng> {\n\t\tprotected:\n\t\t\tstatic_assert(tc::decayed<Func>);\n\t\t\tFunc m_func;\n\n\t\tpublic:\n\t\t\tconstexpr transform_adaptor() = default;\n\t\t\ttemplate< typename RngOther, typename FuncOther >\n\t\t\tconstexpr transform_adaptor( RngOther&& rng, FuncOther&& func ) noexcept\n\t\t\t\t: transform_adaptor::generator_range_adaptor(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_func(tc_move_if_owned(func))\n\t\t\t{}\n\n\t\t\tconstexpr auto size() const& MAYTHROW requires tc::has_size<Rng> {\n\t\t\t\treturn tc::compute_range_adaptor_size<tc::identity{}>(this->base_range());\n\t\t\t}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tconstexpr auto adapted_sink(Sink&& sink, bool /*bReverse*/) const& noexcept {\n\t\t\t\treturn tc::no_adl::transform_sink<Func, tc::decay_t<Sink>>{m_func, tc_move_if_owned(sink)};\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, transform_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<tc::mp_transform<boost::mp11::mp_bind_front<tc::transform_output_t, Func>::template fn, tc::range_output_t<decltype(std::declval<Self>().base_range())>>> {} // unevaluated\n\t\t};\n\n\n\t\ttemplate< typename Func, typename Rng >\n\t\tstruct [[nodiscard]] transform_adaptor<Func, Rng, true>\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\ttransform_adaptor<Func, Rng, true>,\n\t\t\t\tRng, tc::index_range_adaptor_flags::inherit_begin_end | tc::index_range_adaptor_flags::inherit_traversal,\n\t\t\t\ttransform_adaptor<Func, Rng, false>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing base_ = typename transform_adaptor::index_range_adaptor;\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\t\t\t// TODO: static constexpr bool c_bHasStashingIndex=false if dereference returns a prvalue?\n\t\t\tstatic constexpr bool c_bPrefersForEach = tc::prefers_for_each<std::remove_reference_t<Rng>>;\n\n\t\t\tconstexpr transform_adaptor() = default;\n\t\t\tusing base_::base_;\n\t\t\t\n\t\t\ttemplate <ENABLE_SFINAE, typename Index>\n\t\t\tconstexpr auto STATIC_VIRTUAL_METHOD_NAME(dereference_index)(Index&& idx) & return_decltype_allow_xvalue_slow_MAYTHROW(\n\t\t\t\t// always call operator() const, which is assumed to be thread-safe\n\t\t\t\ttc_invoke(tc::as_const(SFINAE_VALUE(this->m_func)), tc::dereference_index(this->base_range(), tc_move_if_owned(idx)))\n\t\t\t)\n\t\t\ttemplate <ENABLE_SFINAE, typename Index>\n\t\t\tconstexpr auto STATIC_VIRTUAL_METHOD_NAME(dereference_index)(Index&& idx) const& return_decltype_allow_xvalue_slow_MAYTHROW(\n\t\t\t\ttc_invoke(SFINAE_VALUE(this->m_func), tc::dereference_index(this->base_range(), tc_move_if_owned(idx)))\n\t\t\t)\n\n\t\t\tstatic constexpr decltype(auto) border_base_index(auto&& idx) noexcept {\n\t\t\t\treturn tc_move_if_owned(idx);\n\t\t\t}\n\n\t\t\tstatic constexpr decltype(auto) element_base_index(auto&& idx) noexcept {\n\t\t\t\treturn tc_move_if_owned(idx);\n\t\t\t}\n\n\t\t\tconstexpr decltype(auto) dereference_untransform(auto&& idx) const& MAYTHROW {\n\t\t\t\treturn tc::dereference_index(this->base_range(), tc_move_if_owned(idx));\n\t\t\t}\n\t\t};\n\t}\n\tusing transform_adaptor_adl::transform_adaptor;\n\n\ttemplate<typename Func, typename Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::transform_adaptor<Func, Rng, true>> = tc::stable_index_on_move<Rng>;\n\n\ttemplate<typename Rng, typename Func>\n\t[[nodiscard]] constexpr auto transform(Rng&& rng, Func&& func)\n\t\treturn_ctor_noexcept(TC_FWD(transform_adaptor<tc::decay_t<Func>, Rng >), (tc_move_if_owned(rng), tc_move_if_owned(func)))\n\n\t// A range like `tc::concat` produces different types for generators, but only the common reference when used as an iterator.\n\t// Use `tc::transform_generator_only` if the transformation function does not work with the common reference.\n\ttemplate<typename Rng, typename Func>\n\t[[nodiscard]] constexpr auto transform_generator_only(Rng&& rng, Func&& func)\n\t\treturn_ctor_noexcept(TC_FWD(transform_adaptor<tc::decay_t<Func>, Rng, false >), (tc_move_if_owned(rng), tc_move_if_owned(func)))\n\n\ttemplate<typename Rng>\n\trequires tc::instance_ttn<std::remove_reference_t<Rng>, transform_adaptor>\n\t[[nodiscard]] decltype(auto) untransform(Rng&& rng) noexcept {\n\t\treturn tc_move_if_owned(rng).base_range();\n\t}\n\n\ttemplate<typename Rng >\n\trequires tc::instance_ttn<std::remove_reference_t<tc::subrange_arg_t<Rng>>, transform_adaptor>\n\t[[nodiscard]] auto untransform(Rng&& rng) noexcept {\n\t\treturn tc::slice(untransform(tc_move_if_owned(rng).base_range()), rng.begin_index(), rng.end_index());\n\t}\n}\n\n"
  },
  {
    "path": "tc/range/union_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/modified.h\"\n#include \"../algorithm/compare.h\"\n#include \"../algorithm/algorithm.h\"\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n\nnamespace tc {\n\tnamespace union_adaptor_detail::no_adl {\n\t\ttemplate<typename Sink, bool bDisjoint>\n\t\tstruct union_adaptor_sink {\n\t\t\tSink const m_sink;\n\n\t\t\tconstexpr auto operator()(interleave_2_detail::lhs_tag_t, auto&& lhs) const& MAYTHROW {\n\t\t\t\treturn tc_invoke(m_sink, tc_move_if_owned(lhs));\n\t\t\t}\n\t\t\tconstexpr auto operator()(interleave_2_detail::rhs_tag_t, auto&& rhs) const& MAYTHROW {\n\t\t\t\treturn tc_invoke(m_sink, tc_move_if_owned(rhs));\n\t\t\t}\n\t\t\tconstexpr auto operator()(interleave_2_detail::lhsrhs_tag_t, auto&& lhs, tc::unused) const& MAYTHROW {\n\t\t\t\tif constexpr(bDisjoint) {\n\t\t\t\t\t_ASSERTFALSE;\n\t\t\t\t}\n\t\t\t\treturn tc_invoke(m_sink, tc_move_if_owned(lhs));\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Comp>\n\t\tstruct SNegateComp { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tComp const m_comp;\n\t\t\tconstexpr auto operator()(auto const& lhs, auto const& rhs) const& MAYTHROW {\n\t\t\t\treturn tc::negate(tc_invoke(m_comp, lhs, rhs));\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace union_adaptor_adl {\n\n\t\ttemplate<\n\t\t\ttypename Comp,\n\t\t\ttypename Rng0,\n\t\t\ttypename Rng1,\n\t\t\tbool bDisjoint = false,\n\t\t\tbool bHasIterator = tc::ranges_with_common_reference<Rng0, Rng1>\n\t\t>\n\t\tstruct union_adaptor;\n\n\t\ttemplate<typename Comp, typename Rng0, typename Rng1, bool bDisjoint>\n\t\tstruct [[nodiscard]] union_adaptor<Comp, Rng0, Rng1, bDisjoint, false>\n\t\t{\n\t\t\ttc::tuple<\n\t\t\t\ttc::range_adaptor_base_range< Rng0 >,\n\t\t\t\ttc::range_adaptor_base_range< Rng1 >\n\t\t\t> m_tupleadaptbaserng;\n\n\t\tprotected:\n\t\t\tComp m_comp;\n\n\t\tpublic:\n\t\t\ttemplate<typename Rhs0, typename Rhs1, typename Comp2>\n\t\t\texplicit union_adaptor(Rhs0&& rhs0, Rhs1&& rhs1, Comp2&& comp) noexcept\n\t\t\t\t: m_tupleadaptbaserng{{\n\t\t\t\t\t{{aggregate_tag, tc_move_if_owned(rhs0)}},\n\t\t\t\t\t{{aggregate_tag, tc_move_if_owned(rhs1)}}\n\t\t\t\t}},\n\t\t\t\tm_comp(tc_move_if_owned(comp))\n\t\t\t{}\n\n\t\tpublic:\n\t\t\ttemplate<tc::decayed_derived_from<union_adaptor> Self, typename Sink>\n\t\t\tfriend auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn interleave_2_detail::internal_interleave_2(\n\t\t\t\t\ttc::get<0>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range(),\n\t\t\t\t\ttc::get<1>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range(),\n\t\t\t\t\ttc_move_if_owned(self).m_comp,\n\t\t\t\t\tunion_adaptor_detail::no_adl::union_adaptor_sink<Sink, bDisjoint>{tc_move_if_owned(sink)}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, union_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<boost::mp11::mp_append<\n\t\t\t\ttc::range_output_t<decltype(tc::get<0>(std::declval<Self>().m_tupleadaptbaserng).base_range())>,\n\t\t\t\ttc::range_output_t<decltype(tc::get<1>(std::declval<Self>().m_tupleadaptbaserng).base_range())>\n\t\t\t>> {} // unevaluated\n\n\t\t\ttemplate<tc::decayed_derived_from<union_adaptor> Self, typename Sink>\n\t\t\tfriend auto for_each_reverse_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\treturn interleave_2_detail::internal_interleave_2(\n\t\t\t\t\ttc::reverse(tc::get<0>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range()),\n\t\t\t\t\ttc::reverse(tc::get<1>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range()),\n\t\t\t\t\tunion_adaptor_detail::no_adl::SNegateComp<Comp>{tc_move_if_owned(self).m_comp},\n\t\t\t\t\tunion_adaptor_detail::no_adl::union_adaptor_sink<Sink, bDisjoint>{tc_move_if_owned(sink)}\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Index0, typename Index1>\n\t\tstruct union_adaptor_index : tc::tuple<Index0, Index1> {\n\t\t\t// Inherit equality from tc::tuple\n\t\t\tstd::weak_ordering m_order=std::weak_ordering::less; // dummy default value to make index default constructible\n\t\t};\n\n\t\ttemplate<\n\t\t\ttypename Comp,\n\t\t\ttypename Rng0,\n\t\t\ttypename Rng1,\n\t\t\tbool bDisjoint\n\t\t>\n\t\tstruct [[nodiscard]] union_adaptor<Comp, Rng0, Rng1, bDisjoint, true> :\n\t\t\tunion_adaptor<Comp, Rng0, Rng1, bDisjoint, false>,\n\t\t\trange_iterator_from_index<\n\t\t\t\tunion_adaptor<Comp, Rng0, Rng1, bDisjoint, true>,\n\t\t\t\tunion_adaptor_index<\n\t\t\t\t\ttc::index_t<std::remove_reference_t<\n\t\t\t\t\t\tRng0\n\t\t\t\t\t>>,\n\t\t\t\t\ttc::index_t<std::remove_reference_t<\n\t\t\t\t\t\tRng1\n\t\t\t\t\t>>\n\t\t\t\t>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = union_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tusing union_adaptor<Comp, Rng0, Rng1, bDisjoint, false>::union_adaptor;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng0>>::value || tc::has_stashing_index<std::remove_reference_t<Rng1>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\tprivate:\n\t\t\tvoid find_order(tc_index& idx) const& noexcept {\n\t\t\t\tif (base_at_end_index<0>(idx)) {\n\t\t\t\t\tidx.m_order = base_at_end_index<1>(idx) ? std::weak_ordering::less : std::weak_ordering::greater;\n\t\t\t\t} else if (base_at_end_index<1>(idx)) {\n\t\t\t\t\tidx.m_order = std::weak_ordering::less;\n\t\t\t\t} else {\n\t\t\t\t\tidx.m_order = this->m_comp(base_dereference_index<0>(idx), base_dereference_index<1>(idx));\n\t\t\t\t\tif constexpr(bDisjoint) {\n\t\t\t\t\t\t_ASSERT(tc::is_neq(idx.m_order));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<int N>\n\t\t\tvoid base_increment_index(tc_index& idx) const& noexcept {\n\t\t\t\ttc::increment_index(tc::get<N>(this->m_tupleadaptbaserng).base_range(), tc::get<N>(idx));\n\t\t\t}\n\n\t\t\ttemplate<int N>\n\t\t\tvoid base_decrement_index(tc_index& idx) const& noexcept {\n\t\t\t\ttc::decrement_index(tc::get<N>(this->m_tupleadaptbaserng).base_range(), tc::get<N>(idx));\n\t\t\t}\n\n\t\t\ttemplate<int N>\n\t\t\tbool base_at_end_index(tc_index const& idx) const& noexcept {\n\t\t\t\treturn tc::at_end_index(tc::get<N>(this->m_tupleadaptbaserng).base_range(), tc::get<N>(idx));\n\t\t\t}\n\n\t\t\ttemplate<int N>\n\t\t\tbool base_at_begin_index(tc_index const& idx) const& noexcept {\n\t\t\t\treturn tc::get<N>(idx) == tc::get<N>(this->m_tupleadaptbaserng).base_begin_index();\n\t\t\t}\n\n\t\t\ttemplate<int N, typename Index>\n\t\t\tauto base_dereference_index(Index&& idx) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::dereference_index(tc::get<N>(this->m_tupleadaptbaserng).base_range(), tc::get<N>(tc_move_if_owned(idx)))\n\t\t\t)\n\n\t\t\tSTATIC_FINAL(at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn std::is_lt(idx.m_order) && base_at_end_index<0>(idx);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(begin_index)() const& noexcept -> tc_index {\n\t\t\t\ttc_index idx{{tc::get<0>(this->m_tupleadaptbaserng).base_begin_index(), tc::get<1>(this->m_tupleadaptbaserng).base_begin_index()}};\n\t\t\t\tfind_order(idx);\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(dereference_index)(auto&& idx) const& MAYTHROW -> decltype(auto) {\n\t\t\t\treturn tc_conditional_prvalue_as_val(\n\t\t\t\t\tstd::is_lteq(idx.m_order),\n\t\t\t\t\tbase_dereference_index<0>(tc_move_if_owned(idx)),\n\t\t\t\t\tbase_dereference_index<1>(tc_move_if_owned(idx))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(end_index)() const& noexcept -> tc_index\n\t\t\t\trequires tc::has_end_index<Rng0> && tc::has_end_index<Rng1>\n\t\t\t{\n\t\t\t\ttc_index idx{{tc::get<0>(this->m_tupleadaptbaserng).base_end_index(), tc::get<1>(this->m_tupleadaptbaserng).base_end_index()}, std::weak_ordering::less};\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\tif(std::is_lt(idx.m_order)) {\n\t\t\t\t\tbase_increment_index<0>(idx);\n\t\t\t\t} else {\n\t\t\t\t\tif(tc::is_eq(idx.m_order)) {\n\t\t\t\t\t\tbase_increment_index<0>(idx);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERTDEBUG(std::is_gt(idx.m_order));\n\t\t\t\t\t}\n\t\t\t\t\tbase_increment_index<1>(idx);\n\t\t\t\t}\n\n\t\t\t\tfind_order(idx);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(decrement_index)(tc_index& idx) const& noexcept -> void\n\t\t\t\trequires tc::has_decrement_index<Rng0> && tc::has_decrement_index<Rng1>\n\t\t\t{\n\t\t\t\tif (base_at_begin_index<0>(idx)) {\n\t\t\t\t\t_ASSERT(!base_at_begin_index<1>(idx));\n\t\t\t\t\tbase_decrement_index<1>(idx);\n\t\t\t\t\tidx.m_order = std::weak_ordering::greater;\n\t\t\t\t} else if (base_at_begin_index<1>(idx)) {\n\t\t\t\t\t_ASSERT(!base_at_begin_index<0>(idx));\n\t\t\t\t\tbase_decrement_index<0>(idx);\n\t\t\t\t\tidx.m_order = std::weak_ordering::less;\n\t\t\t\t} else {\n\t\t\t\t\tauto idxOriginal = idx;\n\t\t\t\t\tbase_decrement_index<0>(idx);\n\t\t\t\t\tbase_decrement_index<1>(idx);\n\t\t\t\t\tidx.m_order = tc::negate(this->m_comp(base_dereference_index<0>(idx), base_dereference_index<1>(idx)));\n\t\t\t\t\tif(std::is_lt(idx.m_order)) {\n\t\t\t\t\t\ttc::get<1>(idx) = tc::get<1>(tc_move(idxOriginal));\n\t\t\t\t\t} else if(std::is_gt(idx.m_order)) {\n\t\t\t\t\t\ttc::get<0>(idx) = tc::get<0>(tc_move(idxOriginal));\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERTDEBUG(tc::is_eq(idx.m_order));\n\t\t\t\t\t\t_ASSERT(!bDisjoint);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// partition_point would be a more efficient customization point\n\t\t\tSTATIC_FINAL(middle_point)(tc_index& idx, tc_index const& idxEnd) const& noexcept -> void\n\t\t\t\trequires tc::has_middle_point<Rng0> && tc::has_middle_point<Rng1>\n\t\t\t{\n\t\t\t\tif (tc::get<0>(idx) == tc::get<0>(idxEnd)) {\n\t\t\t\t\ttc::middle_point(tc::get<1>(this->m_tupleadaptbaserng).base_range(), tc::get<1>(idx), tc::get<1>(idxEnd));\n\t\t\t\t\tidx.m_order = std::weak_ordering::greater;\n\t\t\t\t} else {\n\t\t\t\t\tauto idx0Begin = tc::get<0>(idx);\n\t\t\t\t\ttc::middle_point(tc::get<0>(this->m_tupleadaptbaserng).base_range(), tc::get<0>(idx), tc::get<0>(idxEnd));\n\t\t\t\t\tauto&& ref0 = base_dereference_index<0>(idx);\n\t\t\t\t\ttc::get<1>(idx) = tc::iterator2index<Rng1>(\n\t\t\t\t\t\ttc::lower_bound(\n\t\t\t\t\t\t\ttc::make_iterator(tc::get<1>(tc::as_mutable(this->m_tupleadaptbaserng)).base_range(), tc::get<1>(idx)),\n\t\t\t\t\t\t\ttc::make_iterator(tc::get<1>(tc::as_mutable(this->m_tupleadaptbaserng)).base_range(), tc::get<1>(idxEnd)),\n\t\t\t\t\t\t\tref0,\n\t\t\t\t\t\t\ttc::greaterfrom3way([&](auto const& _1, auto const& _2) noexcept { return this->m_comp(_2, _1); })\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\t\t\tif (base_at_end_index<1>(idx)) {\n\t\t\t\t\t\tidx.m_order = std::weak_ordering::less;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tauto&& ref1 = base_dereference_index<1>(idx);\n\n\t\t\t\t\t\tidx.m_order = this->m_comp(ref0, ref1);\n\t\t\t\t\t\t_ASSERT(std::is_lteq(idx.m_order));\n\n\t\t\t\t\t\tif (tc::is_eq(idx.m_order)) {\n\t\t\t\t\t\t\tauto idx0 = tc::get<0>(idx);\n\t\t\t\t\t\t\ttypename boost::range_size<Rng0>::type n = 0;\n\t\t\t\t\t\t\twhile (idx0Begin != idx0) {\n\t\t\t\t\t\t\t\ttc::decrement_index(tc::get<0>(this->m_tupleadaptbaserng).base_range(), idx0);\n\n\t\t\t\t\t\t\t\tif (tc::is_neq(this->m_comp(tc::dereference_index(tc::get<0>(this->m_tupleadaptbaserng).base_range(), idx0), ref1))) {\n\t\t\t\t\t\t\t\t\t_ASSERT(!bDisjoint);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t++n;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twhile (0<n) {\n\t\t\t\t\t\t\t\tbase_increment_index<1>(idx);\n\t\t\t\t\t\t\t\t--n;\n\n\t\t\t\t\t\t\t\tif (base_at_end_index<1>(idx) || std::is_lt(this->m_comp(ref0, base_dereference_index<1>(idx)))) {\n\t\t\t\t\t\t\t\t\tidx.m_order = std::weak_ordering::less;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing union_adaptor_adl::union_adaptor;\n\n\ttemplate<typename Comp, typename Rng0, typename Rng1, bool bDisjoint>\n\tconstexpr auto enable_stable_index_on_move<tc::union_adaptor<Comp, Rng0, Rng1, bDisjoint, true>>\n\t\t= tc::stable_index_on_move<Rng0> && tc::stable_index_on_move<Rng1>;\n\n\ttemplate<typename Comp, typename Rng0, typename Rng1, bool bDisjoint>\n\t[[nodiscard]] auto split_union(no_adl::subrange<union_adaptor<Comp, Rng0, Rng1, bDisjoint> &> const& rngsubunion) return_decltype_NOEXCEPT( // make_tuple is noexcept(false); the rest of this should only throw bad_alloc\n\t\ttc::make_tuple(\n\t\t\ttc::slice(tc::get<0>(rngsubunion.base_range().m_tupleadaptbaserng).base_range(), tc::get<0>(rngsubunion.begin_index()), tc::get<0>(rngsubunion.end_index())),\n\t\t\ttc::slice(tc::get<1>(rngsubunion.base_range().m_tupleadaptbaserng).base_range(), tc::get<1>(rngsubunion.begin_index()), tc::get<1>(rngsubunion.end_index()))\n\t\t)\n\t)\n\n\ttemplate<typename Rng0, typename Rng1, typename Comp = tc::fn_compare>\n\t[[nodiscard]] auto union_range(Rng0&& rng0, Rng1&& rng1, Comp&& comp = Comp()) return_ctor_noexcept(\n\t\tTC_FWD(union_adaptor< tc::decay_t<Comp>, Rng0, Rng1, /*bDisjoint*/false>),\n\t\t(tc_move_if_owned(rng0), tc_move_if_owned(rng1), tc_move_if_owned(comp))\n\t)\n\n\ttemplate<typename Rng0, typename Rng1, typename Comp = tc::fn_compare>\n\t[[nodiscard]] auto disjoint_union_range(Rng0&& rng0, Rng1&& rng1, Comp&& comp = Comp()) return_ctor_noexcept(\n\t\tTC_FWD(union_adaptor< tc::decay_t<Comp>, Rng0, Rng1, /*bDisjoint*/true>),\n\t\t(tc_move_if_owned(rng0), tc_move_if_owned(rng1), tc_move_if_owned(comp))\n\t)\n}\n"
  },
  {
    "path": "tc/range/unique_range_adaptor.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/static_polymorphism.h\"\n#include \"../algorithm/compare.h\"\n#include \"../algorithm/empty.h\"\n#include \"range_adaptor.h\"\n#include \"meta.h\"\n#include \"subrange.h\"\n\nnamespace tc {\n\tnamespace unique_adaptor_detail {\n\t\ttemplate<typename Rng, typename Index, typename Equals>\n\t\tconstexpr void increment_index(Rng const& rng, Index& idx0, Equals const equals) noexcept(noexcept(equals(tc::dereference_index(rng, idx0), tc::dereference_index(rng, idx0)))) {\n\t\t\tusing RefType = tc::reference_or_value<decltype(tc::dereference_index(rng, idx0))>;\n\t\t\tauto idx1 = idx0;\n\t\t\ttc::increment_index(rng, idx0);\n\t\t\tif (!tc::at_end_index(rng, idx0)) {\n\t\t\t\tRefType ref1(aggregate_tag, tc::dereference_index(rng, idx1));\n\n\t\t\t\tfor (;;) {\n\t\t\t\t\tRefType ref0(aggregate_tag, tc::dereference_index(rng, idx0));\n\t\t\t\t\tif (!equals(tc::as_const(*ref1), tc::as_const(*ref0))) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tidx1 = idx0;\n\t\t\t\t\tif constexpr( tc::has_stashing_index<std::remove_reference_t<Rng>>::value ) {\n\t\t\t\t\t\t// Moving dereferenced stashing index is impossible. Must partially unroll loop.\n\t\t\t\t\t\ttc::increment_index(rng, idx1);\n\t\t\t\t\t\tif (tc::at_end_index(rng, idx1)) {\n\t\t\t\t\t\t\tidx0 = tc_move(idx1);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tref1 = {aggregate_tag, tc::dereference_index(rng, idx1)};\n\t\t\t\t\t\tif (!equals(tc::as_const(*ref0), tc::as_const(*ref1))) {\n\t\t\t\t\t\t\tidx0 = tc_move(idx1);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tidx0 = idx1;\n\t\t\t\t\t}\n\t\t\t\t\ttc::increment_index(rng, idx0);\n\t\t\t\t\tif (tc::at_end_index(rng, idx0)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif constexpr( !tc::has_stashing_index<std::remove_reference_t<Rng>>::value ) {\n\t\t\t\t\t\tref1 = tc_move(ref0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<typename Rng, typename Index, typename Equals>\n\t\tconstexpr void decrement_index(Rng const& rng, Index& idx0, Equals const equals) noexcept(noexcept(equals(tc::dereference_index(rng, idx0), tc::dereference_index(rng, idx0)))) {\n\t\t\tusing RefType = tc::reference_or_value<decltype(tc::dereference_index(rng, idx0))>;\n\t\t\tauto const idxBegin = tc::begin_index(rng);\n\t\t\t_ASSERTE(idxBegin != idx0);\n\t\t\ttc::decrement_index(rng, idx0);\n\t\t\tif (idxBegin != idx0) {\n\t\t\t\tRefType ref0(aggregate_tag, tc::dereference_index(rng, idx0));\n\t\t\t\tauto idx1 = idx0;\n\n\t\t\t\tfor (;;) {\n\t\t\t\t\ttc::decrement_index(rng, idx1);\n\t\t\t\t\tRefType ref1(aggregate_tag, tc::dereference_index(rng, idx1));\n\t\t\t\t\tif (!equals(tc::as_const(*ref1), tc::as_const(*ref0))) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tidx0 = idx1;\n\t\t\t\t\tif (idxBegin == idx1) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif constexpr( tc::has_stashing_index<std::remove_reference_t<Rng>>::value ) {\n\t\t\t\t\t\t// Moving dereferenced stashing index is impossible. Must partially unroll loop.\n\t\t\t\t\t\ttc::decrement_index(rng, idx0);\n\t\t\t\t\t\tref0 = {aggregate_tag, tc::dereference_index(rng, idx0)};\n\t\t\t\t\t\tif (!equals(tc::as_const(*ref0), tc::as_const(*ref1))) {\n\t\t\t\t\t\t\tidx0 = tc_move(idx1);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (idxBegin == idx0) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tidx1 = idx0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tref0 = tc_move(ref1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tnamespace unique_adaptor_adl {\n\t\ttemplate<typename Rng, typename Equals, bool HasIterator = tc::range_with_iterators<Rng>>\n\t\tstruct unique_adaptor;\n\n\t\ttemplate<typename Rng, typename Equals>\n\t\tstruct [[nodiscard]] unique_adaptor<Rng, Equals, false> : tc::range_adaptor_base_range<Rng>, tc::range_output_from_base_range {\n\t\t\texplicit constexpr unique_adaptor(auto&& rng, auto&& equals) noexcept\n\t\t\t\t: tc::range_adaptor_base_range<Rng>(aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_equals(tc_move_if_owned(equals))\n\t\t\t{}\n\n\t\tprotected:\n\t\t\tstatic_assert(tc::decayed<Equals>);\n\t\t\tEquals m_equals;\n\n\t\tpublic:\n\t\t\ttemplate<tc::decayed_derived_from<unique_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tif constexpr( tc::range_with_iterators<Rng> ) {\n\t\t\t\t\tdecltype(auto) rng = self.base_range();\n\t\t\t\t\tstd::array<\n\t\t\t\t\t\tstd::pair<\n\t\t\t\t\t\t\ttc::decay_t<decltype(self.base_begin_index())>,\n\t\t\t\t\t\t\tstd::optional<tc::reference_or_value<decltype(tc::dereference_index(rng, std::declval<tc::decay_t<decltype(self.base_begin_index())>&>()))>>\n\t\t\t\t\t\t>,\n\t\t\t\t\t\t2\n\t\t\t\t\t> apairidxref;\n\t\t\t\t\tauto* ppairidxorefPrev = std::addressof(apairidxref[1]);\n\t\t\t\t\tauto* ppairidxorefCurrent = std::addressof(apairidxref[0]);\n\t\t\t\t\tppairidxorefCurrent->first = { self.base_begin_index() };\n\t\t\t\t\tusing BreakOrContinue = tc::common_type_t<decltype(tc::continue_if_not_break(sink, **ppairidxorefCurrent->second)), tc::constant<tc::continue_>>;\n\n\t\t\t\t\tbool bFirst = true;\n\n\t\t\t\t\twhile( !tc::at_end_index(rng, ppairidxorefCurrent->first) ) { // MAYTHROW\n\t\t\t\t\t\t_ASSERTDEBUG( std::is_trivially_destructible<decltype(ppairidxorefPrev->second)>::value || !ppairidxorefCurrent->second );\n\t\t\t\t\t\ttc::optional_emplace(ppairidxorefCurrent->second, aggregate_tag, tc::dereference_index(rng, ppairidxorefCurrent->first) /* MAYTHROW */ );\n\t\t\t\t\t\tif( tc::change(bFirst, false) || [&]() MAYTHROW {\n\t\t\t\t\t\t\tbool const bEqual = self.m_equals(tc::as_const(**ppairidxorefPrev->second), tc::as_const(**ppairidxorefCurrent->second)); // MAYTHROW\n\t\t\t\t\t\t\tif constexpr( !std::is_trivially_destructible<decltype(ppairidxorefPrev->second)>::value ) {\n\t\t\t\t\t\t\t\tppairidxorefPrev->second = std::nullopt;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn !bEqual;\n\t\t\t\t\t\t}() ) {\n\t\t\t\t\t\t\ttc_return_if_break(tc::implicit_cast<BreakOrContinue>(tc::continue_if_not_break(sink, **ppairidxorefCurrent->second) /* MAYTHROW */));\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttc::swap(ppairidxorefPrev, ppairidxorefCurrent);\n\t\t\t\t\t\tppairidxorefCurrent->first = ppairidxorefPrev->first;\n\t\t\t\t\t\ttc::increment_index(rng, ppairidxorefCurrent->first); // MAYTHROW\n\t\t\t\t\t}\n\n\t\t\t\t\treturn tc::implicit_cast<BreakOrContinue>(tc::constant<tc::continue_>());\n\t\t\t\t} else {\n\t\t\t\t\tstd::optional<tc::range_value_t<decltype(std::declval<Self>().base_range())>> ovalLast;\n\t\t\t\t\treturn tc::for_each(tc_move_if_owned(self).base_range(), [&](auto&& elem) MAYTHROW {\n\t\t\t\t\t\tbool const bSkip = tc::and_then(ovalLast, [&](auto const& valLast) MAYTHROW {\n\t\t\t\t\t\t\treturn self.m_equals(valLast, tc::as_const(elem)); // MAYTHROW\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttc::optional_emplace(ovalLast, tc_move_if_owned(elem));\n\t\t\t\t\t\treturn tc_conditional_prvalue_as_val(bSkip, tc::constant<tc::continue_>(), tc::continue_if_not_break(sink, *ovalLast) /*MAYTHROW*/);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool empty() const& noexcept {\n\t\t\t\treturn tc::empty(this->base_range());\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Rng, typename Equals>\n\t\tstruct [[nodiscard]] unique_adaptor<Rng, Equals, true>\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\tunique_adaptor<Rng, Equals, true>,\n\t\t\t\tRng,\n\t\t\t\ttc::index_range_adaptor_flags::inherit_begin_end | tc::index_range_adaptor_flags::inherit_dereference,\n\t\t\t\tunique_adaptor<Rng, Equals, false>\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = unique_adaptor;\n\t\t\tusing base_ = typename unique_adaptor::index_range_adaptor;\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\t\tconstexpr unique_adaptor() = default;\n\t\t\tusing base_::base_;\n\t\t\t\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept(noexcept(unique_adaptor_detail::increment_index(this->base_range(), idx, this->m_equals))) -> void {\n\t\t\t\t_ASSERTE(!this->at_end_index(idx));\n\t\t\t\tunique_adaptor_detail::increment_index(this->base_range(), idx, this->m_equals);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& noexcept(noexcept(unique_adaptor_detail::decrement_index(this->base_range(), idx, this->m_equals))) -> void\n\t\t\t\trequires tc::has_decrement_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\tunique_adaptor_detail::decrement_index(this->base_range(), idx, this->m_equals);\n\t\t\t}\n\t\t};\n\t}\n\tusing unique_adaptor_adl::unique_adaptor;\n\n\ttemplate<typename Rng, typename Equals>\n\tconstexpr auto enable_stable_index_on_move<unique_adaptor<Rng, Equals, true>> = tc::stable_index_on_move<Rng>;\n\n\tnamespace subrange_range_adaptor_detail::no_adl {\n\t\ttemplate<typename IndexBase>\n\t\tstruct subrange_range_index {\n\t\t\tIndexBase m_idxBegin;\n\t\t\tIndexBase m_idxEnd;\n\n\t\t\tfriend constexpr bool operator==(subrange_range_index const& lhs, subrange_range_index const& rhs) noexcept {\n\t\t\t\treturn EQUAL_MEMBERS(m_idxBegin);\n\t\t\t}\n\t\t};\n\t}\n\n\tnamespace subrange_range_adaptor_adl {\n\t\ttemplate<typename Derived, typename Rng>\n\t\tstruct subrange_range_adaptor\n\t\t\t: range_iterator_from_index<Derived, subrange_range_adaptor_detail::no_adl::subrange_range_index<tc::index_t<std::remove_reference_t<Rng>>>>\n\t\t\t, protected tc::range_adaptor_base_range<Rng>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = subrange_range_adaptor;\n\n\t\tpublic:\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tstatic constexpr bool c_bHasStashingIndex = false;\n\n\t\t\tusing subrange_range_adaptor::range_adaptor_base_range::range_adaptor_base_range;\n\n\t\tprivate:\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\treturn tc::at_end_index(this->base_range(),idx.m_idxBegin);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, end_index)() const& noexcept -> tc_index requires tc::has_end_index<std::remove_reference_t<Rng>> {\n\t\t\t\tauto idxEnd = this->base_end_index();\n\t\t\t\treturn {idxEnd, idxEnd};\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, dereference_index)(auto&& idx) const& noexcept -> decltype(auto) { // return_decltype_noexcept confuses MSVC 19.39\n\t\t\t\treturn tc::slice(this->base_range(), tc_move_if_owned(idx).m_idxBegin, tc_move_if_owned(idx).m_idxEnd);\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, dereference_index)(auto&& idx) & noexcept -> decltype(auto) { // return_decltype_noexcept confuses MSVC 19.39\n\t\t\t\treturn tc::slice(this->base_range(), tc_move_if_owned(idx).m_idxBegin, tc_move_if_owned(idx).m_idxEnd);\n\t\t\t}\n\t\t};\n\t}\n\tusing subrange_range_adaptor_adl::subrange_range_adaptor;\n\n\tnamespace partition_range_adaptor_adl {\n\t\ttemplate<typename Derived, typename Rng>\n\t\tstruct partition_range_adaptor : subrange_range_adaptor<Derived, Rng> {\n\t\t\tusing typename partition_range_adaptor::subrange_range_adaptor::tc_index;\n\t\tprivate:\n\t\t\tusing this_type = partition_range_adaptor;\n\t\tprotected:\n\t\t\tSTATIC_VIRTUAL(FindPartitionEnd) // (index_t<Rng>&) -> void\n\t\tprivate:\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\tauto const idxBegin = this->base_begin_index();\n\t\t\t\ttc_index idx{idxBegin, idxBegin};\n\t\t\t\tif( !tc::at_end_index(this->base_range(), idx.m_idxEnd) ) {\n\t\t\t\t\tFindPartitionEnd(idx.m_idxEnd);\n\t\t\t\t}\n\t\t\t\treturn idx;\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\t_ASSERT( idx.m_idxBegin != idx.m_idxEnd );\n\t\t\t\tidx.m_idxBegin = idx.m_idxEnd;\n\t\t\t\tif( !tc::at_end_index(this->base_range(), idx.m_idxEnd) ) {\n\t\t\t\t\tFindPartitionEnd(idx.m_idxEnd);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tusing this_type::subrange_range_adaptor::subrange_range_adaptor;\n\n\t\t\ttemplate<typename PartitionRange, std::enable_if_t<\n\t\t\t\ttc::decayed_derived_from<PartitionRange, partition_range_adaptor>\n\t\t\t>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend constexpr auto join_impl(PartitionRange&& partrng) return_decltype_allow_xvalue_noexcept(\n\t\t\t\ttc_move_if_owned(partrng).base_range()\n\t\t\t)\n\n\t\t\ttemplate<typename SubPartitionRange, std::enable_if_t<\n\t\t\t\ttc::decayed_derived_from<tc::subrange_arg_t<SubPartitionRange>, partition_range_adaptor>\n\t\t\t>* = nullptr>\n\t\t\tfriend constexpr auto join_impl(SubPartitionRange&& subpartrng) return_decltype_noexcept(\n\t\t\t\ttc::slice(\n\t\t\t\t\ttc_move_if_owned(subpartrng).base_range().base_range(),\n\t\t\t\t\ttc_move_if_owned(subpartrng).begin_index().m_idxBegin,\n\t\t\t\t\ttc_move_if_owned(subpartrng).end_index().m_idxBegin\n\t\t\t\t)\n\t\t\t)\n\t\t};\n\t}\n\tusing partition_range_adaptor_adl::partition_range_adaptor;\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng, typename Equals>\n\t\tstruct [[nodiscard]] unique_range_front_adaptor : partition_range_adaptor<unique_range_front_adaptor<Rng, Equals>, Rng>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = unique_range_front_adaptor;\n\t\t\tstatic_assert(tc::decayed<Equals>);\n\t\t\tEquals m_equals;\n\n\t\tpublic:\n\t\t\ttemplate<typename RhsRng, typename RhsEquals>\n\t\t\tconstexpr unique_range_front_adaptor(RhsRng&& rng, RhsEquals&& equals) noexcept\n\t\t\t\t: this_type::partition_range_adaptor(tc::aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_equals(tc_move_if_owned(equals))\n\t\t\t{}\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, FindPartitionEnd)(tc::index_t<std::remove_reference_t<Rng>>& idx) const& noexcept -> void {\n\t\t\t\tauto idxBegin = idx; // Necessary, if tc::has_stashing_index<std::remove_reference_t<Rng>>::value\n\t\t\t\tdecltype(auto) front = tc::dereference_index(this->base_range(), idxBegin);\n\t\t\t\tstatic_assert( !std::is_rvalue_reference<decltype(front)>::value ); // rvalue reference should be safe, or is it not?\n\t\t\t\tdo {\n\t\t\t\t\ttc::increment_index(this->base_range(),idx);\n\t\t\t\t} while (!tc::at_end_index(this->base_range(),idx) && this->m_equals(tc::as_const(front), tc::as_const(tc::dereference_index(this->base_range(),idx))));\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Rng, typename Equals>\n\t\tstruct [[nodiscard]] unique_range_adjacent_adaptor : partition_range_adaptor<unique_range_adjacent_adaptor<Rng, Equals>, Rng>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = unique_range_adjacent_adaptor;\n\t\t\tstatic_assert(tc::decayed<Equals>);\n\t\t\tEquals m_equals;\n\n\t\tpublic:\n\t\t\ttemplate<typename RhsRng, typename RhsEquals>\n\t\t\texplicit unique_range_adjacent_adaptor(RhsRng&& rng, RhsEquals&& equals) noexcept\n\t\t\t\t: this_type::partition_range_adaptor(tc::aggregate_tag, tc_move_if_owned(rng))\n\t\t\t\t, m_equals(tc_move_if_owned(equals))\n\t\t\t{}\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, FindPartitionEnd)(tc::index_t<std::remove_reference_t<Rng>>& idx) const& noexcept -> void {\n\t\t\t\tunique_adaptor_detail::increment_index(this->base_range(), idx, m_equals);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\tconstexpr,\n\t\t\t\tdecrement_index\n\t\t\t)(typename this_type::tc_index& idx) const& noexcept -> void\n\t\t\t\trequires tc::has_decrement_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\tidx.m_idxEnd = idx.m_idxBegin;\n\t\t\t\tunique_adaptor_detail::decrement_index(this->base_range(), idx.m_idxBegin, m_equals);\n\t\t\t}\n\t\t};\n\t}\n\n\tusing no_adl::unique_range_front_adaptor;\n\tusing no_adl::unique_range_adjacent_adaptor;\n\n\ttemplate<typename Rng, typename Equals>\n\tconstexpr auto enable_stable_index_on_move<unique_range_front_adaptor<Rng, Equals>> = tc::stable_index_on_move<Rng>;\n\ttemplate<typename Rng, typename Equals>\n\tconstexpr auto enable_stable_index_on_move<unique_range_adjacent_adaptor<Rng, Equals>> = tc::stable_index_on_move<Rng>;\n\n\ttemplate<typename Rng, typename Equals = decltype(tc::equal_to)>\n\tconstexpr auto front_unique_range(Rng&& rng, Equals&& equals = {}) return_ctor_noexcept(\n\t\tTC_FWD(unique_range_front_adaptor< Rng, tc::decay_t<Equals> >),\n\t\t(tc_move_if_owned(rng), tc_move_if_owned(equals))\n\t)\n\n\ttemplate<typename Rng, typename Equals = decltype(tc::equal_to)>\n\tauto adjacent_unique_range(Rng&& rng, Equals&& equals = {}) return_ctor_noexcept(\n\t\tTC_FWD(unique_range_adjacent_adaptor< Rng, tc::decay_t<Equals> >),\n\t\t(tc_move_if_owned(rng), tc_move_if_owned(equals))\n\t)\n\n\t/*\n\t\tIn contrast to std::unique, tc::adjacent_unique / tc::adjacent_unique_inplace always compares adjacent elements. This allows implementing\n\t\tbidirectional tc::adjacent_unique, with tc::adjacent_unique_inplace yielding the same result.\n\t*/\n\ttemplate<typename Rng, typename Equals = decltype(tc::equal_to)>\n\tconstexpr auto adjacent_unique(Rng&& rng, Equals&& equals = {}) return_ctor_noexcept(\n\t\tTC_FWD(unique_adaptor< Rng, tc::decay_t<Equals> >),\n\t\t(tc_move_if_owned(rng), tc_move_if_owned(equals))\n\t)\n}\n"
  },
  {
    "path": "tc/range/zip_range.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/functors.h\"\n#include \"../base/utility.h\"\n#include \"../algorithm/quantifier.h\"\n#include \"../algorithm/element.h\"\n#include \"../algorithm/size_linear.h\"\n#include \"../algorithm/empty.h\"\n#include \"filter_adaptor.h\"\n#include \"range_adaptor.h\"\n#include \"reverse_adaptor.h\"\n#include \"iota_range.h\"\n\nnamespace tc {\n\tnamespace zip_detail::no_adl {\n\t\ttemplate<\n\t\t\ttypename Self, typename Sink, bool bReverse,\n\t\t\ttypename PrefixSeq = std::make_index_sequence<Self::generator_index()>,\n\t\t\ttypename SuffixSeq = std::make_index_sequence<Self::c_nZipAdaptorFactors - Self::generator_index() - 1>\n\t\t>\n\t\tstruct zip_adaptor_sink;\n\n\t\ttemplate<typename Self, typename Sink, bool bReverse, std::size_t... nPrefix/*=0,...,generator_index()-1*/, std::size_t... nSuffix/*=0,...,sizeof...(Rng)-generator_index()-2*/>\n\t\tstruct zip_adaptor_sink<Self, Sink, bReverse, std::index_sequence<nPrefix...>, std::index_sequence<nSuffix...>> {\n\t\t\tusing guaranteed_break_or_continue = std::conditional_t<\n\t\t\t\tstd::is_same<tc::constant<tc::continue_>, tc::guaranteed_break_or_continue_t<Sink>>::value,\n\t\t\t\ttc::constant<tc::continue_>,\n\t\t\t\ttc::break_or_continue\n\t\t\t>;\n\n\t\tprivate:\n\t\t\tSelf& m_self;\n\t\t\tSink const m_sink;\n\t\t\ttc::tuple<decltype(tc::get<nPrefix>(std::declval<Self&>().m_tupleadaptbaserng).base_begin_index())...> m_tplidxPrefix;\n\t\t\ttc::tuple<decltype(tc::get<sizeof...(nPrefix) + 1 + nSuffix>(std::declval<Self&>().m_tupleadaptbaserng).base_begin_index())...> m_tplidxSuffix;\n\n\t\t\ttemplate<std::size_t n>\n\t\t\tconstexpr decltype(auto) PrefixBase() const& noexcept {\n\t\t\t\treturn tc::get<n>(m_self.m_tupleadaptbaserng);\n\t\t\t}\n\n\t\t\ttemplate<std::size_t n>\n\t\t\tconstexpr decltype(auto) SuffixBase() const& noexcept {\n\t\t\t\treturn tc::get<sizeof...(nPrefix) + 1 + n>(m_self.m_tupleadaptbaserng);\n\t\t\t}\n\n\t\tpublic:\n\t\t\tconstexpr zip_adaptor_sink(Self& self, auto&& sink) MAYTHROW\n\t\t\t\t: m_self(self)\n\t\t\t\t, m_sink(tc_move_if_owned(sink))\n\t\t\t\t, m_tplidxPrefix{{ {bReverse ? PrefixBase<nPrefix>().base_end_index() : PrefixBase<nPrefix>().base_begin_index()}... }} // MAYTHROW\n\t\t\t\t, m_tplidxSuffix{{ {bReverse ? SuffixBase<nSuffix>().base_end_index() : SuffixBase<nSuffix>().base_begin_index()}... }} // MAYTHROW\n\t\t\t{}\n\n\t\t\tconstexpr auto operator()(auto&& u) & MAYTHROW {\n\t\t\t\tif constexpr(bReverse) {\n\t\t\t\t\t(tc::decrement_index(PrefixBase<nPrefix>().base_range(), tc::get<nPrefix>(m_tplidxPrefix)), ...); // MAYTHROW\n\t\t\t\t\t(tc::decrement_index(SuffixBase<nSuffix>().base_range(), tc::get<nSuffix>(m_tplidxSuffix)), ...); // MAYTHROW\n\t\t\t\t}\n\t\t\t\tauto const boc = tc::continue_if_not_break(\n\t\t\t\t\tm_sink,\n\t\t\t\t\ttc::tie(\n\t\t\t\t\t\ttc::dereference_index(PrefixBase<nPrefix>().base_range(), tc::get<nPrefix>(m_tplidxPrefix))...,  // MAYTHROW\n\t\t\t\t\t\ttc_move_if_owned(u),\n\t\t\t\t\t\ttc::dereference_index(SuffixBase<nSuffix>().base_range(), tc::get<nSuffix>(m_tplidxSuffix))...  // MAYTHROW\n\t\t\t\t\t)\n\t\t\t\t); // MAYTHROW\n\t\t\t\tif constexpr(!bReverse) {\n\t\t\t\t\tif( tc::continue_ == boc ) {\n\t\t\t\t\t\t(tc::increment_index(PrefixBase<nPrefix>().base_range(), tc::get<nPrefix>(m_tplidxPrefix)), ...); // MAYTHROW\n\t\t\t\t\t\t(tc::increment_index(SuffixBase<nSuffix>().base_range(), tc::get<nSuffix>(m_tplidxSuffix)), ...); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn boc;\n\t\t\t}\n#ifdef _CHECKS\n\t\t\tconstexpr bool SameLength() const& MAYTHROW {\n\t\t\t\tif constexpr(bReverse) {\n\t\t\t\t\treturn ((tc::begin_index(PrefixBase<nPrefix>().base_range()) == tc::get<nPrefix>(m_tplidxPrefix)) && ...) // MAYTHROW\n\t\t\t\t\t\t&& ((tc::begin_index(SuffixBase<nSuffix>().base_range()) == tc::get<nSuffix>(m_tplidxSuffix)) && ...); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\treturn (tc::at_end_index(PrefixBase<nPrefix>().base_range(), tc::get<nPrefix>(m_tplidxPrefix)) && ...) // MAYTHROW\n\t\t\t\t\t\t&& (tc::at_end_index(SuffixBase<nSuffix>().base_range(), tc::get<nSuffix>(m_tplidxSuffix)) && ...); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t};\n\t}\n\n\tnamespace no_adl {\n\n\t\ttemplate<typename...>\n\t\tstruct smallest_numeric_type;\n\n\t\ttemplate<typename A>\n\t\tstruct smallest_numeric_type<A> {\n\t\t\tusing type = A;\n\t\t};\n\n\t\ttemplate<typename A, typename B, typename... Rest>\n\t\tstruct smallest_numeric_type<A, B, Rest...>\n\t\t\t: smallest_numeric_type<std::conditional_t<std::numeric_limits<B>::max() < std::numeric_limits<A>::max(), B, A>, Rest...>\n\t\t{};\n\n\t\ttemplate<typename... T>\n\t\tusing smallest_numeric_type_t = typename smallest_numeric_type<T...>::type;\n\n\t\ttemplate<typename Rng>\n\t\tusing range_difference_t = typename boost::range_difference<std::remove_cvref_t<Rng>>::type;\n\n#if defined(__clang__)\n\t\ttemplate<typename T>\n\t\tusing is_range_with_iterators = tc::constant<tc::range_with_iterators<T>>;\n\t\ttemplate<typename T>\n\t\tusing prefers_for_each_workaround = tc::constant<tc::prefers_for_each<T>>;\n#endif\n\n\t\ttemplate<typename T, typename ConstIndex, typename... Rng>\n\t\tusing zip_adaptor_with_generator_forwarding_tuple_t = tc::mp_transform<\n\t\t\tstd::add_rvalue_reference_t,\n\t\t\tboost::mp11::mp_replace_at<\n\t\t\t\tboost::mp11::mp_transform_if<\n#ifdef __clang__\n\t\t\t\t\tis_range_with_iterators, // workaround Xcode14 clang segmentation fault\n#else\n\t\t\t\t\tTRAITFROMCONCEPT(tc::range_with_iterators),\n#endif\n\t\t\t\t\ttc::mp_chained<std::iter_reference_t, tc::iterator_t>::template fn, \n\t\t\t\t\ttc::tuple<Rng...>\n\t\t\t\t>,\n\t\t\t\tConstIndex, T\n\t\t\t>\n\t\t>;\n\n\t\ttemplate<typename... Rng>\n\t\tusing zip_adaptor_prefers_for_each = boost::mp11::mp_any_of<\n\t\t\tboost::mp11::mp_list<std::remove_reference_t<Rng>...>,\n#ifdef __clang__\n\t\t\tprefers_for_each_workaround // workaround Xcode14 clang segmentation fault\n#else\n\t\t\tTRAITFROMCONCEPT(tc::prefers_for_each)\n#endif\n\t\t>;\n\n\t\ttemplate<typename Rng, typename Self>\n\t\tusing apply_cvref_to_base_range_t = decltype(std::declval<tc::apply_cvref_t<tc::range_adaptor_base_range<Rng>, Self>>().base_range());\n\n\t\tnamespace trait_from_concept_workaround { // workaround Xcode14.1 segmentation fault\n\t\t\ttemplate<typename Rng>\n\t\t\tusing has_constexpr_size = tc::constant<tc::has_constexpr_size<Rng>>;\n\t\t}\n\n\t\ttemplate<\n\t\t\tbool HasIterator,\n\t\t\ttypename... Rng\n\t\t>\n\t\tstruct [[nodiscard]] zip_adaptor {\n\t\tprotected:\n\t\t\ttc::tuple<tc::range_adaptor_base_range<Rng>...> m_tupleadaptbaserng;\n\n\t\t\ttemplate<typename Self, typename Sink, bool bReverse, typename PrefixSeq, typename SuffixSeq>\n\t\t\tfriend struct zip_detail::no_adl::zip_adaptor_sink;\n\n\t\tpublic:\n\t\t\tstatic auto constexpr c_nZipAdaptorFactors = sizeof...(Rng);\n\n\t\t\tstatic constexpr std::size_t generator_index() noexcept {\n\t\t\t\tusing PureGenerator = tc::mp_find_unique_if<\n\t\t\t\t\tboost::mp11::mp_list<Rng...>,\n\t\t\t\t\tboost::mp11::mp_not_fn<\n#ifdef __clang__\n\t\t\t\t\t\tis_range_with_iterators // workaround Xcode14 clang segmentation fault\n#else\n\t\t\t\t\t\tTRAITFROMCONCEPT(tc::range_with_iterators)\n#endif\n\t\t\t\t\t>::template fn\n\t\t\t\t>;\n\t\t\t\tif constexpr(PureGenerator::found) {\n\t\t\t\t\treturn PureGenerator::index;\n\t\t\t\t} else {\n\t\t\t\t\t// Heuristically select generator of range with complex iterators.\n\t\t\t\t\treturn boost::mp11::mp_find_if<\n\t\t\t\t\t\tboost::mp11::mp_list<std::remove_reference_t<Rng>...>,\n#ifdef __clang__\n\t\t\t\t\t\tprefers_for_each_workaround // workaround Xcode14 clang segmentation fault\n#else\n\t\t\t\t\t\tTRAITFROMCONCEPT(tc::prefers_for_each)\n#endif\n\t\t\t\t\t>::value % sizeof...(Rng);\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\ttemplate<typename... RngRef>\n\t\t\tconstexpr zip_adaptor(aggregate_tag_t, RngRef&&... rng) noexcept\n\t\t\t\t: m_tupleadaptbaserng{{ {{aggregate_tag, tc_move_if_owned(rng)}}... }}\n\t\t\t{}\n\n\t\t\ttemplate<tc::decayed_derived_from<zip_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tzip_detail::no_adl::zip_adaptor_sink<std::remove_reference_t<Self>, tc::decay_t<Sink>, /*bReverse*/false> adaptedsink(self, tc_move_if_owned(sink)); // MAYTHROW\n\t\t\t\tauto const boc = tc::for_each(\n\t\t\t\t\ttc::get<generator_index()>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range(),\n\t\t\t\t\tstd::ref(adaptedsink)\n\t\t\t\t);  // MAYTHROW\n\t\t\t\t_ASSERTE( tc::break_ == boc || adaptedsink.SameLength() );\n\t\t\t\treturn boc;\n\t\t\t}\n\n\t\t\ttemplate<tc::decayed_derived_from<zip_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_reverse_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tzip_detail::no_adl::zip_adaptor_sink<std::remove_reference_t<Self>, tc::decay_t<Sink>, /*bReverse*/true> adaptedsink(self, tc_move_if_owned(sink)); // MAYTHROW\n\t\t\t\tauto const boc = tc::for_each(\n\t\t\t\t\ttc::reverse(tc::get<generator_index()>(tc_move_if_owned(self).m_tupleadaptbaserng).base_range()),\n\t\t\t\t\tstd::ref(adaptedsink)\n\t\t\t\t); // MAYTHROW\n\t\t\t\t_ASSERTE( tc::break_ == boc || adaptedsink.SameLength() );\n\t\t\t\treturn boc;\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, zip_adaptor>>* = nullptr> // use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> boost::mp11::mp_unique<tc::mp_transform<\n\t\t\t\tboost::mp11::mp_bind_back<\n\t\t\t\t\tzip_adaptor_with_generator_forwarding_tuple_t,\n\t\t\t\t\ttc::constant<generator_index()>,\n\t\t\t\t\tapply_cvref_to_base_range_t<Rng, Self>...\n\t\t\t\t>::template fn,\n\t\t\t\ttc::range_output_t<apply_cvref_to_base_range_t<boost::mp11::mp_at_c<boost::mp11::mp_list<Rng...>, generator_index()>, Self>>\n\t\t\t>> {} // unevaluated\n\n\t\tpublic:\n\t\t\tconstexpr auto size() const& MAYTHROW requires (... || tc::has_size<Rng>) && (!(... || tc::has_constexpr_size<Rng>)) {\n\t\t\t\treturn tc::all_same_element<tc::return_value>(tc::generator_range_output<std::size_t>(tc::transform(\n\t\t\t\t\ttc::filter(m_tupleadaptbaserng, [](auto const& rng) noexcept {\n\t\t\t\t\t\treturn tc::constant<tc::has_size<decltype(rng.base_range())>>{};\n\t\t\t\t\t}),\n\t\t\t\t\t[](auto const& rng) noexcept {\n\t\t\t\t\t\treturn tc::size_raw(rng.base_range());\n\t\t\t\t\t}\n\t\t\t\t)));\n\t\t\t}\n\n\t\t\tconstexpr auto size() const& noexcept requires (... || tc::has_constexpr_size<Rng>) {\n\t\t\t\tusing sized_rng = boost::mp11::mp_front<boost::mp11::mp_filter<trait_from_concept_workaround::has_constexpr_size, boost::mp11::mp_list<Rng...>>>;\n\t\t\t\treturn tc::constexpr_size<sized_rng>;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename... Index>\n\t\tstruct zip_index : tc::tuple<Index...> {\n\t\t\tfriend bool operator==(zip_index const& lhs, zip_index const& rhs) noexcept {\n\t\t\t\treturn tc::get<0>(lhs) == tc::get<0>(rhs);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename... Rng>\n\t\tstruct [[nodiscard]] zip_adaptor<true, Rng...>\n\t\t\t: product_index_range_adaptor<zip_adaptor, zip_index, Rng...>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = zip_adaptor;\n\t\tpublic:\n\t\t\tusing product_index_range_adaptor<zip_adaptor, zip_index, Rng...>::product_index_range_adaptor;\n\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\t\t\tusing difference_type = smallest_numeric_type_t<range_difference_t<Rng>...>;\n\n\t\t\tstatic constexpr bool c_bPrefersForEach = zip_adaptor_prefers_for_each<Rng...>::value;\n\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr, begin_index)() const& noexcept -> tc_index {\n\t\t\t\treturn {tc::tuple_transform(this->m_tupleadaptbaserng, tc_mem_fn(.base_begin_index))};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index\n\t\t\t\trequires (... && tc::has_end_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\treturn {tc::tuple_transform(this->m_tupleadaptbaserng, tc_mem_fn(.base_end_index))};\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, at_end_index)(tc_index const& idx) const& noexcept -> bool {\n\t\t\t\tauto MemberRangeAtEnd = \n\t\t\t\t\t[&](auto const nconstIndex) noexcept {\n\t\t\t\t\t\treturn tc::at_end_index(tc::get<nconstIndex()>(this->m_tupleadaptbaserng).base_range(), tc::get<nconstIndex()>(idx));\n\t\t\t\t\t};\n\n\t\t\t\tbool const bAtEnd = MemberRangeAtEnd(tc::constant<tc::explicit_cast<std::size_t>(0)>());\n\n\t\t\t\t_ASSERT(tc::all_of(\n\t\t\t\t\ttc::make_integer_sequence<std::size_t, 1, sizeof...(Rng)>(),\n\t\t\t\t\t[&](auto const nconstIndex) noexcept { return MemberRangeAtEnd(nconstIndex) == bAtEnd; }\n\t\t\t\t));\n\n\t\t\t\treturn bAtEnd;\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& noexcept -> void {\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx),\n\t\t\t\t\t[](auto&& adaptbaserng, auto& baseidx) noexcept {\n\t\t\t\t\t\ttc::increment_index(adaptbaserng.base_range(), baseidx);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, decrement_index)(tc_index& idx) const& noexcept -> void\n\t\t\t\trequires (... && tc::has_decrement_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx),\n\t\t\t\t\t[](auto&& adaptbaserng, auto& baseidx) noexcept {\n\t\t\t\t\t\ttc::decrement_index(adaptbaserng.base_range(), baseidx);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, advance_index)(tc_index& idx, difference_type d) const& noexcept -> void\n\t\t\t\trequires (... && tc::has_advance_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\ttc::for_each(\n\t\t\t\t\ttc::zip(this->m_tupleadaptbaserng, idx),\n\t\t\t\t\t[&](auto&& adaptbaserng, auto& baseidx) noexcept {\n\t\t\t\t\t\ttc::advance_index(adaptbaserng.base_range(), baseidx, d);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// For consistency with other functions, distance_to_index is only available if all base ranges support it - even though we only require one of the base ranges to support it.\n\t\t\tSTATIC_FINAL_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& noexcept->difference_type\n\t\t\t\trequires (... && tc::has_distance_to_index<std::remove_reference_t<Rng>>)\n\t\t\t{\n\t\t\t\ttc_return_cast(tc::distance_to_index(tc::get<0>(this->m_tupleadaptbaserng).base_range(), tc::get<0>(idxLhs), tc::get<0>(idxRhs)));\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::zip_adaptor;\n\n\ttemplate<bool HasIterator, typename... Rng>\n\tconstexpr auto enable_stable_index_on_move<zip_adaptor<HasIterator, Rng...>>\n\t\t= (tc::stable_index_on_move<Rng> && ...);\n\n\ttemplate<typename... Rng>\n\tconstexpr no_adl::zip_adaptor</*HasIterator*/(... && tc::range_with_iterators<Rng>), Rng...> zip(Rng&&... rng) noexcept {\n\t\treturn {tc::aggregate_tag, tc_move_if_owned(rng)...};\n\t}\n\n\ttemplate<typename Rng0, typename Rng1>\n\tconstexpr auto zip_any(Rng0&& rng0, Rng1&& rng1) noexcept {\n\t\treturn [\n\t\t\trng0_ = tc::reference_or_value<Rng0>(tc::aggregate_tag, tc_move_if_owned(rng0)),\n\t\t\trng1_ = tc::reference_or_value<Rng1>(tc::aggregate_tag, tc_move_if_owned(rng1))\n\t\t](auto sink) MAYTHROW {\n\t\t\tauto it0 = tc::begin(*rng0_);\n\t\t\tauto it1 = tc::begin(*rng1_);\n\n\t\t\ttc_auto_cref(it0End, tc::end(tc::as_const(*rng0_)));\n\t\t\ttc_auto_cref(it1End, tc::end(tc::as_const(*rng1_)));\n\t\t\tfor(;;) {\n\t\t\t\tif (it0End == it0) {\n\t\t\t\t\treturn tc::for_each(\n\t\t\t\t\t\ttc::make_iterator_range(it1,it1End),\n\t\t\t\t\t\t[&](auto&& elem) noexcept {\n\t\t\t\t\t\t\treturn tc::continue_if_not_break(sink, tc::tuple<std::nullopt_t, decltype(elem)>{{ {{std::nullopt}}, {{tc_move_if_owned(elem)}} }});\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else if (it1End == it1) {\n\t\t\t\t\treturn tc::for_each(\n\t\t\t\t\t\ttc::make_iterator_range(it0,it0End),\n\t\t\t\t\t\t[&](auto&& elem) noexcept {\n\t\t\t\t\t\t\treturn tc::continue_if_not_break(sink, tc::tuple<decltype(elem), std::nullopt_t>{{ {{tc_move_if_owned(elem)}}, {{std::nullopt}} }});\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc::tie(*it0, *it1)))\n\t\t\t\t\t++it0;\n\t\t\t\t\t++it1;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Rng> requires tc::instance_n<std::remove_reference_t<Rng>, no_adl::zip_adaptor>\n\t[[nodiscard]] constexpr decltype(auto) unzip(Rng&& rng) noexcept {\n\t\treturn std::remove_reference_t<Rng>::base_ranges(tc_move_if_owned(rng));\n\t}\n\n\ttemplate<typename Rng> requires tc::instance_n<std::remove_reference_t<tc::subrange_arg_t<Rng>>, no_adl::zip_adaptor>\n\t[[nodiscard]] constexpr auto unzip(Rng&& rng) noexcept {\n\t\treturn tc::tuple_transform(\n\t\t\ttc::zip(\n\t\t\t\ttc::unzip(tc_move_if_owned(rng).base_range()),\n\t\t\t\ttc_move_if_owned(rng).begin_index(),\n\t\t\t\ttc_move_if_owned(rng).end_index()\n\t\t\t),\n\t\t\ttc_fn(tc::slice)\n\t\t);\n\t}\n\n\t/*\n\t\tTODO: RT#16520\n\t\tIt is reasonable that the following use case of zip_ranges should work without copying\n\t\tthe R-value range.\n\n\t\tif (auto o = tc::find_last<tc::return_value_or_none>(\n\t\t\ttc::zip_ranges( CreateRValueRngRng() ),\n\t\t\tpredicate\n\t\t)) {\n\t\t\t*o; // must still be valid.\n\t\t}\n\n\t\t- Currently, *o is 'tc::transform(*rngrng, [n](auto const& rng) return_decltype_MAYTHROW(tc::at(rng, n)))'\n\t\twith rngrng beeing then out of scope.\n\n\t\treturn_value_or_none.pack_element(It&&, Rng&&, Ref&& ref) is called with R-Value range, so in principle\n\t\tit can call (note && and tc_move)\n\t\ttransform_adaptor::dereference_index() && {\n\t\t\ttc_move(m_func)(...)\n\t\t},\n\t\tand the transform functor of zip_ranges could overload for '&&' and in that case aggregating rngrng.\n\n\t\tThis is not possible with find_last using iterators. Todo is then to\n\t\t- Specialize find_last (and similar functions) for index-based ranges\n\t\t- Introduce pack_element for index-based results\n\t\t- Introduce transform_adaptor::dereference_index &&\n\t*/\n\ttemplate<typename RngRng>\n\tauto zip_ranges(RngRng&& rngrng) noexcept { // for random access ranges\n\t\t_ASSERT(tc::all_same_element<tc::return_bool>(tc::transform(rngrng, tc_fn(tc::size))));\n\t\tauto const n = tc::empty(rngrng) ? 0 : tc::size(tc::front(rngrng)); // Do not inline, function evaluation order undefined\n\t\treturn tc::transform(\n\t\t\ttc::iota(0, n),\n\t\t\t[rngrng = tc::make_reference_or_value(tc_move_if_owned(rngrng))](auto const n) noexcept {\n\t\t\t\t// return_decltype_MAYTHROW(tc::at(rng, n)) may cause ICE on Apple clang 10\n\t\t\t\treturn tc::transform(*rngrng, [n](auto const& rng) MAYTHROW -> decltype(auto) { return tc::at(rng, n); });\n\t\t\t}\n\t\t);\n\t}\n\t\n\tnamespace enumerate_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct enumerate_generator_adaptor : private tc::range_adaptor_base_range<Rng> {\n\t\t\tusing base_ = tc::range_adaptor_base_range<Rng>;\n\t\t\tenumerate_generator_adaptor(Rng&& rng) noexcept\n\t\t\t\t: base_(tc::aggregate_tag, tc_move_if_owned(rng))\n\t\t\t{}\n\n\t\t\ttemplate<tc::decayed_derived_from<enumerate_generator_adaptor> Self, typename Sink>\n\t\t\tfriend constexpr auto for_each_impl(Self&& self, Sink&& sink) MAYTHROW {\n\t\t\t\tint i = 0;\n\t\t\t\t// return_decltype_MAYTHROW with tc_move_if_owned causes compiler segfault on Mac\n\t\t\t\treturn tc::for_each(tc_move_if_owned(self).base_range(), [&](auto&& t) noexcept(noexcept(tc_invoke(sink, (std::declval<tc::tuple<int, decltype(t)>>())))) -> decltype(auto) {\n\t\t\t\t\treturn tc_invoke(sink, (tc::tuple<int, decltype(t)>{i++, tc_move_if_owned(t)})); // MAYTHROW\n\t\t\t\t});\n\t\t\t}\n\n\t\t\ttemplate<typename Self, std::enable_if_t<tc::decayed_derived_from<Self, enumerate_generator_adaptor>>* = nullptr> // accept any cvref qualifiers. use terse syntax when Xcode supports https://cplusplus.github.io/CWG/issues/2369.html\n\t\t\tfriend auto range_output_t_impl(Self&&) -> tc::mp_transform<boost::mp11::mp_bind_front<tc::tuple, int>::template fn, tc::range_output_t<tc::no_adl::apply_cvref_to_base_range_t<Rng, Self>>> {} // unevaluated\n\t\t};\n\t};\n\n\t// Transform [t0, t1, ..., tn] to [(0, t0), (1, t1), ..., (n, tn)]\n\t// TODO: return iterator range, if range has iterators.\n\ttemplate <typename Rng>\n\t[[nodiscard]] constexpr auto enumerate(Rng&& rng) noexcept {\n\t\tif constexpr( tc::has_size<Rng> ) {\n\t\t\tauto nSize = tc::size(rng); // do not inline, evaluation order important\n\t\t\treturn tc::zip(tc::iota(0, nSize), tc_move_if_owned(rng));\n\t\t} else {\n\t\t\treturn enumerate_adl::enumerate_generator_adaptor<Rng>(tc_move_if_owned(rng));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/range/zip_range.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../interval.h\" // for tc::lohi\n#include \"zip_range.h\"\n\nnamespace\n{\n\ttemplate<typename Rng, typename Traversal>\n\tstruct traversal_override_adaptor\n\t\t: tc::index_range_adaptor<traversal_override_adaptor<Rng, Traversal>, Rng&, tc::index_range_adaptor_flags::inherit_all>\n\t{\n\t\tusing this_type = traversal_override_adaptor;\n\t\tusing base_ = typename traversal_override_adaptor::index_range_adaptor;\n\t\tusing tc_index = typename base_::tc_index;\n\n\t\ttraversal_override_adaptor(Rng& rng) : base_(tc::aggregate_tag, rng) {}\n\n\t\tSTATIC_FINAL(decrement_index)(tc_index& idx) const& MAYTHROW\n\t\t\trequires tc::has_decrement_index<Rng>\n\t\t\t\t&& boost::iterators::detail::is_traversal_at_least<Traversal, boost::iterators::bidirectional_traversal_tag>::value\n\t\t{\n\t\t\ttc::decrement_index(this->base_range(), idx);\n\t\t}\n\n\t\tSTATIC_FINAL_MOD(constexpr, advance_index)(tc_index& idx, typename boost::range_difference<Rng>::type d) const& MAYTHROW -> void\n\t\t\trequires tc::has_advance_index<Rng>\n\t\t\t\t&& boost::iterators::detail::is_traversal_at_least<Traversal, boost::iterators::random_access_traversal_tag>::value\n\t\t{\n\t\t\ttc::advance_index(this->base_range(),idx,d);\n\t\t}\n\n\t\tSTATIC_FINAL_MOD(constexpr, distance_to_index)(tc_index const& idxLhs, tc_index const& idxRhs) const& noexcept\n\t\t\trequires tc::has_distance_to_index<Rng>\n\t\t\t\t&& boost::iterators::detail::is_traversal_at_least<Traversal, boost::iterators::random_access_traversal_tag>::value\n\t\t{\n\t\t\treturn tc::distance_to_index(this->base_range(),idxLhs,idxRhs);\n\t\t}\n\t};\n}\n\nUNITTESTDEF(zip_range_supported_ops) {\n\ttc::vector<int> data = { 1, 2, 3, 4, 5 };\n\ttc::vector<float> dataf = { 1, 2, 3, 4, 5 };\n\tauto data_fwd = traversal_override_adaptor<tc::vector<int>, boost::iterators::forward_traversal_tag>(data);\n\tauto data_bidir = traversal_override_adaptor<tc::vector<int>, boost::iterators::bidirectional_traversal_tag>(data);\n\tauto data_gen = [&](auto sink) noexcept { return tc::for_each(data, sink); };\n\n\tauto zip_ff = tc::zip(data_fwd, data_fwd);\n\tauto zip_fb = tc::zip(data_fwd, data_bidir);\n\tauto zip_fr = tc::zip(data_fwd, data);\n\tauto zip_bb = tc::zip(data_bidir, data_bidir);\n\tauto zip_br = tc::zip(data_bidir, data);\n\tauto zip_rr = tc::zip(data, data);\n\tauto zip_rfgf = tc::zip(dataf, data_fwd, data_gen, data_fwd);\n\n\ttc::for_each(zip_ff, tc::noop());\n\ttc::for_each(zip_fb, tc::noop());\n\ttc::for_each(zip_fr, tc::noop());\n\ttc::for_each(zip_bb, tc::noop());\n\ttc::for_each(zip_br, tc::noop());\n\ttc::for_each(zip_rr, tc::noop());\n\ttc::for_each(zip_rfgf, [](float&,int&,int&,int&) noexcept{});\n\n\tstatic_assert(!tc::has_decrement_index<decltype(zip_ff)>);\n\tstatic_assert(!tc::has_decrement_index<decltype(zip_fb)>);\n\tstatic_assert(!tc::has_decrement_index<decltype(zip_fr)>);\n\tstatic_assert(!tc::has_advance_index<decltype(zip_ff)>);\n\tstatic_assert(!tc::has_advance_index<decltype(zip_fb)>);\n\tstatic_assert(!tc::has_advance_index<decltype(zip_fr)>);\n\tstatic_assert(!tc::has_distance_to_index<decltype(zip_ff)>);\n\tstatic_assert(!tc::has_distance_to_index<decltype(zip_fb)>);\n\tstatic_assert(!tc::has_distance_to_index<decltype(zip_fr)>);\n\n\tstatic_assert(tc::has_decrement_index<decltype(zip_bb)>);\n\tstatic_assert(tc::has_decrement_index<decltype(zip_br)>);\n\tstatic_assert(!tc::has_advance_index<decltype(zip_bb)>);\n\tstatic_assert(!tc::has_advance_index<decltype(zip_br)>);\n\tstatic_assert(!tc::has_distance_to_index<decltype(zip_bb)>);\n\tstatic_assert(!tc::has_distance_to_index<decltype(zip_br)>);\n\n\tstatic_assert(tc::has_decrement_index<decltype(zip_rr)>);\n\tstatic_assert(tc::has_advance_index<decltype(zip_rr)>);\n\tstatic_assert(tc::has_distance_to_index<decltype(zip_rr)>);\n\n\t_ASSERTEQUAL(tc::size(zip_fr), 5);\n\t_ASSERTEQUAL(tc::size(zip_br), 5);\n\t_ASSERTEQUAL(tc::size(zip_rr), 5);\n\t_ASSERTEQUAL(tc::size(zip_rfgf), 5);\n\n\tstatic_assert(!tc::range_with_iterators<decltype(zip_rfgf)>);\n}\n\nUNITTESTDEF(zip_range_difference_type) {\n\tauto rngBigDiff = tc::iota(0, 2);\n\tauto rngSmallDiff = tc::all_values<tc::lohi>();\n\n\tusing BigDiffType = boost::range_difference<decltype(rngBigDiff)>::type;\n\tusing SmallDiffType = boost::range_difference<decltype(rngSmallDiff)>::type;\n\t// e.g. BigDiffType=int, SmallDiffType=signed char\n\n\t// If these initial assertions fail, the test needs to be adjusted. Find two ranges with different difference_types\n\tstatic_assert(!std::is_same<BigDiffType, SmallDiffType>::value);\n\tstatic_assert(sizeof(BigDiffType) > sizeof(SmallDiffType));\n\n\tstatic_assert(std::is_same<boost::range_difference<decltype(tc::zip(rngBigDiff, rngBigDiff))>::type, BigDiffType>::value);\n\tstatic_assert(std::is_same<boost::range_difference<decltype(tc::zip(rngBigDiff, rngSmallDiff))>::type, SmallDiffType>::value);\n\tstatic_assert(std::is_same<boost::range_difference<decltype(tc::zip(rngSmallDiff, rngSmallDiff))>::type, SmallDiffType>::value);\n}\n\nSTATICASSERTSAME( TC_FWD(tc::range_value_t<decltype(tc::zip(std::declval<tc::vector<int>>(), std::declval<std::array<double,4>>()))>), TC_FWD(tc::tuple<int, double>) );\n\nUNITTESTDEF(zip_range_sort_inplace) {\n\ttc::vector<int> veci = {47,11,23};\n\ttc::vector<double> vecf = {1,2,3};\n\ttc::sort_inplace(tc::zip(veci, vecf));\n\t_ASSERTEQUAL( tc::at(veci, 0), 11 );\n\t_ASSERTEQUAL( tc::at(veci, 1), 23 );\n\t_ASSERTEQUAL( tc::at(veci, 2), 47 );\n\t_ASSERTEQUAL( tc::at(vecf, 0), 2 );\n\t_ASSERTEQUAL( tc::at(vecf, 1), 3 );\n\t_ASSERTEQUAL( tc::at(vecf, 2), 1 );\n}\n\nUNITTESTDEF(zip_range_range_output_t) {\n\ttc::vector<int> const vecn ={1, 2, 3};\n\ttc::vector<double> vecf ={1.2, 2.2, 3.2};\n\tauto const rngnf = tc::zip(vecn, vecf);\n\tSTATICASSERTSAME(tc::range_output_t<decltype(rngnf)>, TC_FWD(boost::mp11::mp_list<tc::tuple<int const&, double&>>));\n\tSTATICASSERTSAME(tc::range_value_t<decltype(rngnf)>, TC_FWD(tc::tuple<int, double>));\n\n\tauto const rngch = tc::generator_range_output<char const&>([](auto sink) noexcept {\n\t\ttc::for_each(\"abc\", sink);\n\t});\n\tSTATICASSERTSAME(tc::range_output_t<decltype(rngch)>, TC_FWD(boost::mp11::mp_list<char const&>));\n\tauto const rngnchf = tc::zip(vecn, rngch, vecf);\n\n\tSTATICASSERTSAME(tc::range_output_t<decltype(rngnchf)>, TC_FWD(boost::mp11::mp_list<tc::tuple<int const&, char const&, double&>>));\n\tSTATICASSERTSAME(tc::range_value_t<decltype(rngnchf)>, TC_FWD(tc::tuple<int, char, double>));\n}\n"
  },
  {
    "path": "tc/restricted_enum.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/type_traits.h\"\n#include \"base/safe_comparison.h\"\n#include \"base/casts.h\"\n#include \"base/explicit_cast.h\"\n#include \"algorithm/binary_operators.h\"\n\n// restricted_enum restricts an enum or char type to a subinterval.\n// It provides the following operations:\n// * implicit (checked) conversion to/from base type\n// * forwarding of to/from_underlying\n// * full comparison\n// Additionally, for types other than enum class, it also has affine arithmetic:\n// * value += integer, value + integer\n// * value -= integer, value - integer\n// * value - value resulting in integer\n\nnamespace tc {\n\tnamespace restricted_enum_adl {\n\t\tnamespace detail {\n\t\t\ttemplate <tc::char_type T>\n\t\t\tconstexpr bool is_only_ascii(T, T tLast) noexcept\n\t\t\t{\n\t\t\t\t// No need to check tFirst, it's underlying is <= tLast and the underlying type is unsigned.\n\t\t\t\treturn tc::to_underlying(tLast) <= 0x7F;\n\t\t\t}\n\t\t\t\n\t\t\t// Workaround clang by providing an overload for non-char types.\n\t\t\t// This will never actually be called as it is after a `tc::char_type<T>` check, but has to exist.\n\t\t\ttemplate <typename T>\n\t\t\tconstexpr std::false_type is_only_ascii(T, T) noexcept { return {}; }\n\t\t}\n\n\t\ttemplate<typename T, T tFirst, T tLast>\n\t\tstruct restricted_enum final : tc::additive<> {\n\t\t// private: TODO: inhibits usage as template parameter\n\t\t\tstatic_assert(tc::decayed<T>);\n\t\t\tstatic_assert(std::is_enum<T>::value || tc::char_type<T>);\n\t\t\tstatic_assert(tc::to_underlying(tFirst) <= tc::to_underlying(tLast));\n\n\t\t\tT m_t;\n\n\t\tpublic:\n\t\t\tstatic constexpr T c_tFirst = tFirst;\n\t\t\tstatic constexpr T c_tLast = tLast;\n\n\t\t\tconstexpr restricted_enum() noexcept = default;\n\n\t\t\ttemplate<typename U>\n\t\t\t\trequires tc::explicit_castable_from<T, U const&>\n\t\t\tstatic bool constructible_from(U const& u) noexcept {\n\t\t\t\treturn restricted_enum(c_tFirst) <= u && u <= restricted_enum(c_tLast); // We reuse the SFINAE from the comparison operators of restricted_enum.\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\t\trequires tc::explicit_castable_from<T, U const&>\n\t\t\texplicit constexpr restricted_enum(U const& u) noexcept : tc_member_init(m_t, u) {\n\t\t\t\t_ASSERTE(tc::to_underlying(c_tFirst) <= tc::to_underlying(m_t) && tc::to_underlying(m_t) <= tc::to_underlying(c_tLast));\n\t\t\t}\n\n\t\t\t// Implicit ctor from a more restrictive type.\n\t\t\ttemplate<typename U, U uFirst, U uLast>\n\t\t\t\trequires std::convertible_to<U, T> && (std::cmp_less_equal(tc::to_underlying(c_tFirst), tc::to_underlying(uFirst)) && std::cmp_less_equal(tc::to_underlying(uLast), tc::to_underlying(c_tLast)))\n\t\t\tconstexpr restricted_enum(restricted_enum<U, uFirst, uLast> const rhs) noexcept : m_t(tc::implicit_cast<U>(rhs)) {}\n\n\t\t\t// Explicit ctor otherwise.\n\t\t\ttemplate<typename U, U uFirst, U uLast>\n\t\t\t\trequires std::convertible_to<U, T>\n\t\t\texplicit constexpr restricted_enum(restricted_enum<U, uFirst, uLast> const rhs) noexcept : restricted_enum(tc::implicit_cast<U>(rhs)) {}\n\n\t\t\t// Assignment allows explicit constructors as well.\n\t\t\t// This is needed for spirit: it needs to assign to a restricted_enum attribute.\n\t\t\ttemplate<typename U>\n\t\t\tconstexpr restricted_enum& operator=(U&& u) & noexcept requires tc::explicit_castable_from<restricted_enum, U&&> {\n\t\t\t\treturn *this=tc::explicit_cast<restricted_enum>(tc_move_if_owned(u));\n\t\t\t}\n\n\t\t\ttemplate <typename U>\n\t\t\t\trequires std::same_as<U, T>\n\t\t\t\t\t|| (tc::char_type<T> && tc::char_type<U> && detail::is_only_ascii(tFirst, tLast))\n\t\t\tconstexpr operator U() const& noexcept {\n\t\t\t\ttc_return_cast(m_t);\n\t\t\t}\n\n\t\t\ttemplate<tc::actual_integer Integral>\n\t\t\t\trequires requires (T& value, Integral n) { value += n; }\n\t\t\tconstexpr restricted_enum& operator+=(Integral const n) noexcept {\n\t\t\t\t_ASSERTE(std::cmp_less_equal(c_tFirst - m_t, n) && std::cmp_less_equal(n, c_tLast - m_t));\n\t\t\t\tm_t = static_cast<T>(m_t + n);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate<tc::actual_integer Integral>\n\t\t\t\trequires requires (T& value, Integral n) { value -= n; }\n\t\t\tconstexpr restricted_enum& operator-=(Integral const n) noexcept {\n\t\t\t\t_ASSERTE(std::cmp_less_equal(m_t - c_tLast, n) && std::cmp_less_equal(n, m_t - c_tFirst));\n\t\t\t\tm_t = static_cast<T>(m_t - n);\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t};\n\n\t\tnamespace detail\n\t\t{\n\t\t\ttemplate <typename T>\n\t\t\tconstexpr bool is_restricted_enum = false;\n\t\t\ttemplate <typename T, T tFirst, T tLast>\n\t\t\tconstexpr bool is_restricted_enum<restricted_enum<T, tFirst, tLast>> = true;\n\t\t}\n\n\t\ttemplate<typename T, T tFirst, T tLast>\n\t\tconstexpr auto to_underlying_impl(restricted_enum<T, tFirst, tLast> const t) return_decltype_noexcept(\n\t\t\ttc::to_underlying(tc::implicit_cast<T>(t))\n\t\t)\n\n\t\ttemplate<typename T, T tFirst, T tLast>\n\t\tconstexpr auto from_underlying_impl(std::type_identity<restricted_enum<T, tFirst, tLast>>, tc::underlying_type_t<restricted_enum<T, tFirst, tLast>> const t) return_decltype_noexcept(\n\t\t\t// Range check for T done in its from_underlying implementation.\n\t\t\t// Range check for [tFirst, tLast] done in constructor.\n\t\t\trestricted_enum<T, tFirst, tLast>(tc::from_underlying<T>(t))\n\t\t)\n\n#pragma push_macro(\"DEFINE_COMPARISON_OP\")\n#define DEFINE_COMPARISON_OP(op, type, trait) \\\n\t\ttemplate<typename T, T tFirst, T tLast, typename U> \\\n\t\t\trequires (!detail::is_restricted_enum<U> && trait<T, U>) \\\n\t\tconstexpr type operator op(restricted_enum<T, tFirst, tLast> const lhs, U const& rhs) noexcept { \\\n\t\t\treturn tc::implicit_cast<T>(lhs) op rhs; \\\n\t\t} \\\n\t\ttemplate<tc::char_type T, T tFirst, T tLast, tc::char_type U> \\\n\t\t\trequires (!detail::is_restricted_enum<U> && !trait<T, U> && detail::is_only_ascii(tFirst, tLast)) \\\n\t\tconstexpr type operator op(restricted_enum<T, tFirst, tLast> const lhs, U const& rhs) noexcept { \\\n\t\t\treturn static_cast<U>(tc::implicit_cast<T>(lhs)) op rhs; \\\n\t\t} \\\n\t\ttemplate<typename T, T tFirst, T tLast, typename U, U uFirst, U uLast> \\\n\t\t\trequires trait<T, U> \\\n\t\tconstexpr type operator op(restricted_enum<T, tFirst, tLast> const lhs, restricted_enum<U, uFirst, uLast> const rhs) noexcept { \\\n\t\t\treturn tc::implicit_cast<T>(lhs) op tc::implicit_cast<U>(rhs); \\\n\t\t} \\\n\t\ttemplate<tc::char_type T, T tFirst, T tLast, tc::char_type U, U uFirst, U uLast> \\\n\t\t\trequires (!trait<T, U> && detail::is_only_ascii(tFirst, tLast) && detail::is_only_ascii(uFirst, uLast)) \\\n\t\tconstexpr type operator op(restricted_enum<T, tFirst, tLast> const lhs, restricted_enum<U, uFirst, uLast> const rhs) noexcept { \\\n\t\t\treturn char32_t(tc::implicit_cast<T>(lhs)) op char32_t(tc::implicit_cast<U>(rhs)); \\\n\t\t}\n\n\t\tDEFINE_COMPARISON_OP(==, bool, tc::safely_equality_comparable_with)\n\t\tDEFINE_COMPARISON_OP(<=>, std::weak_ordering, tc::safely_totally_ordered_with)\n#pragma pop_macro(\"DEFINE_COMPARISON_OP\")\n\n\t\ttemplate <typename T, T tFirst, T tLast, typename U>\n\t\t\trequires requires (T const& lhs, U const& rhs) { lhs - rhs; }\n\t\tconstexpr auto operator-(restricted_enum<T, tFirst, tLast> const lhs, U const& rhs) noexcept {\n\t\t\treturn tc::implicit_cast<T>(lhs) - rhs;\n\t\t}\n\t\ttemplate <typename T, typename U, U uFirst, U uLast>\n\t\t\trequires requires (T const& lhs, U const& rhs) { lhs - rhs; }\n\t\tconstexpr auto operator-(T const& lhs, restricted_enum<U, uFirst, uLast> const rhs) noexcept {\n\t\t\treturn lhs - tc::implicit_cast<U>(rhs);\n\t\t}\n\t\ttemplate <typename T, T tFirst, T tLast, typename U, U uFirst, U uLast>\n\t\t\trequires requires (T const& lhs, U const& rhs) { lhs - rhs; }\n\t\tconstexpr auto operator-(restricted_enum<T, tFirst, tLast> const lhs, restricted_enum<U, uFirst, uLast> const rhs) noexcept {\n\t\t\treturn tc::implicit_cast<T>(lhs) - tc::implicit_cast<U>(rhs);\n\t\t}\n\t}\n\tusing restricted_enum_adl::restricted_enum;\n\n\tnamespace char_like_detail {\n\t\ttemplate<typename T, T tFirst, T tLast>\n\t\tinline constexpr bool char_like_impl<tc::restricted_enum<T, tFirst, tLast>> = tc::char_like<T>;\n\t}\n\tnamespace no_adl {\n\t\ttemplate<tc::char_type Char, Char chFirst, Char chLast>\n\t\t\trequires (restricted_enum_adl::detail::is_only_ascii(chFirst, chLast))\n\t\tstruct char_limits<tc::restricted_enum<Char, chFirst, chLast>> {\n\t\t\tstatic constexpr std::size_t c_nMaxCodeUnitsPerCodePoint = 1;\n\n\t\t\t[[nodiscard]] static constexpr bool interval_in_range(unsigned int nFirst, unsigned int nLast) noexcept {\n\t\t\t\treturn static_cast<unsigned>(chFirst) <= nFirst && nLast <= static_cast<unsigned>(chLast);\n\t\t\t}\n\t\t};\n\t}\n\n}\n"
  },
  {
    "path": "tc/restricted_enum.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"unittest.h\"\n#include \"restricted_enum.h\"\n#include \"string/char.h\"\n#include \"base/assert_defs.h\"\n\nnamespace {\n\t// It's safe to compare when the character type can represent all allowed values with a single code point.\n\tusing char16_ascii = tc::restricted_enum<tc::char16, 0, 127>;\n\tusing char32_ascii = tc::restricted_enum<char32_t, 0, 127>;\n\tstatic_assert(char16_ascii('0') == '0');\n\tstatic_assert(char16_ascii('0') == tc_utf16('0'));\n\tstatic_assert(char16_ascii('0') == U'0');\n\tstatic_assert(char32_ascii('0') == '0');\n\tstatic_assert(char32_ascii('0') == tc_utf16('0'));\n\tstatic_assert(char32_ascii('0') == U'0');\n\n\tusing char16_cyrillic = tc::restricted_enum<tc::char16, 0x400, 0x4ff>;\n\t// static_assert(char16_cyrillic(tc_utf16('\\u0410')) == 'A');\n\tstatic_assert(char16_cyrillic(tc_utf16('\\u0410')) == tc_utf16('\\u0410'));\n\n\tusing char32_cyrillic = tc::restricted_enum<char32_t, 0x400, 0x4ff>;\n\t// static_assert(char32_cyrillic(U'\\u0410') == 'A');\n\tstatic_assert(char32_cyrillic(U'\\u0410') == U'\\u0410');\n\n\tusing char32_miscellaneous_symbols_and_pictographs = tc::restricted_enum<char32_t, 0x1f300, 0x1f5ff>;\n\t// static_assert(char32_miscellaneous_symbols_and_pictographs(U'\\U0001f47e') == '0');\n\t// static_assert(char32_miscellaneous_symbols_and_pictographs(U'\\U0001f47e') == tc_utf16('0'));\n\tstatic_assert(char32_miscellaneous_symbols_and_pictographs(U'\\U0001f47e') == U'\\U0001f47e');\n\n\n\tvoid implicit_cast() noexcept {\n\t\t// Should implicitly convert to less restrictive ranges.\n\t\tusing char16_asciilower = tc::restricted_enum<tc::char16, tc_utf16('a'), tc_utf16('z')>;\n\t\tchar16_asciilower chAsciiLower('a');\n\t\t{\n\t\t\tchar16_ascii chAscii(chAsciiLower);\n\t\t}\n\t\t{\n\t\t\tchar16_ascii chAscii = chAsciiLower;\n\t\t\tchAscii = chAsciiLower;\n\t\t}\n\t}\n\n\tvoid test() {\n\t\tusing char16_including_surrogates = tc::restricted_enum<tc::char16, tc_utf16('\\0'), tc_utf16('\\uffff')>;\n\t\t// char16_including_surrogates ch; // Doesn't compile: there are code units in this range that are not a code point\n\t}\n}\n\nnamespace {\n\tTC_DEFINE_ENUM(ELetter, eletter, (A)(B)(C));\n\n\tusing ELetterAB = tc::restricted_enum<ELetter, eletterA, eletterB>;\n\tusing ELetterB = tc::restricted_enum<ELetter, eletterB, eletterB>;\n\tusing ELetterBC = tc::restricted_enum<ELetter, eletterB, eletterC>;\n\tvoid restricted_enums() noexcept {\n\t\ttc_static_auto_constexpr(eletterabA, ELetterAB(eletterA));\n\t\ttc_static_auto_constexpr(eletterabB, ELetterAB(eletterB));\n\t\tELetterAB eletterabOutput;\n\t\teletterabOutput = eletterabA;\n\t\teletterabOutput = eletterA;\n\t\tELetterBC eletterbcOutput;\n\t\teletterbcOutput = eletterabA;\n\t\t_ASSERTEQUAL(eletterabOutput, eletterbcOutput);\n\t\t// _ASSERTEQUAL(eletterabOutput, tc::char_ascii('0')); // Doesn't compile: nonsensical comparison.\n\t\ttc_static_auto_constexpr(eletterb, ELetterB(eletterB));\n\t\t_ASSERTEQUAL(eletterabA - eletterabOutput, 0);\n\t\t_ASSERTEQUAL(eletterabOutput + (eletterabB - eletterabOutput), eletterabB);\n\n\t\t[](ELetter) noexcept {}(eletterA);\n\t\t[](ELetter) noexcept {}(eletterabA);\n\n\t\t// [](ELetterAB) noexcept {}(eletterA); // Doesn't compile: can't be implicit\n\t\t// [](ELetterAB) noexcept {}(tc::implicit_cast<ELetterAB>(eletterA)); // Doesn't compile: can't be implicit\n\t\t[](ELetterAB) noexcept {}(tc::explicit_cast<ELetterAB>(eletterA)); // Compiles: it's explicit\n\t\t[](ELetterAB) noexcept {}(eletterb); // Compiles: it's more specific\n\n\t\t[](ELetterB) noexcept {}(tc::explicit_cast<ELetterB>(eletterabA)); // Compiles: it's explicit\n\t\t[](ELetterB) noexcept {}(tc::explicit_cast<ELetterB>(eletterA)); // Compiles: it's explicit\n\n\t\t[](ELetterBC) noexcept {}(tc::explicit_cast<ELetterBC>(eletterB)); // Compiles: it's explicit\n\t\t[](ELetterBC) noexcept {}(eletterb); // Compiles: it's more specific\n\t}\n}\n\nUNITTESTDEF(restricted_enum_arithmetic) {\n\tchar16_ascii ch('b');\n\tch += 1;\n\t_ASSERTEQUAL(ch, 'c');\n\tch -= 2;\n\t_ASSERTEQUAL(ch, 'a');\n\n\t_ASSERTEQUAL(char16_ascii('a') + 2, 'c');\n\t_ASSERTEQUAL(char16_ascii('c') - 2, 'a');\n\t_ASSERTEQUAL(char16_ascii('c') - char16_ascii('a'), 2);\n\n\tELetterAB eletterab(eletterA);\n\teletterab += 1;\n\t_ASSERTEQUAL(eletterab, eletterB);\n\teletterab -= 1;\n\t_ASSERTEQUAL(eletterab, eletterA);\n\n\t_ASSERTEQUAL(ELetterAB(eletterA) + 1, eletterB);\n\t_ASSERTEQUAL(ELetterAB(eletterB) - 1, eletterA);\n\t_ASSERTEQUAL(ELetterAB(eletterB) - ELetterAB(eletterA), 1);\n}\n"
  },
  {
    "path": "tc/static_vector.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n// #include \"index_iterator.h\"\n#include \"storage_for.h\"\n#include \"base/renew.h\"\n#include \"base/tag_type.h\"\n#include \"algorithm/filter_inplace.h\"\n#include \"algorithm/append.h\"\n\n#include <boost/preprocessor/enum.hpp>\n#include <boost/container/container_fwd.hpp>\n#include <algorithm>\n\nMODIFY_WARNINGS_BEGIN(((disable)(4297))) // 'function' : function assumed not to throw an exception but does.\n\nnamespace tc {\n\tusing static_vector_size_t = std::uint32_t; // fixed width integer for shared heap\n\n\tDEFINE_TAG_TYPE(constexpr_tag)\n\n\tnamespace no_adl {\n\t\ttemplate<typename T, tc::static_vector_size_t N> \n\t\tstruct static_vector_base {\n\t\t\tusing size_type = tc::static_vector_size_t;\n\t\tprotected:\n\t\t\tsize_type m_iEnd = 0;\n\t\tpublic:\n\t\t\t// query state\n\t\t\t[[nodiscard]] constexpr bool full() const& noexcept {\n\t\t\t\treturn N == m_iEnd;\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr size_type size() const& noexcept {\n\t\t\t\treturn m_iEnd;\n\t\t\t}\n\t\t\t[[nodiscard]] static constexpr size_type capacity() noexcept {\n\t\t\t\treturn N;\n\t\t\t}\n\t\t};\n\n\t\t// Inside element dtors, the element is already removed from the container.\n\t\t// Inside element ctors, the element is already in the container.\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tstruct static_vector_base_nontrivial : static_vector_base<T, N> {\n\t\t\tusing base = static_vector_base<T, N>;\n\t\t\tusing typename base::size_type;\n\t\tprivate:\n\t\t\tstatic_assert(!std::is_trivially_destructible<T>::value || !std::is_trivially_default_constructible<T>::value);\n\t\tprotected:\n\t\t\tstd::conditional_t<std::is_trivially_destructible<T>::value, tc::storage_for_without_dtor<T>, tc::storage_for<T>> m_aot[N];\n\t\t\tconstexpr T const& dereference(size_type n) const& noexcept { return *m_aot[n]; }\n\t\t\tconstexpr T& dereference(size_type n) & noexcept { return tc::as_mutable(tc::as_const(*this).dereference(n)); }\n\t\tpublic:\n\t\t\ttemplate<typename... Args>\n\t\t\tconstexpr T& emplace_back(Args&& ... args) & noexcept(noexcept(m_aot[this->m_iEnd - 1].ctor_value(tc_move_if_owned(args)...))) {\n\t\t\t\t_ASSERTE(!this->full());\n\t\t\t\tauto& ot=m_aot[this->m_iEnd];\n\t\t\t\t++this->m_iEnd;\n\t\t\t\t// Inside element ctors, the element is already in the container.\n\t\t\t\ttry {\n\t\t\t\t\tot.ctor_value(tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t\treturn *ot;\n\t\t\t\t} catch (...) {\n\t\t\t\t\t--this->m_iEnd;\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\tprotected:\n\t\t\t[[nodiscard]] constexpr T* data() & noexcept {\n\t\t\t\treturn m_aot[0].uninitialized_addressof();\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T const* data() const& noexcept {\n\t\t\t\treturn m_aot[0].uninitialized_addressof();\n\t\t\t}\n\t\t};\n\n\t\t// Inside element ctors, the element is already in the container.\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tstruct static_vector_base_trivial : static_vector_base<T, N> {\n\t\t\tusing base = static_vector_base<T, N>;\n\t\t\tusing typename base::size_type;\n\t\tprivate:\n\t\t\tstatic_assert(std::is_trivially_destructible<T>::value && std::is_trivially_default_constructible<T>::value);\n\t\t\tstruct SValueInitIfConstexpr final {\n\t\t\t\t// Leave array uninitialized at runtime\n\t\t\t\tSValueInitIfConstexpr() noexcept {}\n\t\t\t\t// All slots in constexpr static_vector must be initialized (for clang and if materialized as a static variable). \n\t\t\t\tconsteval SValueInitIfConstexpr(constexpr_tag_t) : m_at{} {} // Value init implies zero init because of is_trivially_default_constructible.\n\t\t\t\tT m_at[N];\n\t\t\t} m_a;\n\t\tprotected:\n\t\t\tconstexpr T const& dereference(size_type n) const& noexcept { return m_a.m_at[n]; }\n\t\t\tconstexpr T& dereference(size_type n) & noexcept { return m_a.m_at[n]; }\n\t\tpublic:\n\t\t\tconstexpr static_vector_base_trivial() noexcept\n\t\t\t\t: m_a([]() noexcept -> SValueInitIfConstexpr {\n\t\t\t\t\tif( std::is_constant_evaluated() ) {\n\t\t\t\t\t\treturn {constexpr_tag};\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn {};\n\t\t\t\t\t}\n\t\t\t\t}())\n\t\t\t{}\n\n\t\t\tconstexpr T& emplace_back(auto&&... args) & noexcept(noexcept(tc::ctor(std::declval<T&>(), tc_move_if_owned(args)...))) {\n\t\t\t\t_ASSERTE(!this->full());\n\t\t\t\tT& t = m_a.m_at[this->m_iEnd];\n\t\t\t\t// Inside element ctors, the element is already in the container.\n\t\t\t\t++this->m_iEnd;\n\t\t\t\tif constexpr(noexcept(tc::ctor(t, tc_move_if_owned(args)...))) { // Avoid try-catch to not inhibit inlining on MSVC\n\t\t\t\t\ttc::ctor(t, tc_move_if_owned(args)...);\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttc::ctor(t, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t\t} catch (...) {\n\t\t\t\t\t\t--this->m_iEnd;\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn t;\n\t\t\t}\n\t\tprotected:\n\t\t\t[[nodiscard]] constexpr T* data() & noexcept {\n\t\t\t\treturn std::addressof(m_a.m_at[0]);\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T const* data() const& noexcept {\n\t\t\t\treturn std::addressof(m_a.m_at[0]);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tstruct static_vector_base_nontrivial_dtor : static_vector_base_nontrivial<T, N> {\n\t\t\tconstexpr static_vector_base_nontrivial_dtor() = default;\n\t\t\tusing static_vector_base_nontrivial<T, N>::static_vector_base_nontrivial;\n\n\t\t\tconstexpr ~static_vector_base_nontrivial_dtor() {\n\t\t\t\tshrink(0);\n\t\t\t}\n\n\t\t\tconstexpr void pop_back() & noexcept {\n\t\t\t\t_ASSERTE( 0 < this->m_iEnd );\n\t\t\t\t--this->m_iEnd;\n\t\t\t\t// Inside element dtors, the element is already removed from the container.\n\t\t\t\tthis->m_aot[this->m_iEnd].dtor();\n\t\t\t}\n\n\t\tprotected:\n\t\t\tconstexpr void shrink(tc::static_vector_size_t n) noexcept {\n\t\t\t\t_ASSERTE( n <= this->size() );\n\t\t\t\twhile (n < this->size()) {\n\t\t\t\t\tpop_back();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tusing static_vector_base_trivial_dtor_base = std::conditional_t<\n\t\t\tstd::is_trivially_default_constructible<T>::value,\n\t\t\ttc::no_adl::static_vector_base_trivial<T, N>,\n\t\t\ttc::no_adl::static_vector_base_nontrivial<T, N>\n\t\t>;\n\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tstruct static_vector_base_trivial_dtor : static_vector_base_trivial_dtor_base<T, N> {\n\t\t\tconstexpr static_vector_base_trivial_dtor() = default;\n\t\t\tusing static_vector_base_trivial_dtor_base<T, N>::static_vector_base_trivial_dtor_base;\n\n\t\t\tconstexpr void pop_back() & noexcept {\n\t\t\t\t_ASSERTE( 0 < this->m_iEnd );\n\t\t\t\t--this->m_iEnd;\n\t\t\t}\n\n\t\tprotected:\n\t\t\tconstexpr void shrink(tc::static_vector_size_t n) & noexcept {\n\t\t\t\t_ASSERTE( n <= this->size() );\n\t\t\t\tthis->m_iEnd = n;\n\t\t\t}\n\t\t};\n\t} // no_adl\n\n\tnamespace static_vector_adl {\n\t\ttemplate<typename T, tc::static_vector_size_t N>\n\t\tusing static_vector_base_t = std::conditional_t<\n\t\t\tstd::is_trivially_destructible<T>::value,\n\t\t\ttc::no_adl::static_vector_base_trivial_dtor<T, N>,\n\t\t\ttc::no_adl::static_vector_base_nontrivial_dtor<T, N>\n\t\t>;\n\n\t\ttemplate< typename T, tc::static_vector_size_t N >\n\t\tstruct [[nodiscard]] static_vector\n\t\t\t: static_vector_base_t<T, N>\n\t\t\t, tc::iota_range_adaptor<static_vector<T, N>, tc::static_vector_size_t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = static_vector;\n\t\tpublic:\n\t\t\tusing base = static_vector_base_t<T, N>;\n\t\t\tusing typename this_type::index_range_adaptor::tc_index;\n\n\t\t\tusing difference_type = std::make_signed_t<tc::static_vector_size_t>;\n\t\t\tusing reference = T&;\n\t\t\tusing value_type = T;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=false;\n\n\t\t\tSTATICASSERTEQUAL( std::is_trivially_destructible<base>::value, std::is_trivially_destructible<T>::value );\n\n\t\t\tconstexpr static_vector() noexcept {}\n\n\t\t\ttemplate <typename... Args> requires\n\t\t\t\t(0 < sizeof...(Args)) &&\n\t\t\t\t(tc::econstructionIMPLICIT==tc::elementwise_construction_restrictiveness<T, Args...>::value)\n\t\t\tconstexpr static_vector(tc::aggregate_tag_t, Args&& ... args) noexcept(std::conjunction<std::is_nothrow_constructible<T, Args&&>...>::value) {\n\t\t\t\tstatic_assert(sizeof...(Args)<=N, \"vector initializer list contains too many elements\");\n\t\t\t\t(this->emplace_back(tc_move_if_owned(args)), ...);\n\t\t\t}\n\n\t\t\ttemplate <typename... Args> requires\n\t\t\t\t(0 == sizeof...(Args)) ||\n\t\t\t\t(tc::econstructionEXPLICIT==tc::elementwise_construction_restrictiveness<T, Args...>::value)\n\t\t\tconstexpr explicit static_vector(tc::aggregate_tag_t, Args&& ... args) MAYTHROW {\n\t\t\t\tstatic_assert(sizeof...(Args)<=N, \"vector initializer list contains too many elements\");\n\t\t\t\t(tc::cont_emplace_back(*this, tc_move_if_owned(args)), ...); // cont_emplace_back for lazy explicit_cast\n\t\t\t}\n\n\t\t\tconstexpr static_vector(static_vector const& vec) noexcept(std::is_nothrow_copy_constructible<T>::value) {\n\t\t\t\ttc::append(*this, vec);\n\t\t\t}\n\n\t\t\tconstexpr static_vector(static_vector&& vec) noexcept(std::is_nothrow_move_constructible<T>::value) {\n\t\t\t\ttc::append(*this, tc_move(vec));\n\t\t\t}\n\n\t\t\tconstexpr static_vector& operator=(static_vector const& vec) & noexcept(std::is_nothrow_copy_assignable<T>::value) {\n\t\t\t\tif( std::addressof(vec)!=this ) {\n\t\t\t\t\tassign(vec);\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr static_vector& operator=(static_vector&& vec) & noexcept(std::is_nothrow_move_assignable<T>::value) {\n\t\t\t\t_ASSERTE( std::addressof(vec)!=this ); // self assignment from rvalues should not happen, rvalues must be expiring\n\t\t\t\tNOEXCEPT( assign( tc_move(vec) ) );\n\t\t\t\treturn *this;\n\t\t\t}\n\t\tprivate:\n\t\t\tSTATIC_FINAL_MOD(constexpr static, begin_index)() noexcept -> tc_index { return 0; }\n\t\t\tSTATIC_FINAL_MOD(constexpr, end_index)() const& noexcept -> tc_index { return this->m_iEnd; }\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(tc_index idx) & noexcept -> T& { return this->dereference(*idx); }\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(tc_index idx) const& noexcept -> T const& { return this->dereference(*idx); }\n\t\t\tSTATIC_FINAL_MOD(constexpr, index_to_address)(tc_index const& idx) & noexcept ->  T* { return this->data() + *idx; }\n\t\t\tSTATIC_FINAL_MOD(constexpr, index_to_address)(tc_index const& idx) const& noexcept ->  const T* { return this->data() + *idx; }\n\t\tpublic:\n\t\t\tconstexpr void clear() & noexcept {\n\t\t\t\tthis->shrink(0);\n\t\t\t}\n\n\t\t\ttemplate<typename Rng>\n\t\t\tconstexpr void assign(Rng&& rng) & noexcept {\n\t\t\t\tclear();\n\t\t\t\ttc::append( *this, tc_move_if_owned(rng) );\n\t\t\t}\n\n\t\t\tconstexpr void resize(tc::static_vector_size_t const n, boost::container::default_init_t) & noexcept {\n\t\t\t\tif (this->size() < n) {\n\t\t\t\t\tstatic_assert(std::is_trivially_default_constructible<T>::value);\n\t\t\t\t\tthis->m_iEnd = n;\n\t\t\t\t} else {\n\t\t\t\t\tthis->shrink(n);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconstexpr void resize(tc::static_vector_size_t const n) & noexcept(noexcept(this->emplace_back())) {\n\t\t\t\tif (this->size() < n) {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tthis->emplace_back();\n\t\t\t\t\t} while (n != this->size());\n\t\t\t\t} else {\n\t\t\t\t\tthis->shrink(n);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr void take_inplace( It const& it ) & noexcept {\n\t\t\t\tthis->shrink(*it.get_index());\n\t\t\t}\n\n\t\t\ttemplate<typename It>\n\t\t\tconstexpr void drop_inplace(It&& it) & noexcept {\n\t\t\t\tauto iSrc=it.get_index();\n\t\t\t\t_ASSERTE(iSrc<=this->m_iEnd);\n\t\t\t\tif (iSrc!=0) {\n\t\t\t\t\ttc_index iDst=0;\n\t\t\t\t\tfor (; iSrc!=this->m_iEnd; ++iDst, ++iSrc) {\n\t\t\t\t\t\tthis->dereference(iDst)=tc_move_always(this->dereference(iSrc));\n\t\t\t\t\t}\n\t\t\t\t\tthis->shrink(iDst);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} // static_vector_adl\n\tusing static_vector_adl::static_vector;\n\n\ttemplate<tc::static_vector_size_t N, typename Rng>\n\tconstexpr auto make_static_vector(Rng&& rng) MAYTHROW {\n\t\treturn tc::explicit_cast<tc::static_vector<tc::range_value_t<Rng>, N>>(tc_move_if_owned(rng));\n\t}\n\n\ttemplate<tc::static_vector_size_t N, typename... Rng>\n\tconstexpr auto make_static_vector(Rng&&... rng) MAYTHROW {\n\t\treturn make_static_vector<N>(tc::concat(tc_move_if_owned(rng)...));\n\t}\n\n\ttemplate< typename T, tc::static_vector_size_t N >\n\tstruct range_filter_by_move_element<tc::static_vector<T,N>> : tc::constant<true> {};\n\n\ttemplate<typename Char>\n\tusing codepoint = tc::static_vector<Char, tc::char_limits<Char>::c_nMaxCodeUnitsPerCodePoint>;\n}\n\nMODIFY_WARNINGS_END\n"
  },
  {
    "path": "tc/storage_for.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/assert_defs.h\"\n#include \"base/noncopyable.h\"\n#include \"base/type_traits.h\"\n#include \"base/casts.h\"\n#include \"base/static_polymorphism.h\"\n#include \"base/renew.h\"\n\n#include <type_traits>\n\nMODIFY_WARNINGS_BEGIN(((disable)(4297))) // 'function' : function assumed not to throw an exception but does.\n\nnamespace tc {\n\tnamespace no_adl {\n\t\tstruct uninitalized_storage_dummy final {\n\t\t\tconstexpr uninitalized_storage_dummy() noexcept = delete; // non-trival to avoid zero-initialization\n\t\t};\n\n\t\t// clang does not correctly support contrained special member functions before version 15.\n\t\ttemplate<typename T, bool = std::is_trivially_destructible<T>::value>\n\t\tstruct storage_for_select_dtor_base;\n\n\t\ttemplate<typename T>\n\t\tstruct storage_for_select_dtor_base<T, false> {\n\t\t\tconstexpr storage_for_select_dtor_base() noexcept {}\n\t\t\tconstexpr ~storage_for_select_dtor_base() {}\n\n\t\t\tunion {\n\t\t\t\tuninitalized_storage_dummy m_dummy;\n\t\t\t\tT m_buffer;\n\t\t\t};\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tstruct storage_for_select_dtor_base<T, /*is_trivially_destructible*/true> {\n\t\t\tconstexpr storage_for_select_dtor_base() noexcept {}\n\t\t\tconstexpr ~storage_for_select_dtor_base() = default;\n\n\t\t\tunion {\n\t\t\t\tuninitalized_storage_dummy m_dummy;\n\t\t\t\tT m_buffer;\n\t\t\t};\n\t\t};\n\n\t\ttemplate< typename Derived, typename T >\n\t\tstruct [[nodiscard]] storage_for_base : protected storage_for_select_dtor_base<std::remove_const_t<T>> {\n\t\t\tstatic_assert( !std::is_trivially_constructible<storage_for_select_dtor_base<std::remove_const_t<T>>>::value );\n\t\t\tSTATICASSERTEQUAL(\n\t\t\t\tstd::is_trivially_destructible<storage_for_select_dtor_base<std::remove_const_t<T>>>::value,\n\t\t\t\tstd::is_trivially_destructible<T>::value\n\t\t\t);\n\t\t\tusing this_type = storage_for_base<Derived, T>;\n\t\t\tstatic_assert( tc::decayed< std::remove_const_t<T> >, \"only const allowed as qualification\" );\n\n\t\t\t// Avoiding tc::nonmovable because it affects layout on clang, if T is derived from tc::nonmovable as well.\n\t\t\tstorage_for_base& operator=(storage_for_base&&) noexcept = delete;\n\n\t\tpublic:\n\t\t\t[[nodiscard]] static Derived& from_content(T& t) noexcept requires (!std::is_const<T>::value) {\n\t\t\t\tSTATICASSERTEQUAL( sizeof(storage_for_base), sizeof(T) );\n\t\t\t\treturn *tc::derived_cast<Derived>(reinterpret_cast<storage_for_base*>(std::addressof(t)));\n\t\t\t}\n\t\t\t[[nodiscard]] static Derived const& from_content(T const& t) noexcept {\n\t\t\t\tSTATICASSERTEQUAL( sizeof(storage_for_base), sizeof(T) );\n\t\t\t\treturn *tc::derived_cast<Derived>(reinterpret_cast<storage_for_base const*>(std::addressof(t)));\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr std::remove_const_t<T>* uninitialized_addressof() & noexcept {\n\t\t\t\treturn std::addressof(this->m_buffer);\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T const* uninitialized_addressof() const& noexcept {\n\t\t\t\treturn std::addressof(this->m_buffer);\n\t\t\t}\n\t\t\tvoid ctor() & noexcept(std::is_nothrow_default_constructible<T>::value) {\n\t\t\t\t// This check is not strict enough. The following struct is !std::is_trivially_default_constructible,\n\t\t\t\t// but ctor_default does not initialize n to 0, while ctor_value does:\n\t\t\t\t//\tstruct Foo {\n\t\t\t\t//\t\ttc::string<char> s; // has user-defined default ctor\n\t\t\t\t//\t\tint n; // has no user-defined default ctor\n\t\t\t\t//\t};\n\t\t\t\tstatic_assert(!std::is_trivially_default_constructible<T>::value, \"You must decide between ctor_default and ctor_value!\");\n\t\t\t\tctor_default();\n\t\t\t}\n\n\t\t\tvoid ctor_default() & noexcept(std::is_nothrow_default_constructible<T>::value) {\n\t\t\t\t::new (static_cast<void*>(&this->m_buffer)) T; // :: ensures that non-class scope operator new is used, cast to void* ensures that built-in placement new is used  (18.6.1.3)\n\t\t\t}\n\t\t\ttemplate<typename... Args> requires (0 < sizeof...(Args))\n\t\t\tvoid ctor_default(Args&&... args) & noexcept(noexcept(tc::explicit_cast<T>(std::declval<Args>()...))) {\n\t\t\t\t::new (static_cast<void*>(&this->m_buffer)) T(tc::explicit_cast<T>(tc_move_if_owned(args)...)); // :: ensures that non-class scope operator new is used, cast to void* ensures that built-in placement new is used  (18.6.1.3)\n\t\t\t}\n\n\t\t\ttemplate<typename... Args> // ctor_value with non-empty argument list is useful in generic code\n\t\t\tconstexpr void ctor_value(Args&& ... args) & noexcept(std::is_nothrow_constructible<T, Args&&...>::value) {\n \t\t\t\ttc::ctor(this->m_buffer, tc_move_if_owned(args)...);\n\t\t\t}\n\t\t\ttemplate<typename First, typename... Args>\n\t\t\tconstexpr void ctor(First&& first, Args&& ... args) & noexcept(std::is_nothrow_constructible<T, First&&, Args&&...>::value) {\n\t\t\t\ttc::ctor(this->m_buffer, tc_move_if_owned(first), tc_move_if_owned(args)...);\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T const* operator->() const& noexcept {\n\t\t\t\treturn std::addressof(dereference());\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T* operator->() & noexcept {\n\t\t\t\treturn std::addressof(tc::as_mutable(dereference()));\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T const& operator*() const& noexcept {\n\t\t\t\treturn dereference();\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T& operator*() & noexcept {\n\t\t\t\treturn tc::as_mutable(dereference());\n\t\t\t}\n\t\t\t[[nodiscard]] constexpr T&& operator*() && noexcept {\n\t\t\t\treturn tc_move_always(tc::as_mutable(dereference()));\n\t\t\t}\n\t\t\tconstexpr void dtor() & noexcept {\n\t\t\t\ttc::dtor_static(tc::as_mutable(this->m_buffer));\n\t\t\t}\n\t\tprotected:\n\t\t\tSTATIC_VIRTUAL_WITH_DEFAULT_IMPL_MOD(constexpr, dereference)() const& -> T const& {\n\t\t\t\tSTATICASSERTEQUAL( sizeof(storage_for_base), sizeof(T) ); // no extra members, important for arrays\n\t\t\t\treturn this->m_buffer;\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Derived, typename T >\n\t\tstruct [[nodiscard]] storage_for_base<Derived, T&> : tc::nonmovable {\n\t\tprotected:\n\t\t\tstatic_assert(!std::is_reference<T>::value);\n\t\t\tusing this_type = storage_for_base<Derived, T&>;\n\t\t\tT* m_buffer;\n\n\t\t\tSTATIC_VIRTUAL_WITH_DEFAULT_IMPL_MOD(constexpr, dereference)() const& -> T& {\n\t\t\t\treturn *m_buffer;\n\t\t\t}\n\t\tpublic:\n\t\t\tconstexpr void ctor(T& t) & noexcept {\n\t\t\t\tm_buffer = std::addressof(t);\n\t\t\t}\n\n\t\t\t// reference semantics == no deep constness\n\t\t\tconstexpr T* operator->() const& noexcept {\n\t\t\t\treturn std::addressof(dereference());\n\t\t\t}\n\t\t\tconstexpr T& operator*() const& noexcept {\n\t\t\t\treturn dereference();\n\t\t\t}\n\t\t\tconstexpr void dtor() & noexcept {\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\t\tif( !std::is_constant_evaluated() ) tc::fill_with_dead_pattern(this->m_buffer);\n#endif\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Derived, typename T >\n\t\tstruct [[nodiscard]] storage_for_base<Derived, T&&> : tc::nonmovable {\n\t\tprotected:\n\t\t\tstatic_assert(!std::is_reference<T>::value);\n\t\t\tusing this_type = storage_for_base<Derived, T&&>;\n\t\t\tT* m_buffer;\n\n\t\t\tSTATIC_VIRTUAL_WITH_DEFAULT_IMPL_MOD(constexpr, dereference)() const& -> T&& {\n\t\t\t\treturn static_cast<T&&>(*m_buffer);\n\t\t\t}\n\t\tpublic:\n\t\t\tconstexpr void ctor(T&& t) & noexcept {\n\t\t\t\tm_buffer = std::addressof(t);\n\t\t\t}\n\n\t\t\tconstexpr T&& operator*() && noexcept {\n\t\t\t\treturn dereference();\n\t\t\t}\n\t\t\tconstexpr void dtor() & noexcept {\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\t\tif( !std::is_constant_evaluated() ) tc::fill_with_dead_pattern(this->m_buffer);\n#endif\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename Derived, typename T >\n\t\tstruct [[nodiscard]] storage_for_checked_access_base : storage_for_base<Derived, T> {\n\t\t\tusing this_type = storage_for_checked_access_base<Derived, T>;\n\t\t\tusing Base = typename storage_for_checked_access_base::storage_for_base;\n\t\t\t\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\tvoid ctor() & noexcept(noexcept(Base::ctor())) {\n\t\t\t\tcheck_dead_pattern();\n\t\t\t\ttc::remove_dead_pattern(this->m_buffer);\n\t\t\t\ttry {\n\t\t\t\t\tBase::ctor();\n\t\t\t\t} catch (...) {\n\t\t\t\t\ttc::fill_with_dead_pattern(this->m_buffer);\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid ctor_default() & noexcept(noexcept(Base::ctor_default())) {\n\t\t\t\tcheck_dead_pattern();\n\t\t\t\ttc::remove_dead_pattern(this->m_buffer);\n\t\t\t\ttry {\n\t\t\t\t\tBase::ctor_default();\n\t\t\t\t}\tcatch (...) {\n\t\t\t\t\ttc::fill_with_dead_pattern(this->m_buffer);\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttemplate<typename... Args> // ctor_value with non-empty argument list is useful in generic code\n\t\t\tvoid ctor_value(Args&& ... args) & noexcept(noexcept(std::declval<Base&>().ctor_value(tc_move_if_owned(args)...))) {\n\t\t\t\tcheck_dead_pattern();\n\t\t\t\ttc::remove_dead_pattern(this->m_buffer);\n\t\t\t\ttry {\n\t\t\t\t\tBase::ctor_value(tc_move_if_owned(args)...);\n\t\t\t\t} catch (...) {\n\t\t\t\t\ttc::fill_with_dead_pattern(this->m_buffer);\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttemplate<typename First, typename... Args>\n\t\t\tvoid ctor(First&& first, Args&& ... args) & noexcept(noexcept(Base::ctor(tc_move_if_owned(first), tc_move_if_owned(args)...))) {\n\t\t\t\tcheck_dead_pattern();\n\t\t\t\ttc::remove_dead_pattern(this->m_buffer);\n\t\t\t\ttry {\n\t\t\t\t\tBase::ctor(tc_move_if_owned(first), tc_move_if_owned(args)...);\n\t\t\t\t} catch (...) {\n\t\t\t\t\ttc::fill_with_dead_pattern(this->m_buffer);\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid dtor() & noexcept {\n\t\t\t\t_ASSERTDEBUG(!tc::has_dead_pattern(this->m_buffer));\n\t\t\t\tBase::dtor();\n\t\t\t\t// tc::fill_with_dead_pattern implied by Base::dtor\n\t\t\t}\n\n\t\tprotected:\n\t\t\tvoid check_dead_pattern() const& noexcept {\n\t\t\t\t// RT#12004: g_mtxSharedHeap's destructor fails this check in the Excel insider build 16.0.6568.2036\n\t\t\t\t// because this version does not realease all its locks on CTCAddInModule so that tc::shared_heap::shutdown()\n\t\t\t\t// and thus g_mtxSharedHeap.dtor() are never called. This build appears to be broken. It throws and does\n\t\t\t\t// not handle 0xC0000008 (An invalid handle was specified) while closing even without think-cell installed.\n\t\t\t\t// I could not reproduce the error in the next Excel insider build 16.0.6701.1008. -Edgar 2016-03-14\n\t\t\t\t_ASSERTDEBUG(tc::has_dead_pattern(this->m_buffer));\n\t\t\t}\n\n\t\tprivate:\n\t\t\tSTATIC_OVERRIDE(dereference)() const& noexcept -> decltype(auto) {\n\t\t\t\t_ASSERTDEBUG(!tc::has_dead_pattern(this->m_buffer));\n\t\t\t\treturn Base::STATIC_VIRTUAL_METHOD_NAME(dereference)();\n\t\t\t}\n#endif\n\t\t};\n\n\t\ttemplate< typename T >\n\t\tstruct [[nodiscard]] storage_for : storage_for_checked_access_base<storage_for<T>, T> {\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\tstorage_for() noexcept {\n\t\t\t\ttc::fill_with_dead_pattern(this->m_buffer);\n\t\t\t}\n\t\t\t~storage_for() {\n\t\t\t\tthis->check_dead_pattern();\n\t\t\t}\n#endif\n\t\t};\n\n\t\ttemplate< typename T >\n\t\tstruct [[nodiscard]] storage_for_without_dtor : storage_for_base<storage_for_without_dtor<T>, T>{\n\t\t};\n\n\t\ttemplate< typename T >\n\t\t// TODO: inline into derived class\n\t\tstruct [[nodiscard]] storage_for_dtor_at_end_of_scope : storage_for<T> {\n\t\t\tconstexpr ~storage_for_dtor_at_end_of_scope() { this->dtor(); }\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tstruct members_alive_before_ctor : storage_for_base<members_alive_before_ctor<T>, T> {\n\t\t\tusing base_ = typename members_alive_before_ctor::storage_for_base;\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\tmembers_alive_before_ctor() noexcept {\n\t\t\t\ttc::fill_with_dead_pattern(*this); // no members must be alive yet\n\t\t\t}\n#endif\n\n\t\t\t~members_alive_before_ctor() {\n\t\t\t\tthis->dtor();\n\t\t\t}\n\n\t\t\t// Hide ctor variants from storage_for_base that may zero-initialize which would kill lifetime_begins_before_ctor member\n\t\t\tvoid ctor(auto&&...) = delete;\n\t\t\tvoid ctor_value(auto&&...) = delete;\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tstruct lifetime_begins_before_ctor final : storage_for_checked_access_base<lifetime_begins_before_ctor<T>, T> {\n#if defined(_DEBUG) && defined(TC_PRIVATE)\n\t\t\tlifetime_begins_before_ctor() noexcept {\n\t\t\t\t_ASSERTDEBUG( !tc::has_dead_pattern(this->m_buffer) );\n\t\t\t}\n#endif\n\t\t\t~lifetime_begins_before_ctor() {\n\t\t\t\tthis->dtor();\n\t\t\t}\n\t\t};\n\n\t\ttemplate< typename T >\n\t\tstruct scoped_constructor;\n\n\t\ttemplate< typename T >\n\t\tstruct scoped_constructor<storage_for<T>&> final : private tc::nonmovable {\n\t\t\ttemplate<typename... Args>\n\t\t\texplicit scoped_constructor( storage_for<T>& ot, Args&&... args ) MAYTHROW\n\t\t\t:\tm_ot(ot)\n\t\t\t{\n\t\t\t\tm_ot.ctor(tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t}\n\t\t\t~scoped_constructor() {\n\t\t\t\tm_ot.dtor();\n\t\t\t}\n\t\tprivate:\n\t\t\tstorage_for<T>& m_ot;\n\t\t};\n\t}\n\tusing no_adl::storage_for_without_dtor;\n\tusing no_adl::storage_for;\n\tusing no_adl::storage_for_dtor_at_end_of_scope;\n\tusing no_adl::members_alive_before_ctor;\n\tusing no_adl::lifetime_begins_before_ctor;\n\tusing no_adl::scoped_constructor;\n}\n\nMODIFY_WARNINGS_END\n\n#define scoped_construct(var, ...) tc::scoped_constructor< decltype((var)) > UNIQUE_IDENTIFIER((var) __VA_OPT__(,) __VA_ARGS__ );\n"
  },
  {
    "path": "tc/string/ascii.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"char.h\"\n#include \"../base/assert_defs.h\"\n#include \"../base/explicit_cast.h\"\n#include \"../range/meta.h\"\n#include \"../range/transform_adaptor.h\"\n\n#include <cstdint>\n\nnamespace tc {\n\n\t// cast may not be necessary, but let's avoid problems even in case of user-defined T\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciidigit( T ch ) noexcept {\n\t\treturn tc::char_ascii('0')<=ch && ch<=tc::char_ascii('9');\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciixdigit( T ch ) noexcept {\n\t\treturn isasciidigit(ch)\n\t\t\t|| (tc::char_ascii('A')<=ch && ch<=tc::char_ascii('F'))\n\t\t\t|| (tc::char_ascii('a')<=ch && ch<=tc::char_ascii('f'));\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciiupper( T ch ) noexcept {\n\t\treturn tc::char_ascii('A')<=ch && ch<=tc::char_ascii('Z');\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciilower( T ch ) noexcept {\n\t\treturn tc::char_ascii('a')<=ch && ch<=tc::char_ascii('z');\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciicntrl( T ch ) noexcept {\n\t\treturn (tc::char_ascii('\\0')<=ch && ch<=tc::char_ascii('\\x1f')) || tc::char_ascii('\\x7f')==ch;\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciiblank( T ch ) noexcept {\n\t\t// in C locale, it is:\n\t\t// ' '\t(0x20) space (SPC)\n\t\t// '\\t'\t(0x09) horizontal tab (TAB)\n\t\treturn tc::char_ascii('\\t')==ch || tc::char_ascii(' ')==ch;\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr bool isasciispace( T ch ) noexcept {\n\t\t// in C locale, it is:\n\t\t// ' '\t(0x20) space (SPC)\n\t\t// '\\t'\t(0x09) horizontal tab (TAB)\n\t\t// '\\n'\t(0x0a) newline (LF)\n\t\t// '\\v'\t(0x0b) vertical tab (VT)\n\t\t// '\\f'\t(0x0c) feed (FF)\n\t\t// '\\r'\t(0x0d) carriage return (CR)\n\t\treturn tc::isasciiblank(ch) ||\n\t\t\t(tc::char_ascii('\\xa')<=ch && ch<=tc::char_ascii('\\xd'));\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T toasciiupper( T ch ) noexcept {\n\t\tif( tc::isasciilower(ch) ) {\n\t\t\treturn static_cast<T>( ch-('a'-'A') );\n\t\t} else {\n\t\t\treturn ch;\n\t\t}\n\t}\n\n\ttemplate< typename T >\n\t[[nodiscard]] constexpr T toasciilower( T ch ) noexcept {\n\t\tif( tc::isasciiupper(ch) ) {\n\t\t\treturn static_cast<T>( ch+('a'-'A') );\n\t\t} else {\n\t\t\treturn ch;\n\t\t}\n\t}\n\n\ttemplate<typename Rng>\n\tdecltype(auto) transform_asciiupper(Rng&& rng) noexcept { // return_decltype_noexcept in C++20\n\t\treturn tc::transform( tc_move_if_owned(rng), tc_fn(tc::toasciiupper) );\n\t}\n\n\ttemplate<typename Rng>\n\tdecltype(auto) transform_asciilower(Rng&& rng) noexcept { // return_decltype_noexcept in C++20\n\t\treturn tc::transform( tc_move_if_owned(rng), tc_fn(tc::toasciilower) );\n\t}\n\n\tnamespace rfc3986 {\n\t\t// https://tools.ietf.org/html/rfc3986#appendix-A:\n\n\t\ttemplate<typename T>\n\t\tbool is_unreserved(T ch) noexcept {\n\t\t\t// unreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n\t\t\treturn tc::isasciilower(ch)\n\t\t\t\t|| tc::isasciiupper(ch)\n\t\t\t\t|| tc::isasciidigit(ch)\n\t\t\t\t|| tc::char_ascii('-')==ch\n\t\t\t\t|| tc::char_ascii('.')==ch\n\t\t\t\t|| tc::char_ascii('_')==ch\n\t\t\t\t|| tc::char_ascii('~')==ch;\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tbool is_subdelim(T ch) noexcept {\n\t\t\t// sub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\" / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n\t\t\treturn tc::char_ascii('!')==ch\n\t\t\t\t|| tc::char_ascii('$')==ch\n\t\t\t\t|| tc::char_ascii('&')==ch\n\t\t\t\t|| tc::char_ascii('\\'')==ch\n\t\t\t\t|| tc::char_ascii('(')==ch\n\t\t\t\t|| tc::char_ascii(')')==ch\n\t\t\t\t|| tc::char_ascii('*')==ch\n\t\t\t\t|| tc::char_ascii('+')==ch\n\t\t\t\t|| tc::char_ascii(',')==ch\n\t\t\t\t|| tc::char_ascii(';')==ch\n\t\t\t\t|| tc::char_ascii('=')==ch;\n\t\t};\n\n\t\ttemplate<typename T>\n\t\tbool is_unencoded_pchar(T ch) noexcept {\n\t\t\t//pchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n\t\t\treturn tc::rfc3986::is_unreserved(ch)\n\t\t\t\t|| tc::rfc3986::is_subdelim(ch)\n\t\t\t\t|| tc::char_ascii(':')==ch\n\t\t\t\t|| tc::char_ascii('@')==ch;\n\t\t};\n\t}\n\n\tnamespace ascii_byte_literals {\n\t\tconstexpr auto operator \"\" _asc(char const ch) noexcept {\n\t\t\t// Don't use hex or octal escapes; use the char code directly. For example, use 0x80 instead of '\\x80'_asc\n\t\t\t// Other ASCII control characters may be added here as exceptions.\n\t\t\t_ASSERTE((ch >= 0x20 && ch <= 0x7E) || ch == '\\r' || ch == '\\n' || ch == '\\t');\n\n\t\t\treturn tc::to_underlying(ch);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/char.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/string_template_param.h\"\n#include \"../range/literal_range.h\"\n#include \"../array.h\"\n#include \"../restricted_enum.h\"\n\nnamespace tc {\n\tusing char_ascii = tc::restricted_enum<char, '\\0', '\\x7f'>;\n\tusing char_asciidigit = tc::restricted_enum<char, '0', '9'>;\n\tusing char_asciilower = tc::restricted_enum<char, 'a', 'z'>;\n\tusing char_asciiupper = tc::restricted_enum<char, 'A', 'Z'>;\n\n\tnamespace no_adl {\n#pragma push_macro(\"CUSTOMIZE_COMMON_TYPE_CHAR_ASCII\")\n#define CUSTOMIZE_COMMON_TYPE_CHAR_ASCII(char_type) \\\n\t\ttemplate<> \\\n\t\tstruct common_type_decayed_impl<tc::char_ascii, char_type> { \\\n\t\t\tusing type = char_type; \\\n\t\t}; \\\n\t\ttemplate<> \\\n\t\tstruct common_type_decayed_impl<char_type, tc::char_ascii> { \\\n\t\t\tusing type = char_type; \\\n\t\t};\n\n\t\tCUSTOMIZE_COMMON_TYPE_CHAR_ASCII(char)\n\t\tCUSTOMIZE_COMMON_TYPE_CHAR_ASCII(wchar_t)\n\t\tCUSTOMIZE_COMMON_TYPE_CHAR_ASCII(char16_t)\n\t\tCUSTOMIZE_COMMON_TYPE_CHAR_ASCII(char32_t)\n#pragma pop_macro(\"CUSTOMIZE_COMMON_TYPE_CHAR_ASCII\")\n\t}\n}\n\ntemplate<tc::char_type Char, Char chFirst, Char chLast>\nstruct std::char_traits<tc::restricted_enum<Char, chFirst, chLast>> final {\n\tusing char_type = tc::restricted_enum<Char, chFirst, chLast>;\n\tusing int_type = typename tc::char_traits<Char>::int_type;\n\tusing off_type = typename tc::char_traits<Char>::off_type;\n\tusing pos_type = typename tc::char_traits<Char>::pos_type;\n\tusing state_type = typename tc::char_traits<Char>::state_type;\n\n\tstatic constexpr void assign(char_type& r, const char_type& a) noexcept {\n\t\tr = a;\n\t}\n\n\tstatic char_type* assign(char_type* p, std::size_t count, char_type a) {\n\t\tstd::fill(p, p+count, a);\n\t\treturn p;\n\t}\n\n\tstatic constexpr bool eq(char_type a, char_type b) noexcept {\n\t\treturn a == b;\n\t}\n\n\tstatic constexpr bool lt(char_type a, char_type b) noexcept {\n\t\treturn a < b;\n\t}\n\n\tstatic constexpr std::size_t length(const char_type* s) noexcept {\n\t\tstd::size_t n = 0;\n\t\tif(s) {\n\t\t\twhile(char_type() != *s++)\n\t\t\t\t++n;\n\t\t}\n\t\treturn n;\n\t}\n\n\tstatic constexpr const char_type* find(const char_type* p, std::size_t count, const char_type& ch) noexcept {\n\t\twhile(0<count) {\n\t\t\tif(*p == ch) {\n\t\t\t\treturn p;\n\t\t\t} else {\n\t\t\t\t++p;\n\t\t\t\t--count;\n\t\t\t}\n\t\t}\n\t\treturn nullptr;\n\t}\n\n\tstatic constexpr int compare(const char_type* s1, const char_type* s2, std::size_t count) noexcept {\n\t\tfor(std::size_t i=0; i<count; ++i) {\n\t\t\tif (*s1<*s2) return -1;\n\t\t\telse if (*s2<*s1) return 1;\n\t\t}\n\t\treturn 0;\n\t}\n\n\tstatic char_type* move(char_type* dest, const char_type* src, std::size_t count) noexcept {\n\t\tif (src <= dest && dest < src+count) {\n\t\t\tstd::copy_backward(src, src+count, dest+count);\n\t\t} else {\n\t\t\tstd::copy(src, src+count, dest);\n\t\t}\n\t\treturn dest;\n\t}\n\n\tstatic char_type* copy(char_type* dest, const char_type* src, std::size_t count) noexcept {\n\t\treturn move(dest, src, count); // copy works correctly just like move in clang and gcc's implementation\n\t}\n};\n\nnamespace tc {\n#if WCHAR_MAX == 0xFFFF // == 2 bytes unsigned: We want tc::char16 to be unsigned. wchar_t is unsigned on MSVC, but that's implementation-specific.\n\tusing char16 = wchar_t;\n\t#define tc_raw_utf16_(x) L ## x\n#else\n\tusing char16 = char16_t;\n\t#define tc_raw_utf16_(x) u ## x\n#endif\n#define tc_raw_utf16(x) tc_raw_utf16_(x)\n#define tc_utf16(x) tc_raw_utf16(x)\n}\n\n#define tc_ascii_val(str) tc::make_array<tc::char_ascii>(str)  // avoid copy\n#define tc_ascii(str) tc_as_constexpr(tc_ascii_val(str))\n\nnamespace tc {\n\ttemplate <tc::string_template_param String>\n\tconstexpr bool is_ascii_string_literal = []{\n\t\t// Simple for loop to avoid any cyclic dependencies.\n\t\tfor (auto c : String) {\n\t\t\tif (static_cast<unsigned>(tc::to_underlying(c)) > 0x7F) return false;\n\t\t}\n\t\treturn true;\n\t}();\n\n\ttemplate <tc::string_template_param String>\n\tconstexpr auto string_literal = []<std::size_t ... I>(std::index_sequence<I...>){\n\t\tusing char_type = tc::range_value_t<decltype(String)>;\n\t\tstatic_assert(!std::same_as<char_type, wchar_t>, \"use either u or U prefix to force UTF-16 or UTF-32; not L\");\n\n\t\tif constexpr (std::same_as<char_type, char>) {\n\t\t\treturn tc::literal_range<tc::char_ascii, String[I]...>{};\n\t\t} else if constexpr (std::same_as<char_type, char8_t>) {\n\t\t\treturn tc::literal_range<char, String[I]...>{};\n\t\t} else if constexpr (std::same_as<char_type, char16_t>) {\n\t\t\treturn tc::literal_range<tc::char16, String[I]...>{};\n\t\t} else {\n\t\t\treturn tc::literal_range<char_type, String[I]...>{};\n\t\t}\n\t}(std::make_index_sequence<tc::constexpr_size<decltype(String)>()>());\n}\n\n// \"abc\"_tc -> ASCII-8 string with char type tc::char_ascii\n// u8\"abc\"_tc -> UTF-8 string with char type char\n// u\"abc\"_tc -> UTF-16 string with char type tc::char16\n// U\"abc\"_tc -> UTF-32 string with char type char32_t\ntemplate <tc::string_template_param String>\n[[nodiscard]] constexpr auto operator\"\"_tc() noexcept {\n\treturn tc::string_literal<String>;\n}\n\n// 8-bit character literal is always ASCII.\n[[nodiscard]] constexpr auto operator\"\"_tc(char const c) noexcept {\n\treturn tc::char_ascii(c);\n}\n[[nodiscard]] constexpr auto operator\"\"_tc(char8_t const c) noexcept {\n\treturn char(c);\n}\n[[nodiscard]] constexpr auto operator\"\"_tc(char16_t const c) noexcept {\n\treturn tc::char16(c);\n}\n[[nodiscard]] constexpr auto operator\"\"_tc(char32_t const c) noexcept {\n\treturn c;\n}\n// This is not portable.\nvoid operator\"\"_tc(wchar_t) = delete;\n"
  },
  {
    "path": "tc/string/char.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"../algorithm/append.h\"\n#include \"../container/insert.h\"\n#include \"../container/cont_assign.h\"\n#include \"char.h\"\n\nstatic_assert(std::is_trivial<tc::char_ascii>::value);\nstatic_assert(std::is_trivially_copyable<tc::char_ascii>::value);\nstatic_assert(std::is_standard_layout<tc::char_ascii>::value);\n\ntemplate<typename T>\nstruct is_convertible_to_ascii_supporting_types final {\n\tstatic constexpr auto value = tc::safely_convertible_to<tc::char_asciilower, tc::char_ascii> | tc::safely_convertible_to<tc::char_asciilower, char> | tc::safely_convertible_to<tc::char_asciilower, tc::char16>;\n};\n\nstatic_assert(is_convertible_to_ascii_supporting_types<tc::char_asciilower>::value);\nstatic_assert(is_convertible_to_ascii_supporting_types<tc::char_asciiupper>::value);\nstatic_assert(is_convertible_to_ascii_supporting_types<tc::char_asciidigit>::value);\n\nstatic_assert(tc::char_ascii('a') == 'a' && 'a' == tc::char_ascii('a'));\nstatic_assert(tc::char_ascii('a') == u'a' && u'a' == tc::char_ascii('a'));\nstatic_assert(tc::size(\"abc\"_tc) == 3);\nstatic_assert(tc::equal(\"abc\", \"abc\"_tc));\n\nstatic_assert(tc::char_ascii('a') == tc::char_asciilower('a') && tc::char_asciilower('a') == tc::char_ascii('a'));\nstatic_assert(tc::char_ascii('z') == tc::char_asciilower('z') && tc::char_asciilower('z') == tc::char_ascii('z'));\nstatic_assert(tc::char_ascii('z') != tc::char_asciilower('a') && tc::char_asciilower('a') != tc::char_ascii('z'));\nstatic_assert(tc::char_ascii(' ') != tc::char_asciilower('a') && tc::char_asciilower('a') != tc::char_ascii(' '));\n\nstatic_assert(tc::char_ascii('A') == tc::char_asciiupper('A') && tc::char_asciiupper('A') == tc::char_ascii('A'));\nstatic_assert(tc::char_ascii('Z') == tc::char_asciiupper('Z') && tc::char_asciiupper('Z') == tc::char_ascii('Z'));\nstatic_assert(tc::char_ascii('Z') != tc::char_asciiupper('A') && tc::char_asciiupper('A') != tc::char_ascii('Z'));\nstatic_assert(tc::char_ascii(' ') != tc::char_asciiupper('A') && tc::char_asciiupper('A') != tc::char_ascii(' '));\n\nstatic_assert(tc::char_ascii('0') == tc::char_asciidigit('0') && tc::char_asciidigit('0') == tc::char_ascii('0'));\nstatic_assert(tc::char_ascii('9') == tc::char_asciidigit('9') && tc::char_asciidigit('9') == tc::char_ascii('9'));\nstatic_assert(tc::char_ascii('9') != tc::char_asciidigit('0') && tc::char_asciidigit('0') != tc::char_ascii('9'));\nstatic_assert(tc::char_ascii(' ') != tc::char_asciidigit('0') && tc::char_asciidigit('0') != tc::char_ascii(' '));\n\nUNITTESTDEF(append_char_ascii) {\n\ttc::string<char> str1;\n\ttc::cont_emplace_back(str1, tc::char_ascii('a'));\n\t_ASSERT(tc::equal(str1, \"a\"));\n\ttc::append(str1, \"bcd\"_tc);\n\t_ASSERT(tc::equal(str1, \"abcd\"));\n\n\ttc::string<char32_t> str2;\n\ttc::cont_emplace_back(str2, tc::char_ascii('a'));\n\t_ASSERT(tc::equal(str2, U\"a\"));\n\ttc::append(str2, \"bcd\"_tc);\n\t_ASSERT(tc::equal(str2, U\"abcd\"));\n\n\ttc::string<char> str3;\n\ttc::append(str3, \"a\", \"bc\"_tc, \"d\");\n\t_ASSERT(tc::equal(str3, \"abcd\"));\n\n\ttc::string<char32_t> str4;\n\ttc::append(str4, U\"a\", \"bc\"_tc, U\"d\");\n\t_ASSERT(tc::equal(str4, U\"abcd\"));\n\n\ttc::string<char32_t> str5;\n\ttc::append(str5, \"a\", \"bc\"_tc, \"d\");\n\t_ASSERT(tc::equal(str5, U\"abcd\"));\n\n\ttc::string<tc::char_ascii> str6;\n\ttc::append(str6, \"abc\"_tc);\n\t_ASSERT(tc::equal(str6, \"abc\"));\n\ttc::cont_emplace_back(str6, tc::char_ascii('d'));\n\t_ASSERT(tc::equal(str6, \"abcd\"));\n\ttc::drop_first_inplace(str6);\n\t_ASSERT(tc::equal(str6, \"bcd\"));\n\ttc::drop_last_inplace(str6);\n\t_ASSERT(tc::equal(str6, \"bc\"));\n\ttc::cont_assign(str6);\n\t_ASSERT(tc::empty(str6));\n\ttc::append(str6, \"abc\"_tc);\n\n\ttc::span<tc::char_ascii const> str7 = str6;\n\t_ASSERT(tc::equal(str7, \"abc\"));\n}\n\nstatic_assert(std::is_same<char, tc::common_type_t<char, tc::char_ascii>>::value);\nstatic_assert(std::is_same<char, tc::common_type_t<tc::char_ascii, char>>::value);\nstatic_assert(std::is_same<wchar_t, tc::common_type_t<wchar_t, tc::char_ascii>>::value);\nstatic_assert(std::is_same<wchar_t, tc::common_type_t<tc::char_ascii, wchar_t>>::value);\n\nstatic_assert(0 == std::numeric_limits<tc::char16>::lowest() && 0xFFFF == std::numeric_limits<tc::char16>::max());\n\nUNITTESTDEF(string_literal) {\n\tauto ascii = \"abc\"_tc;\n\tSTATICASSERTSAME(decltype(ascii), TC_FWD(tc::literal_range<tc::char_ascii, 'a', 'b', 'c'>));\n\n\t// Due to the bug shown in https://godbolt.org/z/Kzc8orP4j, we can't use the same characters as the ASCII string.\n\t// (MSVC thinks u8\"abc\" is the same instantiation as \"abc\" and re-uses the same result.)\n\t// It is already fixed in newer versions of MSVC and shouldn't affect our codebase - why would we have an ASCII and a UTF-8 string with the same characters.\n\tauto utf8 = u8\"ABC\"_tc;\n\tSTATICASSERTSAME(decltype(utf8), TC_FWD(tc::literal_range<char, u8'A', u8'B', u8'C'>));\n\n\tauto utf16 = u\"abc\"_tc;\n\tSTATICASSERTSAME(decltype(utf16), TC_FWD(tc::literal_range<tc::char16, u'a', u'b', u'c'>));\n\n\tauto utf32 = U\"abc\"_tc;\n\tSTATICASSERTSAME(decltype(utf32), TC_FWD(tc::literal_range<char32_t, U'a', U'b', U'c'>));\n}\n\nUNITTESTDEF(char_literal) {\n\tstd::same_as<tc::char_ascii> auto ascii = 'a'_tc;\n\t_ASSERTEQUAL(ascii, 'a');\n\n\tstd::same_as<char> auto utf8 = u8'a'_tc;\n\t_ASSERTEQUAL(utf8, 'a');\n\n\tstd::same_as<tc::char16> auto utf16 = u'a'_tc;\n\t_ASSERTEQUAL(utf16, static_cast<tc::char16>('a'));\n\n\tstd::same_as<char32_t> auto utf32 = U'a'_tc;\n\t_ASSERTEQUAL(utf32, U'a');\n}\n"
  },
  {
    "path": "tc/string/convert_enc.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/bitfield.h\"\n#include \"../base/rvalue_property.h\"\n#include \"../base/bit_cast.h\"\n#include \"../algorithm/empty.h\"\n#include \"../algorithm/compare.h\"\n#include \"../range/range_adaptor.h\"\n\n#include \"char.h\"\n\nnamespace tc {\n\t// Code unit predicates\n\t//\n\t// These names are based on the terminology used in the Unicode Standard: https://www.unicode.org/versions/Unicode13.0.0/UnicodeStandard-13.0.pdf\n\t// \"(...) reserved for the first, or leading, element of a UTF-8 code unit sequences, (...) reserved for the subsequent, or trailing, elements of such sequences;\"\n\t// \"(...) for the lead, trail, or single code units in any of those encoding forms overlap.\"\n\t[[nodiscard]] constexpr bool is_leading_codeunit(char const ch) noexcept {\n\t\treturn 0xc0 == (ch & 0xc0); // matches 11xxxxxx\n\t}\n\t[[nodiscard]] constexpr bool is_leading_codeunit(tc::char16 const ch) noexcept {\n\t\treturn 0xd800u == (ch & 0xfc00u); // high surrogate\n\t}\n\ttemplate <tc::char_type Char, Char chFirst, Char chLast>\n\t[[nodiscard]] constexpr auto is_leading_codeunit(tc::restricted_enum<Char, chFirst, chLast> const ch) noexcept {\n\t\tif constexpr(chLast < 0x80) {\n\t\t\treturn tc::constant<false>{};\n\t\t} else {\n\t\t\treturn is_leading_codeunit(tc::implicit_cast<Char>(ch));\n\t\t}\n\t}\n\n\t[[nodiscard]] constexpr bool is_trailing_codeunit(char const ch) noexcept {\n\t\treturn 0x80 == (ch & 0xc0); // matches 10xxxxxx\n\t}\n\t[[nodiscard]] constexpr bool is_trailing_codeunit(tc::char16 const ch) noexcept {\n\t\treturn 0xdc00u == (ch & 0xfc00u); // low surrogate\n\t}\n\ttemplate <tc::char_type Char, Char chFirst, Char chLast>\n\t[[nodiscard]] constexpr auto is_trailing_codeunit(tc::restricted_enum<Char, chFirst, chLast> const ch) noexcept {\n\t\tif constexpr(chLast < 0x80) {\n\t\t\treturn tc::constant<false>{};\n\t\t} else {\n\t\t\treturn is_trailing_codeunit(tc::implicit_cast<Char>(ch));\n\t\t}\n\t}\n\n\ttemplate<typename T>\n\t[[nodiscard]] constexpr bool is_single_codeunit(T const ch) noexcept {\n\t\treturn char_in_range<T>(tc::to_underlying(ch));\n\t}\n\n\tnamespace codeunit_sequence_size_detail {\n\t\t[[nodiscard]] constexpr inline std::optional<int> codeunit_sequence_size_raw(char const ch) noexcept {\n\t\t\tif( auto const n=0xffu & ~tc::to_underlying(ch); 0!=n ) { // code unit 0xff is invalid\n\t\t\t\tswitch(tc::index_of_most_significant_bit(n)) {\n\t\t\t\t\tcase 7: return 1;\n\t\t\t\t\tcase 5: return 2;\n\t\t\t\t\tcase 4: return 3;\n\t\t\t\t\tcase 3: return 4;\n\t\t\t\t\tdefault: break; // 6=continuation, otherwise invalid\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn std::nullopt;\n\t\t}\n\n\t\t// tc::make_interval not used to avoid dependency cycle\n\t\t[[nodiscard]] constexpr std::optional<int> codeunit_sequence_size_raw(tc::char16 const ch) noexcept {\n\t\t\tif( auto const n=tc::to_underlying(ch); n<0xd800u || 0xdfffu<n) return 1;\n\t\t\telse if( n<0xdc00u ) return 2; // high-surrogate\n\t\t\telse return std::nullopt; // low-surrogate, continuation\n\t\t}\n\n\t\t[[nodiscard]] constexpr std::optional<int> codeunit_sequence_size_raw(tc::char_ascii const ch) noexcept {\n\t\t\treturn 1;\n\t\t}\n\n\t\tusing osize_t = std::optional<tc::size_proxy<int>>;\n\n\t\ttemplate<typename Char>\n\t\t[[nodiscard]] constexpr inline osize_t codeunit_sequence_size(Char ch) noexcept { \n\t\t\treturn osize_t(codeunit_sequence_size_raw(ch));\n\t\t}\n\t}\n\tusing codeunit_sequence_size_detail::codeunit_sequence_size_raw;\n\tusing codeunit_sequence_size_detail::codeunit_sequence_size;\n\n\tTC_DEFINE_ENUM(ECodeunitSequenceType, ecodeunitseqtyp,\n\t\t(TRUNCATED) // The sequence lacks continuation code unit(s). In UTF-16, an unpaired high-surrogate.\n\t\t// Embedded in any code unit sequence, end == increment(decrement(end)) for sequence types below.\n\t\t(VALID) // A structurally well formed sequence. In UTF-8, the sequence may still encode surrogate code points or be an overlong encoding. In utf-16, such a sequence is always a valid encoding.\n\t\t// Embedded in any code unit sequence, begin == decrement(increment(begin)) for sequence types above.\n\t\t(CONTINUATION) // The sequence is a single continuation code unit. In UTF-16, an unpaired low-surrogate.\n\t)\n\n\ttemplate<typename Rng, typename Index>\n\tconstexpr ECodeunitSequenceType codepoint_increment_index(Rng const& rng, Index& idx) MAYTHROW {\n\t\tauto onSequenceSize = tc::codeunit_sequence_size_raw(tc::dereference_index(rng, idx) /*MAYTHROW*/);\n\t\ttc::increment_index(rng, idx); // MAYTHROW\n\t\tif( onSequenceSize ) {\n\t\t\tfor( ; 0 != --*onSequenceSize; tc::increment_index(rng, idx) /* MAYTHROW*/ ) {\n\t\t\t\tif( tc::at_end_index(rng, idx) || !tc::is_trailing_codeunit(tc::dereference_index(rng, idx) /*MAYTHROW*/) ) TC_UNLIKELY {\n\t\t\t\t\treturn ecodeunitseqtypTRUNCATED;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ecodeunitseqtypVALID;\n\t\t} else {\n\t\t\t// Not [[unlikely]], if idx is an arbitrary index.\n\t\t\treturn ecodeunitseqtypCONTINUATION;\n\t\t}\n\t}\n\n\ttemplate<tc::has_decrement_index Rng, typename Index> requires\n\t\ttc::is_equality_comparable<Index>::value\n\tconstexpr ECodeunitSequenceType codepoint_decrement_index(Rng const& rng, Index& idx) MAYTHROW {\n\t\ttc::decrement_index(rng, idx); // MAYTHROW\n\t\tint nCodeUnits = 1;\n\t\tstatic_assert( 1 < tc::char_limits<tc::range_value_t<Rng const&>>::c_nMaxCodeUnitsPerCodePoint );\n\n\t\tfor (auto idxPeek = idx;; ++nCodeUnits, tc::decrement_index(rng, idxPeek) /* MAYTHROW*/) {\n\t\t\tif( auto const onSequenceSize = tc::codeunit_sequence_size_raw(tc::dereference_index(rng, idxPeek) /*MAYTHROW*/) ) {\n\t\t\t\tif( nCodeUnits <= *onSequenceSize ) {\n\t\t\t\t\tidx = tc_move(idxPeek);\n\t\t\t\t\tif( nCodeUnits == *onSequenceSize ) {\n\t\t\t\t\t\treturn ecodeunitseqtypVALID;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We decrement arbitrary indices to establish code-point-alignment in codepoint_range.\n\t\t\t\t\t\t// Hence, this branch is not [[unlikely]].\n\t\t\t\t\t\treturn ecodeunitseqtypTRUNCATED;\n\t\t\t\t\t}\n\t\t\t\t} else TC_UNLIKELY {\n\t\t\t\t\treturn ecodeunitseqtypCONTINUATION;\n\t\t\t\t}\n\t\t\t} else if( tc::explicit_cast<int>(tc::char_limits<tc::range_value_t<Rng const&>>::c_nMaxCodeUnitsPerCodePoint) <= nCodeUnits\n\t\t\t\t|| tc::begin_index(rng) == idxPeek //MAYTHROW\n\t\t\t) TC_UNLIKELY {\n\t\t\t\treturn ecodeunitseqtypCONTINUATION;\n\t\t\t}\n\t\t}\n\t}\n\n\tconstexpr char32_t surrogate_pair_value(tc::char16 const chLeading, tc::char16 const chTrailing) noexcept {\n\t\tauto n = tc::to_underlying(chLeading) - 0xd800u;\n\t\t_ASSERTDEBUG(n<0x400u);\n\t\tn<<=10;\n\n\t\tunsigned int n2=tc::to_underlying(chTrailing)-0xdc00u;\n\t\t_ASSERTDEBUG(n2<0x400u);\n\t\tn+=n2+0x10000u;\n\t\t_ASSERTDEBUG(n<0x110000u);\n\t\treturn static_cast<char32_t>(n);\n\t}\n\n\ttemplate<typename Rng>\n\tconstexpr std::optional<char32_t> codepoint_value_impl(Rng const& rng, tc::index_t<Rng const> idx) MAYTHROW {\n\t\tstatic_assert(\n\t\t\tstd::is_same<tc::char16, tc::range_value_t<Rng const&>>::value ||\n\t\t\tstd::is_same<char, tc::range_value_t<Rng const&>>::value ||\n\t\t\tstd::is_same<tc::char_ascii, tc::range_value_t<Rng const&>>::value\n\t\t);\n\t\tif(\tauto const ch=tc::dereference_index(rng, idx); // MAYTHROW\n\t\t\tauto const onSequenceSize=tc::codeunit_sequence_size_raw(ch)\n\t\t) {\n\t\t\tunsigned int n=tc::to_underlying(ch);\n\t\t\ttc::increment_index(rng, idx); // MAYTHROW\n\t\t\tif( 1==*onSequenceSize || (!tc::at_end_index(rng, idx) && [&]() MAYTHROW {\n\t\t\t\tif constexpr( std::is_same<tc::char16, tc::range_value_t<Rng const&>>::value ) {\n\t\t\t\t\tauto const ch2=tc::dereference_index(rng, idx); // MAYTHROW\n\t\t\t\t\t_ASSERTDEBUGEQUAL(*onSequenceSize, 2);\n\t\t\t\t\tif(tc::is_trailing_codeunit(ch2)) {\n\t\t\t\t\t\tn=tc::to_underlying(tc::surrogate_pair_value(ch, ch2));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else if constexpr(std::is_same<char, tc::range_value_t<Rng const&>>::value) {\n\t\t\t\t\t_ASSERTDEBUGANYOF(*onSequenceSize, (2)(3)(4));\n\t\t\t\t\tn &= 0x7fu >> *onSequenceSize; // 2 -> 0x1f, 3 -> 0xf, 4 -> 0x7\n\t\t\t\t\tint i=*onSequenceSize;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tauto const ch2=tc::dereference_index(rng, idx); // MAYTHROW\n\t\t\t\t\t\tif(!tc::is_trailing_codeunit(ch2)) TC_UNLIKELY return false;\n\n\t\t\t\t\t\tn<<=6;\n\t\t\t\t\t\tn|=tc::to_underlying(ch2) & 0x3fu;\n\t\t\t\t\t\tif(1 == --i) {\n\t\t\t\t\t\t\tswitch_no_default(*onSequenceSize) {\n\t\t\t\t\t\t\t\tcase 2: return 0x80u<=n;\n\t\t\t\t\t\t\t\tcase 3: return (0x800u<=n && n<0xd800u) || 0xdfffu<n;\n\t\t\t\t\t\t\t\tcase 4: return 0x10000u<=n && n<0x110000u;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttc::increment_index(rng, idx); // MAYTHROW\n\t\t\t\t\t} while(!tc::at_end_index(rng, idx));\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERTE(false); // *onSequenceSize is always 1 for tc::char_ascii\n\t\t\t\t}\n\t\t\t\tTC_UNLIKELY return false;\n\t\t\t}()/*MAYTHROW*/) ) {\n\t\t\t\treturn tc::bit_cast<char32_t>(n);\n\t\t\t}\n\t\t}\n\t\tTC_UNLIKELY return std::nullopt;\n\t}\n\n\ttemplate<typename Rng>\n\tconstexpr decltype(auto) codepoint_value(Rng const& rng) MAYTHROW {\n\t\t_ASSERTE( !tc::empty(rng) );\n\t\treturn tc::codepoint_value_impl(rng, tc::begin_index(rng)); // MAYTHROW\n\t}\n\n\ttemplate<typename Char>\n\tconstexpr int codepoint_codeunit_count(unsigned int nCodePoint) noexcept {\n\t\tif constexpr( std::same_as<char, Char> ) {\n\t\t\treturn \n\t\t\t\tnCodePoint<0x80u ? 1\n\t\t\t\t: nCodePoint<0x800u\t? 2\n\t\t\t\t: nCodePoint<0x10000u ? 3 : 4;\n\t\t} else if constexpr( std::same_as<tc::char16, Char> ) {\n\t\t\treturn nCodePoint<0x10000u ? 1 : 2;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\ttemplate<typename Char>\n\tconstexpr Char codepoint_codeunit_at(unsigned int nCodePoint, int const nCodeUnitIndex) noexcept {\n\t\t_ASSERTDEBUG(nCodePoint<0x110000u);\n\t\tauto const nLastIndex=tc::codepoint_codeunit_count<Char>(nCodePoint) - 1;\n\t\tif constexpr( std::same_as<char, Char> ) {\n\t\t\treturn tc::bit_cast<char>(tc::explicit_cast<std::uint8_t>([&]() noexcept {\n\t\t\t\tswitch_no_default(nCodeUnitIndex) {\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\treturn 0==nLastIndex\n\t\t\t\t\t\t\t? nCodePoint\n\t\t\t\t\t\t\t: nCodePoint>>nLastIndex*6 | ((1 << (nLastIndex+1))-1)<<(7-nLastIndex);\n\t\t\t\t\tcase 1:\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t_ASSERTDEBUG(nCodeUnitIndex<=nLastIndex);\n\t\t\t\t\t\treturn (nCodePoint>>(nLastIndex-nCodeUnitIndex)*6 & 0x3fu) | 0x80u;\n\t\t\t\t}\n\t\t\t}()));\n\t\t} else if constexpr( std::same_as<tc::char16, Char> ) {\n\t\t\treturn tc::bit_cast<tc::char16>(tc::explicit_cast<std::uint16_t>([&]() noexcept {\n\t\t\t\tswitch_no_default(nCodeUnitIndex) {\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tswitch_no_default(nLastIndex) {\n\t\t\t\t\t\t\tcase 0: return nCodePoint;\n\t\t\t\t\t\t\tcase 1: return ((nCodePoint-0x10000u) >> 10)+0xd800u;\n\t\t\t\t\t\t}\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t_ASSERTDEBUG(1==nLastIndex);\n\t\t\t\t\t\treturn (nCodePoint-0x10000u & 0x3ffu)+0xdc00u;\n\t\t\t\t}\n\t\t\t}()));\n\t\t} else {\n\t\t\ttc_return_cast(nCodePoint);\n\t\t}\n\t}\n\n\tnamespace convert_enc_impl {\n\t\ttemplate <typename Dst, typename Rng, typename Src=tc::range_value_t<Rng>>\n\t\tstruct SStringConversionRange;\n\n\t\t// Lazily convert UTF-8/UTF-16 strings to UTF-32\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] SStringConversionRange<char32_t, Rng>\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\tSStringConversionRange<char32_t, Rng>,\n\t\t\t\tRng,\n\t\t\t\ttc::index_range_adaptor_flags::inherit_begin_end\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing base_ = typename SStringConversionRange::index_range_adaptor;\n\t\t\tstatic_assert( std::is_same<char, tc::range_value_t<Rng>>::value || std::is_same<tc::char16, tc::range_value_t<Rng>>::value );\n\n\t\tpublic:\n\t\t\tusing base_::base_;\n\t\t\tusing typename base_::tc_index;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=false;\n\n\t\tprivate:\n\t\t\tusing this_type = SStringConversionRange;\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, increment_index)(tc_index& idx) const& MAYTHROW {\n\t\t\t\tVERIFYNOTIFYEQUAL(tc::codepoint_increment_index(this->base_range(), idx), ecodeunitseqtypVALID);\n\t\t\t}\n\n\t\t\tSTATIC_FINAL_MOD(\n\t\t\t\ttemplate<ENABLE_SFINAE> constexpr,\n\t\t\t\tdecrement_index\n\t\t\t)(SFINAE_TYPE(tc_index)& idx) const& return_decltype_MAYTHROW(\n\t\t\t\tvoid(VERIFYNOTIFYEQUAL( tc::codepoint_decrement_index(this->base_range(), idx) /*MAYTHROW*/, ecodeunitseqtypVALID ))\n\t\t\t)\n\n\t\t\tSTATIC_FINAL_MOD(constexpr, dereference_index)(tc_index const& idx) const& MAYTHROW {\n\t\t\t\tif (auto och=VERIFYNOTIFY( tc::codepoint_value_impl(this->base_range(), idx) )) { // MAYTHROW\n\t\t\t\t\treturn *och;\n\t\t\t\t} else {\n\t\t\t\t\treturn U'\\uFFFD'; // REPLACEMENT CHARACTER\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\tstatic constexpr auto border_base_index(tc_index const& idx) noexcept {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename Index>\n\t\tstruct SCodeUnitIndex final {\n\t\t\tIndex m_idx;\n\t\t\tint m_nCodeUnitIndex;\n\n\t\t\tfriend bool operator==(SCodeUnitIndex const& lhs, SCodeUnitIndex const& rhs) noexcept = default;\n\t\t};\n\n\t\ttemplate<typename Derived, typename Rng, typename Char>\n\t\tstruct SStringConversionFromUtf32RangeBase\n\t\t\t: tc::range_iterator_from_index<\n\t\t\t\tDerived,\n\t\t\t\tSCodeUnitIndex<tc::index_t<std::remove_reference_t<Rng>>>\n\t\t\t>\n\t\t\t, tc::range_adaptor_base_range<Rng>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = SStringConversionFromUtf32RangeBase;\n\t\t\tusing base_ = tc::range_adaptor_base_range<Rng>;\n\n\t\tpublic:\n\t\t\tusing base_::base_;\n\t\t\tusing typename this_type::range_iterator_from_index::tc_index;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\n\t\tprivate:\n\t\t\t// Indexes pointing to continuation code units are invalid. If the underlying range contains lone continuation units, they will be converted to a\n\t\t\t// REPLACEMENT CHARACTER\n\t\t\ttemplate<ENABLE_SFINAE> // clang workaround\n\t\t\tconstexpr auto codepoint_at(decltype(tc_index::m_idx) const& idxBaseRng) const& MAYTHROW {\n\t\t\t\tif(\tauto const n=tc::to_underlying(tc::dereference_index(SFINAE_VALUE(this)->base_range(), idxBaseRng)); // MAYTHROW\n\t\t\t\t\tVERIFYNOTIFY(n<0x110000u) && VERIFYNOTIFY(n<0xd800u || 0xdfffu<n) \n\t\t\t\t) {\n\t\t\t\t\treturn n;\n\t\t\t\t} else {\n\t\t\t\t\treturn tc::explicit_cast<decltype(n)>(0xfffd); // U+FFFD REPLACEMENT CHARACTER\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, begin_index)() const& return_ctor_MAYTHROW(\n\t\t\t\ttc_index,\n\t\t\t\t{this->base_begin_index() /*MAYTHROW*/, 0}\n\t\t\t)\n\n\t\t\tSTATIC_OVERRIDE_MOD(TC_FWD(\n\t\t\t\ttemplate<\n\t\t\t\t\tENABLE_SFINAE,\n\t\t\t\t\tstd::enable_if_t<tc::has_mem_fn_end_index<std::remove_reference_t<SFINAE_TYPE(Rng)>>>* = nullptr\n\t\t\t\t> constexpr),\n\t\t\t\tend_index\n\t\t\t)() const& return_ctor_MAYTHROW(\n\t\t\t\ttc_index,\n\t\t\t\t{tc::end_index(SFINAE_VALUE(this->base_range())) /*MAYTHROW*/, 0}\n\t\t\t)\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, at_end_index)(tc_index const& idx) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::at_end_index(this->base_range(), idx.m_idx) && (_ASSERTE(0==idx.m_nCodeUnitIndex), true)\n\t\t\t)\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, dereference_index)(tc_index const& idx) const& return_MAYTHROW(\n\t\t\t\ttc::codepoint_codeunit_at<Char>(codepoint_at(idx.m_idx) /*MAYTHROW*/, idx.m_nCodeUnitIndex)\n\t\t\t)\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, increment_index)(tc_index& idx) const& MAYTHROW {\n\t\t\t\tif(++idx.m_nCodeUnitIndex == tc::codepoint_codeunit_count<Char>(codepoint_at(idx.m_idx) /*MAYTHROW*/)) {\n\t\t\t\t\tidx.m_nCodeUnitIndex=0;\n\t\t\t\t\ttc::increment_index(this->base_range(), idx.m_idx); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_OVERRIDE_MOD(constexpr, decrement_index)(tc_index& idx) const& MAYTHROW\n\t\t\t\trequires tc::has_decrement_index<std::remove_reference_t<Rng>>\n\t\t\t{\n\t\t\t\tif(0==idx.m_nCodeUnitIndex) {\n\t\t\t\t\ttc::decrement_index(this->base_range(), idx.m_idx); // MAYTHROW\n\t\t\t\t\tidx.m_nCodeUnitIndex=tc::codepoint_codeunit_count<Char>(codepoint_at(idx.m_idx) /*MAYTHROW*/) - 1;\n\t\t\t\t} else {\n\t\t\t\t\t--idx.m_nCodeUnitIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\tstatic constexpr auto border_base_index(tc_index const& idx) noexcept {\n\t\t\t\t_ASSERTE(0==idx.m_nCodeUnitIndex);\n\t\t\t\treturn idx.m_idx;\n\t\t\t}\n\t\t};\n\n\t\t// Lazily convert UTF-32 strings to UTF-16\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] SStringConversionRange<tc::char16, Rng, char32_t>\n\t\t\t: SStringConversionFromUtf32RangeBase<SStringConversionRange<tc::char16, Rng>, Rng, tc::char16>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = SStringConversionRange<tc::char16, Rng>;\n\t\t\tusing base_ = SStringConversionFromUtf32RangeBase<this_type, Rng, tc::char16>;\n\n\t\tpublic:\n\t\t\tusing base_::base_;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] SStringConversionRange<char, Rng, char32_t>\n\t\t\t: SStringConversionFromUtf32RangeBase<SStringConversionRange<char, Rng>, Rng, char>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = SStringConversionRange<char, Rng>;\n\t\t\tusing base_ = SStringConversionFromUtf32RangeBase<this_type, Rng, char>;\n\n\t\tpublic:\n\t\t\tusing base_::base_;\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] SStringConversionRange<char, Rng, tc::char16> final\n\t\t\t: SStringConversionRange<char, SStringConversionRange<char32_t, Rng>>\n\t\t{\n\t\tprivate:\n\t\t\tusing base_ = SStringConversionRange<char, SStringConversionRange<char32_t, Rng>>;\n\n\t\t\ttemplate<typename Self>\n\t\t\tstatic constexpr decltype(auto) base_range_(Self&& self) noexcept {\n\t\t\t\treturn tc_move_if_owned(self).base_::base_range().base_range();\n\t\t\t}\n\n\t\tpublic:\n\t\t\tconstexpr explicit SStringConversionRange(aggregate_tag_t, Rng&& rng) noexcept\n\t\t\t\t: base_(aggregate_tag, SStringConversionRange<char32_t, Rng>(aggregate_tag, tc_move_if_owned(rng)))\n\t\t\t{}\n\t\t\tusing typename base_::tc_index;\n\n\t\t\tconstexpr auto border_base_index(tc_index const& idx) const& return_decltype_noexcept(\n\t\t\t\tbase_::base_range().border_base_index(base_::border_base_index(idx))\n\t\t\t)\n\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(base_range)\n\t\t};\n\n\t\ttemplate<typename Rng>\n\t\tstruct [[nodiscard]] SStringConversionRange<tc::char16, Rng, char> final\n\t\t\t: SStringConversionRange<tc::char16, SStringConversionRange<char32_t, Rng>>\n\t\t{\n\t\tprivate:\n\t\t\tusing base_ = SStringConversionRange<tc::char16, SStringConversionRange<char32_t, Rng>>;\n\n\t\t\ttemplate<typename Self>\n\t\t\tstatic constexpr decltype(auto) base_range_(Self&& self) noexcept {\n\t\t\t\treturn tc_move_if_owned(self).base_::base_range().base_range();\n\t\t\t}\n\n\t\tpublic:\n\t\t\tconstexpr explicit SStringConversionRange(aggregate_tag_t, Rng&& rng) noexcept\n\t\t\t\t: base_(aggregate_tag, SStringConversionRange<char32_t, Rng>(aggregate_tag, tc_move_if_owned(rng)))\n\t\t\t{}\n\t\t\tusing typename base_::tc_index;\n\n\t\t\tconstexpr auto border_base_index(tc_index const& idx) const& return_decltype_noexcept(\n\t\t\t\tbase_::base_range().border_base_index(base_::border_base_index(idx))\n\t\t\t)\n\n\t\t\tRVALUE_THIS_OVERLOAD_MOVABLE_MUTABLE_REF(base_range)\n\t\t};\n\t} // namespace convert_enc_impl\n\n\t//--------------------------------------------------------------------------------------------------------------------------\n\t// convert_enc\n\t// Either forwards its argument (if it is a range of Dst), or converts it to a lazy range of Dst (if it is a range of another char type).\n\n\tnamespace no_adl {\n\t\ttemplate<typename Sink, tc::char_like Dst>\n\t\tstruct convert_enc_sink;\n\t}\n\n\tnamespace convert_enc_detail {\n\t\ttemplate<tc::char_like Dst, typename Src>\n\t\t[[nodiscard]] decltype(auto) with_sink_impl(Src&& src) noexcept {\n\t\t\treturn tc::generator_range_output<Dst>([src=tc::make_reference_or_value(tc_move_if_owned(src))](auto&& sink) MAYTHROW {\n\t\t\t\treturn tc::for_each(*src, no_adl::convert_enc_sink<decltype(sink), Dst>(tc_move_if_owned(sink)));\n\t\t\t});\n\t\t}\n\n\t\ttemplate <tc::char_like Dst, auto ... Cs>\n\t\t[[nodiscard]] constexpr auto convert_literal(tc::literal_range<tc::char_ascii, Cs...>) noexcept {\n\t\t\t// We cast the Cs to char, to keep a simple type as NTTP and because presumably every char_like type is constructible from char.\n\t\t\treturn tc::literal_range<Dst, tc::implicit_cast<char>(Cs)...>{};\n\t\t}\n\t}\n\n\ttemplate<tc::char_like Dst, typename Src>\n\t[[nodiscard]] decltype(auto) convert_enc(Src&& src) noexcept {\n\t\tif constexpr(tc::has_range_value<Src>) {\n\t\t\tstatic_assert(tc::char_like<tc::range_value_t<Src>>);\n\t\t\tif constexpr(tc::safely_convertible_to<tc::range_value_t<Src>, Dst>) {\n\t\t\t\treturn tc_move_if_owned(src);\n\t\t\t} else if constexpr(tc::char_type<Dst> && tc::char_type<tc::range_value_t<Src>> && tc::range_with_iterators<Src>) {\n\t\t\t\treturn convert_enc_impl::SStringConversionRange<Dst, Src>{aggregate_tag, tc_move_if_owned(src)};\n\t\t\t} else if constexpr(std::same_as<Dst, tc::char_ascii>) {\n\t\t\t\treturn tc::transform(tc_move_if_owned(src), tc::fn_explicit_cast<tc::char_ascii>());\n\t\t\t} else {\n\t\t\t\treturn convert_enc_detail::with_sink_impl<Dst>(tc_move_if_owned(src));\n\t\t\t}\n\t\t} else {\n\t\t\treturn convert_enc_detail::with_sink_impl<Dst>(tc_move_if_owned(src));\n\t\t}\n\t}\n\n\ttemplate<tc::char_like Dst, typename Src> requires tc::instance_or_derived<std::remove_reference_t<Src>, convert_enc_impl::SStringConversionRange>\n\t[[nodiscard]] auto convert_enc(Src&& src) noexcept {\n\t\treturn tc::convert_enc<Dst>(tc_move_if_owned(src).base_range());\n\t}\n\n\ttemplate<tc::char_like Dst, typename Src> requires tc::is_literal_range<Src> && std::same_as<tc::range_value_t<Src>, tc::char_ascii>\n\t[[nodiscard]] auto convert_enc(Src&& src) noexcept {\n\t\treturn convert_enc_detail::convert_literal<Dst>(src);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Sink, tc::char_like Dst>\n\t\tstruct convert_enc_sink /*final*/ {\n\t\tprivate:\n\t\t\ttc::decay_t<Sink> m_sink;\n\n\t\tpublic:\n\t\t\texplicit convert_enc_sink(Sink&& sink) noexcept\n\t\t\t\t: m_sink(tc_move_if_owned(sink)) \n\t\t\t{}\n\n\t\t\ttemplate<tc::char_like CharT, std::enable_if_t<tc::safely_convertible_to<CharT, Dst>>* = nullptr>\n\t\t\tauto operator()(CharT ch) const& return_decltype_MAYTHROW(\n\t\t\t\tm_sink(ch)\n\t\t\t)\n\n\t\t\ttemplate<typename Rng, std::enable_if_t<tc::range_with_iterators<Rng> && tc::char_like<tc::range_value_t<Rng>>>* = nullptr> // terse syntax triggers VS17.1 ICE\n\t\t\tauto chunk(Rng&& rng) const& return_decltype_MAYTHROW(\n\t\t\t\ttc::for_each(tc::convert_enc<Dst>(tc_move_if_owned(rng)), m_sink)\n\t\t\t)\n\t\t};\n\t}\n}\n\n"
  },
  {
    "path": "tc/string/convert_enc.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"convert_enc.h\"\n\nnamespace {\n\t// Only one of is_single_codeunit, is_leading_codeunit, and is_trailing_codeunit should be true for a code unit. These predicates help asserting this.\n\ttemplate <typename Char>\n\t[[nodiscard]] bool constexpr IsSingle(Char const ch) noexcept {\n\t\treturn tc::is_single_codeunit(ch) && !tc::is_leading_codeunit(ch) && !tc::is_trailing_codeunit(ch);\n\t}\n\n\ttemplate <typename Char>\n\t[[nodiscard]] bool constexpr IsLeading(Char const ch) noexcept {\n\t\treturn !tc::is_single_codeunit(ch) && tc::is_leading_codeunit(ch) && !tc::is_trailing_codeunit(ch);\n\t}\n\n\ttemplate <typename Char>\n\t[[nodiscard]] bool constexpr IsTrailing(Char const ch) noexcept {\n\t\treturn !tc::is_single_codeunit(ch) && !tc::is_leading_codeunit(ch) && tc::is_trailing_codeunit(ch);\n\t}\n}\n\n// UTF-8\n\nstatic_assert(IsSingle('\\0'));\nstatic_assert(IsSingle('!'));\nstatic_assert(IsSingle('~'));\nstatic_assert(IsSingle('\\x7f'));\n\nstatic_assert(IsLeading('\\xc2'));\nstatic_assert(IsLeading('\\xf4'));\n\nstatic_assert(IsTrailing('\\x80'));\nstatic_assert(IsTrailing('\\xbf'));\n\nstatic_assert(IsLeading(static_cast<char>(\"\\u200B\"[0])) && IsTrailing(static_cast<char>(\"\\u200B\"[1])) && IsTrailing(static_cast<char>(\"\\u200B\"[2])));\n\n// UTF-16\n\nstatic_assert(IsSingle(tc_utf16('\\x7FFF')));\nstatic_assert(IsLeading(tc_utf16('\\xD800')));\nstatic_assert(IsLeading(tc_utf16('\\xDBFF')));\nstatic_assert(IsTrailing(tc_utf16('\\xDC00')));\nstatic_assert(IsTrailing(tc_utf16('\\xDFFF')));\n"
  },
  {
    "path": "tc/string/format.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"../base/assert_defs.h\"\n#include \"../base/explicit_cast.h\"\n#include \"../base/bit_cast.h\"\n#include \"../algorithm/for_each.h\"\n#include \"../algorithm/empty.h\"\n#include \"../algorithm/minmax.h\"\n#include \"../range/subrange.h\"\n#include \"../range/concat_adaptor.h\"\n#include \"../range/repeat_n.h\"\n#include \"char.h\"\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\" // sprintf is deprecated in Xcode14.1 RC\n#endif\n#include <boost/lexical_cast.hpp>\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\nnamespace tc {\n\t///////////////\n\t// Wrapper to print integers as decimal\n\n\tnamespace integral_as_padded_dec_adl {\n\t\ttemplate< typename T, std::size_t N>\n\t\tstruct integral_as_padded_dec_impl;\n\n\t\ttemplate< typename T>\n\t\tstruct integral_as_padded_dec_impl<T,1>;\n\n\t\ttemplate< typename T, std::size_t N>\n\t\tstruct [[nodiscard]] integral_as_padded_dec_impl : protected integral_as_padded_dec_impl<T,N-1> {\n\t\t\tfriend auto range_output_t_impl(integral_as_padded_dec_impl const&) -> boost::mp11::mp_list<tc::char_ascii>; // declaration only\n\t\t\tstatic constexpr unsigned long long c_nTenPow=integral_as_padded_dec_impl<T,N-1>::c_nTenPow*10;\n\t\t\tconstexpr integral_as_padded_dec_impl( T n ) noexcept : integral_as_padded_dec_impl<T,N-1>(n) {}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink sink) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\tdecltype(tc::continue_if_not_break(std::declval<Sink&>(), std::declval<tc::char_ascii>())),\n\t\t\t\tdecltype(std::declval<integral_as_padded_dec_impl<T,N-1> const&>()(std::declval<Sink>()))\n\t\t\t> {\n\t\t\t\tstatic_assert( std::is_unsigned<T>::value );\n\t\t\t\tif( this->m_n<integral_as_padded_dec_impl::c_nTenPow ) {\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, tc::char_ascii('0')))\n\t\t\t\t}\n\t\t\t\treturn tc::base_cast< integral_as_padded_dec_impl<T,N-1> >(*this)(tc_move(sink));\n\t\t\t}\n\n\t\t\tconstexpr bool empty() const& noexcept { return false; }\n\t\t};\n\n\t\ttemplate< typename T>\n\t\tstruct [[nodiscard]] integral_as_padded_dec_impl<T,1> {\n\t\t\tfriend auto range_output_t_impl(integral_as_padded_dec_impl const&) -> boost::mp11::mp_list<tc::char_ascii>; // declaration only\n\t\t\tT m_n;\n\t\t\tstatic constexpr unsigned long long c_nTenPow=1;\n\t\t\tconstexpr integral_as_padded_dec_impl( T n ) noexcept : m_n(n) {}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink&& sink) const& MAYTHROW {\n\t\t\t\ttc_auto_cref(str, boost::lexical_cast< std::array<char,50> >(m_n+0/*force integral promotion, otherwise unsigned/signed char gets printed as character*/));\n\t\t\t\treturn tc::for_each(tc::transform(tc::ptr_begin(str), tc::fn_explicit_cast<tc::char_ascii>()), tc_move_if_owned(sink));\n\t\t\t}\n\n\t\t\tconstexpr bool empty() const& noexcept { return false; }\n\t\t};\n\t}\n\n\ttemplate< tc::actual_integer T>\n\tconstexpr auto as_dec(T t) return_ctor_noexcept(\n\t\tTC_FWD(integral_as_padded_dec_adl::integral_as_padded_dec_impl<T, 1>),\n\t\t(t)\n\t)\n\n\ttemplate< typename T >\n\tconstexpr auto as_dec(tc::size_proxy<T> const& t) return_decltype_noexcept(\n\t\ttc::as_dec(t.m_t)\n\t)\n\n\ttemplate< std::size_t N, tc::actual_integer T>\n\tconstexpr auto as_padded_dec(T t) return_ctor_noexcept(\n\t\tTC_FWD(integral_as_padded_dec_adl::integral_as_padded_dec_impl<std::make_unsigned_t<T>, N>),\n\t\t(tc::as_unsigned(t))\n\t)\n\n\ttemplate< std::size_t N, typename T >\n\tconstexpr auto as_padded_dec(tc::size_proxy<T> const& t) return_decltype_noexcept(\n\t\ttc::as_padded_dec<N>(t.m_t)\n\t)\n\n\tTC_DEFINE_ENUM(casing, BOOST_PP_EMPTY(), (uppercase)(lowercase));\n\n\tnamespace as_hex_adl {\n\t\t///////////////\n\t\t// Wrapper to print integers as hex\n\t\ttemplate< typename T, unsigned int nWidth, tc::casing c>\n\t\tstruct [[nodiscard]] as_hex_impl final {\n\t\t\tfriend auto range_output_t_impl(as_hex_impl const&) -> boost::mp11::mp_list<tc::char_ascii>; // declaration only\n\t\tprivate:\n\t\t\ttypename boost::uint_t< CHAR_BIT*sizeof(T) >::exact m_n;\n\t\tpublic:\n\t\t\tconstexpr as_hex_impl( T const& n ) noexcept : m_n(tc::bit_cast< typename boost::uint_t< CHAR_BIT*sizeof(T) >::exact >(n)) {} // print the bit pattern of anything we get\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink sink) const& MAYTHROW -> decltype(tc::continue_if_not_break(std::declval<Sink&>(), std::declval<tc::char_ascii>())) {\n\t\t\t\tstatic_assert( 0<nWidth );\n\t\t\t\tstatic_assert( nWidth<=(sizeof(m_n)*CHAR_BIT+3)/4 );\n\t\t\t\tusing return_t = decltype(tc::continue_if_not_break(std::declval<Sink&>(), std::declval<tc::char_ascii>()));\n\n\t\t\t\tauto nShift=sizeof(m_n)*CHAR_BIT;\n\t\t\t\tdo {\n\t\t\t\t\tnShift-=4;\n\t\t\t\t} while( nWidth*4<=nShift && 0==(m_n>>nShift) );\n\t\t\t\tfor(;;) {\n\t\t\t\t\tauto const nDigit=(m_n>>nShift)&0xf;\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, nDigit<10 ? tc::char_ascii('0')+nDigit : tc::char_ascii(tc::lowercase==c ? 'a' : 'A')+(nDigit-10)))\n\t\t\t\t\tif constexpr (!std::is_same<return_t, tc::constant<tc::break_>>::value) {\n\t\t\t\t\t\tif (0 == nShift) break;\n\t\t\t\t\t\tnShift -= 4;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif constexpr (!std::is_same<return_t, tc::constant<tc::break_>>::value) {\n\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing as_hex_adl::as_hex_impl;\n\n\ttemplate< unsigned int nWidth, tc::casing c=tc::uppercase, typename T >\n\tconstexpr auto as_hex(T const& t) return_ctor_noexcept(\n\t\tTC_FWD(as_hex_impl<T, nWidth, c>),\n\t\t(t)\n\t)\n\n\ttemplate< tc::casing c=tc::uppercase, typename T >\n\tconstexpr auto as_padded_hex(T const& t) return_ctor_noexcept(\n\t\tTC_FWD(as_hex_impl<T, (sizeof(T)*CHAR_BIT+3)/4, c>),\n\t\t(t)\n\t)\n\n\t//Do not use in XML, because the standard wants hexBinary to be padded to an even length\n\ttemplate< tc::casing c=tc::uppercase, typename T >\n\tconstexpr auto as_unpadded_hex(T const& t) return_ctor_noexcept(\n\t\tTC_FWD(as_hex_impl<T, 1, c>),\n\t\t(t)\n\t)\n\n\t//////////////////////////////////////////////////\n\t// conversion from string to number\n\n\ttemplate< typename T, typename Rng >\n\tauto unsigned_integer_from_string_head(Rng&& rng) noexcept {\n\t\tauto pairnit=std::make_pair(tc::explicit_cast<T>(0),tc::begin(rng));\n\t\tauto const itEnd=tc::end(rng);\n\t\twhile( pairnit.second!=itEnd ) {\n\t\t\tunsigned int const nDigit=*pairnit.second-tc::explicit_cast<tc::range_value_t<Rng&>>('0');\n\t\t\tif( 9<nDigit || (std::numeric_limits<T>::max()-static_cast<int>(nDigit))/10<pairnit.first ) break; // overflow\n\t\t\tpairnit.first*=10;\nMODIFY_WARNINGS_BEGIN(((disable)(4244))) // conversion from 'const unsigned int' to 'uint16_t', possible loss of data\n\t\t\tpairnit.first+=nDigit;\nMODIFY_WARNINGS_END\n\t\t\t++pairnit.second;\n\t\t}\n\t\treturn pairnit;\n\t}\n\n\ttemplate< typename T, typename Rng >\n\tauto signed_integer_from_string_head(Rng&& rng) noexcept {\n\t\tauto pairnit=std::make_pair(tc::explicit_cast<T>(0),tc::begin(rng));\n\t\tauto const itEnd=tc::end(rng);\n\t\tif( pairnit.second!=itEnd ) {\n\t\t\tif (tc::char_ascii('-') == *pairnit.second) {\n\t\t\t\t++pairnit.second;\n\t\t\t\twhile (pairnit.second != itEnd) {\n\t\t\t\t\tunsigned int const nDigit = *pairnit.second - tc::explicit_cast<tc::range_value_t<Rng&>>('0');\n\t\t\t\t\tif (9 < nDigit || pairnit.first < (std::numeric_limits<T>::lowest() + static_cast<int>(nDigit)) / 10) break; // underflow\n\t\t\t\t\tpairnit.first *= 10;\nMODIFY_WARNINGS_BEGIN(((disable)(4244))) // conversion from 'const unsigned int' to 'uint16_t', possible loss of data\n\t\t\t\t\tpairnit.first -= nDigit;\nMODIFY_WARNINGS_END\n\t\t\t\t\t++pairnit.second;\n\t\t\t\t}\n\t\t\t} else if (tc::char_ascii('+') == *pairnit.second) {\n\t\t\t\tpairnit = unsigned_integer_from_string_head<T>(tc::begin_next<tc::return_drop>(rng));\n\t\t\t} else {\n\t\t\t\tpairnit = unsigned_integer_from_string_head<T>(rng);\n\t\t\t}\n\t\t}\n\t\treturn pairnit;\n\t}\n\n\tstruct integer_parse_exception final {};\n\n\ttemplate< typename T, typename Rng >\n\tT signed_integer_from_string( Rng const& rng ) THROW(tc::integer_parse_exception) {\n\t\tif (tc::empty(rng)) throw tc::integer_parse_exception();\n\t\tauto pairnit=tc::signed_integer_from_string_head<T>(rng);\n\t\tif( pairnit.second!=tc::end(rng) ) throw tc::integer_parse_exception();\n\t\treturn pairnit.first;\n\t}\n\n\ttemplate< typename T, typename Rng >\n\tT unsigned_integer_from_string( Rng const& rng ) THROW(tc::integer_parse_exception) {\n\t\tif (tc::empty(rng)) throw tc::integer_parse_exception();\n\t\tauto pairnit=tc::unsigned_integer_from_string_head<T>(rng);\n\t\tif( pairnit.second!=tc::end(rng) ) throw tc::integer_parse_exception();\n\t\treturn pairnit.first;\n\t}\n}\n"
  },
  {
    "path": "tc/string/jsonparser.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../interval.h\"\n#include \"char.h\"\n#include \"named.h\"\n#include \"spirit_algorithm.h\"\n#include \"parserbase.h\"\n\n#include <boost/predef/architecture.h>\n#if BOOST_ARCH_X86\n# define TC_JSON_SIMD 1\n# include <emmintrin.h>\n#elif BOOST_ARCH_ARM\n# define TC_JSON_SIMD 1\n# ifdef TC_WIN\n#  include <arm64_neon.h> // https://developercommunity.visualstudio.com/t/ARM64EC-should-be-considered-in-arm_neon/1477300\n# else\n#  include <arm_neon.h>\n# endif\n#else\n# define TC_JSON_SIMD 0\n#endif\n\nnamespace tc::json {\n\tnamespace no_adl {\n\t\ttemplate<typename Func>\n\t\tstruct simple_error_handler {\n\t\t\texplicit constexpr simple_error_handler(Func func) noexcept\n\t\t\t\t: m_func(tc_move(func))\n\t\t\t{}\n\n\t\t\ttemplate<typename... Args>\n\t\t\tvoid semantic_error(auto const& strJson, auto const& itch, Args&&...) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid end_unexpected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid end_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid char_expected(auto const& strJson, auto const& itch, tc::char_ascii const ch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid null_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid boolean_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid number_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid object_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid key_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid array_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid element_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid value_expected(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid unescaped_control_character(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid invalid_escape(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid invalid_encoding(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid nesting_too_deep(auto const& strJson, auto const& itch) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid must_contain_one_of_keys(auto const& strJson, auto const& itch, auto const& astrNames) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\t\t\tvoid may_contain_only_one_of_keys(auto const& strJson, auto const& itch, auto const& astrNames) const& MAYTHROW {\n\t\t\t\tm_func(strJson);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tFunc m_func;\n\t\t};\n\n\t\ttemplate<typename Index, typename Char>\n\t\tstruct SDecodeAdaptorIndex final {\n\t\t\tIndex m_baseidx;\n\n\t\t\tfriend bool operator==(SDecodeAdaptorIndex const& lhs, SDecodeAdaptorIndex const& rhs) noexcept = default;\n\t\t};\n\n\t\ttemplate<typename Index>\n\t\tstruct SDecodeAdaptorIndex<Index, char> final {\n\t\t\tIndex m_baseidx;\n\t\t\tint m_nCodeUnitIndex;\n\n\t\t\tfriend bool operator==(SDecodeAdaptorIndex const& lhs, SDecodeAdaptorIndex const& rhs) noexcept = default;\n\t\t};\n\n\t\ttemplate< typename Rng >\n\t\tstruct [[nodiscard]] decode_adaptor\n\t\t\t: tc::range_iterator_from_index<\n\t\t\t\tdecode_adaptor<Rng>,\n\t\t\t\tSDecodeAdaptorIndex<tc::index_t<std::remove_reference_t<Rng>>, tc::range_value_t<Rng>>\n\t\t\t>\n\t\t\t, tc::range_adaptor_base_range<Rng>\n\t\t{\n\t\t\tconstexpr decode_adaptor() = default;\n\t\t\tusing tc::range_adaptor_base_range<Rng>::range_adaptor_base_range;\n\t\t\tusing typename decode_adaptor::range_iterator_from_index::tc_index;\n\n\t\t\tstatic constexpr bool c_bHasStashingIndex=tc::has_stashing_index<std::remove_reference_t<Rng>>::value;\n\t\t\tstatic constexpr bool c_bPrefersForEach = true;\n\n\t\tprivate:\n\t\t\tusing this_type = decode_adaptor;\n\t\t\tusing Char=tc::range_value_t<Rng>;\n\n\t\t\ttemplate<bool bIncrement>\n\t\t\ttc::char16 ParseUTF16CodeUnit(tc::index_t<std::remove_reference_t<Rng>>& baseidx) const& MAYTHROW {\n\t\t\t\t_ASSERT(!tc::at_end_index(this->base_range(), baseidx));\n\t\t\t\tint n;\n\t\t\t\tauto it = tc::make_iterator(this->base_range(), baseidx);\n\t\t\t\tVERIFY(x3::parse(it, tc::end(this->base_range()), x3::uint_parser<int, 16, 4, 4>(), n ));\n\t\t\t\tif constexpr(bIncrement) {\n\t\t\t\t\tbaseidx = tc::iterator2index<Rng>(it);\n\t\t\t\t}\n\t\t\t\treturn static_cast<tc::char16>(n);\n\t\t\t}\n\n\t\t\ttemplate<bool bIncrement, typename SinkChar, typename SinkCodepoint>\n\t\t\tauto ProcessEscaped(tc::index_t<std::remove_reference_t<Rng>>& baseidx, SinkChar sinkch, SinkCodepoint sinkcp) const& MAYTHROW {\n\t\t\t\t // read_string should have ensured well-formed escaping, so we can _ASSERT for it.\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\ttc::increment_index(base, baseidx);\n\t\t\t\t_ASSERT(!tc::at_end_index(base, baseidx));\n\t\t\t\tauto const ch=tc::dereference_index(base, baseidx);\n\t\t\t\tswitch_no_default(ch) {\n\t\t\t\tcase tc::explicit_cast<Char>('\"'):\n\t\t\t\tcase tc::explicit_cast<Char>('\\\\'):\n\t\t\t\tcase tc::explicit_cast<Char>('/'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(ch);\n\t\t\t\tcase tc::explicit_cast<Char>('b'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(tc::explicit_cast<Char>('\\b'));\n\t\t\t\tcase tc::explicit_cast<Char>('f'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(tc::explicit_cast<Char>('\\f'));\n\t\t\t\tcase tc::explicit_cast<Char>('n'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(tc::explicit_cast<Char>('\\n'));\n\t\t\t\tcase tc::explicit_cast<Char>('r'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(tc::explicit_cast<Char>('\\r'));\n\t\t\t\tcase tc::explicit_cast<Char>('t'):\n\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, baseidx);\n\t\t\t\t\treturn sinkch(tc::explicit_cast<Char>('\\t'));\n\t\t\t\tcase tc::explicit_cast<Char>('u'):\n\t\t\t\t\ttc::increment_index(base, baseidx);\n\t\t\t\t\t{\n\t\t\t\t\t\tif constexpr(std::same_as<Char, tc::char16>) {\n\t\t\t\t\t\t\treturn sinkch(ParseUTF16CodeUnit<bIncrement>(baseidx));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tchar32_t ch32 = U'\\uFFFD'; // REPLACEMENT CHARACTER\n\t\t\t\t\t\t\ttc::char16 const ch0 = ParseUTF16CodeUnit<true>(baseidx);\n\t\t\t\t\t\t\tif(tc::is_leading_codeunit(ch0)) {\n\t\t\t\t\t\t\t\tif(!tc::at_end_index(base, baseidx) && tc::char_ascii('\\\\') == tc::dereference_index(base, baseidx)) {\n\t\t\t\t\t\t\t\t\tstd::conditional_t<bIncrement, tc::decay_t<decltype(baseidx)>, decltype(baseidx)> baseidxPeek = baseidx;\n\t\t\t\t\t\t\t\t\ttc::increment_index(base, baseidxPeek);\n\t\t\t\t\t\t\t\t\t_ASSERT(!tc::at_end_index(base, baseidxPeek));\n\t\t\t\t\t\t\t\t\tif('u'_tc == tc::dereference_index(base, baseidxPeek)) {\n\t\t\t\t\t\t\t\t\t\ttc::increment_index(base, baseidxPeek);\n\t\t\t\t\t\t\t\t\t\ttc::char16 const ch1 = ParseUTF16CodeUnit<bIncrement>(baseidxPeek);\n\t\t\t\t\t\t\t\t\t\tif(tc::is_trailing_codeunit(ch1)) {\n\t\t\t\t\t\t\t\t\t\t\tif constexpr(bIncrement) baseidx = tc_move(baseidxPeek); // only consume subsequent UTF-16 escape sequence, if a valid UTF-16 code unit sequence is formed.\n\t\t\t\t\t\t\t\t\t\t\tch32 = tc::surrogate_pair_value(ch0, ch1);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if(!tc::is_trailing_codeunit(ch0)) {\n\t\t\t\t\t\t\t\ttc::assign_explicit_cast(ch32, ch0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif constexpr(std::same_as<Char, char32_t>) {\n\t\t\t\t\t\t\t\treturn sinkch(ch32);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn sinkcp(ch32);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tSTATIC_FINAL(begin_index)() const& return_MAYTHROW(\n\t\t\t\ttc_index{this->base_begin_index()} // m_nCodeUnitIndex zero-initialized, if present\n\t\t\t)\n\n\t\t\tSTATIC_FINAL(end_index)() const& MAYTHROW requires tc::has_end_index<Rng> {\n\t\t\t\treturn tc_index{this->base_end_index()}; // m_nCodeUnitIndex zero-initialized, if present\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(at_end_index)(tc_index const& idx) const& return_MAYTHROW(\n\t\t\t\ttc::at_end_index(this->base_range(), idx.m_baseidx)\n\t\t\t)\n\n\t\t\tSTATIC_FINAL(dereference_index)(tc_index const& idx) const& MAYTHROW {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tauto t=tc::dereference_index(base, idx.m_baseidx); // we return characters, which we can always return by value\n\t\t\t\tif(tc::char_ascii('\\\\')==t) {\n\t\t\t\t\treturn ProcessEscaped<false>(\n\t\t\t\t\t\ttc::as_lvalue(tc::decay_copy(idx.m_baseidx)),\n\t\t\t\t\t\t/*sinkch*/tc::identity(),\n\t\t\t\t\t\t/*sinkcp*/[&](auto const ch32) noexcept {\n\t\t\t\t\t\t\tSTATICASSERTSAME(decltype(ch32), char32_t const);\n\t\t\t\t\t\t\treturn tc::codepoint_codeunit_at<Char>(static_cast<unsigned int>(ch32), idx.m_nCodeUnitIndex);\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn t;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& MAYTHROW -> void {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tif(tc::char_ascii('\\\\')==tc::dereference_index(base, idx.m_baseidx)) {\n\t\t\t\t\tauto baseidxOriginal = idx.m_baseidx;\n\t\t\t\t\tProcessEscaped<true>(\n\t\t\t\t\t\tidx.m_baseidx,\n\t\t\t\t\t\t/*sinkch*/tc::noop(),\n\t\t\t\t\t\t/*sinkcp*/[&](auto const ch32) noexcept {\n\t\t\t\t\t\t\tif constexpr(std::same_as<Char, char>) {\n\t\t\t\t\t\t\t\tif(++idx.m_nCodeUnitIndex == tc::codepoint_codeunit_count<char>(static_cast<unsigned int>(ch32))) {\n\t\t\t\t\t\t\t\t\tidx.m_nCodeUnitIndex = 0;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tidx.m_baseidx = tc_move(baseidxOriginal);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttc::increment_index(base, idx.m_baseidx);\n\t\t\t\t\t_ASSERTDEBUGEQUAL(idx.m_nCodeUnitIndex, 0);\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\tstatic constexpr auto border_base_index(tc_index const& idx) noexcept {\n\t\t\t\tif constexpr( std::same_as<Char, char> ) {\n\t\t\t\t\t_ASSERTEQUAL(idx.m_nCodeUnitIndex, 0);\n\t\t\t\t}\n\t\t\t\treturn idx.m_baseidx;\n\t\t\t}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink const sink) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\tdecltype(tc::continue_if_not_break(sink, std::declval<Char const&>())),\n\t\t\t\ttc::constant<tc::continue_>\n\t\t\t> {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tauto idx=this->base_begin_index();\n\t\t\t\tfor(;;) {\n\t\t\t\t\tif(tc::at_end_index(base, idx)) return tc::constant<tc::continue_>();\n\t\t\t\t\tif(tc::char_ascii('\\\\')!=tc::dereference_index(base, idx)) {\n\t\t\t\t\t\tauto idxBegin=idx;\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\t\tif(tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\t\treturn tc::for_each(tc::slice(base, idxBegin, idx), sink);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while(tc::char_ascii('\\\\')!=tc::dereference_index(base, idx));\n\t\t\t\t\t\ttc_return_if_break( tc::for_each(tc::slice(base, idxBegin, idx), sink) );\n\t\t\t\t\t}\n\t\t\t\t\ttc_return_if_break( ProcessEscaped<true>(\n\t\t\t\t\t\tidx,\n\t\t\t\t\t\t[&](auto const ch) MAYTHROW {\n\t\t\t\t\t\t\treturn tc::continue_if_not_break(sink, ch);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[&](auto const ch32) MAYTHROW {\n\t\t\t\t\t\t\treturn tc::for_each(tc::convert_enc<Char>(tc::single(tc::decay_copy(ch32))), sink);\n\t\t\t\t\t\t}\n\t\t\t\t\t) );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n}\n\nnamespace tc {\n\ttemplate<typename Rng>\n\tconstexpr auto enable_stable_index_on_move<tc::json::no_adl::decode_adaptor<Rng>> = tc::stable_index_on_move<Rng>;\n}\n\nnamespace tc::json {\n\ttemplate<typename Rng>\n\tconstexpr auto decode(Rng&& rng)\n\t\treturn_ctor_noexcept( no_adl::decode_adaptor<Rng>, (aggregate_tag, tc_move_if_owned(rng)) )\n\n\tusing no_adl::simple_error_handler;\n\n\t// The inline here is necessary to ensure that the type of the lambda is the same in all compilation units.\n\ttemplate <typename T>\n\tinline auto constexpr assert_and_throw = tc::json::simple_error_handler([](tc::unused) THROW(T) {\n\t\t_ASSERTNOTIFYFALSE; throw T();\n\t});\n\tinline auto constexpr assert_no_error = tc::json::simple_error_handler([](tc::unused) noexcept {\n\t\t_ASSERTNORETURNFALSE;\n\t});\n\n\tnamespace no_adl {\n\t\ttemplate<bool c_bRequired, typename... Keys>\n\t\tstruct group final {\n\t\tprivate:\n\t\t\ttc::tuple<Keys...> m_tplkey;\n\n\t\t\ttemplate <typename Fn, typename Parser>\n\t\t\tstatic decltype(auto) invoke_with_parser(Fn const& fn, Parser& parser) {\n\t\t\t\tif constexpr (tc::invocable<Fn const&, Parser&>) {\n\t\t\t\t\tRETURNS_VOID(tc_invoke(fn, parser));\n\t\t\t\t} else {\n\t\t\t\t\treturn fn();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tusing ResultT = tc::common_type_t<boost::mp11::mp_eval_or<void, tc::invoke_result_t, decltype(std::declval<Keys>().m_t)>...>;\n\t\t\tusing OptionalResultT = std::conditional_t<std::is_void<ResultT>::value, bool, std::optional<ResultT>>;\n\t\t\tOptionalResultT m_oresult = {}; // value initialize: bool to false, optional to nullopt\n\n\t\tpublic:\n\t\t\tstatic constexpr auto c_bHasResult = !std::is_void<ResultT>::value;\n\t\t\tstatic constexpr tc::span<tc::char_ascii const> c_astrKeys[]= { Keys::c_strName... };\n\n\t\t\texplicit group(Keys... keys) noexcept : m_tplkey{keys...} {}\n\n\t\t\tbool parse(auto& parser, auto const& strParsedName) & MAYTHROW {\n\t\t\t\treturn tc::any_of(m_tplkey, [&](auto const& key) MAYTHROW {\n\t\t\t\t\tif (!tc::equal(strParsedName, key.c_strName)) return false;\n\n\t\t\t\t\tif (m_oresult) {\n\t\t\t\t\t\tparser.template may_contain_only_one_of_keys<c_astrKeys>(); // MAYTHROW\n\t\t\t\t\t} else if constexpr (c_bHasResult) {\n\t\t\t\t\t\ttc::optional_emplace(m_oresult, invoke_with_parser(key.m_t, parser));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinvoke_with_parser(key.m_t, parser);\n\t\t\t\t\t\tm_oresult = true;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tvoid finalize(auto& parser) const& MAYTHROW {\n\t\t\t\tif constexpr (c_bRequired) {\n\t\t\t\t\tif (!m_oresult) {\n\t\t\t\t\t\tparser.template must_contain_one_of_keys<c_astrKeys>(); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto result() && noexcept(std::is_nothrow_move_constructible<ResultT>::value) {\n\t\t\t\tif constexpr (c_bRequired) {\n\t\t\t\t\tif constexpr (c_bHasResult) {\n\t\t\t\t\t\treturn *tc_move(m_oresult); // result is ResultT\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn; // result is void\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn tc_move(m_oresult); // result is std::optional<ResultT> / bool\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\ttemplate<typename... Keys>\n\tconstexpr auto required(Keys... keys) noexcept {\n\t\treturn no_adl::group<true,Keys...>(tc_move(keys)...);\n\t}\n\ttemplate<typename... Keys>\n\tconstexpr auto optional(Keys... keys) noexcept {\n\t\treturn no_adl::group<false,Keys...>(tc_move(keys)...);\n\t}\n\n\tnamespace no_adl {\n\n\t\tstruct skip_exception {};\n\n\t\ttemplate<typename String, typename ErrorHandler>\n\t\tstruct [[nodiscard]] parser : parser_base<String, ErrorHandler> {\n\t\t\tusing typename parser_base<String, ErrorHandler>::char_type;\n\n\t\t\texplicit parser(String&& strInput, ErrorHandler errorhandler) MAYTHROW\n\t\t\t\t: parser_base<String, ErrorHandler>(tc_move_if_owned(strInput), tc_move(errorhandler))\n\t\t\t{\n\t\t\t\tthis->skip_whitespace(); // guarantees !end()\n\t\t\t}\n\n\t\t\t//-------------------------------------------------------------------------------------------------------------------------\n\t\t\t// Primitive values\n\t\t\tbool null() & MAYTHROW {\n\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\tcase 'n':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tthis->expect_literal(\"ull\"_tc);\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t\treturn true;\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid expect_null() & MAYTHROW {\n\t\t\t\tif (!null()) {\n\t\t\t\t\tthis->template error<tc_mem_fn(.null_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstd::optional<bool> boolean() & MAYTHROW {\n\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\tcase 't':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tthis->expect_literal(\"rue\"_tc);\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase 'f':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tthis->expect_literal(\"alse\"_tc);\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t\treturn false;\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbool expect_boolean() & MAYTHROW {\n\t\t\t\tif (auto ob = boolean()) {\n\t\t\t\t\treturn *ob;\n\t\t\t\t} else {\n\t\t\t\t\tthis->template error<tc_mem_fn(.boolean_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<typename T>\n\t\t\tstd::optional<T> number() & MAYTHROW {\n\t\t\t\tstatic_assert(tc::common_range<String>, \"Spirit requires common ranges\"); // TODO?\n\t\t\t\tif ( auto const ch = this->unchecked_peek(); '-'_tc != ch && !tc::make_interval('0'_tc, '9'_tc).contains_inclusive(ch) ) {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\n\t\t\t\t// TODO: the x3 parsers don't follow the exact same grammar as JSON numbers\n\t\t\t\tstd::optional<T> ot(std::in_place);\n\t\t\t\tif constexpr( std::floating_point<T> ) {\n\t\t\t\t\tauto it = this->position();\n\t\t\t\t\tif (!tc::parse_iterator(it, this->end_position(), x3::real_parser<T>(), *ot)) {\n\t\t\t\t\t\tot=std::nullopt;\n\t\t\t\t\t}\n\t\t\t\t\tthis->set_position(it);\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert( tc::actual_integer<T> );\n\t\t\t\t\tauto it = this->position();\n\t\t\t\t\tif (!tc::parse_iterator(it, this->end_position(), x3::int_parser<T>(), *ot)) {\n\t\t\t\t\t\tot=std::nullopt;\n\t\t\t\t\t}\n\t\t\t\t\tthis->set_position(it);\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t}\n\t\t\t\treturn ot;\n\t\t\t}\n\t\t\ttemplate<typename T>\n\t\t\tT expect_number() & MAYTHROW {\n\t\t\t\tif (auto ot = number<T>()) {\n\t\t\t\t\treturn *tc_move(ot);\n\t\t\t\t} else {\n\t\t\t\t\tthis->template error<tc_mem_fn(.number_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\t\t\ttemplate<typename T>\n\t\t\tvoid assign_expect_number(T& t) & MAYTHROW {\n\t\t\t\tt = expect_number<T>();\n\t\t\t}\n\n\t\t\tauto number() & MAYTHROW {\n\t\t\t\tusing Result = std::optional<decltype(tc::slice(this->input(), this->position(), this->position()))>;\n\n\t\t\t\ttc_static_auto_constexpr(digits, \"0123456789\"_tc);\n\t\t\t\tauto const skip_one_or_more_digits = [&]() MAYTHROW {\n\t\t\t\t\tif (!this->one_of(digits)) {\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.number_expected)>(); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t\twhile (this->one_of(digits)) {}\n\t\t\t\t};\n\n\t\t\t\tauto const itchBegin = this->position();\n\t\t\t\tauto bCommitted = false;\n\n\t\t\t\t// Sign and integer.\n\t\t\t\tinteger: switch(this->unchecked_peek()) {\n\t\t\t\tcase '0':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tif (this->end()) goto end;\n\t\t\t\t\t\tswitch (auto const ch = this->unchecked_peek()) {\n\t\t\t\t\t\tcase '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '.':\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tgoto fraction;\n\t\t\t\t\t\tcase 'e': case 'E':\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tgoto exponent;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tgoto end;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t_ASSERTFALSE;\n\n\t\t\t\tcase '-':\n\t\t\t\t\tif (tc::change(bCommitted, true)) {\n\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\tthis->expect_not_end();\n\t\t\t\t\t\tgoto integer;\n\t\t\t\t\t}\n\t\t\t\t\t// fallthrough\n\t\t\t\tdefault:\n\t\t\t\t\tif (bCommitted) {\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.number_expected)>(); // MAYTHROW\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn Result();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fraction and exponent.\n\t\t\t\tif (!this->end()) {\n\t\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\t\tcase '.':\n\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tfraction:\n\t\t\t\t\t\tskip_one_or_more_digits();\n\t\t\t\t\t\tif (this->one_of(\"eE\"_tc)) {\n\t\t\t\t\t\t\tgoto exponent;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'e': case 'E':\n\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\texponent:\n\t\t\t\t\t\ttc::discard(this->one_of(\"+-\"_tc));\n\t\t\t\t\t\tskip_one_or_more_digits();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tend:\n\t\t\t\tauto const itchEnd = this->position();\n\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\treturn Result(tc::slice(this->input(), itchBegin, itchEnd));\n\t\t\t}\n\t\t\tauto expect_number() & MAYTHROW {\n\t\t\t\tif (auto on = number()) {\n\t\t\t\t\treturn *on;\n\t\t\t\t} else {\n\t\t\t\t\tthis->template error<tc_mem_fn(.number_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto string() & MAYTHROW {\n\t\t\t\tusing Result = std::optional<decltype(read_string())>;\n\t\t\t\tswitch(this->unchecked_peek()) {\n\t\t\t\tcase '\"': {\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tauto result = read_string(); // MAYTHROW\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t\treturn Result(result);\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn Result();\n\t\t\t\t}\n\t\t\t}\n\t\t\tauto expect_string() & MAYTHROW {\n\t\t\t\tthis->expect_literal(\"\\\"\"_tc);\n\t\t\t\tauto str = read_string();\n\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\treturn str;\n\t\t\t}\n\t\t\tauto expect_string_or_null() & MAYTHROW {\n\t\t\t\tif (null()) {\n\t\t\t\t\treturn decode(tc::slice(this->input(), this->position(), this->position()));\n\t\t\t\t} else {\n\t\t\t\t\treturn expect_string();\n\t\t\t\t}\n\t\t\t}\n\t\t\tauto expect_non_empty_string() & MAYTHROW {\n\t\t\t\tauto str = expect_string();\n\t\t\t\tif (tc::empty(str)) this->semantic_error();\n\t\t\t\treturn str;\n\t\t\t}\n\n\t\t\t//-------------------------------------------------------------------------------------------------------------------------\n\t\t\t// Array\n\t\t\tbool array()& MAYTHROW {\n\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\tcase '[':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tVERIFY(tc::change(this->m_bAtArrayOrObjectStart, true));\n\t\t\t\t\tthis->skip_whitespace(); // MAYTHROW\n\t\t\t\t\treturn true;\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid expect_array() & MAYTHROW {\n\t\t\t\tif (!array()) {\n\t\t\t\t\tthis->template error<tc_mem_fn(.array_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool element() & MAYTHROW {\n\t\t\t\t// After some value (null/boolean/number/string/array/object) ends, we allow EOI by calling skip_whitespace_maybe_end()\n\t\t\t\t// because it may be the root value. If it is not, another element() or key() must follow, so there, we must check for EOI.\n\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\n\t\t\t\tauto const ch = this->unchecked_peek();\n\t\t\t\tif (']' == ch) {\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tthis->m_bAtArrayOrObjectStart = false;\n\t\t\t\t\tthis->skip_whitespace_maybe_end(); // MAYTHROW\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tif (!tc::change(this->m_bAtArrayOrObjectStart, false)) {\n\t\t\t\t\t\tif (',' == ch) {\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tthis->skip_whitespace();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.char_expected)>(tc::char_ascii(',')); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid expect_element() & MAYTHROW {\n\t\t\t\tif(!element()) {\n\t\t\t\t\tthis->template error<tc_mem_fn(.element_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate <typename Func> requires tc::invocable<Func&, std::size_t>\n\t\t\tauto elements(Func func) & MAYTHROW {\n\t\t\t\tusing result_t = decltype(func(std::size_t(0)));\n\t\t\t\treturn tc::generator_range_output<result_t&&>([this, func=tc_move(func)](auto sink) MAYTHROW {\n\t\t\t\t\tauto const invoke_sink = [&](std::size_t const idx) MAYTHROW {\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn tc::continue_if_not_break(sink, func(idx));\n\t\t\t\t\t\t} catch (skip_exception const&) {\n\t\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\t\tthrow;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif constexpr (std::is_same<decltype(invoke_sink(0)), tc::constant<tc::break_>>::value) {\n\t\t\t\t\t\tif (element()) {\n\t\t\t\t\t\t\ttc::discard(invoke_sink(0));\n\t\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if constexpr (std::is_same<decltype(invoke_sink(0)), tc::constant<tc::continue_>>::value) {\n\t\t\t\t\t\tfor (std::size_t idx = 0; element(); ++idx) {\n\t\t\t\t\t\t\ttc::discard(invoke_sink(idx));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn tc::constant<tc::continue_>{};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (std::size_t idx = 0; element(); ++idx) {\n\t\t\t\t\t\t\tif (tc::break_ == invoke_sink(idx)) {\n\t\t\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\t\t\treturn tc::break_;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn tc::continue_;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\ttemplate<typename Func> requires tc::invocable<Func&> && (!tc::invocable<Func&, std::size_t>)\n\t\t\tauto elements(Func func) & MAYTHROW {\n\t\t\t\treturn elements([func = tc_move(func)](std::size_t) return_decltype_allow_xvalue_MAYTHROW(func()));\n\t\t\t}\n\t\t\ttemplate<typename Func> requires tc::invocable<Func&> || tc::invocable<Func&, std::size_t>\n\t\t\tauto expect_array(Func func) & MAYTHROW {\n\t\t\t\texpect_array();\n\t\t\t\treturn elements(tc_move(func));\n\t\t\t}\n\n\t\t\tvoid expect_array_end() & MAYTHROW {\n\t\t\t\tthis->expect_literal(\"]\"_tc);\n\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t}\n\n\t\t\ttemplate <typename Sink> requires tc::invocable<Sink const&, std::size_t>\n\t\t\tauto for_each_element(Sink const sink) & MAYTHROW \n\t\t\t\t-> tc::common_type_t<decltype(tc::continue_if_not_break(std::declval<Sink const&>(), std::size_t(0))), tc::constant<tc::continue_>> {\n\t\t\t\tfor (std::size_t idx = 0; element(); ++idx) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tauto const boc = tc::continue_if_not_break(sink, idx);\n\t\t\t\t\t\tif constexpr (!std::same_as<std::remove_const_t<decltype(boc)>, tc::constant<tc::continue_>>) {\n\t\t\t\t\t\t\tif (tc::break_ == boc) {\n\t\t\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\t\t\treturn tc::constant<tc::break_>();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (skip_exception const&) {\n\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t\ttemplate <typename Sink> requires tc::invocable<tc::decay_t<Sink> const&> && (!tc::invocable<tc::decay_t<Sink> const&, std::size_t>)\n\t\t\tauto for_each_element(Sink&& sink) & MAYTHROW {\n\t\t\t\treturn for_each_element([sink = tc_move_if_owned(sink)](std::size_t) return_decltype_MAYTHROW(sink()));\n\t\t\t}\n\n\t\t\ttemplate<typename Func>\n\t\t\tauto expect_single_element_or_empty_array(Func func) & MAYTHROW {\n\t\t\t\texpect_array();\n\t\t\t\tusing T = decltype(func());\n\t\t\t\tusing OptT = std::conditional_t<std::is_void<T>::value, bool, std::optional<T>>;\n\t\t\t\tOptT ot{}; // if bool, value-initialize to false, otherwise to std::nullopt\n\t\t\t\tif (element()) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif constexpr (std::is_void<T>::value) {\n\t\t\t\t\t\t\tfunc();\n\t\t\t\t\t\t\tot = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttc::optional_emplace(ot, func());\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (skip_exception const&) {\n\t\t\t\t\t\twhile (element()) skip_value();\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\texpect_array_end();\n\t\t\t\t}\n\t\t\t\treturn ot;\n\t\t\t}\n\t\t\ttemplate<typename Func>\n\t\t\tauto expect_single_element(Func func) & MAYTHROW {\n\t\t\t\texpect_array();\n\t\t\t\texpect_element();\n\t\t\t\ttry {\n\t\t\t\t\tif constexpr (std::is_void<decltype(func())>::value) {\n\t\t\t\t\t\tfunc(); // MAYTHROW\n\t\t\t\t\t\texpect_array_end();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tauto t = func(); // MAYTHROW\n\t\t\t\t\t\texpect_array_end();\n\t\t\t\t\t\treturn t;\n\t\t\t\t\t}\n\t\t\t\t} catch (skip_exception const&) {\n\t\t\t\t\twhile(element()) skip_value();\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//-------------------------------------------------------------------------------------------------------------------------\n\t\t\t// Object\n\t\t\tbool object() & MAYTHROW {\n\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\tcase '{':\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tVERIFY(tc::change(this->m_bAtArrayOrObjectStart, true));\n\t\t\t\t\tthis->skip_whitespace(); // MAYTHROW\n\t\t\t\t\treturn true;\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid expect_object() & MAYTHROW {\n\t\t\t\tif (!object()) {\n\t\t\t\t\tthis->template error<tc_mem_fn(.object_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tauto key() & MAYTHROW {\n\t\t\t\t// After some value (object/array/number/boolean/...) ends, we allow EOI by calling skip_whitespace_maybe_end()\n\t\t\t\t// because it may be the root value. If it is not, another element() or key() must follow, so there, we must check for EOI.\n\t\t\t\tthis->expect_not_end();\n\n\t\t\t\tusing Result = std::optional<decltype(read_string())>;\n\t\t\t\tauto const ch = this->unchecked_peek();\n\t\t\t\tif ('}' == ch) {\n\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\tthis->m_bAtArrayOrObjectStart = false;\n\t\t\t\t\tthis->skip_whitespace_maybe_end();\n\t\t\t\t\treturn Result{};\n\t\t\t\t} else {\n\t\t\t\t\tif (!tc::change(this->m_bAtArrayOrObjectStart, false)) {\n\t\t\t\t\t\tif (',' == ch) {\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tthis->skip_whitespace();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.char_expected)>(tc::char_ascii(',')); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!this->literal(\"\\\"\"_tc)) {\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.key_expected)>(); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t\tauto strKey = read_string();\n\n\t\t\t\t\tthis->skip_whitespace();\n\t\t\t\t\tthis->expect_literal(\":\"_tc);\n\t\t\t\t\tthis->skip_whitespace();\n\n\t\t\t\t\treturn tc::explicit_cast<Result>(tc_move(strKey));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate <typename... Groups> requires( 0<sizeof...(Groups) )\n\t\t\tvoid members(Groups&&... group) & MAYTHROW {\n\t\t\t\tstatic_assert(((std::is_lvalue_reference<Groups>::value || !std::remove_reference_t<Groups>::c_bHasResult) && ...),\n\t\t\t\t\t\"at least one member returns a value that we're discarding\");\n\n\t\t\t\twhile (tc_auto_cref(ostr, key())) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!(group.parse(*this, *ostr) || ...)) {\n\t\t\t\t\t\t\tskip_value();\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (skip_exception const&) {\n\t\t\t\t\t\twhile(key()) skip_value();\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t(group.finalize(*this), ...);\n\t\t\t}\n\t\t\ttemplate <typename... Groups> requires( 0<sizeof...(Groups) )\n\t\t\tvoid expect_object(Groups&&... group) & MAYTHROW {\n\t\t\t\texpect_object();\n\t\t\t\tmembers(tc_move_if_owned(group)...);\n\t\t\t}\n\n\t\t\ttemplate <typename Group> requires std::is_rvalue_reference<Group&&>::value\n\t\t\t[[nodiscard]] auto expect_single_member_object(Group&& group) & MAYTHROW {\n\t\t\t\texpect_object(group);\n\t\t\t\treturn tc_move(group).result();\n\t\t\t}\n\n\t\t\ttemplate<auto const& c_astrNames>\n\t\t\t[[noreturn]] void must_contain_one_of_keys() & MAYTHROW {\n\t\t\t\tthis->template error<[](auto& error, auto const& rng, auto const& it) MAYTHROW {\n\t\t\t\t\terror.must_contain_one_of_keys(rng, it, c_astrNames);\n\t\t\t\t}>(); // MAYTHROW\n\t\t\t}\n\t\t\ttemplate<auto const& c_astrNames>\n\t\t\t[[noreturn]] void may_contain_only_one_of_keys() & MAYTHROW {\n\t\t\t\tthis->template error<[](auto& error, auto const& rng, auto const& it) MAYTHROW {\n\t\t\t\t\terror.may_contain_only_one_of_keys(rng, it, c_astrNames);\n\t\t\t\t}>(); // MAYTHROW\n\t\t\t}\n\n\t\t\t//-------------------------------------------------------------------------------------------------------------------------\n\t\t\t// Any value.\n\t\t\tvoid skip_value() & MAYTHROW {\n\t\t\t\tstd::bitset<256> bitsetIsArray; // (unnecessarily) zero-initialized.\n\t\t\t\tstd::size_t nNestingLevel = 0;\n\t\t\t\tfor(;;) {\n\t\t\t\t\t// Optimization: we do one switch here to dispatch to the appropriate member function, instead of individual branches in each member function.\n\t\t\t\t\t// After inlining of trivial functions like null or boolean, this is faster.\n\t\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\t\tcase 'n':\n\t\t\t\t\t\tVERIFY(null()); // MAYTHROW\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 't':\n\t\t\t\t\tcase 'f':\n\t\t\t\t\t\tVERIFY(boolean()); // MAYTHROW\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '-':\n\t\t\t\t\tcase '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':\n\t\t\t\t\t\tVERIFY(number()); // MAYTHROW\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tVERIFY(string()); // MAYTHROW\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase '[':\n\t\t\t\t\t\tif (bitsetIsArray.size() <= nNestingLevel) {\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.nesting_too_deep)>(); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t\tVERIFY(array()); // MAYTHROW\n\t\t\t\t\t\tbitsetIsArray.set(nNestingLevel++);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '{':\n\t\t\t\t\t\tif (bitsetIsArray.size() <= nNestingLevel) {\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.nesting_too_deep)>(); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t\tVERIFY(object()); // MAYTHROW\n\t\t\t\t\t\tbitsetIsArray.reset(nNestingLevel++);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.value_expected)>(); // MAYTHROW\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\tif(0==nNestingLevel) return;\n\t\t\t\t\t\tif(bitsetIsArray.test(nNestingLevel - 1) ? element() : tc::explicit_cast<bool>(key())) break;\n\t\t\t\t\t\t--nNestingLevel;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tusing parser_base<String, ErrorHandler>::expect_end;\n\n\t\tprivate:\n\t\t\t// Precondition: We have just consumed the opening '\"'.\n\t\t\tauto read_string() & MAYTHROW {\n\t\t\t\tauto itchBegin = this->position();\n\n\t\t\t\t#if TC_JSON_SIMD\n\t\t\t\tif constexpr (sizeof(char_type) == 1 && tc::contiguous_range<String> && tc::common_range<String>) {\n\t\t\t\t\t// Quickly fast forward to first occurrence of byte values 0-0x1F (control characters), 0x22 (\"), 0x5C (\\) or 0x80-0xFF (non-ascii).\n\t\t\t\t\tauto it = this->position();\n\t\t\t\t\tauto const end = this->end_position();\n\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\tif (16 <= end - it) {\n\t\t\t\t\t\t#if BOOST_ARCH_X86\n\t\t\t\t\t\t\tauto const m128Chunk = _mm_loadu_si128(reinterpret_cast<__m128i const*>(std::to_address(it)));\n\t\t\t\t\t\t\tauto const nSpecialCaseMask = static_cast<std::uint16_t>(_mm_movemask_epi8( // get 16 most significant bits as bitmask\n\t\t\t\t\t\t\t\t_mm_or_si128(\n\t\t\t\t\t\t\t\t\t_mm_or_si128(\n\t\t\t\t\t\t\t\t\t\t_mm_cmpeq_epi8(m128Chunk, _mm_set1_epi8('\"')), // sets lane to 0xFF, if quote\n\t\t\t\t\t\t\t\t\t\t_mm_cmpeq_epi8(m128Chunk, _mm_set1_epi8('\\\\')) // sets lane to 0xFF, if backslash\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t_mm_cmplt_epi8(m128Chunk, _mm_set1_epi8(0x20)) // sets lane to 0xFF, if control character or non-ascii\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t));\n\t\t\t\t\t\t#else\n\t\t\t\t\t\t\tauto const s8x16Chunk = vld1q_s8(reinterpret_cast<std::int8_t const*>(std::to_address(it)));\n\t\t\t\t\t\t\t// https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon\n\t\t\t\t\t\t\tauto const nSpecialCaseMask = vget_lane_u64(\n\t\t\t\t\t\t\t\tvreinterpret_u64_u8( // treat 8 bytes as 64 bit word\n\t\t\t\t\t\t\t\t\tvshrn_n_u16( // shift 16bit word right by 4, s.t., the low byte in each word contain a nibble of the original low byte and the original high byte, and return the 8 resulting low bytes\n\t\t\t\t\t\t\t\t\t\tvreinterpretq_u16_u8(vorrq_u8(\n\t\t\t\t\t\t\t\t\t\t\tvorrq_u8(\n\t\t\t\t\t\t\t\t\t\t\t\tvceqq_s8(s8x16Chunk, vdupq_n_s8('\"')), // sets lane to 0xFF, if quote\n\t\t\t\t\t\t\t\t\t\t\t\tvceqq_s8(s8x16Chunk, vdupq_n_s8('\\\\')) // sets lane to 0xFF, if backslash\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tvcltq_s8(s8x16Chunk, vdupq_n_s8(0x20)) // sets lane to 0xFF, if control character or non-ascii\n\t\t\t\t\t\t\t\t\t\t)),\n\t\t\t\t\t\t\t\t\t\t4\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t0\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t#endif\n\t\t\t\t\t\t\tif(0 != nSpecialCaseMask) {\n\t\t\t\t\t\t\t\tit += tc::index_of_least_significant_bit(nSpecialCaseMask) / (BOOST_ARCH_ARM ? 4 : 1);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tit += 16;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else /*not near EOI most of the time*/[[unlikely]] {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis->set_position(it);\n\t\t\t\t}\n\t\t\t\t#endif\n\n\t\t\t\tfor (;;) {\n\t\t\t\t\tthis->expect_not_end();\n\t\t\t\t\tswitch (auto const ch = this->unchecked_peek()) {\n\t\t\t\t\tcase '\"': {\n\t\t\t\t\t\tauto itchEnd = this->position();\n\t\t\t\t\t\tthis->unchecked_increment();\n\n\t\t\t\t\t\treturn decode(tc::slice(this->input(), itchBegin, itchEnd));\n\t\t\t\t\t}\n\n\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\tthis->expect_not_end();\n\t\t\t\t\t\tswitch (this->unchecked_peek()) {\n\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tcase '/':\n\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\tcase 'f':\n\t\t\t\t\t\tcase 'n':\n\t\t\t\t\t\tcase 'r':\n\t\t\t\t\t\tcase 't':\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'u':\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tfor (auto i = 0; i < 4; ++i) {\n\t\t\t\t\t\t\t\tif (!this->char_class(tc_fn(tc::isasciixdigit))) {\n\t\t\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.invalid_escape)>(); // MAYTHROW\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.invalid_escape)>(); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (tc::make_interval(0x00, 0x1F).contains_inclusive(ch)) {\n\t\t\t\t\t\t\t// The control characters (U+0000 through U+001F) must be escaped (RFC 8259). U+007F is fine.\n\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.unescaped_control_character)>(); // MAYTHROW\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis->unchecked_increment();\n\t\t\t\t\t\t\tif constexpr (sizeof(char_type) == 1) {\n\t\t\t\t\t\t\t\tthis->skip_utf8_code_point(ch);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool m_bAtArrayOrObjectStart = false;\n\t\t};\n\n\t\ttemplate<typename String, typename ErrorHandler>\n\t\tparser(String&&, ErrorHandler) -> parser<String, ErrorHandler>;\n\t}\n\tusing no_adl::parser;\n\tusing no_adl::skip_exception;\n\n\t// Json uses only UTF-8 encoding: https://tools.ietf.org/html/rfc8259#section-8.1\n\t// ' JSON text exchanged between systems that are not part of a closed ecosystem MUST be encoded using UTF-8 [RFC3629].'\n\ttemplate<typename Rng>\n\tdecltype(auto) remove_bom(Rng&& rngbyte) {\n\t\treturn tc::starts_with<tc::return_drop_or_all>(tc_move_if_owned(rngbyte), tc_as_constexpr(tc::make_array<unsigned char>(tc::aggregate_tag, 0xef, 0xbb, 0xbf)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/jsonparser.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n#include \"jsonparser.h\"\n#include \"../range/join_adaptor.h\"\n#include \"../range/repeat_n.h\"\n\n#pragma push_macro(\"AS_ARRAY\")\n#define AS_ARRAY(str) tc::end_prev<tc::return_take>(tc::as_array(str))\n\nnamespace {\n\tbool Accepts(auto const& str) noexcept {\n\t\tstruct ExFailure final {};\n\t\tbool bAccepted = true;\n\t\ttry {\n\t\t\ttc::json::parser parser(\n\t\t\t\tstr,\n\t\t\t\ttc::json::simple_error_handler([](tc::unused) THROW(ExFailure) {\n\t\t\t\t\tthrow ExFailure();\n\t\t\t\t})\n\t\t\t);\n\t\t\tparser.skip_value(); // THROW(ExFailure)\n\t\t\tparser.expect_end(); // THROW(ExFailure)\n\t\t} catch (ExFailure const&) {\n\t\t\tbAccepted = false;\n\t\t}\n\t\treturn bAccepted;\n\t};\n}\n\nUNITTESTDEF(JSONTestSuite) {\n\t// Create from https://github.com/nst/JSONTestSuite with the following code.\n\t//\n\t//\ttc::temporaryfile tmpfile; // THROW(tc::file_failure)\n\t//\ttc::for_each(\n\t//\t\ttc::filesystem::file_range(FILESTR(\"/git/JSONTestSuite/test_parsing/\")),\n\t//\t\t[&](auto const& pathTestCase) noexcept {\n\t//\t\t\ttc::readfile file(tc::as_c_str(pathTestCase)); // THROW(tc::file_failure)\n\t//\t\t\tauto str = tc::make_str(tc::repeat_n(tc::size(file), '0'));\n\t//\t\t\ttc::read(file, tc::ptr_begin(str), tc::size(str)); // THROW(tc::file_failure)\n\t//\t\t\ttc_auto_cref(strFilename, FilenameWithoutPath<tc::return_drop>(pathTestCase));\n\t//\t\t\ttc_auto_cref(chExpectation, tc::front(strFilename));\n\t//\t\t\ttc::append(\n\t//\t\t\t\ttc::make_typed_stream<char>(tmpfile),\n\t//\t\t\t\ttc_conditional_range(\n\t//\t\t\t\t\tFILESTR('i') != chExpectation,\n\t//\t\t\t\t\ttc::concat(\n\t//\t\t\t\t\t\t\"_ASSERT(\",\n\t//\t\t\t\t\t\ttc_conditional_range(\n\t//\t\t\t\t\t\t\tFILESTR('n') == chExpectation,\n\t//\t\t\t\t\t\t\t\"!\"\n\t//\t\t\t\t\t\t)\n\t//\t\t\t\t\t)\n\t//\t\t\t\t),\n\t//\t\t\t\t\"Accepts(AS_ARRAY(\\\"\",\n\t//\t\t\t\t\ttc_conditional_range(\n\t//\t\t\t\t\t\ttc::all_of(tc::codepoint_range(str), tc_fn(tc::codepoint_value)),\n\t//\t\t\t\t\t\ttc::as_cppstr(str),\n\t//\t\t\t\t\t\ttc::join(tc::transform(str, [](char const ch) noexcept {\n\t//\t\t\t\t\t\t\treturn tc::concat(\"\\\\x\", tc::as_padded_hex(tc::to_underlying(ch)));\n\t//\t\t\t\t\t\t}))\n\t//\t\t\t\t\t),\n\t//\t\t\t\t\"\\\"))\",\n\t//\t\t\t\ttc_conditional_range(\n\t//\t\t\t\t\tFILESTR('i') != chExpectation,\n\t//\t\t\t\t\t\")\"\n\t//\t\t\t\t),\n\t//\t\t\t\t\"; // \", FileExtension<tc::return_take>(strFilename), \"\\n\"\n\t//\t\t\t);\n\t//\t\t}\n\t//\t);\n\t//\t_ASSERTKNOWNFALSEPRINT(\"Wrote asserts to \", tmpfile.flush_and_close());\n\tAccepts(AS_ARRAY(\"[123.456e-789]\")); // i_number_double_huge_neg_exp\n\tAccepts(AS_ARRAY(\"[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]\")); // i_number_huge_exp\n\tAccepts(AS_ARRAY(\"[-1e+9999]\")); // i_number_neg_int_huge_exp\n\tAccepts(AS_ARRAY(\"[1.5e+9999]\")); // i_number_pos_double_huge_exp\n\tAccepts(AS_ARRAY(\"[-123123e100000]\")); // i_number_real_neg_overflow\n\tAccepts(AS_ARRAY(\"[123123e100000]\")); // i_number_real_pos_overflow\n\tAccepts(AS_ARRAY(\"[123e-10000000]\")); // i_number_real_underflow\n\tAccepts(AS_ARRAY(\"[-123123123123123123123123123123]\")); // i_number_too_big_neg_int\n\tAccepts(AS_ARRAY(\"[100000000000000000000]\")); // i_number_too_big_pos_int\n\tAccepts(AS_ARRAY(\"[-237462374673276894279832749832423479823246327846]\")); // i_number_very_big_negative_int\n\tAccepts(AS_ARRAY(\"{\\\"\\\\uDFAA\\\":0}\")); // i_object_key_lone_2nd_surrogate\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uDADA\\\"]\")); // i_string_1st_surrogate_but_2nd_missing\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uD888\\\\u1234\\\"]\")); // i_string_1st_valid_surrogate_2nd_invalid\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\uD800\\\\n\\\"]\")); // i_string_incomplete_surrogates_escape_valid\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\n\\\"]\")); // i_string_incomplete_surrogate_and_escape_valid\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uDd1ea\\\"]\")); // i_string_incomplete_surrogate_pair\n\tAccepts(AS_ARRAY(\"[\\\"\\\\ud800\\\"]\")); // i_string_invalid_lonely_surrogate\n\tAccepts(AS_ARRAY(\"[\\\"\\\\ud800abc\\\"]\")); // i_string_invalid_surrogate\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xFF\\x22\\x5D\")); // i_string_invalid_utf-8\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uDd1e\\\\uD834\\\"]\")); // i_string_inverted_surrogates_U+1D11E\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xE9\\x22\\x5D\")); // i_string_iso_latin_1\n\tAccepts(AS_ARRAY(\"[\\\"\\\\uDFAA\\\"]\")); // i_string_lone_second_surrogate\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\x81\\x22\\x5D\")); // i_string_lone_utf8_continuation_byte\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xF4\\xBF\\xBF\\xBF\\x22\\x5D\")); // i_string_not_in_unicode_range\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xC0\\xAF\\x22\\x5D\")); // i_string_overlong_sequence_2_bytes\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xFC\\x83\\xBF\\xBF\\xBF\\xBF\\x22\\x5D\")); // i_string_overlong_sequence_6_bytes\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xFC\\x80\\x80\\x80\\x80\\x80\\x22\\x5D\")); // i_string_overlong_sequence_6_bytes_null\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xE0\\xFF\\x22\\x5D\")); // i_string_truncated-utf-8\n\tAccepts(AS_ARRAY(\"\\xFF\\xFE\\x5B\\x00\\x22\\x00\\xE9\\x00\\x22\\x00\\x5D\\x00\")); // i_string_UTF-16LE_with_BOM\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xE6\\x97\\xA5\\xD1\\x88\\xFA\\x22\\x5D\")); // i_string_UTF-8_invalid_sequence\n\tAccepts(AS_ARRAY(\"\\x00\\x5B\\x00\\x22\\x00\\xE9\\x00\\x22\\x00\\x5D\")); // i_string_utf16BE_no_BOM\n\tAccepts(AS_ARRAY(\"\\x5B\\x00\\x22\\x00\\xE9\\x00\\x22\\x00\\x5D\\x00\")); // i_string_utf16LE_no_BOM\n\tAccepts(AS_ARRAY(\"\\x5B\\x22\\xED\\xA0\\x80\\x22\\x5D\")); // i_string_UTF8_surrogate_U+D800\n\tAccepts(AS_ARRAY(\"\\uFEFF{}\")); // i_structure_UTF-8_BOM_empty_object\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1 true]\"))); // n_array_1_true_without_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x61\\xE5\\x5D\"))); // n_array_a_invalid_utf8\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\": 1]\"))); // n_array_colon_instead_of_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\"],\"))); // n_array_comma_after_close\n\t_ASSERT(!Accepts(AS_ARRAY(\"[,1]\"))); // n_array_comma_and_number\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1,,2]\"))); // n_array_double_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"x\\\",,]\"))); // n_array_double_extra_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"x\\\"]]\"))); // n_array_extra_close\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\",]\"))); // n_array_extra_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"x\\\"\"))); // n_array_incomplete\n\t_ASSERT(!Accepts(AS_ARRAY(\"[x\"))); // n_array_incomplete_invalid_value\n\t_ASSERT(!Accepts(AS_ARRAY(\"[3[4]]\"))); // n_array_inner_array_no_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\xFF\\x5D\"))); // n_array_invalid_utf8\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1:2]\"))); // n_array_items_separated_by_semicolon\n\t_ASSERT(!Accepts(AS_ARRAY(\"[,]\"))); // n_array_just_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-]\"))); // n_array_just_minus\n\t_ASSERT(!Accepts(AS_ARRAY(\"[   , \\\"\\\"]\"))); // n_array_missing_value\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"a\\\",\\n4\\n,1,\"))); // n_array_newlines_unclosed\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1,]\"))); // n_array_number_and_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1,,]\"))); // n_array_number_and_several_commas\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\u000Ba\\\"\\\\f]\"))); // n_array_spaces_vertical_tab_formfeed\n\t_ASSERT(!Accepts(AS_ARRAY(\"[*]\"))); // n_array_star_inside\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\"\"))); // n_array_unclosed\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1,\"))); // n_array_unclosed_trailing_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1,\\n1\\n,1\"))); // n_array_unclosed_with_new_lines\n\t_ASSERT(!Accepts(AS_ARRAY(\"[{}\"))); // n_array_unclosed_with_object_inside\n\t_ASSERT(!Accepts(AS_ARRAY(\"[fals]\"))); // n_incomplete_false\n\t_ASSERT(!Accepts(AS_ARRAY(\"[nul]\"))); // n_incomplete_null\n\t_ASSERT(!Accepts(AS_ARRAY(\"[tru]\"))); // n_incomplete_true\n\t_ASSERT(!Accepts(AS_ARRAY(\"123\\u0000\"))); // n_multidigit_number_then_00\n\t_ASSERT(!Accepts(AS_ARRAY(\"[++1234]\"))); // n_number_++\n\t_ASSERT(!Accepts(AS_ARRAY(\"[+1]\"))); // n_number_+1\n\t_ASSERT(!Accepts(AS_ARRAY(\"[+Inf]\"))); // n_number_+Inf\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-01]\"))); // n_number_-01\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-1.0.]\"))); // n_number_-1.0.\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-2.]\"))); // n_number_-2.\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-NaN]\"))); // n_number_-NaN\n\t_ASSERT(!Accepts(AS_ARRAY(\"[.-1]\"))); // n_number_.-1\n\t_ASSERT(!Accepts(AS_ARRAY(\"[.2e-3]\"))); // n_number_.2e-3\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0.1.2]\"))); // n_number_0.1.2\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0.3e+]\"))); // n_number_0.3e+\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0.3e]\"))); // n_number_0.3e\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0.e1]\"))); // n_number_0.e1\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0e+]\"))); // n_number_0e+\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0e]\"))); // n_number_0e\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0E+]\"))); // n_number_0_capital_E+\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0E]\"))); // n_number_0_capital_E\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.0e+]\"))); // n_number_1.0e+\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.0e-]\"))); // n_number_1.0e-\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.0e]\"))); // n_number_1.0e\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1eE2]\"))); // n_number_1eE2\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1 000.0]\"))); // n_number_1_000\n\t_ASSERT(!Accepts(AS_ARRAY(\"[2.e+3]\"))); // n_number_2.e+3\n\t_ASSERT(!Accepts(AS_ARRAY(\"[2.e-3]\"))); // n_number_2.e-3\n\t_ASSERT(!Accepts(AS_ARRAY(\"[2.e3]\"))); // n_number_2.e3\n\t_ASSERT(!Accepts(AS_ARRAY(\"[9.e+]\"))); // n_number_9.e+\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1+2]\"))); // n_number_expression\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0x1]\"))); // n_number_hex_1_digit\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0x42]\"))); // n_number_hex_2_digits\n\t_ASSERT(!Accepts(AS_ARRAY(\"[Inf]\"))); // n_number_Inf\n\t_ASSERT(!Accepts(AS_ARRAY(\"[Infinity]\"))); // n_number_infinity\n\t_ASSERT(!Accepts(AS_ARRAY(\"[0e+-1]\"))); // n_number_invalid+-\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-123.123foo]\"))); // n_number_invalid-negative-real\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x31\\x32\\x33\\xE5\\x5D\"))); // n_number_invalid-utf-8-in-bigger-int\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x31\\x65\\x31\\xE5\\x5D\"))); // n_number_invalid-utf-8-in-exponent\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x30\\xE5\\x5D\\x0A\"))); // n_number_invalid-utf-8-in-int\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-Infinity]\"))); // n_number_minus_infinity\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-foo]\"))); // n_number_minus_sign_with_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\"[- 1]\"))); // n_number_minus_space_1\n\t_ASSERT(!Accepts(AS_ARRAY(\"[NaN]\"))); // n_number_NaN\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-012]\"))); // n_number_neg_int_starting_with_zero\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-.123]\"))); // n_number_neg_real_without_int_part\n\t_ASSERT(!Accepts(AS_ARRAY(\"[-1x]\"))); // n_number_neg_with_garbage_at_end\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1ea]\"))); // n_number_real_garbage_after_e\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.]\"))); // n_number_real_without_fractional_part\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x31\\x65\\xE5\\x5D\"))); // n_number_real_with_invalid_utf8_after_e\n\t_ASSERT(!Accepts(AS_ARRAY(\"[.123]\"))); // n_number_starting_with_dot\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\uFF11]\"))); // n_number_U+FF11_fullwidth_digit_one\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.2a-3]\"))); // n_number_with_alpha\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1.8011670033376514H-308]\"))); // n_number_with_alpha_char\n\t_ASSERT(!Accepts(AS_ARRAY(\"[012]\"))); // n_number_with_leading_zero\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"x\\\", truth]\"))); // n_object_bad_value\n\t_ASSERT(!Accepts(AS_ARRAY(\"{[: \\\"x\\\"}\\n\"))); // n_object_bracket_key\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"x\\\", null}\"))); // n_object_comma_instead_of_colon\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"x\\\"::\\\"b\\\"}\"))); // n_object_double_colon\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\U0001F1E8\\U0001F1ED}\"))); // n_object_emoji\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"a\\\" 123}\"))); // n_object_garbage_at_end\n\t_ASSERT(!Accepts(AS_ARRAY(\"{key: 'value'}\"))); // n_object_key_with_single_quotes\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x7B\\x22\\xB9\\x22\\x3A\\x22\\x30\\x22\\x2C\\x7D\"))); // n_object_lone_continuation_byte_in_key_and_trailing_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\" b}\"))); // n_object_missing_colon\n\t_ASSERT(!Accepts(AS_ARRAY(\"{:\\\"b\\\"}\"))); // n_object_missing_key\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\" \\\"b\\\"}\"))); // n_object_missing_semicolon\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\"))); // n_object_missing_value\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\"\"))); // n_object_no-colon\n\t_ASSERT(!Accepts(AS_ARRAY(\"{1:1}\"))); // n_object_non_string_key\n\t_ASSERT(!Accepts(AS_ARRAY(\"{9999E9999:1}\"))); // n_object_non_string_key_but_huge_number_instead\n\t_ASSERT(!Accepts(AS_ARRAY(\"{null:null,null:null}\"))); // n_object_repeated_null_null\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"id\\\":0,,,,,}\"))); // n_object_several_trailing_commas\n\t_ASSERT(!Accepts(AS_ARRAY(\"{'a':0}\"))); // n_object_single_quote\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"id\\\":0,}\"))); // n_object_trailing_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}/**/\"))); // n_object_trailing_comment\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}/**//\"))); // n_object_trailing_comment_open\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}//\"))); // n_object_trailing_comment_slash_open\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}/\"))); // n_object_trailing_comment_slash_open_incomplete\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\",,\\\"c\\\":\\\"d\\\"}\"))); // n_object_two_commas_in_a_row\n\t_ASSERT(!Accepts(AS_ARRAY(\"{a: \\\"b\\\"}\"))); // n_object_unquoted_key\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"a\"))); // n_object_unterminated-value\n\t_ASSERT(!Accepts(AS_ARRAY(\"{ \\\"foo\\\" : \\\"bar\\\", \\\"a\\\" }\"))); // n_object_with_single_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}#\"))); // n_object_with_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\" \"))); // n_single_space\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\\\\"]\"))); // n_string_1_surrogate_then_escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\u\\\"]\"))); // n_string_1_surrogate_then_escape_u\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\u1\\\"]\"))); // n_string_1_surrogate_then_escape_u1\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\u1x\\\"]\"))); // n_string_1_surrogate_then_escape_u1x\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\u00E9]\"))); // n_string_accentuated_char_no_quotes\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\\u0000\\\"]\"))); // n_string_backslash_00\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\\\\\\\\\\\"]\"))); // n_string_escaped_backslash_bad\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\\t\\\"]\"))); // n_string_escaped_ctrl_char_tab\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\\U0001F300\\\"]\"))); // n_string_escaped_emoji\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\x00\\\"]\"))); // n_string_escape_x\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\\\"]\"))); // n_string_incomplete_escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\u00A\\\"]\"))); // n_string_incomplete_escaped_character\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD834\\\\uDd\\\"]\"))); // n_string_incomplete_surrogate\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uD800\\\\uD800\\\\x\\\"]\"))); // n_string_incomplete_surrogate_escape_invalid\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x22\\x5C\\x75\\xE5\\x22\\x5D\"))); // n_string_invalid-utf-8-in-escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\a\\\"]\"))); // n_string_invalid_backslash_esc\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\uqqqq\\\"]\"))); // n_string_invalid_unicode_escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\x5B\\x22\\x5C\\xE5\\x22\\x5D\"))); // n_string_invalid_utf8_after_escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\\u0020\\\"asd\\\"]\"))); // n_string_leading_uescaped_thinspace\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\\n]\"))); // n_string_no_quotes_with_bad_escape\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\\"\"))); // n_string_single_doublequote\n\t_ASSERT(!Accepts(AS_ARRAY(\"['single quote']\"))); // n_string_single_quote\n\t_ASSERT(!Accepts(AS_ARRAY(\"abc\"))); // n_string_single_string_no_double_quotes\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\\"))); // n_string_start_escape_unclosed\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"a\\u0000a\\\"]\"))); // n_string_unescaped_ctrl_char\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"new\\nline\\\"]\"))); // n_string_unescaped_newline\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\t\\\"]\"))); // n_string_unescaped_tab\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\\"\\\\UA66D\\\"\"))); // n_string_unicode_CapitalU\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\\"\\\"x\"))); // n_string_with_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\"<.>\"))); // n_structure_angle_bracket_.\n\t_ASSERT(!Accepts(AS_ARRAY(\"[<null>]\"))); // n_structure_angle_bracket_null\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1]x\"))); // n_structure_array_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1]]\"))); // n_structure_array_with_extra_array_close\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"asd]\"))); // n_structure_array_with_unclosed_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"a\\u00E5\"))); // n_structure_ascii-unicode-identifier\n\t_ASSERT(!Accepts(AS_ARRAY(\"[True]\"))); // n_structure_capitalized_True\n\t_ASSERT(!Accepts(AS_ARRAY(\"1]\"))); // n_structure_close_unopened_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"x\\\": true,\"))); // n_structure_comma_instead_of_closing_brace\n\t_ASSERT(!Accepts(AS_ARRAY(\"[][]\"))); // n_structure_double_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"]\"))); // n_structure_end_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\xEF\\xBB\\x7B\\x7D\"))); // n_structure_incomplete_UTF8_BOM\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\xE5\"))); // n_structure_lone-invalid-utf-8\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\"))); // n_structure_lone-open-bracket\n\t_ASSERT(!Accepts(AS_ARRAY(\"\"))); // n_structure_no_data\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\u0000]\"))); // n_structure_null-byte-outside-string\n\t_ASSERT(!Accepts(AS_ARRAY(\"2@\"))); // n_structure_number_with_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\"{}}\"))); // n_structure_object_followed_by_closing_object\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"\\\":\"))); // n_structure_object_unclosed_no_value\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":/*comment*/\\\"b\\\"}\"))); // n_structure_object_with_comment\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\": true} \\\"x\\\"\"))); // n_structure_object_with_trailing_garbage\n\t_ASSERT(!Accepts(AS_ARRAY(\"['\"))); // n_structure_open_array_apostrophe\n\t_ASSERT(!Accepts(AS_ARRAY(\"[,\"))); // n_structure_open_array_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"[{\"))); // n_structure_open_array_open_object\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"a\"))); // n_structure_open_array_open_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"a\\\"\"))); // n_structure_open_array_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\"))); // n_structure_open_object\n\t_ASSERT(!Accepts(AS_ARRAY(\"{]\"))); // n_structure_open_object_close_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"{,\"))); // n_structure_open_object_comma\n\t_ASSERT(!Accepts(AS_ARRAY(\"{[\"))); // n_structure_open_object_open_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\"))); // n_structure_open_object_open_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"{'a'\"))); // n_structure_open_object_string_with_apostrophes\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\"\\\\{[\\\"\\\\{[\\\"\\\\{[\\\"\\\\{\"))); // n_structure_open_open\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\xE9\"))); // n_structure_single_eacute\n\t_ASSERT(!Accepts(AS_ARRAY(\"*\"))); // n_structure_single_star\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\"}#{}\"))); // n_structure_trailing_#\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\u2060]\"))); // n_structure_U+2060_word_joined\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\\\u000A\\\"\\\"]\"))); // n_structure_uescaped_LF_before_string\n\t_ASSERT(!Accepts(AS_ARRAY(\"[1\"))); // n_structure_unclosed_array\n\t_ASSERT(!Accepts(AS_ARRAY(\"[ false, nul\"))); // n_structure_unclosed_array_partial_null\n\t_ASSERT(!Accepts(AS_ARRAY(\"[ true, fals\"))); // n_structure_unclosed_array_unfinished_false\n\t_ASSERT(!Accepts(AS_ARRAY(\"[ false, tru\"))); // n_structure_unclosed_array_unfinished_true\n\t_ASSERT(!Accepts(AS_ARRAY(\"{\\\"asd\\\":\\\"asd\\\"\"))); // n_structure_unclosed_object\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\u00E5\"))); // n_structure_unicode-identifier\n\t_ASSERT(!Accepts(AS_ARRAY(\"\\uFEFF\"))); // n_structure_UTF8_BOM_no_data\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\u000C]\"))); // n_structure_whitespace_formfeed\n\t_ASSERT(!Accepts(AS_ARRAY(\"[\\u2060]\"))); // n_structure_whitespace_U+2060_word_joiner\n\t_ASSERT(Accepts(AS_ARRAY(\"[[]   ]\"))); // y_array_arraysWithSpaces\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\"]\"))); // y_array_empty-string\n\t_ASSERT(Accepts(AS_ARRAY(\"[]\"))); // y_array_empty\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"a\\\"]\"))); // y_array_ending_with_newline\n\t_ASSERT(Accepts(AS_ARRAY(\"[false]\"))); // y_array_false\n\t_ASSERT(Accepts(AS_ARRAY(\"[null, 1, \\\"1\\\", {}]\"))); // y_array_heterogeneous\n\t_ASSERT(Accepts(AS_ARRAY(\"[null]\"))); // y_array_null\n\t_ASSERT(Accepts(AS_ARRAY(\"[1\\n]\"))); // y_array_with_1_and_newline\n\t_ASSERT(Accepts(AS_ARRAY(\" [1]\"))); // y_array_with_leading_space\n\t_ASSERT(Accepts(AS_ARRAY(\"[1,null,null,null,2]\"))); // y_array_with_several_null\n\t_ASSERT(Accepts(AS_ARRAY(\"[2] \"))); // y_array_with_trailing_space\n\t_ASSERT(Accepts(AS_ARRAY(\"[123e65]\"))); // y_number\n\t_ASSERT(Accepts(AS_ARRAY(\"[0e+1]\"))); // y_number_0e+1\n\t_ASSERT(Accepts(AS_ARRAY(\"[0e1]\"))); // y_number_0e1\n\t_ASSERT(Accepts(AS_ARRAY(\"[ 4]\"))); // y_number_after_space\n\t_ASSERT(Accepts(AS_ARRAY(\"[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]\\n\"))); // y_number_double_close_to_zero\n\t_ASSERT(Accepts(AS_ARRAY(\"[20e1]\"))); // y_number_int_with_exp\n\t_ASSERT(Accepts(AS_ARRAY(\"[-0]\"))); // y_number_minus_zero\n\t_ASSERT(Accepts(AS_ARRAY(\"[-123]\"))); // y_number_negative_int\n\t_ASSERT(Accepts(AS_ARRAY(\"[-1]\"))); // y_number_negative_one\n\t_ASSERT(Accepts(AS_ARRAY(\"[-0]\"))); // y_number_negative_zero\n\t_ASSERT(Accepts(AS_ARRAY(\"[1E22]\"))); // y_number_real_capital_e\n\t_ASSERT(Accepts(AS_ARRAY(\"[1E-2]\"))); // y_number_real_capital_e_neg_exp\n\t_ASSERT(Accepts(AS_ARRAY(\"[1E+2]\"))); // y_number_real_capital_e_pos_exp\n\t_ASSERT(Accepts(AS_ARRAY(\"[123e45]\"))); // y_number_real_exponent\n\t_ASSERT(Accepts(AS_ARRAY(\"[123.456e78]\"))); // y_number_real_fraction_exponent\n\t_ASSERT(Accepts(AS_ARRAY(\"[1e-2]\"))); // y_number_real_neg_exp\n\t_ASSERT(Accepts(AS_ARRAY(\"[1e+2]\"))); // y_number_real_pos_exponent\n\t_ASSERT(Accepts(AS_ARRAY(\"[123]\"))); // y_number_simple_int\n\t_ASSERT(Accepts(AS_ARRAY(\"[123.456789]\"))); // y_number_simple_real\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"asd\\\":\\\"sdf\\\", \\\"dfg\\\":\\\"fgh\\\"}\"))); // y_object\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"asd\\\":\\\"sdf\\\"}\"))); // y_object_basic\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\",\\\"a\\\":\\\"c\\\"}\"))); // y_object_duplicated_key\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"a\\\":\\\"b\\\",\\\"a\\\":\\\"b\\\"}\"))); // y_object_duplicated_key_and_value\n\t_ASSERT(Accepts(AS_ARRAY(\"{}\"))); // y_object_empty\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"\\\":0}\"))); // y_object_empty_key\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"foo\\\\u0000bar\\\": 42}\"))); // y_object_escaped_null_in_key\n\t_ASSERT(Accepts(AS_ARRAY(\"{ \\\"min\\\": -1.0e+28, \\\"max\\\": 1.0e+28 }\"))); // y_object_extreme_numbers\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"x\\\":[{\\\"id\\\": \\\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\\"}], \\\"id\\\": \\\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\\"}\"))); // y_object_long_strings\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"a\\\":[]}\"))); // y_object_simple\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\\"title\\\":\\\"\\\\u041f\\\\u043e\\\\u043b\\\\u0442\\\\u043e\\\\u0440\\\\u0430 \\\\u0417\\\\u0435\\\\u043c\\\\u043b\\\\u0435\\\\u043a\\\\u043e\\\\u043f\\\\u0430\\\" }\"))); // y_object_string_unicode\n\t_ASSERT(Accepts(AS_ARRAY(\"{\\n\\\"a\\\": \\\"b\\\"\\n}\"))); // y_object_with_newlines\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0060\\\\u012a\\\\u12AB\\\"]\"))); // y_string_1_2_3_bytes_UTF-8_sequences\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uD801\\\\udc37\\\"]\"))); // y_string_accepted_surrogate_pair\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\ud83d\\\\ude39\\\\ud83d\\\\udc8d\\\"]\"))); // y_string_accepted_surrogate_pairs\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\\\\"\\\\\\\\\\\\/\\\\b\\\\f\\\\n\\\\r\\\\t\\\"]\"))); // y_string_allowed_escapes\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\\\\\u0000\\\"]\"))); // y_string_backslash_and_u_escaped_zero\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\\\\"\\\"]\"))); // y_string_backslash_doublequotes\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"a/*b*/c/*d//e\\\"]\"))); // y_string_comments\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\\\\\a\\\"]\"))); // y_string_double_escape_a\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\\\\\n\\\"]\"))); // y_string_double_escape_n\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0012\\\"]\"))); // y_string_escaped_control_character\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uFFFF\\\"]\"))); // y_string_escaped_noncharacter\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"asd\\\"]\"))); // y_string_in_array\n\t_ASSERT(Accepts(AS_ARRAY(\"[ \\\"asd\\\"]\"))); // y_string_in_array_with_leading_space\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uDBFF\\\\uDFFF\\\"]\"))); // y_string_last_surrogates_1_and_2\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"new\\\\u00A0line\\\"]\"))); // y_string_nbsp_uescaped\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\U0010FFFF\\\"]\"))); // y_string_nonCharacterInUTF-8_U+10FFFF\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\uFFFF\\\"]\"))); // y_string_nonCharacterInUTF-8_U+FFFF\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0000\\\"]\"))); // y_string_null_escape\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u002c\\\"]\"))); // y_string_one-byte-utf-8\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u03C0\\\"]\"))); // y_string_pi\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\U0001BFFF\\\"]\"))); // y_string_reservedCharacterInUTF-8_U+1BFFF\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"asd \\\"]\"))); // y_string_simple_ascii\n\t_ASSERT(Accepts(AS_ARRAY(\"\\\" \\\"\"))); // y_string_space\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uD834\\\\uDd1e\\\"]\"))); // y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0821\\\"]\"))); // y_string_three-byte-utf-8\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0123\\\"]\"))); // y_string_two-byte-utf-8\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u2028\\\"]\"))); // y_string_u+2028_line_sep\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u2029\\\"]\"))); // y_string_u+2029_par_sep\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0061\\\\u30af\\\\u30EA\\\\u30b9\\\"]\"))); // y_string_uEscape\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"new\\\\u000Aline\\\"]\"))); // y_string_uescaped_newline\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u007F\\\"]\"))); // y_string_unescaped_char_delete\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uA66D\\\"]\"))); // y_string_unicode\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u005C\\\"]\"))); // y_string_unicodeEscapedBackslash\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u2342\\u3234\\u2342\\\"]\"))); // y_string_unicode_2\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u0022\\\"]\"))); // y_string_unicode_escaped_double_quote\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uDBFF\\\\uDFFE\\\"]\"))); // y_string_unicode_U+10FFFE_nonchar\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uD83F\\\\uDFFE\\\"]\"))); // y_string_unicode_U+1FFFE_nonchar\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u200B\\\"]\"))); // y_string_unicode_U+200B_ZERO_WIDTH_SPACE\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\u2064\\\"]\"))); // y_string_unicode_U+2064_invisible_plus\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uFDD0\\\"]\"))); // y_string_unicode_U+FDD0_nonchar\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\\\uFFFE\\\"]\"))); // y_string_unicode_U+FFFE_nonchar\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"\\u20AC\\U0001D11E\\\"]\"))); // y_string_utf8\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"a\\u007Fa\\\"]\"))); // y_string_with_del_character\n\t_ASSERT(Accepts(AS_ARRAY(\"false\"))); // y_structure_lonely_false\n\t_ASSERT(Accepts(AS_ARRAY(\"42\"))); // y_structure_lonely_int\n\t_ASSERT(Accepts(AS_ARRAY(\"-0.1\"))); // y_structure_lonely_negative_real\n\t_ASSERT(Accepts(AS_ARRAY(\"null\"))); // y_structure_lonely_null\n\t_ASSERT(Accepts(AS_ARRAY(\"\\\"asd\\\"\"))); // y_structure_lonely_string\n\t_ASSERT(Accepts(AS_ARRAY(\"true\"))); // y_structure_lonely_true\n\t_ASSERT(Accepts(AS_ARRAY(\"\\\"\\\"\"))); // y_structure_string_empty\n\t_ASSERT(Accepts(AS_ARRAY(\"[\\\"a\\\"]\\n\"))); // y_structure_trailing_newline\n\t_ASSERT(Accepts(AS_ARRAY(\"[true]\"))); // y_structure_true_in_array\n\t_ASSERT(Accepts(AS_ARRAY(\" [] \"))); // y_structure_whitespace_array\n}\n\nUNITTESTDEF(JSONTestSuiteStress) {\n\tAccepts(tc::concat(tc::join(tc::repeat_n(500, \"[\")), tc::join(tc::repeat_n(500, \"]\")))); // i_structure_500_nested_arrays\n\t_ASSERT(!Accepts(tc::join(tc::repeat_n(100000, \"[\")))); // n_structure_100000_opening_arrays\n\t_ASSERT(!Accepts(tc::join(tc::repeat_n(50000, \"[{\\\"\\\":\")))); // n_structure_open_array_object\n}\n\nUNITTESTDEF(JSONDecode) {\n\ttc_static_auto_constexpr_lambda(Test) = [](tc::span<char const> strJson, tc::span<char const> strExpected) noexcept {\n\t\tauto const MakeParser = [&]() noexcept {\n\t\t\treturn tc::json::parser(tc::concat(\"\\\"\", strJson, \"\\\"\"), tc::json::assert_no_error);\n\t\t};\n\t\t_ASSERT(tc::equal(tc::as_lvalue(MakeParser()).expect_string(), tc::make_generator_range(strExpected)));\n\t\t_ASSERT(tc::equal(tc::make_generator_range(tc::as_lvalue(MakeParser()).expect_string()), strExpected));\n\t};\n\tTest(\n\t\t/*   */R\"(abc 1\\n\\u0000\\u20AC\\uD834\\uDD1E\\t23 \\u0022\\\" \\\\\\b\\f\\r\\/)\",\n\t\tAS_ARRAY(\"abc 1\\n\\0\"  \"\\u20AC\\U0001D11E\"\"\\t23 \\\"\"  \"\\\" \\\\\\b\\f\\r/\")\n\t);\n\tTest(\"\\u20AC\", \"\\u20AC\");\n\tTest(\"\\U0001D11E\", \"\\U0001D11E\");\n\tTest(R\"(\\uD800\\uDBFF_\\uDC00\\uDFFF)\", \"\\uFFFD\\uFFFD_\\uFFFD\\uFFFD\");\n\tTest(R\"(\\uD800\\uD834\\uDD1E\\uD800\\u20AC)\", \"\\uFFFD\\U0001D11E\\uFFFD\\u20AC\");\n}\n\n#pragma pop_macro(\"AS_ARRAY\")\n\nUNITTESTDEF(JSONArray_Manual) {\n\tauto parser = tc::json::parser(\"[1, 2, 3]\", tc::json::assert_no_error);\n\n\tparser.expect_array();\n\n\tparser.expect_element();\n\t_ASSERTEQUAL(parser.expect_number<int>(), 1);\n\n\tparser.expect_element();\n\t_ASSERTEQUAL(parser.expect_number<int>(), 2);\n\n\tparser.expect_element();\n\t_ASSERTEQUAL(parser.expect_number<int>(), 3);\n\n\tparser.expect_array_end();\n}\nUNITTESTDEF(JSONArray_ManualLoop) {\n\tauto parser = tc::json::parser(\"[1, 2, 3]\", tc::json::assert_no_error);\n\n\tparser.expect_array();\n\tfor (auto i = 1; parser.element(); ++i) {\n\t\t_ASSERTEQUAL(parser.expect_number<int>(), i);\n\t}\n}\nUNITTESTDEF(JSONArray_FuncIdx) {\n\tauto parser = tc::json::parser(\"[1, 2, 3]\", tc::json::assert_no_error);\n\n\tauto rng = parser.expect_array([&](std::size_t const idx) noexcept {\n\t\treturn std::pair(tc::explicit_cast<int>(idx), parser.expect_number<int>());\n\t});\n\tTEST_RANGE_EQUAL(rng, TC_FWD(tc::literal_range_of<std::pair(0, 1), std::pair(1, 2), std::pair(2, 3)>));\n}\nUNITTESTDEF(JSONArray_Func) {\n\tauto parser = tc::json::parser(\"[1, 2, 3]\", tc::json::assert_no_error);\n\n\tauto rng = parser.expect_array([&] {\n\t\treturn parser.expect_number<int>();\n\t});\n\tTEST_RANGE_EQUAL(rng, TC_FWD(tc::literal_range_of<1, 2, 3>));\n}\n\nUNITTESTDEF(JSONObject_ManualLoop) {\n\tauto parser = tc::json::parser(R\"({\"a\": 1, \"b\": 2, \"c\": 3})\", tc::json::assert_no_error);\n\n\tparser.expect_object();\n\twhile (auto const key = parser.key()) {\n\t\tauto const expected_number = [&]{\n\t\t\tif (tc::equal(*key, \"a\")) return 1;\n\t\t\tif (tc::equal(*key, \"b\")) return 2;\n\t\t\tif (tc::equal(*key, \"c\")) return 3;\n\t\t\t_ASSERTFALSE;\n\t\t\treturn -1;\n\t\t}();\n\t\tVERIFYEQUAL(parser.expect_number<int>(), expected_number);\n\t}\n}\nUNITTESTDEF(JSONObject_Members) {\n\tauto parser = tc::json::parser(R\"({\"a\": 1, \"b\": 2, \"c\": 3})\", tc::json::assert_no_error);\n\n\tint a, b, c, d;\n\td = -1;\n\n\tauto const assign = [&](int& var) noexcept {\n\t\treturn [&] {\n\t\t\tvar = parser.expect_number<int>();\n\t\t};\n\t};\n\tparser.expect_object(\n\t\ttc::json::required(tc::named<\"b\">(assign(b))),\n\t\ttc::json::required(tc::named<\"a\">(assign(a)), tc::named<\"A\">(assign(a))),\n\t\ttc::json::optional(tc::named<\"c\">(assign(c))),\n\t\ttc::json::optional(tc::named<\"d\">(assign(d)))\n\t);\n\n\t_ASSERTEQUAL(a, 1);\n\t_ASSERTEQUAL(b, 2);\n\t_ASSERTEQUAL(c, 3);\n\t_ASSERTEQUAL(d, -1);\n}\n"
  },
  {
    "path": "tc/string/make_c_str.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../base/generic_macros.h\"\n#include \"../base/reference_or_value.h\"\n#include \"../base/casts.h\"\n#include \"../algorithm/append.h\"\n\nnamespace tc {\n\ttemplate<typename Rng, typename Char>\n\tconcept has_c_str = requires(Rng&& rng) {\n\t\t{ tc::as_c_str(rng) } -> tc::safely_convertible_to<Char*>;\n\t};\n\n\tnamespace no_adl {\n\t\ttemplate< typename Char, typename Rng >\n\t\tstruct [[nodiscard]] make_c_str_impl final : private tc::reference_or_value<Rng> {\n\t\t\texplicit make_c_str_impl(Rng&& rng) noexcept: tc::reference_or_value<Rng>(tc::aggregate_tag, tc_move_if_owned(rng)) {}\n\n\t\t\t// We don't want make_c_str_impl to be able to implicitly cast to bool. Deleting operator bool() won't work because\n\t\t\t// a deleted function is still considered in overload resolution and will cause ambiguity between foo(bool) and foo(char const*).\n\t\t\ttemplate<typename T> requires std::is_same<T, Char const*>::value\n\t\t\toperator T() const /*no &*/ noexcept {\n\t\t\t\treturn tc::as_c_str(**this);\n\t\t\t}\n\n\t\t\ttemplate<typename T> requires std::is_same<T, Char*>::value\n\t\t\toperator T() /*no &*/ noexcept {\n\t\t\t\treturn tc::as_c_str(**this);\n\t\t\t}\n\t\t\t\n\t\t\toperator tc::span<Char const>() const /*no &*/ noexcept {\n\t\t\t\treturn **this;\n\t\t\t}\n\t\t};\n\t}\n\n\t/////////////////////////////////////////////////////////////////////////////////////////////////\n\t//  make_c_str(<Char>): create a value or reference holder which is castable to c string\n\n\t//   1. One input range, tc::as_c_str(rng) is valid and convertible to Char const*: hold the value or reference of the rng, castable to tc::as_c_str(rng)\n\t//   2. Otherwise: create and hold a tc::string<Char>, castable to Char const*\n\t//   3. Explicitly specified <Char> could be omitted if the char pointer type deduced from the first rng is convertible to destination c string\n\t//   4. make_mutable_c_str(<Char>): create a value or reference holder which is castable to mutable c string\n\n\ttemplate< typename Char, tc::has_c_str<Char const> Rng0 >\n\tauto make_c_str(Rng0&& rng0) noexcept {\n\t\tstatic_assert(tc::decayed<Char>);\n\t\treturn tc::no_adl::make_c_str_impl<Char const, Rng0>(tc_move_if_owned(rng0));\n\t}\n\n\ttemplate< typename Rng0 >\n\tauto make_c_str(Rng0&& rng0) return_decltype_noexcept(\n\t\ttc::make_c_str<std::remove_cv_t<typename std::pointer_traits<decltype(tc::as_c_str(std::declval<Rng0>()))>::element_type>>(tc_move_if_owned(rng0))\n\t)\n\n\ttemplate< typename Char, typename Rng0, typename... Rng >\n\tauto make_c_str(Rng0&& rng0, Rng&& ... rng) MAYTHROW {\n\t\tstatic_assert(tc::decayed<Char>);\n\t\treturn tc::no_adl::make_c_str_impl<Char const, tc::string<Char>>(tc::make_str<Char>(tc_move_if_owned(rng0), tc_move_if_owned(rng)...));\n\t}\n\n\ttemplate< typename Rng0, typename... Rng >\n\tauto make_c_str(Rng0&& rng0, Rng&& ... rng) MAYTHROW {\n\t\treturn tc::make_c_str<tc::range_value_t<decltype(tc::concat(std::declval<Rng0>(), std::declval<Rng>()...))>>(tc_move_if_owned(rng0), tc_move_if_owned(rng)...);\n\t}\n\n\ttemplate< typename Char, tc::has_c_str<Char> Rng0 >\n\tauto make_mutable_c_str(Rng0&& rng0) noexcept {\n\t\tstatic_assert(tc::decayed<Char>);\n\t\treturn tc::no_adl::make_c_str_impl<Char, Rng0>(tc_move_if_owned(rng0));\n\t}\n\n\ttemplate< typename Rng0 >\n\tauto make_mutable_c_str(Rng0&& rng0) return_decltype_noexcept(\n\t\ttc::make_mutable_c_str<std::remove_cv_t<typename std::pointer_traits<decltype(tc::as_c_str(std::declval<Rng0>()))>::element_type>>(tc_move_if_owned(rng0))\n\t)\n\n\ttemplate< typename Char, typename Rng0, typename... Rng >\n\tauto make_mutable_c_str(Rng0&& rng0, Rng&& ... rng) MAYTHROW {\n\t\tstatic_assert(tc::decayed<Char>);\n\t\treturn tc::no_adl::make_c_str_impl<Char, tc::string<Char>>(tc::make_str<Char>(tc_move_if_owned(rng0), tc_move_if_owned(rng)...));\n\t}\n\n\ttemplate< typename Rng0, typename... Rng >\n\tauto make_mutable_c_str(Rng0&& rng0, Rng&& ... rng) MAYTHROW {\n\t\treturn tc::make_mutable_c_str<tc::range_value_t<decltype(tc::concat(std::declval<Rng0>(), std::declval<Rng>()...))>>(tc_move_if_owned(rng0), tc_move_if_owned(rng)...);\n\t}\n}\n\n"
  },
  {
    "path": "tc/string/make_c_str.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../unittest.h\"\n\n#include \"make_c_str.h\"\n\n#ifdef TC_PRIVATE\n#include \"Library/Internationalization/i18n_fwd.h\"\n#endif\n\nstatic_assert(tc::has_c_str<std::string const&, char const>);\nstatic_assert(!tc::has_c_str<std::string const&, char>);\nstatic_assert(tc::has_c_str<std::string&, char const>);\nstatic_assert(tc::has_c_str<std::string&, char>);\nstatic_assert(tc::has_c_str<std::string&&, char const>);\nstatic_assert(tc::has_c_str<std::string&&, char>);\nstatic_assert(tc::has_c_str<char const*, char const>);\nstatic_assert(!tc::has_c_str<char const*, char>);\nstatic_assert(tc::has_c_str<char*, char const>);\nstatic_assert(tc::has_c_str<char*, char>);\n\nnamespace {\n\ttemplate<typename Char1, typename Char2> requires std::is_same<Char1, Char2>::value\n\tbool check_make_c_str_fwd(Char1 const* str1, Char2 const* str2) noexcept {\n\t\treturn str1 == str2;\n\t}\n\n\ttemplate<typename Char1, typename Char2>\n\tbool check_make_c_str_fwd(Char1 const*, Char2 const*) noexcept {\n\t\treturn false;\n\t}\n}\n\nUNITTESTDEF(make_c_str_fwd_test) {\n\ttc::string<char> str1(\"ab\");\n\t_ASSERT(check_make_c_str_fwd<char>(tc::make_c_str(str1), tc::as_c_str(str1)));\n\t_ASSERT(!check_make_c_str_fwd<tc::char16>(tc::make_c_str(tc::convert_enc<tc::char16>(str1)), tc::as_c_str(str1)));\n\ttc::string<char> const str2(\"cd\");\n\t_ASSERT(check_make_c_str_fwd<char>(tc::make_c_str(str2), tc::as_c_str(str2)));\n\t_ASSERT(!check_make_c_str_fwd<tc::char16>(tc::make_c_str(tc::convert_enc<tc::char16>(str2)), tc::as_c_str(str2)));\n\tchar const* str3 = \"ef\";\n\t_ASSERT(check_make_c_str_fwd<char>(tc::make_c_str(str3), tc::as_c_str(str3)));\n\t_ASSERT(!check_make_c_str_fwd<tc::char16>(tc::make_c_str(tc::convert_enc<tc::char16>(str3)), tc::as_c_str(str3)));\n\tchar ach4[] = {\"gh\"};\n\t_ASSERT(check_make_c_str_fwd<char>(tc::make_c_str(ach4), tc::as_c_str(ach4)));\n\ttc::span<char const> str5 = str1;\n\t_ASSERT(!check_make_c_str_fwd<char>(tc::make_c_str(str5), tc::ptr_begin(str5)));\n#ifdef TC_PRIVATE\n\ttc::uichar const* str6 = UISTR(\"ij\");\n\t_ASSERTEQUAL(TC_FWD(std::is_same<tc::uichar, char>::value), check_make_c_str_fwd<char>(tc::make_c_str(tc::convert_enc<char>(str6)), tc::as_c_str(str6)));\n#endif\n}\n\nnamespace {\n\ttemplate<typename Char, typename Str>\n\tbool check_make_c_str(Char const* str1, Str const& str2) noexcept {\n\t\treturn tc::equal(str1, str2);\n\t}\n}\n\nUNITTESTDEF(make_c_str_test) {\n\ttc::string<char> str1(\"ab\");\n\tauto strLocal1 = tc::make_c_str(str1);\n\t_ASSERT(check_make_c_str<char>(strLocal1, \"ab\"));\n\t_ASSERT(check_make_c_str<char>(tc::make_c_str(tc::string<char>(\"cd\")), \"cd\"));\n\tauto strLocal3 = tc::make_c_str(tc::string<char>(\"ef\"));\n\t_ASSERT(check_make_c_str<char>(strLocal3, \"ef\"));\n#ifdef TC_PRIVATE\n\t_ASSERT(check_make_c_str<tc::uichar>(tc::make_c_str<tc::uichar>(tc_ascii(\"ab\"), tc_ascii(\"cd\"), tc_ascii(\"ef\")), tc::make_str<tc::uichar>(\"ab\", \"cd\", \"ef\")));\n\t_ASSERT(check_make_c_str<char>(tc::make_c_str<char>(tc_ascii(\"abcdef\")), tc::explicit_cast<tc::string<char>>(UISTR(\"abcdef\"))));\n#endif\n}\n\n"
  },
  {
    "path": "tc/string/named.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/string_template_param.h\"\n#include \"char.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate <tc::string_template_param strName, typename T>\n\t\t\trequires tc::is_ascii_string_literal<strName>\n\t\tstruct named final {\n\t\t\tT m_t;\n\n\t\t\tstatic auto constexpr c_strName = tc::string_literal<strName>;\n\t\t};\n\t}\n\n\tIS_INSTANCE_TRAIT(_str, ((tc::string_template_param)(str))((typename)(...)(T)), using arguments=boost::mp11::mp_list<T...>; static constexpr auto first_argument=str;)\n\n\ttemplate<typename T>\n\tusing is_named = tc::constant<tc::instance_str<std::remove_reference_t<T>, no_adl::named>>;\n\n\tstatic_assert(is_named< no_adl::named<\"test\",int> >::value);\n\n\ttemplate<tc::string_template_param strName, typename T>\n\tconstexpr auto named(T&& t) return_ctor_MAYTHROW(\n\t\tTC_FWD(no_adl::named<strName, std::remove_cv_t<T>>), {tc_move_if_owned(t)}\n\t)\n}\n"
  },
  {
    "path": "tc/string/parserbase.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/reference_or_value.h\"\n#include \"../range/meta.h\"\n#include \"char.h\"\n#include \"ascii.h\"\n\nnamespace tc {\n\tnamespace no_adl {\n\t\t// Naming convention for parser functions:\n\t\t// * `optional<T> foo()`: Try to consume `foo` and return its value. If `T == void`, return `bool`.\n\t\t// * `T expect_foo()`: Consume `foo` and return its value. It is an error if `foo` isn't next.\n\t\t// * `void skip_foo()`: Consume `foo`. It is an error if `foo` isn't next.\n\n\t\ttemplate<typename String, typename ErrorHandler>\n\t\tstruct parser_base {\n\t\t\tusing char_type=tc::range_value_t<String>;\n\t\t\tusing iterator = tc::iterator_t<String const>;\n\n\t\t\tdecltype(auto) input() const& noexcept {\n\t\t\t\treturn *m_strInput;\n\t\t\t}\n\n\t\t\texplicit operator bool() const& noexcept {\n\t\t\t\treturn !m_bError;\n\t\t\t}\n\n\t\t\titerator position() const& noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\treturn m_itchInput;\n\t\t\t}\n\n\t\t\ttemplate<typename... Args>\n\t\t\t[[noreturn]] void semantic_error(Args&&... args) & MAYTHROW {\n\t\t\t\tthis->error<tc_mem_fn(.semantic_error)>(tc_move_if_owned(args)...);\n\t\t\t}\n\n\t\tprotected:\n\t\t\texplicit parser_base(String&& strInput, ErrorHandler errorhandler) noexcept\n\t\t\t\t: m_strInput(tc::aggregate_tag, tc_move_if_owned(strInput))\n\t\t\t\t, m_itchInput(tc::begin(*m_strInput))\n\t\t\t\t, m_end(tc::end(*m_strInput))\n\t\t\t\t, m_errorhandler(tc_move(errorhandler))\n\t\t\t\t, m_bError(false)\n\t\t\t{}\n\t\t\tparser_base(const parser_base&) = default;\n\t\t\tparser_base& operator=(const parser_base&) = default;\n\t\t\t~parser_base() = default;\n\n\t\tprotected:\n\t\t\ttemplate<auto memfn, typename... Args>\n\t\t\tvoid warning_at(iterator it, Args&&... args) & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tmemfn(m_errorhandler, *m_strInput, it, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t}\n\t\t\ttemplate<auto memfn, typename... Args>\n\t\t\tvoid warning(Args&&... args) & MAYTHROW {\n\t\t\t\twarning_at<memfn>(this->m_itchInput, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t}\n\n\t\t\ttemplate<auto memfn, typename... Args>\n\t\t\t[[noreturn]] void error_at(iterator it, Args&&... args) & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tm_bError = true;\n\t\t\t\tmemfn(m_errorhandler, *m_strInput, it, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t\t_ASSERTNORETURNFALSE;\n\t\t\t}\n\t\t\ttemplate<auto memfn, typename... Args>\n\t\t\t[[noreturn]] void error(Args&&... args) & MAYTHROW {\n\t\t\t\terror_at<memfn>(this->m_itchInput, tc_move_if_owned(args)...); // MAYTHROW\n\t\t\t}\n\n\t\tprotected:\n\t\t\tchar_type unchecked_peek() & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\t_ASSERTDEBUG(!end());\n\t\t\t\treturn *m_itchInput;\n\t\t\t}\n\n\t\t\tvoid unchecked_increment() & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\t_ASSERTDEBUG(!end());\n\t\t\t\t++m_itchInput;\n\t\t\t}\n\n\t\t\ttc::sentinel_t<String const> end_position() const& noexcept {\n\t\t\t\treturn m_end;\n\t\t\t}\n\n\t\t\tvoid set_position(iterator pos) & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif constexpr (std::random_access_iterator<iterator> && tc::common_range<String>) {\n\t\t\t\t\t// If pos is outside the range, the comparison is UB, but so is calling set_position() in the first place.\n\t\t\t\t\t// So we assert it to hope that it causes a nicer error.\t\n\t\t\t\t\t_ASSERT(tc::begin(input()) <= pos && pos <= m_end);\n\t\t\t\t}\n\t\t\t\tm_itchInput = pos;\n\t\t\t}\n\n\t\tprotected:\n\t\t\tbool end() const& noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\treturn m_itchInput == m_end;\n\t\t\t}\n\t\t\tvoid expect_end() & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput != m_end) {\n\t\t\t\t\terror<tc_mem_fn(.end_expected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid expect_not_end() & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput == m_end) {\n\t\t\t\t\terror<tc_mem_fn(.end_unexpected)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[[nodiscard]] std::optional<char_type> any_char() & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput == m_end) {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\t\t\t\treturn *m_itchInput++;\n\t\t\t}\n\t\t\t[[nodiscard]] char_type expect_any_char() & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\texpect_not_end();\n\t\t\t\treturn *m_itchInput++;\n\t\t\t}\n\n\t\t\ttemplate <auto C>\n\t\t\t[[nodiscard]] bool literal(tc::literal_range<tc::char_ascii, C>) & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput == m_end || C != *m_itchInput) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t++m_itchInput;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttemplate <auto C>\n\t\t\tvoid expect_literal(tc::literal_range<tc::char_ascii, C>) & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\texpect_not_end();\n\t\t\t\tif (C != *m_itchInput) {\n\t\t\t\t\terror<tc_mem_fn(.char_expected)>(tc::char_ascii(C)); // MAYTHROW\n\t\t\t\t}\n\t\t\t\t++m_itchInput;\n\t\t\t}\n\n\t\t\ttemplate <auto ... Cs>\n\t\t\tvoid expect_literal(tc::literal_range<tc::char_ascii, Cs...>) & MAYTHROW {\n\t\t\t\t(expect_literal(tc::literal_range<tc::char_ascii, Cs>()), ...);\n\t\t\t}\n\n\t\t\ttemplate <typename Fn>\n\t\t\t[[nodiscard]] std::optional<char_type> char_class(Fn const predicate) & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput == m_end || !predicate(*m_itchInput)) {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\n\t\t\t\treturn *m_itchInput++;\n\t\t\t}\n\t\t\ttemplate <auto ... Cs>\n\t\t\t[[nodiscard]] std::optional<char_type> one_of(tc::literal_range<tc::char_ascii, Cs...>) & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tif (m_itchInput == m_end) return std::nullopt;\n\n\t\t\t\tauto ch = *m_itchInput;\n\t\t\t\tif (((Cs == ch) || ...)) {\n\t\t\t\t\t++m_itchInput;\n\t\t\t\t\treturn ch;\n\t\t\t\t}\n\n\t\t\t\treturn std::nullopt;\n\t\t\t}\n\n\t\tprotected:\n\t\t\tvoid skip_whitespace() & MAYTHROW {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tfor (;;) {\n\t\t\t\t\texpect_not_end(); // MAYTHROW\n\t\t\t\t\tswitch(*m_itchInput) {\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase '\\t':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase ' ':\n\t\t\t\t\t\t++m_itchInput;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid skip_whitespace_maybe_end() & noexcept {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\twhile (m_itchInput != m_end) {\n\t\t\t\t\tswitch(*m_itchInput) {\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase '\\t':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase ' ':\n\t\t\t\t\t\t++m_itchInput;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Precondition: We've already consumed one character and want to skip the rest of the code point.\n\t\t\tvoid skip_utf8_code_point(char_type const ch0) & MAYTHROW requires (sizeof(char_type) == 1) {\n\t\t\t\t_ASSERTDEBUG(*this);\n\t\t\t\tauto const n0 = tc::to_underlying(ch0); // MAYTHROW\n\t\t\t\tif(0 == (n0 & 0x80)) { // ASCII\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tauto const n1 = tc::to_underlying(expect_any_char()); // MAYTHROW\n\t\t\t\tswitch( (n0 >> 4) & 0x7 ) {\n\t\t\t\t\tcase 0b100:\n\t\t\t\t\tcase 0b101:\n\t\t\t\t\t\t{\t// ([\\xC2-\\xDF][\\x80-\\xBF])\n\t\t\t\t\t\t\tif( (n0 < 0xC2) | (0x80 != (0xC0 & n1)) ) goto InvalidEncoding; // No short-circuit-evaluation\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase 0b110:\n\t\t\t\t\t\t{\t// ((([\\xE0][\\xA0-\\xBF])|([\\xE1-\\xEC\\xEE-\\xEF][\\x80-\\xBF])|([\\xED][\\x80-\\x9F]))[\\x80-\\xBF])\n\t\t\t\t\t\t\tauto const n2 = tc::to_underlying(expect_any_char()); // MAYTHROW\n\t\t\t\t\t\t\tif( (0x80 != (0xC0 & (n1 | n2))) | // not continuation bytes\n\t\t\t\t\t\t\t\t(0xE0 == n0) & (n1 < 0xA0) | // non-shortest form\n\t\t\t\t\t\t\t\t(0xED == n0) & (0xA0 <= n1) // range 0xd800-0xdfff\n\t\t\t\t\t\t\t) goto InvalidEncoding; // No short-circuit-evaluation\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase 0b111:\n\t\t\t\t\t\t{\t// ((([\\xF0][\\x90-\\xBF])|([\\xF1-\\xF3][\\x80-\\xBF])|([\\xF4][\\x80-\\x8F]))[\\x80-\\xBF][\\x80-\\xBF])\n\t\t\t\t\t\t\tauto const n2 = tc::to_underlying(expect_any_char()); // MAYTHROW\n\t\t\t\t\t\t\tauto const n3 = tc::to_underlying(expect_any_char()); // MAYTHROW\n\t\t\t\t\t\t\tif( (n0 < 0xF5) & // value less than U+10FFFF\n\t\t\t\t\t\t\t\t((0xF0 != n0) | (0x90 <= n1)) & // non-shortest form\n\t\t\t\t\t\t\t\t((0xF4 != n0) | (n1 < 0x90)) & // value less than U+10FFFF\n\t\t\t\t\t\t\t\t(0x80 == (0xC0 & (n1 | n2 | n3))) // continuation bytes\n\t\t\t\t\t\t\t) {  // No short-circuit-evaluation\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t[[fallthrough]];\n\n\t\t\t\t\tdefault:\n\t\t\t\t\tInvalidEncoding:\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.invalid_encoding)>(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\tprotected: // TODO: refactor XML parser\n\t\t\ttc::reference_or_value<String> m_strInput;\n\t\t\titerator m_itchInput;\n\t\t\ttc::sentinel_t<String const> m_end; // cached for performance\n\t\t\tErrorHandler m_errorhandler;\n\t\t\tbool m_bError;\n\t\t};\n\t}\n\tusing no_adl::parser_base;\n}\n"
  },
  {
    "path": "tc/string/spirit/support/assert_msg.hpp",
    "content": "//  Copyright (c) 2001-2013 Hartmut Kaiser\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#if !defined(BOOST_SPIRIT_ASSERT_MSG_JUN_23_2009_0836AM)\n#define BOOST_SPIRIT_ASSERT_MSG_JUN_23_2009_0836AM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <boost/config.hpp>\n\n// Work around the MPL problem in BOOST_MPL_ASSERT_MSG generating\n// multiple definition linker errors for certain compilers (VC++ 8).\n// BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG can also be defined by user.\n#if !defined(BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG)\n# if defined(BOOST_MSVC) && BOOST_MSVC < 1500\n#  define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1\n# endif\n#endif\n\n#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG != 0\n#include <boost/static_assert.hpp>\n#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types)                             \\\n\t\tBOOST_STATIC_ASSERT_MSG(Cond, # Msg)\n#else\n#include <boost/mpl/assert.hpp>\n#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types)                             \\\n\t\tBOOST_MPL_ASSERT_MSG(Cond, Msg, Types)\n#endif\n\n#define BOOST_SPIRIT_ASSERT_MATCH(Domain, Expr)                               \\\n\t\tBOOST_SPIRIT_ASSERT_MSG((                                             \\\n\t\t\tboost::spirit::traits::matches< Domain, Expr >::value             \\\n\t\t), error_invalid_expression, (Expr))\n\n// GCC 4.7 will overeagerly instantiate static_asserts in template functions,\n// if the assert condition does not depend on template parameters\n// (see https://svn.boost.org/trac/boost/ticket/8381).\n// There are places where we want to use constant false as the condition in\n// template functions to indicate that these function overloads should never\n// be called. This allows to generate better error messages. To solve this\n// problem we make the condition dependent on the template argument and use\n// the following macro in such places.\n#include <boost/type_traits/is_same.hpp>\n\n#define BOOST_SPIRIT_ASSERT_FAIL(TemplateParam, Msg, Types)                   \\\n\t\tBOOST_SPIRIT_ASSERT_MSG((!boost::is_same<                             \\\n\t\t\tTemplateParam, TemplateParam >::value), Msg, Types)\n\n#endif\n\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/ascii.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_ASCII_APRIL_26_2006_1106PM)\n#define BOOST_SPIRIT_ASCII_APRIL_26_2006_1106PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <climits>\n#include <boost/assert.hpp>\n#include <boost/cstdint.hpp>\n\n///////////////////////////////////////////////////////////////////////////////\n// constants used to classify the single characters\n///////////////////////////////////////////////////////////////////////////////\n#define BOOST_CC_DIGIT    0x0001\n#define BOOST_CC_XDIGIT   0x0002\n#define BOOST_CC_ALPHA    0x0004\n#define BOOST_CC_CTRL     0x0008\n#define BOOST_CC_LOWER    0x0010\n#define BOOST_CC_UPPER    0x0020\n#define BOOST_CC_SPACE    0x0040\n#define BOOST_CC_PUNCT    0x0080\n\nnamespace boost { namespace spirit { namespace char_encoding\n{\n\t// The detection of isgraph(), isprint() and isblank() is done programmatically\n\t// to keep the character type table small. Additionally, these functions are\n\t// rather seldom used and the programmatic detection is very simple.\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// ASCII character classification table\n\t///////////////////////////////////////////////////////////////////////////\n\tconst unsigned char ascii_char_types[] =\n\t{\n\t\t/* NUL   0   0 */   BOOST_CC_CTRL,\n\t\t/* SOH   1   1 */   BOOST_CC_CTRL,\n\t\t/* STX   2   2 */   BOOST_CC_CTRL,\n\t\t/* ETX   3   3 */   BOOST_CC_CTRL,\n\t\t/* EOT   4   4 */   BOOST_CC_CTRL,\n\t\t/* ENQ   5   5 */   BOOST_CC_CTRL,\n\t\t/* ACK   6   6 */   BOOST_CC_CTRL,\n\t\t/* BEL   7   7 */   BOOST_CC_CTRL,\n\t\t/* BS    8   8 */   BOOST_CC_CTRL,\n\t\t/* HT    9   9 */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* NL   10   a */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* VT   11   b */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* NP   12   c */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* CR   13   d */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* SO   14   e */   BOOST_CC_CTRL,\n\t\t/* SI   15   f */   BOOST_CC_CTRL,\n\t\t/* DLE  16  10 */   BOOST_CC_CTRL,\n\t\t/* DC1  17  11 */   BOOST_CC_CTRL,\n\t\t/* DC2  18  12 */   BOOST_CC_CTRL,\n\t\t/* DC3  19  13 */   BOOST_CC_CTRL,\n\t\t/* DC4  20  14 */   BOOST_CC_CTRL,\n\t\t/* NAK  21  15 */   BOOST_CC_CTRL,\n\t\t/* SYN  22  16 */   BOOST_CC_CTRL,\n\t\t/* ETB  23  17 */   BOOST_CC_CTRL,\n\t\t/* CAN  24  18 */   BOOST_CC_CTRL,\n\t\t/* EM   25  19 */   BOOST_CC_CTRL,\n\t\t/* SUB  26  1a */   BOOST_CC_CTRL,\n\t\t/* ESC  27  1b */   BOOST_CC_CTRL,\n\t\t/* FS   28  1c */   BOOST_CC_CTRL,\n\t\t/* GS   29  1d */   BOOST_CC_CTRL,\n\t\t/* RS   30  1e */   BOOST_CC_CTRL,\n\t\t/* US   31  1f */   BOOST_CC_CTRL,\n\t\t/* SP   32  20 */   BOOST_CC_SPACE,\n\t\t/*  !   33  21 */   BOOST_CC_PUNCT,\n\t\t/*  \"   34  22 */   BOOST_CC_PUNCT,\n\t\t/*  #   35  23 */   BOOST_CC_PUNCT,\n\t\t/*  $   36  24 */   BOOST_CC_PUNCT,\n\t\t/*  %   37  25 */   BOOST_CC_PUNCT,\n\t\t/*  &   38  26 */   BOOST_CC_PUNCT,\n\t\t/*  '   39  27 */   BOOST_CC_PUNCT,\n\t\t/*  (   40  28 */   BOOST_CC_PUNCT,\n\t\t/*  )   41  29 */   BOOST_CC_PUNCT,\n\t\t/*  *   42  2a */   BOOST_CC_PUNCT,\n\t\t/*  +   43  2b */   BOOST_CC_PUNCT,\n\t\t/*  ,   44  2c */   BOOST_CC_PUNCT,\n\t\t/*  -   45  2d */   BOOST_CC_PUNCT,\n\t\t/*  .   46  2e */   BOOST_CC_PUNCT,\n\t\t/*  /   47  2f */   BOOST_CC_PUNCT,\n\t\t/*  0   48  30 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  1   49  31 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  2   50  32 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  3   51  33 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  4   52  34 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  5   53  35 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  6   54  36 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  7   55  37 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  8   56  38 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  9   57  39 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  :   58  3a */   BOOST_CC_PUNCT,\n\t\t/*  ;   59  3b */   BOOST_CC_PUNCT,\n\t\t/*  <   60  3c */   BOOST_CC_PUNCT,\n\t\t/*  =   61  3d */   BOOST_CC_PUNCT,\n\t\t/*  >   62  3e */   BOOST_CC_PUNCT,\n\t\t/*  ?   63  3f */   BOOST_CC_PUNCT,\n\t\t/*  @   64  40 */   BOOST_CC_PUNCT,\n\t\t/*  A   65  41 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  B   66  42 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  C   67  43 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  D   68  44 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  E   69  45 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  F   70  46 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  G   71  47 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  H   72  48 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  I   73  49 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  J   74  4a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  K   75  4b */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  L   76  4c */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  M   77  4d */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  N   78  4e */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  O   79  4f */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  P   80  50 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Q   81  51 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  R   82  52 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  S   83  53 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  T   84  54 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  U   85  55 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  V   86  56 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  W   87  57 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  X   88  58 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Y   89  59 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Z   90  5a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  [   91  5b */   BOOST_CC_PUNCT,\n\t\t/*  \\   92  5c */   BOOST_CC_PUNCT,\n\t\t/*  ]   93  5d */   BOOST_CC_PUNCT,\n\t\t/*  ^   94  5e */   BOOST_CC_PUNCT,\n\t\t/*  _   95  5f */   BOOST_CC_PUNCT,\n\t\t/*  `   96  60 */   BOOST_CC_PUNCT,\n\t\t/*  a   97  61 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  b   98  62 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  c   99  63 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  d  100  64 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  e  101  65 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  f  102  66 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  g  103  67 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  h  104  68 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  i  105  69 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  j  106  6a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  k  107  6b */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  l  108  6c */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  m  109  6d */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  n  110  6e */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  o  111  6f */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  p  112  70 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  q  113  71 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  r  114  72 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  s  115  73 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  t  116  74 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  u  117  75 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  v  118  76 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  w  119  77 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  x  120  78 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  y  121  79 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  z  122  7a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  {  123  7b */   BOOST_CC_PUNCT,\n\t\t/*  |  124  7c */   BOOST_CC_PUNCT,\n\t\t/*  }  125  7d */   BOOST_CC_PUNCT,\n\t\t/*  ~  126  7e */   BOOST_CC_PUNCT,\n\t\t/* DEL 127  7f */   BOOST_CC_CTRL,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Test characters for specified conditions (using ASCII)\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct ascii\n\t{\n\t\ttypedef char char_type;\n\t\ttypedef unsigned char classify_type;\n\n\t\tstatic bool\n\t\tisascii_(int ch)\n\t\t{\n\t\t\treturn 0 == (ch & ~0x7f);\n\t\t}\n\n\t\tstatic bool\n\t\tischar(int ch)\n\t\t{\n\t\t\treturn isascii_(ch);\n\t\t}\n\n\t\t// *** Note on assertions: The precondition is that the calls to\n\t\t// these functions do not violate the required range of ch (type int)\n\t\t// which is that strict_ischar(ch) should be true. It is the\n\t\t// responsibility of the caller to make sure this precondition is not\n\t\t// violated.\n\n\t\tstatic bool\n\t\tstrict_ischar(int ch)\n\t\t{\n\t\t\treturn ch >= 0 && ch <= 127;\n\t\t}\n\n\t\tstatic bool\n\t\tisalnum(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_ALPHA)\n\t\t\t\t|| (ascii_char_types[ch] & BOOST_CC_DIGIT);\n\t\t}\n\n\t\tstatic bool\n\t\tisalpha(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_ALPHA) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_DIGIT) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisxdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_XDIGIT) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tiscntrl(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_CTRL) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisgraph(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ('\\x21' <= ch && ch <= '\\x7e');\n\t\t}\n\n\t\tstatic bool\n\t\tislower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_LOWER) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisprint(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ('\\x20' <= ch && ch <= '\\x7e');\n\t\t}\n\n\t\tstatic bool\n\t\tispunct(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_PUNCT) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisspace(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_SPACE) ? true : false;\n\t\t}\n\n\t\tstatic bool\n\t\tisblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ('\\x09' == ch || '\\x20' == ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ascii_char_types[ch] & BOOST_CC_UPPER) ? true : false;\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t//  Simple character conversions\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\tstatic int\n\t\ttolower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn isupper(ch) ? (ch - 'A' + 'a') : ch;\n\t\t}\n\n\t\tstatic int\n\t\ttoupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn islower(ch) ? (ch - 'a' + 'A') : ch;\n\t\t}\n\n\t\tstatic ::boost::uint32_t\n\t\ttoucs4(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ch;\n\t\t}\n\t};\n\n}}}\n\n///////////////////////////////////////////////////////////////////////////////\n// undefine macros\n///////////////////////////////////////////////////////////////////////////////\n#undef BOOST_CC_DIGIT\n#undef BOOST_CC_XDIGIT\n#undef BOOST_CC_ALPHA\n#undef BOOST_CC_CTRL\n#undef BOOST_CC_LOWER\n#undef BOOST_CC_UPPER\n#undef BOOST_CC_PUNCT\n#undef BOOST_CC_SPACE\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/iso8859_1.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_ISO8859_1_APRIL_26_2006_1106PM)\n#define BOOST_SPIRIT_ISO8859_1_APRIL_26_2006_1106PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <climits>\n#include <boost/assert.hpp>\n#include <boost/cstdint.hpp>\n\n///////////////////////////////////////////////////////////////////////////////\n// constants used to classify the single characters\n///////////////////////////////////////////////////////////////////////////////\n#define BOOST_CC_DIGIT    0x0001\n#define BOOST_CC_XDIGIT   0x0002\n#define BOOST_CC_ALPHA    0x0004\n#define BOOST_CC_CTRL     0x0008\n#define BOOST_CC_LOWER    0x0010\n#define BOOST_CC_UPPER    0x0020\n#define BOOST_CC_SPACE    0x0040\n#define BOOST_CC_PUNCT    0x0080\n\nnamespace boost { namespace spirit { namespace char_encoding\n{\n\t// The detection of isgraph(), isprint() and isblank() is done programmatically\n\t// to keep the character type table small. Additionally, these functions are\n\t// rather seldom used and the programmatic detection is very simple.\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// ISO 8859-1 character classification table\n\t//\n\t// the comments intentionally contain non-ascii characters\n\t// boostinspect:noascii\n\t///////////////////////////////////////////////////////////////////////////\n\tconst unsigned char iso8859_1_char_types[] =\n\t{\n\t\t/* NUL   0   0 */   BOOST_CC_CTRL,\n\t\t/* SOH   1   1 */   BOOST_CC_CTRL,\n\t\t/* STX   2   2 */   BOOST_CC_CTRL,\n\t\t/* ETX   3   3 */   BOOST_CC_CTRL,\n\t\t/* EOT   4   4 */   BOOST_CC_CTRL,\n\t\t/* ENQ   5   5 */   BOOST_CC_CTRL,\n\t\t/* ACK   6   6 */   BOOST_CC_CTRL,\n\t\t/* BEL   7   7 */   BOOST_CC_CTRL,\n\t\t/* BS    8   8 */   BOOST_CC_CTRL,\n\t\t/* HT    9   9 */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* NL   10   a */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* VT   11   b */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* NP   12   c */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* CR   13   d */   BOOST_CC_CTRL|BOOST_CC_SPACE,\n\t\t/* SO   14   e */   BOOST_CC_CTRL,\n\t\t/* SI   15   f */   BOOST_CC_CTRL,\n\t\t/* DLE  16  10 */   BOOST_CC_CTRL,\n\t\t/* DC1  17  11 */   BOOST_CC_CTRL,\n\t\t/* DC2  18  12 */   BOOST_CC_CTRL,\n\t\t/* DC3  19  13 */   BOOST_CC_CTRL,\n\t\t/* DC4  20  14 */   BOOST_CC_CTRL,\n\t\t/* NAK  21  15 */   BOOST_CC_CTRL,\n\t\t/* SYN  22  16 */   BOOST_CC_CTRL,\n\t\t/* ETB  23  17 */   BOOST_CC_CTRL,\n\t\t/* CAN  24  18 */   BOOST_CC_CTRL,\n\t\t/* EM   25  19 */   BOOST_CC_CTRL,\n\t\t/* SUB  26  1a */   BOOST_CC_CTRL,\n\t\t/* ESC  27  1b */   BOOST_CC_CTRL,\n\t\t/* FS   28  1c */   BOOST_CC_CTRL,\n\t\t/* GS   29  1d */   BOOST_CC_CTRL,\n\t\t/* RS   30  1e */   BOOST_CC_CTRL,\n\t\t/* US   31  1f */   BOOST_CC_CTRL,\n\t\t/* SP   32  20 */   BOOST_CC_SPACE,\n\t\t/*  !   33  21 */   BOOST_CC_PUNCT,\n\t\t/*  \"   34  22 */   BOOST_CC_PUNCT,\n\t\t/*  #   35  23 */   BOOST_CC_PUNCT,\n\t\t/*  $   36  24 */   BOOST_CC_PUNCT,\n\t\t/*  %   37  25 */   BOOST_CC_PUNCT,\n\t\t/*  &   38  26 */   BOOST_CC_PUNCT,\n\t\t/*  '   39  27 */   BOOST_CC_PUNCT,\n\t\t/*  (   40  28 */   BOOST_CC_PUNCT,\n\t\t/*  )   41  29 */   BOOST_CC_PUNCT,\n\t\t/*  *   42  2a */   BOOST_CC_PUNCT,\n\t\t/*  +   43  2b */   BOOST_CC_PUNCT,\n\t\t/*  ,   44  2c */   BOOST_CC_PUNCT,\n\t\t/*  -   45  2d */   BOOST_CC_PUNCT,\n\t\t/*  .   46  2e */   BOOST_CC_PUNCT,\n\t\t/*  /   47  2f */   BOOST_CC_PUNCT,\n\t\t/*  0   48  30 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  1   49  31 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  2   50  32 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  3   51  33 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  4   52  34 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  5   53  35 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  6   54  36 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  7   55  37 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  8   56  38 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  9   57  39 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,\n\t\t/*  :   58  3a */   BOOST_CC_PUNCT,\n\t\t/*  ;   59  3b */   BOOST_CC_PUNCT,\n\t\t/*  <   60  3c */   BOOST_CC_PUNCT,\n\t\t/*  =   61  3d */   BOOST_CC_PUNCT,\n\t\t/*  >   62  3e */   BOOST_CC_PUNCT,\n\t\t/*  ?   63  3f */   BOOST_CC_PUNCT,\n\t\t/*  @   64  40 */   BOOST_CC_PUNCT,\n\t\t/*  A   65  41 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  B   66  42 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  C   67  43 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  D   68  44 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  E   69  45 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  F   70  46 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,\n\t\t/*  G   71  47 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  H   72  48 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  I   73  49 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  J   74  4a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  K   75  4b */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  L   76  4c */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  M   77  4d */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  N   78  4e */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  O   79  4f */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  P   80  50 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Q   81  51 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  R   82  52 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  S   83  53 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  T   84  54 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  U   85  55 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  V   86  56 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  W   87  57 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  X   88  58 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Y   89  59 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  Z   90  5a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  [   91  5b */   BOOST_CC_PUNCT,\n\t\t/*  \\   92  5c */   BOOST_CC_PUNCT,\n\t\t/*  ]   93  5d */   BOOST_CC_PUNCT,\n\t\t/*  ^   94  5e */   BOOST_CC_PUNCT,\n\t\t/*  _   95  5f */   BOOST_CC_PUNCT,\n\t\t/*  `   96  60 */   BOOST_CC_PUNCT,\n\t\t/*  a   97  61 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  b   98  62 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  c   99  63 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  d  100  64 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  e  101  65 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  f  102  66 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,\n\t\t/*  g  103  67 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  h  104  68 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  i  105  69 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  j  106  6a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  k  107  6b */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  l  108  6c */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  m  109  6d */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  n  110  6e */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  o  111  6f */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  p  112  70 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  q  113  71 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  r  114  72 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  s  115  73 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  t  116  74 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  u  117  75 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  v  118  76 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  w  119  77 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  x  120  78 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  y  121  79 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  z  122  7a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  {  123  7b */   BOOST_CC_PUNCT,\n\t\t/*  |  124  7c */   BOOST_CC_PUNCT,\n\t\t/*  }  125  7d */   BOOST_CC_PUNCT,\n\t\t/*  ~  126  7e */   BOOST_CC_PUNCT,\n\t\t/* DEL 127  7f */   BOOST_CC_CTRL,\n\t\t/* --  128  80 */   BOOST_CC_CTRL,\n\t\t/* --  129  81 */   BOOST_CC_CTRL,\n\t\t/* --  130  82 */   BOOST_CC_CTRL,\n\t\t/* --  131  83 */   BOOST_CC_CTRL,\n\t\t/* --  132  84 */   BOOST_CC_CTRL,\n\t\t/* --  133  85 */   BOOST_CC_CTRL,\n\t\t/* --  134  86 */   BOOST_CC_CTRL,\n\t\t/* --  135  87 */   BOOST_CC_CTRL,\n\t\t/* --  136  88 */   BOOST_CC_CTRL,\n\t\t/* --  137  89 */   BOOST_CC_CTRL,\n\t\t/* --  138  8a */   BOOST_CC_CTRL,\n\t\t/* --  139  8b */   BOOST_CC_CTRL,\n\t\t/* --  140  8c */   BOOST_CC_CTRL,\n\t\t/* --  141  8d */   BOOST_CC_CTRL,\n\t\t/* --  142  8e */   BOOST_CC_CTRL,\n\t\t/* --  143  8f */   BOOST_CC_CTRL,\n\t\t/* --  144  90 */   BOOST_CC_CTRL,\n\t\t/* --  145  91 */   BOOST_CC_CTRL,\n\t\t/* --  146  92 */   BOOST_CC_CTRL,\n\t\t/* --  147  93 */   BOOST_CC_CTRL,\n\t\t/* --  148  94 */   BOOST_CC_CTRL,\n\t\t/* --  149  95 */   BOOST_CC_CTRL,\n\t\t/* --  150  96 */   BOOST_CC_CTRL,\n\t\t/* --  151  97 */   BOOST_CC_CTRL,\n\t\t/* --  152  98 */   BOOST_CC_CTRL,\n\t\t/* --  153  99 */   BOOST_CC_CTRL,\n\t\t/* --  154  9a */   BOOST_CC_CTRL,\n\t\t/* --  155  9b */   BOOST_CC_CTRL,\n\t\t/* --  156  9c */   BOOST_CC_CTRL,\n\t\t/* --  157  9d */   BOOST_CC_CTRL,\n\t\t/* --  158  9e */   BOOST_CC_CTRL,\n\t\t/* --  159  9f */   BOOST_CC_CTRL,\n\t\t/*     160  a0 */   BOOST_CC_SPACE,\n\t\t/*  �  161  a1 */   BOOST_CC_PUNCT,\n\t\t/*  �  162  a2 */   BOOST_CC_PUNCT,\n\t\t/*  �  163  a3 */   BOOST_CC_PUNCT,\n\t\t/*  �  164  a4 */   BOOST_CC_PUNCT,\n\t\t/*  �  165  a5 */   BOOST_CC_PUNCT,\n\t\t/*  �  166  a6 */   BOOST_CC_PUNCT,\n\t\t/*  �  167  a7 */   BOOST_CC_PUNCT,\n\t\t/*  �  168  a8 */   BOOST_CC_PUNCT,\n\t\t/*  �  169  a9 */   BOOST_CC_PUNCT,\n\t\t/*  �  170  aa */   BOOST_CC_PUNCT,\n\t\t/*  �  171  ab */   BOOST_CC_PUNCT,\n\t\t/*  �  172  ac */   BOOST_CC_PUNCT,\n\t\t/*  �  173  ad */   BOOST_CC_PUNCT,\n\t\t/*  �  174  ae */   BOOST_CC_PUNCT,\n\t\t/*  �  175  af */   BOOST_CC_PUNCT,\n\t\t/*  �  176  b0 */   BOOST_CC_PUNCT,\n\t\t/*  �  177  b1 */   BOOST_CC_PUNCT,\n\t\t/*  �  178  b2 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,\n\t\t/*  �  179  b3 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,\n\t\t/*  �  180  b4 */   BOOST_CC_PUNCT,\n\t\t/*  �  181  b5 */   BOOST_CC_PUNCT,\n\t\t/*  �  182  b6 */   BOOST_CC_PUNCT,\n\t\t/*  �  183  b7 */   BOOST_CC_PUNCT,\n\t\t/*  �  184  b8 */   BOOST_CC_PUNCT,\n\t\t/*  �  185  b9 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,\n\t\t/*  �  186  ba */   BOOST_CC_PUNCT,\n\t\t/*  �  187  bb */   BOOST_CC_PUNCT,\n\t\t/*  �  188  bc */   BOOST_CC_PUNCT,\n\t\t/*  �  189  bd */   BOOST_CC_PUNCT,\n\t\t/*  �  190  be */   BOOST_CC_PUNCT,\n\t\t/*  �  191  bf */   BOOST_CC_PUNCT,\n\t\t/*  �  192  c0 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  193  c1 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  194  c2 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  195  c3 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  196  c4 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  197  c5 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  198  c6 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  199  c7 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  200  c8 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  201  c9 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  202  ca */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  203  cb */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  204  cc */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  205  cd */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  206  ce */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  207  cf */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  208  d0 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  209  d1 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  210  d2 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  211  d3 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  212  d4 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  213  d5 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  214  d6 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  215  d7 */   BOOST_CC_PUNCT,\n\t\t/*  �  216  d8 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  217  d9 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  218  da */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  219  db */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  220  dc */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  221  dd */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  222  de */   BOOST_CC_ALPHA|BOOST_CC_UPPER,\n\t\t/*  �  223  df */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  224  e0 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  225  e1 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  226  e2 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  227  e3 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  228  e4 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  229  e5 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  230  e6 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  231  e7 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  232  e8 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  233  e9 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  234  ea */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  235  eb */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  236  ec */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  237  ed */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  238  ee */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  239  ef */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  240  f0 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  241  f1 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  242  f2 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  243  f3 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  244  f4 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  245  f5 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  246  f6 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  247  f7 */   BOOST_CC_PUNCT,\n\t\t/*  �  248  f8 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  249  f9 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  250  fa */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  251  fb */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  252  fc */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  253  fd */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  254  fe */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t\t/*  �  255  ff */   BOOST_CC_ALPHA|BOOST_CC_LOWER,\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// ISO 8859-1 character conversion table\n\t///////////////////////////////////////////////////////////////////////////\n\tconst unsigned char iso8859_1_char_conversion[] =\n\t{\n\t\t/* NUL   0   0 */   '\\0',\n\t\t/* SOH   1   1 */   '\\0',\n\t\t/* STX   2   2 */   '\\0',\n\t\t/* ETX   3   3 */   '\\0',\n\t\t/* EOT   4   4 */   '\\0',\n\t\t/* ENQ   5   5 */   '\\0',\n\t\t/* ACK   6   6 */   '\\0',\n\t\t/* BEL   7   7 */   '\\0',\n\t\t/* BS    8   8 */   '\\0',\n\t\t/* HT    9   9 */   '\\0',\n\t\t/* NL   10   a */   '\\0',\n\t\t/* VT   11   b */   '\\0',\n\t\t/* NP   12   c */   '\\0',\n\t\t/* CR   13   d */   '\\0',\n\t\t/* SO   14   e */   '\\0',\n\t\t/* SI   15   f */   '\\0',\n\t\t/* DLE  16  10 */   '\\0',\n\t\t/* DC1  17  11 */   '\\0',\n\t\t/* DC2  18  12 */   '\\0',\n\t\t/* DC3  19  13 */   '\\0',\n\t\t/* DC4  20  14 */   '\\0',\n\t\t/* NAK  21  15 */   '\\0',\n\t\t/* SYN  22  16 */   '\\0',\n\t\t/* ETB  23  17 */   '\\0',\n\t\t/* CAN  24  18 */   '\\0',\n\t\t/* EM   25  19 */   '\\0',\n\t\t/* SUB  26  1a */   '\\0',\n\t\t/* ESC  27  1b */   '\\0',\n\t\t/* FS   28  1c */   '\\0',\n\t\t/* GS   29  1d */   '\\0',\n\t\t/* RS   30  1e */   '\\0',\n\t\t/* US   31  1f */   '\\0',\n\t\t/* SP   32  20 */   '\\0',\n\t\t/*  !   33  21 */   '\\0',\n\t\t/*  \"   34  22 */   '\\0',\n\t\t/*  #   35  23 */   '\\0',\n\t\t/*  $   36  24 */   '\\0',\n\t\t/*  %   37  25 */   '\\0',\n\t\t/*  &   38  26 */   '\\0',\n\t\t/*  '   39  27 */   '\\0',\n\t\t/*  (   40  28 */   '\\0',\n\t\t/*  )   41  29 */   '\\0',\n\t\t/*  *   42  2a */   '\\0',\n\t\t/*  +   43  2b */   '\\0',\n\t\t/*  ,   44  2c */   '\\0',\n\t\t/*  -   45  2d */   '\\0',\n\t\t/*  .   46  2e */   '\\0',\n\t\t/*  /   47  2f */   '\\0',\n\t\t/*  0   48  30 */   '\\0',\n\t\t/*  1   49  31 */   '\\0',\n\t\t/*  2   50  32 */   '\\0',\n\t\t/*  3   51  33 */   '\\0',\n\t\t/*  4   52  34 */   '\\0',\n\t\t/*  5   53  35 */   '\\0',\n\t\t/*  6   54  36 */   '\\0',\n\t\t/*  7   55  37 */   '\\0',\n\t\t/*  8   56  38 */   '\\0',\n\t\t/*  9   57  39 */   '\\0',\n\t\t/*  :   58  3a */   '\\0',\n\t\t/*  ;   59  3b */   '\\0',\n\t\t/*  <   60  3c */   '\\0',\n\t\t/*  =   61  3d */   '\\0',\n\t\t/*  >   62  3e */   '\\0',\n\t\t/*  ?   63  3f */   '\\0',\n\t\t/*  @   64  40 */   '\\0',\n\t\t/*  A   65  41 */   'a',\n\t\t/*  B   66  42 */   'b',\n\t\t/*  C   67  43 */   'c',\n\t\t/*  D   68  44 */   'd',\n\t\t/*  E   69  45 */   'e',\n\t\t/*  F   70  46 */   'f',\n\t\t/*  G   71  47 */   'g',\n\t\t/*  H   72  48 */   'h',\n\t\t/*  I   73  49 */   'i',\n\t\t/*  J   74  4a */   'j',\n\t\t/*  K   75  4b */   'k',\n\t\t/*  L   76  4c */   'l',\n\t\t/*  M   77  4d */   'm',\n\t\t/*  N   78  4e */   'n',\n\t\t/*  O   79  4f */   'o',\n\t\t/*  P   80  50 */   'p',\n\t\t/*  Q   81  51 */   'q',\n\t\t/*  R   82  52 */   'r',\n\t\t/*  S   83  53 */   's',\n\t\t/*  T   84  54 */   't',\n\t\t/*  U   85  55 */   'u',\n\t\t/*  V   86  56 */   'v',\n\t\t/*  W   87  57 */   'w',\n\t\t/*  X   88  58 */   'x',\n\t\t/*  Y   89  59 */   'y',\n\t\t/*  Z   90  5a */   'z',\n\t\t/*  [   91  5b */   '\\0',\n\t\t/*  \\   92  5c */   '\\0',\n\t\t/*  ]   93  5d */   '\\0',\n\t\t/*  ^   94  5e */   '\\0',\n\t\t/*  _   95  5f */   '\\0',\n\t\t/*  `   96  60 */   '\\0',\n\t\t/*  a   97  61 */   'A',\n\t\t/*  b   98  62 */   'B',\n\t\t/*  c   99  63 */   'C',\n\t\t/*  d  100  64 */   'D',\n\t\t/*  e  101  65 */   'E',\n\t\t/*  f  102  66 */   'F',\n\t\t/*  g  103  67 */   'G',\n\t\t/*  h  104  68 */   'H',\n\t\t/*  i  105  69 */   'I',\n\t\t/*  j  106  6a */   'J',\n\t\t/*  k  107  6b */   'K',\n\t\t/*  l  108  6c */   'L',\n\t\t/*  m  109  6d */   'M',\n\t\t/*  n  110  6e */   'N',\n\t\t/*  o  111  6f */   'O',\n\t\t/*  p  112  70 */   'P',\n\t\t/*  q  113  71 */   'Q',\n\t\t/*  r  114  72 */   'R',\n\t\t/*  s  115  73 */   'S',\n\t\t/*  t  116  74 */   'T',\n\t\t/*  u  117  75 */   'U',\n\t\t/*  v  118  76 */   'V',\n\t\t/*  w  119  77 */   'W',\n\t\t/*  x  120  78 */   'X',\n\t\t/*  y  121  79 */   'Y',\n\t\t/*  z  122  7a */   'Z',\n\t\t/*  {  123  7b */   '\\0',\n\t\t/*  |  124  7c */   '\\0',\n\t\t/*  }  125  7d */   '\\0',\n\t\t/*  ~  126  7e */   '\\0',\n\t\t/* DEL 127  7f */   '\\0',\n\t\t/* --  128  80 */   '\\0',\n\t\t/* --  129  81 */   '\\0',\n\t\t/* --  130  82 */   '\\0',\n\t\t/* --  131  83 */   '\\0',\n\t\t/* --  132  84 */   '\\0',\n\t\t/* --  133  85 */   '\\0',\n\t\t/* --  134  86 */   '\\0',\n\t\t/* --  135  87 */   '\\0',\n\t\t/* --  136  88 */   '\\0',\n\t\t/* --  137  89 */   '\\0',\n\t\t/* --  138  8a */   '\\0',\n\t\t/* --  139  8b */   '\\0',\n\t\t/* --  140  8c */   '\\0',\n\t\t/* --  141  8d */   '\\0',\n\t\t/* --  142  8e */   '\\0',\n\t\t/* --  143  8f */   '\\0',\n\t\t/* --  144  90 */   '\\0',\n\t\t/* --  145  91 */   '\\0',\n\t\t/* --  146  92 */   '\\0',\n\t\t/* --  147  93 */   '\\0',\n\t\t/* --  148  94 */   '\\0',\n\t\t/* --  149  95 */   '\\0',\n\t\t/* --  150  96 */   '\\0',\n\t\t/* --  151  97 */   '\\0',\n\t\t/* --  152  98 */   '\\0',\n\t\t/* --  153  99 */   '\\0',\n\t\t/* --  154  9a */   '\\0',\n\t\t/* --  155  9b */   '\\0',\n\t\t/* --  156  9c */   '\\0',\n\t\t/* --  157  9d */   '\\0',\n\t\t/* --  158  9e */   '\\0',\n\t\t/* --  159  9f */   '\\0',\n\t\t/*     160  a0 */   '\\0',\n\t\t/*  �  161  a1 */   '\\0',\n\t\t/*  �  162  a2 */   '\\0',\n\t\t/*  �  163  a3 */   '\\0',\n\t\t/*  �  164  a4 */   '\\0',\n\t\t/*  �  165  a5 */   '\\0',\n\t\t/*  �  166  a6 */   '\\0',\n\t\t/*  �  167  a7 */   '\\0',\n\t\t/*  �  168  a8 */   '\\0',\n\t\t/*  �  169  a9 */   '\\0',\n\t\t/*  �  170  aa */   '\\0',\n\t\t/*  �  171  ab */   '\\0',\n\t\t/*  �  172  ac */   '\\0',\n\t\t/*  �  173  ad */   '\\0',\n\t\t/*  �  174  ae */   '\\0',\n\t\t/*  �  175  af */   '\\0',\n\t\t/*  �  176  b0 */   '\\0',\n\t\t/*  �  177  b1 */   '\\0',\n\t\t/*  �  178  b2 */   '\\0',\n\t\t/*  �  179  b3 */   '\\0',\n\t\t/*  �  180  b4 */   '\\0',\n\t\t/*  �  181  b5 */   '\\0',\n\t\t/*  �  182  b6 */   '\\0',\n\t\t/*  �  183  b7 */   '\\0',\n\t\t/*  �  184  b8 */   '\\0',\n\t\t/*  �  185  b9 */   '\\0',\n\t\t/*  �  186  ba */   '\\0',\n\t\t/*  �  187  bb */   '\\0',\n\t\t/*  �  188  bc */   '\\0',\n\t\t/*  �  189  bd */   '\\0',\n\t\t/*  �  190  be */   '\\0',\n\t\t/*  �  191  bf */   '\\0',\n\t\t/*  �  192  c0 */   0xe0,\n\t\t/*  �  193  c1 */   0xe1,\n\t\t/*  �  194  c2 */   0xe2,\n\t\t/*  �  195  c3 */   0xe3,\n\t\t/*  �  196  c4 */   0xe4,\n\t\t/*  �  197  c5 */   0xe5,\n\t\t/*  �  198  c6 */   0xe6,\n\t\t/*  �  199  c7 */   0xe7,\n\t\t/*  �  200  c8 */   0xe8,\n\t\t/*  �  201  c9 */   0xe9,\n\t\t/*  �  202  ca */   0xea,\n\t\t/*  �  203  cb */   0xeb,\n\t\t/*  �  204  cc */   0xec,\n\t\t/*  �  205  cd */   0xed,\n\t\t/*  �  206  ce */   0xee,\n\t\t/*  �  207  cf */   0xef,\n\t\t/*  �  208  d0 */   0xf0,\n\t\t/*  �  209  d1 */   0xf1,\n\t\t/*  �  210  d2 */   0xf2,\n\t\t/*  �  211  d3 */   0xf3,\n\t\t/*  �  212  d4 */   0xf4,\n\t\t/*  �  213  d5 */   0xf5,\n\t\t/*  �  214  d6 */   0xf6,\n\t\t/*  �  215  d7 */   '\\0',\n\t\t/*  �  216  d8 */   0xf8,\n\t\t/*  �  217  d9 */   0xf9,\n\t\t/*  �  218  da */   0xfa,\n\t\t/*  �  219  db */   0xfb,\n\t\t/*  �  220  dc */   0xfc,\n\t\t/*  �  221  dd */   0xfd,\n\t\t/*  �  222  de */   0xfe,\n\t\t/*  �  223  df */   '\\0',\n\t\t/*  �  224  e0 */   0xc0,\n\t\t/*  �  225  e1 */   0xc1,\n\t\t/*  �  226  e2 */   0xc2,\n\t\t/*  �  227  e3 */   0xc3,\n\t\t/*  �  228  e4 */   0xc4,\n\t\t/*  �  229  e5 */   0xc5,\n\t\t/*  �  230  e6 */   0xc6,\n\t\t/*  �  231  e7 */   0xc7,\n\t\t/*  �  232  e8 */   0xc8,\n\t\t/*  �  233  e9 */   0xc9,\n\t\t/*  �  234  ea */   0xca,\n\t\t/*  �  235  eb */   0xcb,\n\t\t/*  �  236  ec */   0xcc,\n\t\t/*  �  237  ed */   0xcd,\n\t\t/*  �  238  ee */   0xce,\n\t\t/*  �  239  ef */   0xcf,\n\t\t/*  �  240  f0 */   0xd0,\n\t\t/*  �  241  f1 */   0xd1,\n\t\t/*  �  242  f2 */   0xd2,\n\t\t/*  �  243  f3 */   0xd3,\n\t\t/*  �  244  f4 */   0xd4,\n\t\t/*  �  245  f5 */   0xd5,\n\t\t/*  �  246  f6 */   0xd6,\n\t\t/*  �  247  f7 */   '\\0',\n\t\t/*  �  248  f8 */   0xd8,\n\t\t/*  �  249  f9 */   0xd9,\n\t\t/*  �  250  fa */   0xda,\n\t\t/*  �  251  fb */   0xdb,\n\t\t/*  �  252  fc */   0xdc,\n\t\t/*  �  253  fd */   0xdd,\n\t\t/*  �  254  fe */   0xde,\n\t\t/*  �  255  ff */   '\\0',\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Test characters for specified conditions (using iso8859-1)\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct iso8859_1\n\t{\n\t\ttypedef unsigned char char_type;\n\t\ttypedef unsigned char classify_type;\n\n\t\tstatic bool\n\t\tisascii_(int ch)\n\t\t{\n\t\t\treturn 0 == (ch & ~0x7f);\n\t\t}\n\n\t\tstatic bool\n\t\tischar(int ch)\n\t\t{\n\t\t\t// iso8859.1 uses all 8 bits\n\t\t\t// we have to watch out for sign extensions\n\t\t\treturn (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) != 0;\n\t\t}\n\n\t\t// *** Note on assertions: The precondition is that the calls to\n\t\t// these functions do not violate the required range of ch (type int)\n\t\t// which is that strict_ischar(ch) should be true. It is the\n\t\t// responsibility of the caller to make sure this precondition is not\n\t\t// violated.\n\n\t\tstatic bool\n\t\tstrict_ischar(int ch)\n\t\t{\n\t\t\treturn ch >= 0 && ch <= 255;\n\t\t}\n\n\t\tstatic bool\n\t\tisalnum(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_ALPHA)\n\t\t\t\t|| (iso8859_1_char_types[ch] & BOOST_CC_DIGIT);\n\t\t}\n\n\t\tstatic bool\n\t\tisalpha(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_ALPHA) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_DIGIT) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisxdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_XDIGIT) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tiscntrl(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_CTRL) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisgraph(int ch)\n\t\t{\n\t\t\treturn ('\\x21' <= ch && ch <= '\\x7e') || ('\\xa1' <= ch && ch <= '\\xff');\n\t\t}\n\n\t\tstatic bool\n\t\tislower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_LOWER) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisprint(int ch)\n\t\t{\n\t\t\treturn ('\\x20' <= ch && ch <= '\\x7e') || ('\\xa0' <= ch && ch <= '\\xff');\n\t\t}\n\n\t\tstatic bool\n\t\tispunct(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_PUNCT) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisspace(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_SPACE) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ('\\x09' == ch || '\\x20' == ch || '\\xa0' == ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (iso8859_1_char_types[ch] & BOOST_CC_UPPER) != 0;\n\t\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Simple character conversions\n\t///////////////////////////////////////////////////////////////////////////\n\n\t\tstatic int\n\t\ttolower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn isupper(ch) && '\\0' != iso8859_1_char_conversion[ch] ?\n\t\t\t\tiso8859_1_char_conversion[ch] : ch;\n\t\t}\n\n\t\tstatic int\n\t\ttoupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn islower(ch) && '\\0' != iso8859_1_char_conversion[ch] ?\n\t\t\t\tiso8859_1_char_conversion[ch] : ch;\n\t\t}\n\n\t\tstatic ::boost::uint32_t\n\t\ttoucs4(int ch)\n\t\t{\n\t\t\t// The first 256 characters in Unicode and the UCS are\n\t\t\t// identical to those in ISO/IEC-8859-1.\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ch;\n\t\t}\n\t};\n\n}}}\n\n///////////////////////////////////////////////////////////////////////////////\n// undefine macros\n///////////////////////////////////////////////////////////////////////////////\n#undef BOOST_CC_DIGIT\n#undef BOOST_CC_XDIGIT\n#undef BOOST_CC_ALPHA\n#undef BOOST_CC_CTRL\n#undef BOOST_CC_LOWER\n#undef BOOST_CC_UPPER\n#undef BOOST_CC_PUNCT\n#undef BOOST_CC_SPACE\n\n#endif\n\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/standard.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_STANDARD_APRIL_26_2006_1106PM)\n#define BOOST_SPIRIT_STANDARD_APRIL_26_2006_1106PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <cctype>\n#include <climits>\n#include <boost/assert.hpp>\n#include <boost/cstdint.hpp>\n\nnamespace boost { namespace spirit { namespace char_encoding\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Test characters for specified conditions (using std functions)\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct standard\n\t{\n\t\ttypedef char char_type;\n\t\ttypedef unsigned char classify_type;\n\n\t\tstatic bool\n\t\tisascii_(int ch)\n\t\t{\n\t\t\treturn 0 == (ch & ~0x7f);\n\t\t}\n\n\t\tstatic bool\n\t\tischar(int ch)\n\t\t{\n\t\t\t// uses all 8 bits\n\t\t\t// we have to watch out for sign extensions\n\t\t\treturn (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) != 0;\n\t\t}\n\n\t\t// *** Note on assertions: The precondition is that the calls to\n\t\t// these functions do not violate the required range of ch (int)\n\t\t// which is that strict_ischar(ch) should be true. It is the\n\t\t// responsibility of the caller to make sure this precondition is not\n\t\t// violated.\n\n\t\tstatic bool\n\t\tstrict_ischar(int ch)\n\t\t{\n\t\t\t// ch should be representable as an unsigned char\n\t\t\treturn ch >= 0 && ch <= UCHAR_MAX;\n\t\t}\n\n\t\tstatic bool\n\t\tisalnum(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isalnum(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisalpha(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isalpha(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isdigit(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisxdigit(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isxdigit(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tiscntrl(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::iscntrl(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisgraph(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isgraph(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tislower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::islower(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisprint(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isprint(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tispunct(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::ispunct(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisspace(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isspace(ch) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn (ch == ' ' || ch == '\\t');\n\t\t}\n\n\t\tstatic bool\n\t\tisupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::isupper(ch) != 0;\n\t\t}\n\n\t///////////////////////////////////////////////////////////////////////////////\n\t//  Simple character conversions\n\t///////////////////////////////////////////////////////////////////////////////\n\n\t\tstatic int\n\t\ttolower(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::tolower(ch);\n\t\t}\n\n\t\tstatic int\n\t\ttoupper(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn std::toupper(ch);\n\t\t}\n\n\t\tstatic ::boost::uint32_t\n\t\ttoucs4(int ch)\n\t\t{\n\t\t\tBOOST_ASSERT(strict_ischar(ch));\n\t\t\treturn ch;\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/standard_wide.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM)\n#define BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <cwctype>\n#include <string>\n\n#include <boost/assert.hpp>\n#include <boost/cstdint.hpp>\n#include \"../assert_msg.hpp\"\n\n#include <boost/type_traits/make_unsigned.hpp>\n\nnamespace boost { namespace spirit { namespace traits\n{\n\ttemplate <std::size_t N>\n\tstruct wchar_t_size\n\t{\n\t\tBOOST_SPIRIT_ASSERT_MSG(N == 1 || N == 2 || N == 4,\n\t\t\tnot_supported_size_of_wchar_t, ());\n\t};\n\n\ttemplate <> struct wchar_t_size<1> { enum { mask = 0xff }; };\n\ttemplate <> struct wchar_t_size<2> { enum { mask = 0xffff }; };\n\ttemplate <> struct wchar_t_size<4> { enum { mask = 0xffffffff }; };\n\n}}}\n\nnamespace boost { namespace spirit { namespace char_encoding\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Test characters for specified conditions (using std wchar_t functions)\n\t///////////////////////////////////////////////////////////////////////////\n\n\tstruct standard_wide\n\t{\n\t\ttypedef wchar_t char_type;\n\t\ttypedef wchar_t classify_type;\n\n\t\ttemplate <typename Char>\n\t\tstatic typename std::char_traits<Char>::int_type\n\t\tto_int_type(Char ch)\n\t\t{\n\t\t\treturn std::char_traits<Char>::to_int_type(ch);\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tstatic Char\n\t\tto_char_type(typename std::char_traits<Char>::int_type ch)\n\t\t{\n\t\t\treturn std::char_traits<Char>::to_char_type(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tischar(int ch)\n\t\t{\n\t\t\t// we have to watch out for sign extensions (casting is there to\n\t\t\t// silence certain compilers complaining about signed/unsigned\n\t\t\t// mismatch)\n\t\t\treturn (\n\t\t\t\tstd::size_t(0) ==\n\t\t\t\t\tstd::size_t(ch & ~traits::wchar_t_size<sizeof(wchar_t)>::mask) ||\n\t\t\t\tstd::size_t(~0) ==\n\t\t\t\t\tstd::size_t(ch | traits::wchar_t_size<sizeof(wchar_t)>::mask)\n\t\t\t) != 0;     // any wchar_t, but no other bits set\n\t\t}\n\n\t\tstatic bool\n\t\tisalnum(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswalnum(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisalpha(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswalpha(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tiscntrl(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswcntrl(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisdigit(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswdigit(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisgraph(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswgraph(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tislower(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswlower(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisprint(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswprint(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tispunct(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswpunct(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisspace(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswspace(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisupper(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswupper(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisxdigit(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn iswxdigit(to_int_type(ch)) != 0;\n\t\t}\n\n\t\tstatic bool\n\t\tisblank BOOST_PREVENT_MACRO_SUBSTITUTION (wchar_t ch)\n\t\t{\n\t\t\treturn (ch == L' ' || ch == L'\\t');\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t//  Simple character conversions\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\tstatic wchar_t\n\t\ttolower(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn isupper(ch) ?\n\t\t\t\tto_char_type<wchar_t>(towlower(to_int_type(ch))) : ch;\n\t\t}\n\n\t\tstatic wchar_t\n\t\ttoupper(wchar_t ch)\n\t\t{\n\t\t\tusing namespace std;\n\t\t\treturn islower(ch) ?\n\t\t\t\tto_char_type<wchar_t>(towupper(to_int_type(ch))) : ch;\n\t\t}\n\n\t\tstatic ::boost::uint32_t\n\t\ttoucs4(wchar_t ch)\n\t\t{\n\t\t\treturn static_cast<make_unsigned<wchar_t>::type>(ch);\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode/category_table.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n\n\tAUTOGENERATED. DO NOT EDIT!!!\n==============================================================================*/\n#include <boost/cstdint.hpp>\n\nnamespace boost { namespace spirit { namespace ucd { namespace detail\n{\n\tstatic const ::boost::uint8_t category_stage1[] = {\n\n\t  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15, \n\t 16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31, \n\t 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  34,  42,  43,  44,  45,  46, \n\t 47,  48,  49,  40,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  50,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 51,  21,  21,  21,  52,  21,  53,  54,  55,  56,  57,  58,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  59,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  21,  62,  63,  21,  64,  65,  66, \n\t 67,  68,  69,  70,  71,  72,  21,  73,  74,  75,  76,  77,  78,  79,  80,  81, \n\t 82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97, \n\t 21,  21,  21,  98,  99, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, \n\t 21,  21,  21,  21, 103, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101,  21,  21, 104, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101,  21,  21, 105, 106, 101, 101, 107, 108, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21, 109,  21,  21,  21,  21, 110, 111, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 112, \n\t 21, 113, 114, 101, 101, 101, 101, 101, 101, 101, 101, 101, 115, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 116, \n\t117, 118, 119, 120, 121, 122, 123, 124,  40,  40, 125, 101, 101, 101, 101, 126, \n\t127, 128, 129, 101, 130, 101, 101, 131, 132, 133, 101, 101, 134, 135, 136, 101, \n\t137, 138, 139, 140,  40,  40, 141, 142, 143,  40, 144, 145, 101, 101, 101, 146, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21, 147,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21, 148, 149,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, 150,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, 151, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101,  21,  21, 152, 101, 101, 101, 101, 146, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21, 153,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21, 154, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t155, 156, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 146, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, 158, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, 158\n\t};\n\n\tstatic const ::boost::uint16_t category_stage2[] = {\n\n\t// block 0\n\t  32,   32,   32,   32,   32,   32,   32,   32,   32,  544,  544,  544,  544,  544,   32,   32, \n\t  32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32, \n\t 536,   44,   44,   44,   49,   44,   44,   44,   41,   42,   44,   48,   44,   40,   44,   44, \n\t1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,   44,   44,   48,   48,   48,   44, \n\t  44, 1216, 1216, 1216, 1216, 1216, 1216,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   41,   44,   42,   50,   43, \n\t  50, 1345, 1345, 1345, 1345, 1345, 1345,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   41,   48,   42,   48,   32, \n\t  32,   32,   32,   32,   32,  544,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32, \n\t  32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32,   32, \n\t 536,   44,   49,   49,   49,   49,   51,   44,   50,   51,  324,   45,   48, 4129,   51,   50, \n\t  51,   48,   18,   18,   50,  321,   44,   44,   50,   18,  324,   46,   18,   18,   18,   44, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,   48,  192,  192,  192,  192,  192,  192,  192,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,   48,  321,  321,  321,  321,  321,  321,  321,  321, \n\n\n\t// block 1\n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  321,  192,  321,  192,  321,  192,  321,  192, \n\t 321,  192,  321,  192,  321,  192,  321,  192,  321,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  192,  321,  192,  321,  192,  321,  321, \n\t 321,  192,  192,  321,  192,  321,  192,  192,  321,  192,  192,  192,  321,  321,  192,  192, \n\t 192,  192,  321,  192,  192,  321,  192,  192,  192,  321,  321,  321,  192,  192,  321,  192, \n\t 192,  321,  192,  321,  192,  321,  192,  192,  321,  192,  321,  321,  192,  321,  192,  192, \n\t 321,  192,  192,  192,  321,  192,  321,  192,  192,  321,  321,   68,  192,  321,  321,  321, \n\t  68,   68,   68,   68,  192,   66,  321,  192,   66,  321,  192,   66,  321,  192,  321,  192, \n\t 321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 321,  192,   66,  321,  192,  321,  192,  192,  192,  321,  192,  321,  192,  321,  192,  321, \n\n\n\t// block 2\n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  321,  321,  321,  321,  321,  321,  192,  192,  321,  192,  192,  321, \n\t 321,  192,  321,  192,  192,  192,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,   68,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,   67,   67,   67,   67,   67,   67,   67, \n\t 323,  323,   50,   50,   50,   50,   67,   67,   67,   67,   67,   67,   67,   67,   67,   67, \n\t  67,   67,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50, \n\t 323,  323,  323,  323,  323,   50,   50,   50,   50,   50,   50,   50,   67,   50,   67,   50, \n\t  50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50, \n\n\n\t// block 3\n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,  328,    8,    8,    8,    8,    8,    8,    8,    8,    8, 4104, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t 192,  321,  192,  321,   67,   50,  192,  321,   36,   36,  323,  321,  321,  321,   44,  192, \n\t  36,   36,   36,   36,   50,   50,  192,   44,  192,  192,  192,   36,  192,   36,  192,  192, \n\t 321,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,   36,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  192, \n\t 321,  321,  192,  192,  192,  321,  321,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 321,  321,  321,  321,  192,  321,   48,  192,  321,  192,  192,  321,  321,  192,  192,  192, \n\n\n\t// block 4\n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,   51,    8,    8,    8,    8,    8,    9,    9,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\n\n\t// block 5\n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t  36,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,   36,   36,   67,   44,   44,   44,   44,   44,   44, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,   44,   40,   36,   36,   51,   51,   49, \n\t  36,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   40,   72, \n\t  44,   72,   72,   44,   72,   72,   44,   72,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   68, \n\t  68,   68,   68,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 6\n\t  33,   33,   33,   33,   33,   33,   48,   48,   48,   44,   44,   49,   44,   44,   51,   51, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   44, 4129,   44,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  67,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,    8,   72,   72,   72,   72,   72,   72,   72, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   44,   44,   44,   44,   68,   68, \n\t  72,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   44,   68,   72,   72,   72,   72,   72,   72,   72,   33,   51,    8, \n\t   8,   72,   72,   72,   72,   67,   67,   72,   72,   51,    8,    8,    8,   72,   68,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   51,   51,   68, \n\n\n\t// block 7\n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   36,   33, \n\t  68,   72,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,   36,   36,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,   67,   67,   51,   44,   44,   44,   67,   36,   36,    8,   49,   49, \n\n\n\t// block 8\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   72,   72,    8,    8,   67,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   67,   72,   72,   72,   67,   72,   72,   72,   72,    8,   36,   36, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,    8,    8,    8,   36,   36,   44,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   50,   68,   68,   68,   68,   68,   68,   36, \n\t  33,   33,   36,   36,   36,   36,   36,   36,    8,    8,    8,    8,    8,    8,    8,    8, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   67,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t   8,    8,   33,   72,   72,   72,   72,   72,   72,   72,    8,    8,    8,    8,    8,    8, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\n\n\t// block 9\n\t  72,   72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   74,    8,   68,   74,   74, \n\t  74,   72,   72,   72,   72,   72,   72,   72,   72,   74,   74,   74,   74,    8,   74,   74, \n\t  68,    8,    8,    8,    8,   72,   72,   72,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   72,   72,   44,   44,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  44,   67,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   72,   74,   74,   36,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   68, \n\t  68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   36,   36,   36,   68,   68,   68,   68,   36,   36,    8,   68,   74,   74, \n\t  74,   72,   72,   72,   72,   36,   36,   74,   74,   36,   36,   74,   74,    8,   68,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   74,   36,   36,   36,   36,   68,   68,   36,   68, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  68,   68,   49,   49,   18,   18,   18,   18,   18,   18,   51,   49,   68,   44,    8,   36, \n\n\n\t// block 10\n\t  36,   72,   72,   74,   36,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   68, \n\t  68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   36,   68,   68,   36,   68,   68,   36,   36,    8,   36,   74,   74, \n\t  74,   72,   72,   36,   36,   36,   36,   72,   72,   36,   36,   72,   72,    8,   36,   36, \n\t  36,   72,   36,   36,   36,   36,   36,   36,   36,   68,   68,   68,   68,   36,   68,   36, \n\t  36,   36,   36,   36,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  72,   72,   68,   68,   68,   72,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   72,   72,   74,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68, \n\t  68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   36,   36,    8,   68,   74,   74, \n\t  74,   72,   72,   72,   72,   72,   36,   72,   72,   74,   36,   74,   74,    8,   36,   36, \n\t  68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  44,   49,   36,   36,   36,   36,   36,   36,   36,   68,   72,   72,   72,    8,    8,    8, \n\n\n\t// block 11\n\t  36,   72,   74,   74,   36,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   68, \n\t  68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   36,   36,    8,   68,   74,   72, \n\t  74,   72,   72,   72,   72,   36,   36,   74,   74,   36,   36,   74,   74,    8,   36,   36, \n\t  36,   36,   36,   36,   36,    8,   72,   74,   36,   36,   36,   36,   68,   68,   36,   68, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  51,   68,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   72,   68,   36,   68,   68,   68,   68,   68,   68,   36,   36,   36,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   36,   36,   36,   68,   68,   36,   68,   36,   68,   68, \n\t  36,   36,   36,   68,   68,   36,   36,   36,   68,   68,   68,   36,   36,   36,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   74,   74, \n\t  72,   74,   74,   36,   36,   36,   74,   74,   74,   36,   74,   74,   74,    8,   36,   36, \n\t  68,   36,   36,   36,   36,   36,   36,   74,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  18,   18,   18,   51,   51,   51,   51,   51,   51,   49,   51,   36,   36,   36,   36,   36, \n\n\n\t// block 12\n\t  72,   74,   74,   74,   72,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,    8,   68,   72,   72, \n\t  72,   74,   74,   74,   74,   36,   72,   72,   72,   36,   72,   72,   72,    8,   36,   36, \n\t  36,   36,   36,   36,   36,   72,   72,   36,   68,   68,   68,   36,   36,   68,   36,   36, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  36,   36,   36,   36,   36,   36,   36,   44,   18,   18,   18,   18,   18,   18,   18,   51, \n\t  68,   72,   74,   74,   44,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   36,   36,    8,   68,   74,   72, \n\t  74,   74,   74,   74,   74,   36,   72,   74,   74,   36,   74,   74,   72,    8,   36,   36, \n\t  36,   36,   36,   36,   36,   74,   74,   36,   36,   36,   36,   36,   36,   68,   68,   36, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  36,   68,   68,   74,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 13\n\t  72,   72,   74,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,    8,    8,   68,   74,   74, \n\t  74,   72,   72,   72,   72,   36,   74,   74,   74,   36,   74,   74,   74,    8,   68,   51, \n\t  36,   36,   36,   36,   68,   68,   68,   74,   18,   18,   18,   18,   18,   18,   18,   68, \n\t  68,   68,   72,   72,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   68,   68,   68,   68,   68,   68, \n\t  36,   72,   74,   74,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,    8,   36,   36,   36,   36,   74, \n\t  74,   74,   72,   72,   72,   36,   72,   36,   74,   74,   74,   74,   74,   74,   74,   74, \n\t  36,   36,   36,   36,   36,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  36,   36,   74,   74,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 14\n\t  36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   72,   68,   68,   72,   72,   72,   72,   72,   72,   72,   36,   36,   36,   36,   49, \n\t  68,   68,   68,   68,   68,   68,   67,    8,    8,    8,    8,    8,    8,   72,    8,   44, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   44,   44,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   68,   68,   36,   68,   36,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   72,   68,   68,   72,   72,   72,   72,   72,   72,    8,   72,   72,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   36,   67,   36,    8,    8,    8,    8,    8,   72,    8,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   68,   68,   68,   68, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 15\n\t  68,   51,   51,   51,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44, \n\t  44,   44,   44,   51,   44,   51,   51,   51,    8,    8,   51,   51,   51,   51,   51,   51, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   51,    8,   51,    8,   51,    8,   41,   42,   41,   42,   10,   10, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  36,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   74, \n\t  72,   72,   72,   72,    8,   44,    8,    8,   68,   68,   68,   68,   68,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   36,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   36,   51,   51, \n\t  51,   51,   51,   51,   51,   51,    8,   51,   51,   51,   51,   51,   51,   36,   51,   51, \n\t  44,   44,   44,   44,   44,   51,   51,   51,   51,   44,   44,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 16\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74,   74,   72,   72,   72, \n\t  72,   74,   72,   72,   72,   72,   72,    8,   74,    8,    8,   74,   74,   72,   72,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   44,   44,   44,   44,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   74,   74,   72,   72,   68,   68,   68,   68,   72,   72, \n\t  72,   68,   74,   74,   74,   68,   68,   74,   74,   74,   74,   74,   74,   74,   68,   68, \n\t  68,   72,   72,   72,   72,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   72,   74,   74,   72,   72,   74,   74,   74,   74,   74,   74,   72,   68,   74, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   74,   74,   74,   72,   51,   51, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,   36,  192,   36,   36,   36,   36,   36,  192,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   44,  323,  321,  321,  321, \n\n\n\t// block 17\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, 4164, \n\t4164,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 18\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   36,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  68,   36,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 19\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,    8,    8,    8, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,   36,   36,  321,  321,  321,  321,  321,  321,   36,   36, \n\n\n\t// block 20\n\t  40,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 21\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 22\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   51,   44,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t 536,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   41,   42,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   44,   44,   44,   81,   81, \n\t  81,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 23\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   72,   72,    8,   10,   36,   36,   36,   36,   36,   36,   36,   36,   36,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   72,   72,   10,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   72,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68, \n\t  68,   36,   72,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68, 4104, 4104,   74,   72,   72,   72,   72,   72,   72,   72,   74,   74, \n\t  74,   74,   74,   74,   74,   74,   72,   74,   74,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,   44,   44,   44,   67,   44,   44,   44,   49,   68,    8,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 24\n\t  44,   44,   44,   44,   44,   44,   40,   44,   44,   44,   44, 4104, 4104, 4104, 4129, 4104, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   67,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   72,   72,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   68,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 25\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  72,   72,   72,   74,   74,   74,   74,   72,   72,   74,   74,   74,   36,   36,   36,   36, \n\t  74,   74,   72,   74,   74,   74,   74,   74,   74,    8,    8,    8,   36,   36,   36,   36, \n\t  51,   36,   36,   36,   44,   44,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   18,   36,   36,   36,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 26\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   72,   72,   74,   74,   72,   36,   36,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   74,   72,   74,   72,   72,   72,   72,   72,   72,   72,   36, \n\t   8,   74,   72,   74,   74,   72,   72,   72,   72,   72,   72,   72,   72,   74,   74,   74, \n\t  74,   74,   74,   72,   72,    8,    8,    8,    8,    8,    8,    8,    8,   36,   36,    8, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  44,   44,   44,   44,   44,   44,   44,   67,   44,   44,   44,   44,   44,   44,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    9,   72, \n\t  72,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,   72,   72,   72,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 27\n\t  72,   72,   72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,    8,   74,   72,   72,   72,   72,   72,   74,   72,   74,   74,   74, \n\t  74,   74,   72,   74,   10,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   44,   44,   44,   44,   44,   44, \n\t  44,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,   51,   51,   51,   51,   51,   51,   51,   51,   51,   44,   44,   36, \n\t  72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   74,   72,   72,   72,   72,   74,   74,   72,   72,   10,    8,   72,   72,   68,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,    8,   74,   72,   72,   74,   74,   74,   72,   74,   72, \n\t  72,   72,   10,   10,   36,   36,   36,   36,   36,   36,   36,   36,   44,   44,   44,   44, \n\n\n\t// block 28\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   74,   74,   74,   74,   74,   74,   74,   74,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   74,   74,   72,    8,   36,   36,   36,   44,   44,   44,   44,   44, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   68,   68,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   67,   67,   67,   67,   67,   67,   44,   44, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,   36,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   36,   36,  192,  192,  192, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36, \n\t   8,    8,    8,   44,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,   10,    8,    8,    8,    8,    8,    8,    8,   68,   68,   68,   68,    8,   68,   68, \n\t  68,   68,   68,   68,    8,   68,   68,   10,    8,    8,   68,   36,   36,   36,   36,   36, \n\n\n\t// block 29\n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  323,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\n\n\t// block 30\n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\n\n\t// block 31\n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,   36,   36,  192,  192,  192,  192,  192,  192,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,   36,   36,  192,  192,  192,  192,  192,  192,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,   36,  192,   36,  192,   36,  192,   36,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,   66,   66,   66,   66,   66,   66,   66,   66, \n\t 321,  321,  321,  321,  321,  321,  321,  321,   66,   66,   66,   66,   66,   66,   66,   66, \n\t 321,  321,  321,  321,  321,  321,  321,  321,   66,   66,   66,   66,   66,   66,   66,   66, \n\t 321,  321,  321,  321,  321,   36,  321,  321,  192,  192,  192,  192,   66,   50,  321,   50, \n\t  50,   50,  321,  321,  321,   36,  321,  321,  192,  192,  192,  192,   66,   50,   50,   50, \n\t 321,  321,  321,  321,   36,   36,  321,  321,  192,  192,  192,  192,   36,   50,   50,   50, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,   50,   50,   50, \n\t  36,   36,  321,  321,  321,   36,  321,  321,  192,  192,  192,  192,   66,   50,   50,   36, \n\n\n\t// block 32\n\t 536,  536,  536,  536,  536,  536,  536,  536,  536,  536,  536, 4129, 4129, 4129, 4129, 4129, \n\t  40,   40,   40,   40,   40,   40,   44,   44,   45,   46,   41,   45,   45,   46,   41,   45, \n\t  44,   44,   44,   44,   44,   44,   44,   44,  537,  538, 4129, 4129, 4129, 4129, 4129,  536, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   45,   46,   44,   44,   44,   44,   43, \n\t  43,   44,   44,   44,   48,   41,   42,   44,   44,   44,   44,   44,   44,   44,   44,   44, \n\t  44,   44,   48,   44,   43,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,  536, \n\t4129, 4129, 4129, 4129, 4129, 4132, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t  18,  323,   36,   36,   18,   18,   18,   18,   18,   18,   48,   48,   48,   41,   42,  323, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   48,   48,   48,   41,   42,   36, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,   36,   36,   36, \n\t  49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49, \n\t  49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,   49, \n\t  49,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    9,    9,    9, \n\t   9,    8,    9,    9,    9,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 33\n\t  51,   51,  192,   51,   51,   51,   51,  192,   51,   51,  321,  192,  192,  192,  321,  321, \n\t 192,  192,  192,  321,   51,  192,   51,   51,   48,  192,  192,  192,  192,  192,   51,   51, \n\t  51,   51,   51,   51,  192,   51,  192,   51,  192,   51,  192,  192,  192,  192,   51,  321, \n\t 192,  192,  192,  192,  321,   68,   68,   68,   68,  321,   51,   51,  321,  321,  192,  192, \n\t  48,   48,   48,   48,   48,  192,  321,  321,  321,  321,   51,   48,   51,   51,  321,   51, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t 209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209,  209, \n\t 337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337,  337, \n\t  81,   81,   81,  192,  321,   81,   81,   81,   81,   18,   51,   51,   36,   36,   36,   36, \n\t  48,   48,   48,   48,   48,   51,   51,   51,   51,   51,   48,   48,   51,   51,   51,   51, \n\t  48,   51,   51,   48,   51,   51,   48,   51,   51,   51,   51,   51,   51,   51,   48,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   48,   48, \n\t  51,   51,   48,   51,   48,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\n\n\t// block 34\n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\n\n\t// block 35\n\t  51,   51,   51,   51,   51,   51,   51,   51,   41,   42,   41,   42,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  48,   48,   51,   51,   51,   51,   51,   51,   51,   41,   42,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   48,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   48,   48,   48,   48, \n\t  48,   48,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 36\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243, \n\t 371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371,  371, \n\t 371,  371,  371,  371,  371,  371,  371,  371,  371,  371,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\n\n\t// block 37\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   48,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   48,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   48,   48,   48,   48,   48,   48,   48,   48, \n\n\n\t// block 38\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   48, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 39\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   41,   42,   41,   42,   41,   42,   41,   42, \n\t  41,   42,   41,   42,   41,   42,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  48,   48,   48,   48,   48,   41,   42,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   41,   42,   41,   42,   41,   42,   41,   42,   41,   42, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\n\n\t// block 40\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 41\n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   41,   42,   41,   42,   41,   42,   41,   42,   41,   42,   41,   42,   41, \n\t  42,   41,   42,   41,   42,   41,   42,   41,   42,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   41,   42,   41,   42,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   41,   42,   48,   48, \n\n\n\t// block 42\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48,   48, \n\t  48,   48,   48,   48,   48,   51,   51,   48,   48,   48,   48,   48,   48,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   36,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 43\n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 192,  321,  192,  192,  192,  321,  321,  192,  321,  192,  321,  192,  321,  192,  192,  192, \n\t 192,  321,  192,  321,  321,  192,  321,  321,  321,  321,  321,  321,  323,  323,  192,  192, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  321,   51,   51,   51,   51,   51,   51,  192,  321,  192,  321,    8, \n\t   8,    8,  192,  321,   36,   36,   36,   36,   36,   44,   44,   44,   44,   18,   44,   44, \n\n\n\t// block 44\n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,   36,  321,   36,   36,   36,   36,   36,  321,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   67, \n\t  44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,    8, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\n\n\t// block 45\n\t  44,   44,   45,   46,   45,   46,   44,   44,   44,   45,   46,   44,   45,   46,   44,   44, \n\t  44,   44,   44,   44,   44,   44,   44,   40,   44,   44,   40,   44,   45,   46,   44,   44, \n\t  45,   46,   41,   42,   41,   42,   41,   42,   41,   42,   44,   44,   44,   44,   44,   67, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   40,   40,   44,   44,   44,   44, \n\t  40,   44,   41,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44, \n\t  51,   51,   44,   44,   44,   41,   42,   41,   42,   41,   42,   41,   42,   40,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 46\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\n\n\t// block 47\n\t 536,   44,   44,   44,   51,   67,   68,   81,   41,   42,   41,   42,   41,   42,   41,   42, \n\t  41,   42,   51,   51,   41,   42,   41,   42,   41,   42,   41,   42,   40,   41,   42,   42, \n\t  51,   81,   81,   81,   81,   81,   81,   81,   81,   81,    8,    8,    8,    8,   10,   10, \n\t  40,   67,   67,   67,   67,   67,   51,   51,   81,   81,   81,   67,   68,   44,   51,   51, \n\t  36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,    8,    8,   50,   50,   67,   67,   68, \n\t  40,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   44,   67,   67,   67,   68, \n\n\n\t// block 48\n\t  36,   36,   36,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68, 4164,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  51,   51,   18,   18,   18,   18,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 49\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  51,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 50\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 51\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   67,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 52\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   67,   67,   67,   67,   67,   67,   44,   44, \n\n\n\t// block 53\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   67,   44,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,   68,    8, \n\t   9,    9,    9,   44,   72,   72,   72,   72,   72,   72,   72,   72,    8,    8,   44,   67, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  323,  323,   72,   72, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t   8,    8,   44,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 54\n\t  50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50, \n\t  50,   50,   50,   50,   50,   50,   50,   67,   67,   67,   67,   67,   67,   67,   67,   67, \n\t  50,   50,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 321,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 323,  321,  321,  321,  321,  321,  321,  321,  321,  192,  321,  192,  321,  192,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,   67,   50,   50,  192,  321,  192,  321,   68, \n\t 192,  321,  192,  321,  321,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  192,  192,  192,  192,  321, \n\t 192,  192,  192,  192,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321,  192,  321, \n\t 192,  321,  192,  321,  192,  192,  192,  192,  321,  192,  321,   36,   36,   36,   36,   36, \n\t 192,  321,   36,  321,   36,  321,  192,  321,  192,  321,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,  323,  323,  323,  192,  321,   68,  323,  323,  321,   68,   68,   68,   68,   68, \n\n\n\t// block 55\n\t  68,   68,   72,   68,   68,   68,    8,   68,   68,   68,   68,   72,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   74,   74,   72,   72,   74,   51,   51,   51,   51,    8,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   51,   51,   49,   51,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  74,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74, \n\t  74,   74,   74,   74,    8,   72,   36,   36,   36,   36,   36,   36,   36,   36,   44,   44, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,   68,   68,   68,   68,   68,   68,   44,   44,   44,   68,   44,   68,   68,   72, \n\n\n\t// block 56\n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,    8,    8,    8,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   74,   10,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  72,   72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,    8,   74,   74,   72,   72,   72,   72,   74,   74,   72,   72,   74,   74, \n\t  10,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   36,   67, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   44,   44, \n\t  68,   68,   68,   68,   68,   72,   67,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   68,   68,   68,   68,   36, \n\n\n\t// block 57\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   72,   74, \n\t  74,   72,   72,   74,   74,   72,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   72,   68,   68,   68,   68,   68,   68,   68,   68,   72,   74,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   44,   44,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  67,   68,   68,   68,   68,   68,   68,   51,   51,   51,   68,   74,   72,   74,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  72,   68,   72,   72,   72,   68,   68,   72,   72,   68,   68,   68,   68,   68,   72,    8, \n\t  68,    8,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   68,   68,   67,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74,   72,   72,   74,   74, \n\t  44,   44,   68,   67,   67,   74,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 58\n\t  36,   68,   68,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68,   36, \n\t  36,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   50,  323,  323,  323,  323, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  323,   50,   50,   36,   36,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   74,   74,   72,   74,   74,   72,   74,   74,   44,   10,    8,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 59\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36, \n\n\n\t// block 60\n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\t  35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35,   35, \n\n\n\t// block 61\n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\n\n\t// block 62\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 63\n\t 321,  321,  321,  321,  321,  321,  321,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,  321,  321,  321,  321,  321,   36,   36,   36,   36,   36,   68,   72,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   48,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   36,   68,   36, \n\t  68,   68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50,   50, \n\t  50,   50,   50,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 64\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   42,   41, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   51, \n\t2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, \n\t2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, 2084, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   49,   51,   51,   51, \n\n\n\t// block 65\n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t  44,   44,   44,   44,   44,   44,   44,   41,   42,   44,   36,   36,   36,   36,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t  44,   40,   40,   43,   43,   41,   42,   41,   42,   41,   42,   41,   42,   41,   42,   41, \n\t  42,   41,   42,   41,   42,   44,   44,   41,   42,   44,   44,   44,   44,   43,   43,   43, \n\t  44,   44,   44,   36,   44,   44,   44,   44,   40,   41,   42,   41,   42,   41,   42,   44, \n\t  44,   44,   48,   40,   48,   48,   48,   36,   44,   49,   44,   44,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, 4129, \n\n\n\t// block 66\n\t  36,   44,   44,   44,   49,   44,   44,   44,   41,   42,   44,   48,   44,   40,   44,   44, \n\t1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,   44,   44,   48,   48,   48,   44, \n\t  44, 1216, 1216, 1216, 1216, 1216, 1216,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   41,   44,   42,   50,   43, \n\t  50, 1345, 1345, 1345, 1345, 1345, 1345,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   41,   48,   42,   48,   41, \n\t  42,   44,   41,   42,   44,   44,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  67,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   67,   67, \n\t4164,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  36,   36,   68,   68,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   68,   68,   68,   68,   68,   68,   36,   36,   68,   68,   68,   36,   36,   36, \n\t  49,   49,   48,   50,   51,   49,   49,   36,   51,   48,   48,   48,   48,   51,   51,   36, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132,   33,   33,   33,   51,   51, 2084, 2084, \n\n\n\t// block 67\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   36,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36, \n\n\n\t// block 68\n\t  44,   44,   44,   36,   36,   36,   36,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   36,   36,   36,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   18,   18,   18,   18,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   18,   18,   51,   51,   51,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36, \n\t  51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,    8,   36,   36, \n\n\n\t// block 69\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t   8,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36, \n\n\n\t// block 70\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   81,   68,   68,   68,   68,   68,   68,   68,   68,   81,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   36,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  44,   81,   81,   81,   81,   81,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 71\n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,   36,   36,   36,   36,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   36,   36,   36,   36, \n\n\n\t// block 72\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   44, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   36,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   36,  192,  192,  192,  192, \n\t 192,  192,  192,   36,  192,  192,   36,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,   36,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,   36,  321,  321,  321,  321,  321,  321,  321,   36,  321,  321,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 73\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 323,   67,   67,  323,  323,  323,   36,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,   36,  323,  323,  323,  323,  323,  323,  323,  323,  323,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 74\n\t  68,   68,   68,   68,   68,   68,   36,   36,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   68,   68,   36,   36,   36,   68,   36,   36,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   44,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   51,   51,   18,   18,   18,   18,   18,   18,   18, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   36,   68,   68,   36,   36,   36,   36,   36,   18,   18,   18,   18,   18, \n\n\n\t// block 75\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   18,   18,   18,   18,   18,   18,   36,   36,   36,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   44, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   18,   18,   68,   68, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  36,   36,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\n\n\t// block 76\n\t  68,   72,   72,   72,   36,   72,   72,   36,   36,   36,   36,   36,   72,   72,   72,   72, \n\t  68,   68,   68,   68,   36,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,    8,    8,    8,   36,   36,   36,   36,    8, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   18,   18,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   18,   18,   18, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   51,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,    8,    8,   36,   36,   36,   36,   18,   18,   18,   18,   18, \n\t  44,   44,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 77\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,   36,   44,   44,   44,   44,   44,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   36,   36,   36,   36,   36,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   36,   36,   36,   36,   36,   36,   36,   44,   44,   44,   44,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   18,   18,   18,   18,   18,   18,   18, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 78\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,   36,   36,   36,   36,   36,   36,   36,   18,   18,   18,   18,   18,   18, \n\n\n\t// block 79\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   72,   72,   72,   72,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 80\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   72,   72,   40,   36,   36, \n\t  68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,    8,    8,    8, \n\n\n\t// block 81\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,   18,   18,   18,   18,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,    8,    8,    8,    8,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 82\n\t  74,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,    8,   44,   44,   44,   44,   44,   44,   44,   36,   36, \n\t  36,   36,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t   8,   68,   68,   72,   72,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,    8, \n\t  72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  74,   74,   74,   72,   72,   72,   72,   74,   74,    8,    8,   44,   44,   33,   44,   44, \n\t  44,   44,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   33,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 83\n\t  72,   72,   72,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   74,   72,   72,   72, \n\t  72,   72,   72,    8,    8,   36,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  44,   44,   44,   44,   68,   74,   74,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,    8,   44,   44,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  72,   72,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   74,   74,   74,   72,   72,   72,   72,   72,   72,   72,   72,   72,   74, \n\t  10,   68,   68,   68,   68,   44,   44,   44,   44,    8,    8,    8,    8,   44,   74,   72, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   68,   44,   68,   44,   44,   44, \n\t  36,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 84\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74,   74,   74,   72, \n\t  72,   72,   74,   74,   72,   10,    8,   72,   44,   44,   44,   44,   44,   44,   72,   68, \n\t  68,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   36,   68,   68,   68,   68,   36,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   44,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   72, \n\t  74,   74,   74,   72,   72,   72,   72,   72,   72,    8,    8,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 85\n\t  72,   72,   74,   74,   36,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   68, \n\t  68,   36,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   36,    8,    8,   68,   74,   74, \n\t  72,   74,   74,   74,   74,   36,   36,   74,   74,   36,   36,   74,   74,   10,   36,   36, \n\t  68,   36,   36,   36,   36,   36,   36,   74,   36,   36,   36,   36,   36,   68,   68,   68, \n\t  68,   68,   74,   74,   36,   36,    8,    8,    8,    8,    8,    8,    8,   36,   36,   36, \n\t   8,    8,    8,    8,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 86\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   74,   74,   74,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  74,   74,    8,   72,   72,   74,    8,   68,   68,   68,   68,   44,   44,   44,   44,   44, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   44,   44,   36,   44,    8,   68, \n\t  68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  74,   74,   74,   72,   72,   72,   72,   72,   72,   74,   72,   74,   74,   74,   74,   72, \n\t  72,   74,    8,    8,   68,   68,   44,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 87\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74, \n\t  74,   74,   72,   72,   72,   72,   36,   36,   74,   74,   74,   74,   72,   72,   74,    8, \n\t   8,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   68,   68,   68,   68,   72,   72,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 88\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  74,   74,   74,   72,   72,   72,   72,   72,   72,   72,   72,   74,   74,   72,   74,    8, \n\t  72,   44,   44,   44,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   74,   72,   74,   74, \n\t  72,   72,   72,   72,   72,   72,   10,    8,   68,   44,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 89\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   72,   72,   72, \n\t  74,   74,   72,   72,   72,   72,   74,   72,   72,   72,   72,    8,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   18,   18,   44,   44,   44,   51, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 90\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74,   74,   74,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   74,    8,    8,   44,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   68, \n\n\n\t// block 91\n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   68,   36,   36,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  74,   74,   74,   74,   74,   74,   36,   74,   74,   36,   36,   72,   72,   10,    8,   68, \n\t  74,   68,   74,    8,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   74,   74,   74,   72,   72,   72,   72,   36,   36,   72,   72,   74,   74,   74,   74, \n\t   8,   68,   44,   68,   74,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 92\n\t  68,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,    8,    8,   72,   72,   72,   72,   74,   68,   72,   72,   72,   72,   44, \n\t  44,   44,   44,   44,   44,   44,   44,    8,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   72,   72,   72,   72,   72,   72,   74,   74,   72,   72,   72,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   74,    8,    8,   44,   44,   44,   68,   44,   44, \n\t  44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 93\n\t  44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 94\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74, \n\t  72,   72,   72,   72,   72,   72,   72,   36,   72,   72,   72,   72,   72,   72,   74,    8, \n\t  68,   44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36, \n\t  44,   44,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   36,   74,   72,   72,   72,   72,   72,   72, \n\t  72,   74,   72,   72,   74,   72,   72,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 95\n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   36,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   72,   72,   72,   72,   72,   72,   36,   36,   36,   72,   36,   72,   72,   36,   72, \n\t  72,   72,    8,   72,    8,    8,   68,   72,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   36,   68,   68,   36,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   74,   74,   74,   74,   74,   36, \n\t  72,   72,   36,   74,   74,   72,   74,    8,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 96\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   72,   72,   74,   74,   44,   44,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 97\n\t  72,   72,   68,   74,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   74,   74,   72,   72,   72,   72,   72,   36,   36,   36,   74,   74, \n\t  72,   10,    8,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44,   44, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   51,   51,   51,   51,   51,   51,   51,   51,   49,   49,   49, \n\t  49,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   44, \n\n\n\t// block 98\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 99\n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81, \n\t  81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   81,   36, \n\t  44,   44,   44,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 100\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 101\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 102\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   44,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 103\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33,   33, \n\t   8,   68,   68,   68,   68,   68,   68,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 104\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 105\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   44,   44, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t   8,    8,    8,    8,    8,   44,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 106\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t   8,    8,    8,    8,    8,    8,    8,   44,   44,   44,   44,   44,   51,   51,   51,   51, \n\t  67,   67,   67,   67,   44,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   18,   18,   18,   18,   18, \n\t  18,   18,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 107\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   44,   44,   44,   44,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 108\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   72, \n\t  68,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74, \n\t  74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74, \n\t  74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74,   74, \n\t  74,   74,   74,   74,   74,   74,   74,   74,   36,   36,   36,   36,   36,   36,   36,   72, \n\t  72,   72,   72,   67,   67,   67,   67,   67,   67,   67,   67,   67,   67,   67,   67,   67, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  67,   67,   44,   67,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  74,   74,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 109\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 110\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 111\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 112\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  67,   67,   67,   67,   36,   67,   67,   67,   67,   67,   67,   67,   36,   67,   67,   36, \n\n\n\t// block 113\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   36,   36,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 114\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36, \n\n\n\t// block 115\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   51,    8,   72,   44, \n\t4129, 4129, 4129, 4129,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 116\n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 117\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 118\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   36,   36,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   10,   10,    8,    8,    8,   51,   51,   51,   10,   10,   10, \n\t  10,   10,   10, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129,    8,    8,    8,    8,    8, \n\t   8,    8,    8,   51,   51,    8,    8,    8,    8,    8,    8,    8,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,    8,    8,    8,    8,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 119\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,    8,    8,    8,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 120\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 121\n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321, \n\t 321,  321,  321,  321,  321,   36,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  192,   36,  192,  192, \n\t  36,   36,  192,   36,   36,  192,  192,   36,   36,  192,  192,  192,  192,   36,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  321,  321,  321,  321,   36,  321,   36,  321,  321,  321, \n\t 321,  321,  321,  321,   36,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\n\n\t// block 122\n\t 321,  321,  321,  321,  192,  192,   36,  192,  192,  192,  192,   36,   36,  192,  192,  192, \n\t 192,  192,  192,  192,  192,   36,  192,  192,  192,  192,  192,  192,  192,   36,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,   36,  192,  192,  192,  192,   36, \n\t 192,  192,  192,  192,  192,   36,  192,   36,   36,   36,  192,  192,  192,  192,  192,  192, \n\t 192,   36,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\n\n\t// block 123\n\t 321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,   36,   36,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,   48,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   48,  321,  321,  321,  321, \n\t 321,  321,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   48,  321,  321,  321,  321, \n\n\n\t// block 124\n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,   48,  321,  321,  321,  321,  321,  321,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,   48,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   48, \n\t 321,  321,  321,  321,  321,  321,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,   48, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,   48,  321,  321,  321,  321,  321,  321, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,   48,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,   48,  321,  321,  321,  321,  321,  321,  192,  321,   36,   36,   16,   16, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   16, \n\n\n\t// block 125\n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,   51,   51,   51,   51,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t   8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,   51,   51,   51, \n\t  51,   51,   51,   51,   51,    8,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,    8,   51,   51,   44,   44,   44,   44,   44,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,    8,    8,    8,    8,    8, \n\t  36,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8,    8, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 126\n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   68,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,   36, \n\t  36,   36,   36,   36,   36,  321,  321,  321,  321,  321,  321,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 127\n\t  72,   72,   72,   72,   72,   72,   72,   36,   72,   72,   72,   72,   72,   72,   72,   72, \n\t  72,   72,   72,   72,   72,   72,   72,   72,   72,   36,   36,   72,   72,   72,   72,   72, \n\t  72,   72,   36,   72,   72,   36,   72,   72,   72,   72,   72,   36,   36,   36,   36,   36, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323, \n\t 323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,  323,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   72, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 128\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36, \n\t   8,    8,    8,    8,    8,    8,    8,   67,   67,   67,   67,   67,   67,   67,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   68,   51, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 129\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,    8,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,    8,    8,    8,    8, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   49, \n\n\n\t// block 130\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   67,    8,    8,    8,    8, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 131\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   36,   68,   68,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36, \n\n\n\t// block 132\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   36,   36,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t   8,    8,    8,    8,    8,    8,    8,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 133\n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192,  192, \n\t 192,  192,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321,  321, \n\t 321,  321,  321,  321,    8,    8,    8,   72,    8,    8,    8,   67,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   44,   44, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 134\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   18,   18,   18, \n\t  49,   18,   18,   18,   18,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 135\n\t  36,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   18, \n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 136\n\t  68,   68,   68,   68,   36,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   68,   68,   36,   68,   36,   36,   68,   36,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   36,   68,   68,   68,   68,   36,   68,   36,   68,   36,   36,   36,   36, \n\t  36,   36,   68,   36,   36,   36,   36,   68,   36,   68,   36,   68,   36,   68,   68,   68, \n\t  36,   68,   68,   36,   68,   36,   36,   68,   36,   68,   36,   68,   36,   68,   36,   68, \n\t  36,   68,   68,   36,   68,   36,   36,   68,   68,   68,   68,   36,   68,   68,   68,   68, \n\t  68,   68,   68,   36,   68,   68,   68,   68,   36,   68,   68,   68,   68,   36,   68,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36, \n\t  36,   68,   68,   68,   36,   68,   68,   68,   68,   68,   36,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  48,   48,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 137\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36, \n\t  36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 138\n\t  18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,   51,   51,   51,   51,   51,   51, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,   51,   51,   51,   51,   51,   51, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243,  243, \n\t 243,  243,  243,  243,  243,  243,  243,  243,  243,  243,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\n\n\t// block 139\n\t  51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 140\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   50,   50,   50,   50,   50, \n\n\n\t// block 141\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36, \n\n\n\t// block 142\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\t  51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 143\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36, \n\t  51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 144\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   51, \n\t  51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36,   36,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 145\n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   36,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51, \n\t  51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  16,   16,   16,   16,   16,   16,   16,   16,   16,   16,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 146\n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, 2084, 2084, \n\n\n\t// block 147\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 148\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 149\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 150\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 151\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 152\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 153\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   36,   36,   36,   36,   36, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\n\n\t// block 154\n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68,   68, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\t  36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36,   36, \n\n\n\t// block 155\n\t4132, 4129, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\n\n\t// block 156\n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\n\n\t// block 157\n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\t4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, \n\n\n\t// block 158\n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, \n\t  34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34,   34, 2084, 2084\n\t};\n\n\tinline ::boost::uint16_t category_lookup(::boost::uint32_t ch)\n\t{\n\t\t::boost::uint32_t block_offset = category_stage1[ch / 256] * 256;\n\t\treturn category_stage2[block_offset + ch % 256];\n\t}\n\n}}}} // namespace boost::spirit::unicode::detail\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode/lowercase_table.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n\n\tAUTOGENERATED. DO NOT EDIT!!!\n==============================================================================*/\n#include <boost/cstdint.hpp>\n\nnamespace boost { namespace spirit { namespace ucd { namespace detail\n{\n\tstatic const ::boost::uint8_t lowercase_stage1[] = {\n\n\t  0,   1,   2,   3,   4,   5,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  7,   6,   6,   8,   6,   6,   6,   6,   6,   6,   6,   6,   9,   6,  10,  11, \n\t  6,  12,   6,   6,  13,   6,   6,   6,   6,   6,   6,   6,  14,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,  15,  16,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,  17, \n\t  6,   6,   6,   6,  18,  19,   6,   6,   6,   6,   6,   6,  20,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,  21,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,  22,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,  23,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6\n\t};\n\n\tstatic const ::boost::uint32_t lowercase_stage2[] = {\n\n\t// block 0\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,     97,     98,     99,    100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111, \n\t   112,    113,    114,    115,    116,    117,    118,    119,    120,    121,    122,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t   224,    225,    226,    227,    228,    229,    230,    231,    232,    233,    234,    235,    236,    237,    238,    239, \n\t   240,    241,    242,    243,    244,    245,    246,      0,    248,    249,    250,    251,    252,    253,    254,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 1\n\t   257,      0,    259,      0,    261,      0,    263,      0,    265,      0,    267,      0,    269,      0,    271,      0, \n\t   273,      0,    275,      0,    277,      0,    279,      0,    281,      0,    283,      0,    285,      0,    287,      0, \n\t   289,      0,    291,      0,    293,      0,    295,      0,    297,      0,    299,      0,    301,      0,    303,      0, \n\t   105,      0,    307,      0,    309,      0,    311,      0,      0,    314,      0,    316,      0,    318,      0,    320, \n\t\t 0,    322,      0,    324,      0,    326,      0,    328,      0,      0,    331,      0,    333,      0,    335,      0, \n\t   337,      0,    339,      0,    341,      0,    343,      0,    345,      0,    347,      0,    349,      0,    351,      0, \n\t   353,      0,    355,      0,    357,      0,    359,      0,    361,      0,    363,      0,    365,      0,    367,      0, \n\t   369,      0,    371,      0,    373,      0,    375,      0,    255,    378,      0,    380,      0,    382,      0,      0, \n\t\t 0,    595,    387,      0,    389,      0,    596,    392,      0,    598,    599,    396,      0,      0,    477,    601, \n\t   603,    402,      0,    608,    611,      0,    617,    616,    409,      0,      0,      0,    623,    626,      0,    629, \n\t   417,      0,    419,      0,    421,      0,    640,    424,      0,    643,      0,      0,    429,      0,    648,    432, \n\t\t 0,    650,    651,    436,      0,    438,      0,    658,    441,      0,      0,      0,    445,      0,      0,      0, \n\t\t 0,      0,      0,      0,    454,    454,      0,    457,    457,      0,    460,    460,      0,    462,      0,    464, \n\t\t 0,    466,      0,    468,      0,    470,      0,    472,      0,    474,      0,    476,      0,      0,    479,      0, \n\t   481,      0,    483,      0,    485,      0,    487,      0,    489,      0,    491,      0,    493,      0,    495,      0, \n\t\t 0,    499,    499,      0,    501,      0,    405,    447,    505,      0,    507,      0,    509,      0,    511,      0, \n\n\n\t// block 2\n\t   513,      0,    515,      0,    517,      0,    519,      0,    521,      0,    523,      0,    525,      0,    527,      0, \n\t   529,      0,    531,      0,    533,      0,    535,      0,    537,      0,    539,      0,    541,      0,    543,      0, \n\t   414,      0,    547,      0,    549,      0,    551,      0,    553,      0,    555,      0,    557,      0,    559,      0, \n\t   561,      0,    563,      0,      0,      0,      0,      0,      0,      0,  11365,    572,      0,    410,  11366,      0, \n\t\t 0,    578,      0,    384,    649,    652,    583,      0,    585,      0,    587,      0,    589,      0,    591,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 3\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t   881,      0,    883,      0,      0,      0,    887,      0,      0,      0,      0,      0,      0,      0,      0,   1011, \n\t\t 0,      0,      0,      0,      0,      0,    940,      0,    941,    942,    943,      0,    972,      0,    973,    974, \n\t\t 0,    945,    946,    947,    948,    949,    950,    951,    952,    953,    954,    955,    956,    957,    958,    959, \n\t   960,    961,      0,    963,    964,    965,    966,    967,    968,    969,    970,    971,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,    983, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,    985,      0,    987,      0,    989,      0,    991,      0, \n\t   993,      0,    995,      0,    997,      0,    999,      0,   1001,      0,   1003,      0,   1005,      0,   1007,      0, \n\t\t 0,      0,      0,      0,    952,      0,      0,   1016,      0,   1010,   1019,      0,      0,    891,    892,    893, \n\n\n\t// block 4\n\t  1104,   1105,   1106,   1107,   1108,   1109,   1110,   1111,   1112,   1113,   1114,   1115,   1116,   1117,   1118,   1119, \n\t  1072,   1073,   1074,   1075,   1076,   1077,   1078,   1079,   1080,   1081,   1082,   1083,   1084,   1085,   1086,   1087, \n\t  1088,   1089,   1090,   1091,   1092,   1093,   1094,   1095,   1096,   1097,   1098,   1099,   1100,   1101,   1102,   1103, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  1121,      0,   1123,      0,   1125,      0,   1127,      0,   1129,      0,   1131,      0,   1133,      0,   1135,      0, \n\t  1137,      0,   1139,      0,   1141,      0,   1143,      0,   1145,      0,   1147,      0,   1149,      0,   1151,      0, \n\t  1153,      0,      0,      0,      0,      0,      0,      0,      0,      0,   1163,      0,   1165,      0,   1167,      0, \n\t  1169,      0,   1171,      0,   1173,      0,   1175,      0,   1177,      0,   1179,      0,   1181,      0,   1183,      0, \n\t  1185,      0,   1187,      0,   1189,      0,   1191,      0,   1193,      0,   1195,      0,   1197,      0,   1199,      0, \n\t  1201,      0,   1203,      0,   1205,      0,   1207,      0,   1209,      0,   1211,      0,   1213,      0,   1215,      0, \n\t  1231,   1218,      0,   1220,      0,   1222,      0,   1224,      0,   1226,      0,   1228,      0,   1230,      0,      0, \n\t  1233,      0,   1235,      0,   1237,      0,   1239,      0,   1241,      0,   1243,      0,   1245,      0,   1247,      0, \n\t  1249,      0,   1251,      0,   1253,      0,   1255,      0,   1257,      0,   1259,      0,   1261,      0,   1263,      0, \n\t  1265,      0,   1267,      0,   1269,      0,   1271,      0,   1273,      0,   1275,      0,   1277,      0,   1279,      0, \n\n\n\t// block 5\n\t  1281,      0,   1283,      0,   1285,      0,   1287,      0,   1289,      0,   1291,      0,   1293,      0,   1295,      0, \n\t  1297,      0,   1299,      0,   1301,      0,   1303,      0,   1305,      0,   1307,      0,   1309,      0,   1311,      0, \n\t  1313,      0,   1315,      0,   1317,      0,   1319,      0,   1321,      0,   1323,      0,   1325,      0,   1327,      0, \n\t\t 0,   1377,   1378,   1379,   1380,   1381,   1382,   1383,   1384,   1385,   1386,   1387,   1388,   1389,   1390,   1391, \n\t  1392,   1393,   1394,   1395,   1396,   1397,   1398,   1399,   1400,   1401,   1402,   1403,   1404,   1405,   1406,   1407, \n\t  1408,   1409,   1410,   1411,   1412,   1413,   1414,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 6\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 7\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 11520,  11521,  11522,  11523,  11524,  11525,  11526,  11527,  11528,  11529,  11530,  11531,  11532,  11533,  11534,  11535, \n\t 11536,  11537,  11538,  11539,  11540,  11541,  11542,  11543,  11544,  11545,  11546,  11547,  11548,  11549,  11550,  11551, \n\t 11552,  11553,  11554,  11555,  11556,  11557,      0,  11559,      0,      0,      0,      0,      0,  11565,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 8\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 43888,  43889,  43890,  43891,  43892,  43893,  43894,  43895,  43896,  43897,  43898,  43899,  43900,  43901,  43902,  43903, \n\t 43904,  43905,  43906,  43907,  43908,  43909,  43910,  43911,  43912,  43913,  43914,  43915,  43916,  43917,  43918,  43919, \n\t 43920,  43921,  43922,  43923,  43924,  43925,  43926,  43927,  43928,  43929,  43930,  43931,  43932,  43933,  43934,  43935, \n\t 43936,  43937,  43938,  43939,  43940,  43941,  43942,  43943,  43944,  43945,  43946,  43947,  43948,  43949,  43950,  43951, \n\t 43952,  43953,  43954,  43955,  43956,  43957,  43958,  43959,  43960,  43961,  43962,  43963,  43964,  43965,  43966,  43967, \n\t  5112,   5113,   5114,   5115,   5116,   5117,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 9\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  4304,   4305,   4306,   4307,   4308,   4309,   4310,   4311,   4312,   4313,   4314,   4315,   4316,   4317,   4318,   4319, \n\t  4320,   4321,   4322,   4323,   4324,   4325,   4326,   4327,   4328,   4329,   4330,   4331,   4332,   4333,   4334,   4335, \n\t  4336,   4337,   4338,   4339,   4340,   4341,   4342,   4343,   4344,   4345,   4346,      0,      0,   4349,   4350,   4351, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 10\n\t  7681,      0,   7683,      0,   7685,      0,   7687,      0,   7689,      0,   7691,      0,   7693,      0,   7695,      0, \n\t  7697,      0,   7699,      0,   7701,      0,   7703,      0,   7705,      0,   7707,      0,   7709,      0,   7711,      0, \n\t  7713,      0,   7715,      0,   7717,      0,   7719,      0,   7721,      0,   7723,      0,   7725,      0,   7727,      0, \n\t  7729,      0,   7731,      0,   7733,      0,   7735,      0,   7737,      0,   7739,      0,   7741,      0,   7743,      0, \n\t  7745,      0,   7747,      0,   7749,      0,   7751,      0,   7753,      0,   7755,      0,   7757,      0,   7759,      0, \n\t  7761,      0,   7763,      0,   7765,      0,   7767,      0,   7769,      0,   7771,      0,   7773,      0,   7775,      0, \n\t  7777,      0,   7779,      0,   7781,      0,   7783,      0,   7785,      0,   7787,      0,   7789,      0,   7791,      0, \n\t  7793,      0,   7795,      0,   7797,      0,   7799,      0,   7801,      0,   7803,      0,   7805,      0,   7807,      0, \n\t  7809,      0,   7811,      0,   7813,      0,   7815,      0,   7817,      0,   7819,      0,   7821,      0,   7823,      0, \n\t  7825,      0,   7827,      0,   7829,      0,      0,      0,      0,      0,      0,      0,      0,      0,    223,      0, \n\t  7841,      0,   7843,      0,   7845,      0,   7847,      0,   7849,      0,   7851,      0,   7853,      0,   7855,      0, \n\t  7857,      0,   7859,      0,   7861,      0,   7863,      0,   7865,      0,   7867,      0,   7869,      0,   7871,      0, \n\t  7873,      0,   7875,      0,   7877,      0,   7879,      0,   7881,      0,   7883,      0,   7885,      0,   7887,      0, \n\t  7889,      0,   7891,      0,   7893,      0,   7895,      0,   7897,      0,   7899,      0,   7901,      0,   7903,      0, \n\t  7905,      0,   7907,      0,   7909,      0,   7911,      0,   7913,      0,   7915,      0,   7917,      0,   7919,      0, \n\t  7921,      0,   7923,      0,   7925,      0,   7927,      0,   7929,      0,   7931,      0,   7933,      0,   7935,      0, \n\n\n\t// block 11\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   7936,   7937,   7938,   7939,   7940,   7941,   7942,   7943, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   7952,   7953,   7954,   7955,   7956,   7957,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   7968,   7969,   7970,   7971,   7972,   7973,   7974,   7975, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   7984,   7985,   7986,   7987,   7988,   7989,   7990,   7991, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8000,   8001,   8002,   8003,   8004,   8005,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,   8017,      0,   8019,      0,   8021,      0,   8023, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8032,   8033,   8034,   8035,   8036,   8037,   8038,   8039, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8064,   8065,   8066,   8067,   8068,   8069,   8070,   8071, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8080,   8081,   8082,   8083,   8084,   8085,   8086,   8087, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8096,   8097,   8098,   8099,   8100,   8101,   8102,   8103, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8112,   8113,   8048,   8049,   8115,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8050,   8051,   8052,   8053,   8131,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8144,   8145,   8054,   8055,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8160,   8161,   8058,   8059,   8165,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   8056,   8057,   8060,   8061,   8179,      0,      0,      0, \n\n\n\t// block 12\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,    969,      0,      0,      0,    107,    229,      0,      0,      0,      0, \n\t\t 0,      0,   8526,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8560,   8561,   8562,   8563,   8564,   8565,   8566,   8567,   8568,   8569,   8570,   8571,   8572,   8573,   8574,   8575, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,   8580,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 13\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,   9424,   9425,   9426,   9427,   9428,   9429,   9430,   9431,   9432,   9433, \n\t  9434,   9435,   9436,   9437,   9438,   9439,   9440,   9441,   9442,   9443,   9444,   9445,   9446,   9447,   9448,   9449, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 14\n\t 11312,  11313,  11314,  11315,  11316,  11317,  11318,  11319,  11320,  11321,  11322,  11323,  11324,  11325,  11326,  11327, \n\t 11328,  11329,  11330,  11331,  11332,  11333,  11334,  11335,  11336,  11337,  11338,  11339,  11340,  11341,  11342,  11343, \n\t 11344,  11345,  11346,  11347,  11348,  11349,  11350,  11351,  11352,  11353,  11354,  11355,  11356,  11357,  11358,  11359, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 11361,      0,    619,   7549,    637,      0,      0,  11368,      0,  11370,      0,  11372,      0,    593,    625,    592, \n\t   594,      0,  11379,      0,      0,  11382,      0,      0,      0,      0,      0,      0,      0,      0,    575,    576, \n\t 11393,      0,  11395,      0,  11397,      0,  11399,      0,  11401,      0,  11403,      0,  11405,      0,  11407,      0, \n\t 11409,      0,  11411,      0,  11413,      0,  11415,      0,  11417,      0,  11419,      0,  11421,      0,  11423,      0, \n\t 11425,      0,  11427,      0,  11429,      0,  11431,      0,  11433,      0,  11435,      0,  11437,      0,  11439,      0, \n\t 11441,      0,  11443,      0,  11445,      0,  11447,      0,  11449,      0,  11451,      0,  11453,      0,  11455,      0, \n\t 11457,      0,  11459,      0,  11461,      0,  11463,      0,  11465,      0,  11467,      0,  11469,      0,  11471,      0, \n\t 11473,      0,  11475,      0,  11477,      0,  11479,      0,  11481,      0,  11483,      0,  11485,      0,  11487,      0, \n\t 11489,      0,  11491,      0,      0,      0,      0,      0,      0,      0,      0,  11500,      0,  11502,      0,      0, \n\t\t 0,      0,  11507,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 15\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 42561,      0,  42563,      0,  42565,      0,  42567,      0,  42569,      0,  42571,      0,  42573,      0,  42575,      0, \n\t 42577,      0,  42579,      0,  42581,      0,  42583,      0,  42585,      0,  42587,      0,  42589,      0,  42591,      0, \n\t 42593,      0,  42595,      0,  42597,      0,  42599,      0,  42601,      0,  42603,      0,  42605,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 42625,      0,  42627,      0,  42629,      0,  42631,      0,  42633,      0,  42635,      0,  42637,      0,  42639,      0, \n\t 42641,      0,  42643,      0,  42645,      0,  42647,      0,  42649,      0,  42651,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 16\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,  42787,      0,  42789,      0,  42791,      0,  42793,      0,  42795,      0,  42797,      0,  42799,      0, \n\t\t 0,      0,  42803,      0,  42805,      0,  42807,      0,  42809,      0,  42811,      0,  42813,      0,  42815,      0, \n\t 42817,      0,  42819,      0,  42821,      0,  42823,      0,  42825,      0,  42827,      0,  42829,      0,  42831,      0, \n\t 42833,      0,  42835,      0,  42837,      0,  42839,      0,  42841,      0,  42843,      0,  42845,      0,  42847,      0, \n\t 42849,      0,  42851,      0,  42853,      0,  42855,      0,  42857,      0,  42859,      0,  42861,      0,  42863,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,  42874,      0,  42876,      0,   7545,  42879,      0, \n\t 42881,      0,  42883,      0,  42885,      0,  42887,      0,      0,      0,      0,  42892,      0,    613,      0,      0, \n\t 42897,      0,  42899,      0,      0,      0,  42903,      0,  42905,      0,  42907,      0,  42909,      0,  42911,      0, \n\t 42913,      0,  42915,      0,  42917,      0,  42919,      0,  42921,      0,    614,    604,    609,    620,    618,      0, \n\t   670,    647,    669,  43859,  42933,      0,  42935,      0,  42937,      0,  42939,      0,  42941,      0,  42943,      0, \n\t 42945,      0,  42947,      0,  42900,    642,   7566,  42952,      0,  42954,      0,      0,      0,      0,      0,      0, \n\t 42961,      0,      0,      0,      0,      0,  42967,      0,  42969,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,  42998,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 17\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,  65345,  65346,  65347,  65348,  65349,  65350,  65351,  65352,  65353,  65354,  65355,  65356,  65357,  65358,  65359, \n\t 65360,  65361,  65362,  65363,  65364,  65365,  65366,  65367,  65368,  65369,  65370,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 18\n\t 66600,  66601,  66602,  66603,  66604,  66605,  66606,  66607,  66608,  66609,  66610,  66611,  66612,  66613,  66614,  66615, \n\t 66616,  66617,  66618,  66619,  66620,  66621,  66622,  66623,  66624,  66625,  66626,  66627,  66628,  66629,  66630,  66631, \n\t 66632,  66633,  66634,  66635,  66636,  66637,  66638,  66639,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 66776,  66777,  66778,  66779,  66780,  66781,  66782,  66783,  66784,  66785,  66786,  66787,  66788,  66789,  66790,  66791, \n\t 66792,  66793,  66794,  66795,  66796,  66797,  66798,  66799,  66800,  66801,  66802,  66803,  66804,  66805,  66806,  66807, \n\t 66808,  66809,  66810,  66811,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 19\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 66967,  66968,  66969,  66970,  66971,  66972,  66973,  66974,  66975,  66976,  66977,      0,  66979,  66980,  66981,  66982, \n\t 66983,  66984,  66985,  66986,  66987,  66988,  66989,  66990,  66991,  66992,  66993,      0,  66995,  66996,  66997,  66998, \n\t 66999,  67000,  67001,      0,  67003,  67004,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 20\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 68800,  68801,  68802,  68803,  68804,  68805,  68806,  68807,  68808,  68809,  68810,  68811,  68812,  68813,  68814,  68815, \n\t 68816,  68817,  68818,  68819,  68820,  68821,  68822,  68823,  68824,  68825,  68826,  68827,  68828,  68829,  68830,  68831, \n\t 68832,  68833,  68834,  68835,  68836,  68837,  68838,  68839,  68840,  68841,  68842,  68843,  68844,  68845,  68846,  68847, \n\t 68848,  68849,  68850,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 21\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 71872,  71873,  71874,  71875,  71876,  71877,  71878,  71879,  71880,  71881,  71882,  71883,  71884,  71885,  71886,  71887, \n\t 71888,  71889,  71890,  71891,  71892,  71893,  71894,  71895,  71896,  71897,  71898,  71899,  71900,  71901,  71902,  71903, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 22\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 93792,  93793,  93794,  93795,  93796,  93797,  93798,  93799,  93800,  93801,  93802,  93803,  93804,  93805,  93806,  93807, \n\t 93808,  93809,  93810,  93811,  93812,  93813,  93814,  93815,  93816,  93817,  93818,  93819,  93820,  93821,  93822,  93823, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 23\n\t125218, 125219, 125220, 125221, 125222, 125223, 125224, 125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233, \n\t125234, 125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244, 125245, 125246, 125247, 125248, 125249, \n\t125250, 125251,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0\n\t};\n\n\tinline ::boost::uint32_t lowercase_lookup(::boost::uint32_t ch)\n\t{\n\t\t::boost::uint32_t block_offset = lowercase_stage1[ch / 256] * 256;\n\t\treturn lowercase_stage2[block_offset + ch % 256];\n\t}\n\n}}}} // namespace boost::spirit::unicode::detail\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode/query.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n\n\tAutogenerated by MultiStageTable.py (Unicode multi-stage\n\ttable builder) (c) Peter Kankowski, 2008\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010)\n#define BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010\n\n#include <boost/cstdint.hpp>\n\n# include \"category_table.hpp\"\n# include \"script_table.hpp\"\n# include \"lowercase_table.hpp\"\n# include \"uppercase_table.hpp\"\n\nnamespace boost { namespace spirit { namespace ucd\n{\n\t// This header provides Basic (Level 1) Unicode Support\n\t// See http://unicode.org/reports/tr18/ for details\n\n\tstruct properties\n\t{\n\t\t// bit pattern: xxMMMCCC\n\t\t// MMM: major_category\n\t\t// CCC: category\n\n\t\tenum major_category\n\t\t{\n\t\t\tletter,\n\t\t\tmark,\n\t\t\tnumber,\n\t\t\tseparator,\n\t\t\tother,\n\t\t\tpunctuation,\n\t\t\tsymbol\n\t\t};\n\n\t\tenum category\n\t\t{\n\t\t\tuppercase_letter = 0,   // [Lu] an uppercase letter\n\t\t\tlowercase_letter,       // [Ll] a lowercase letter\n\t\t\ttitlecase_letter,       // [Lt] a digraphic character, with first part uppercase\n\t\t\tmodifier_letter,        // [Lm] a modifier letter\n\t\t\tother_letter,           // [Lo] other letters, including syllables and ideographs\n\n\t\t\tnonspacing_mark = 8,    // [Mn] a nonspacing combining mark (zero advance width)\n\t\t\tenclosing_mark,         // [Me] an enclosing combining mark\n\t\t\tspacing_mark,           // [Mc] a spacing combining mark (positive advance width)\n\n\t\t\tdecimal_number = 16,    // [Nd] a decimal digit\n\t\t\tletter_number,          // [Nl] a letterlike numeric character\n\t\t\tother_number,           // [No] a numeric character of other type\n\n\t\t\tspace_separator = 24,   // [Zs] a space character (of various non-zero widths)\n\t\t\tline_separator,         // [Zl] U+2028 LINE SEPARATOR only\n\t\t\tparagraph_separator,    // [Zp] U+2029 PARAGRAPH SEPARATOR only\n\n\t\t\tcontrol = 32,           // [Cc] a C0 or C1 control code\n\t\t\tformat,                 // [Cf] a format control character\n\t\t\tprivate_use,            // [Co] a private-use character\n\t\t\tsurrogate,              // [Cs] a surrogate code point\n\t\t\tunassigned,             // [Cn] a reserved unassigned code point or a noncharacter\n\n\t\t\tdash_punctuation = 40,  // [Pd] a dash or hyphen punctuation mark\n\t\t\topen_punctuation,       // [Ps] an opening punctuation mark (of a pair)\n\t\t\tclose_punctuation,      // [Pe] a closing punctuation mark (of a pair)\n\t\t\tconnector_punctuation,  // [Pc] a connecting punctuation mark, like a tie\n\t\t\tother_punctuation,      // [Po] a punctuation mark of other type\n\t\t\tinitial_punctuation,    // [Pi] an initial quotation mark\n\t\t\tfinal_punctuation,      // [Pf] a final quotation mark\n\n\t\t\tmath_symbol = 48,       // [Sm] a symbol of primarily mathematical use\n\t\t\tcurrency_symbol,        // [Sc] a currency sign\n\t\t\tmodifier_symbol,        // [Sk] a non-letterlike modifier symbol\n\t\t\tother_symbol            // [So] a symbol of other type\n\t\t};\n\n\t\tenum derived_properties\n\t\t{\n\t\t\talphabetic = 64,\n\t\t\tuppercase = 128,\n\t\t\tlowercase = 256,\n\t\t\twhite_space = 512,\n\t\t\thex_digit = 1024,\n\t\t\tnoncharacter_code_point = 2048,\n\t\t\tdefault_ignorable_code_point = 4096\n\t\t};\n\n\t\tenum script\n\t\t{\n\t\t\tadlam,\n\t\t\tcaucasian_albanian,\n\t\t\tahom,\n\t\t\tarabic,\n\t\t\timperial_aramaic,\n\t\t\tarmenian,\n\t\t\tavestan,\n\t\t\tbalinese,\n\t\t\tbamum,\n\t\t\tbassa_vah,\n\t\t\tbatak,\n\t\t\tbengali,\n\t\t\tbhaiksuki,\n\t\t\tbopomofo,\n\t\t\tbrahmi,\n\t\t\tbraille,\n\t\t\tbuginese,\n\t\t\tbuhid,\n\t\t\tchakma,\n\t\t\tcanadian_aboriginal,\n\t\t\tcarian,\n\t\t\tcham,\n\t\t\tcherokee,\n\t\t\tchorasmian,\n\t\t\tcoptic,\n\t\t\tcypro_minoan,\n\t\t\tcypriot,\n\t\t\tcyrillic,\n\t\t\tdevanagari,\n\t\t\tdives_akuru,\n\t\t\tdogra,\n\t\t\tdeseret,\n\t\t\tduployan,\n\t\t\tegyptian_hieroglyphs,\n\t\t\telbasan,\n\t\t\telymaic,\n\t\t\tethiopic,\n\t\t\tgeorgian,\n\t\t\tglagolitic,\n\t\t\tgunjala_gondi,\n\t\t\tmasaram_gondi,\n\t\t\tgothic,\n\t\t\tgrantha,\n\t\t\tgreek,\n\t\t\tgujarati,\n\t\t\tgurmukhi,\n\t\t\thangul,\n\t\t\than,\n\t\t\thanunoo,\n\t\t\thatran,\n\t\t\thebrew,\n\t\t\thiragana,\n\t\t\tanatolian_hieroglyphs,\n\t\t\tpahawh_hmong,\n\t\t\tnyiakeng_puachue_hmong,\n\t\t\tkatakana_or_hiragana,\n\t\t\told_hungarian,\n\t\t\told_italic,\n\t\t\tjavanese,\n\t\t\tkayah_li,\n\t\t\tkatakana,\n\t\t\tkawi,\n\t\t\tkharoshthi,\n\t\t\tkhmer,\n\t\t\tkhojki,\n\t\t\tkhitan_small_script,\n\t\t\tkannada,\n\t\t\tkaithi,\n\t\t\ttai_tham,\n\t\t\tlao,\n\t\t\tlatin,\n\t\t\tlepcha,\n\t\t\tlimbu,\n\t\t\tlinear_a,\n\t\t\tlinear_b,\n\t\t\tlisu,\n\t\t\tlycian,\n\t\t\tlydian,\n\t\t\tmahajani,\n\t\t\tmakasar,\n\t\t\tmandaic,\n\t\t\tmanichaean,\n\t\t\tmarchen,\n\t\t\tmedefaidrin,\n\t\t\tmende_kikakui,\n\t\t\tmeroitic_cursive,\n\t\t\tmeroitic_hieroglyphs,\n\t\t\tmalayalam,\n\t\t\tmodi,\n\t\t\tmongolian,\n\t\t\tmro,\n\t\t\tmeetei_mayek,\n\t\t\tmultani,\n\t\t\tmyanmar,\n\t\t\tnag_mundari,\n\t\t\tnandinagari,\n\t\t\told_north_arabian,\n\t\t\tnabataean,\n\t\t\tnewa,\n\t\t\tnko,\n\t\t\tnushu,\n\t\t\togham,\n\t\t\tol_chiki,\n\t\t\told_turkic,\n\t\t\toriya,\n\t\t\tosage,\n\t\t\tosmanya,\n\t\t\told_uyghur,\n\t\t\tpalmyrene,\n\t\t\tpau_cin_hau,\n\t\t\told_permic,\n\t\t\tphags_pa,\n\t\t\tinscriptional_pahlavi,\n\t\t\tpsalter_pahlavi,\n\t\t\tphoenician,\n\t\t\tmiao,\n\t\t\tinscriptional_parthian,\n\t\t\trejang,\n\t\t\thanifi_rohingya,\n\t\t\trunic,\n\t\t\tsamaritan,\n\t\t\told_south_arabian,\n\t\t\tsaurashtra,\n\t\t\tsignwriting,\n\t\t\tshavian,\n\t\t\tsharada,\n\t\t\tsiddham,\n\t\t\tkhudawadi,\n\t\t\tsinhala,\n\t\t\tsogdian,\n\t\t\told_sogdian,\n\t\t\tsora_sompeng,\n\t\t\tsoyombo,\n\t\t\tsundanese,\n\t\t\tsyloti_nagri,\n\t\t\tsyriac,\n\t\t\ttagbanwa,\n\t\t\ttakri,\n\t\t\ttai_le,\n\t\t\tnew_tai_lue,\n\t\t\ttamil,\n\t\t\ttangut,\n\t\t\ttai_viet,\n\t\t\ttelugu,\n\t\t\ttifinagh,\n\t\t\ttagalog,\n\t\t\tthaana,\n\t\t\tthai,\n\t\t\ttibetan,\n\t\t\ttirhuta,\n\t\t\ttangsa,\n\t\t\ttoto,\n\t\t\tugaritic,\n\t\t\tvai,\n\t\t\tvithkuqi,\n\t\t\twarang_citi,\n\t\t\twancho,\n\t\t\told_persian,\n\t\t\tcuneiform,\n\t\t\tyezidi,\n\t\t\tyi,\n\t\t\tzanabazar_square,\n\t\t\tinherited,\n\t\t\tcommon,\n\t\t\tunknown\n\t\t};\n\t};\n\n\tinline properties::category get_category(::boost::uint32_t ch)\n\t{\n\t\treturn static_cast<properties::category>(detail::category_lookup(ch) & 0x3F);\n\t}\n\n\tinline properties::major_category get_major_category(::boost::uint32_t ch)\n\t{\n\t\treturn static_cast<properties::major_category>(get_category(ch) >> 3);\n\t}\n\n\tinline bool is_punctuation(::boost::uint32_t ch)\n\t{\n\t\treturn get_major_category(ch) == properties::punctuation;\n\t}\n\n\tinline bool is_decimal_number(::boost::uint32_t ch)\n\t{\n\t\treturn get_category(ch) == properties::decimal_number;\n\t}\n\n\tinline bool is_hex_digit(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::hex_digit) != 0;\n\t}\n\n\tinline bool is_control(::boost::uint32_t ch)\n\t{\n\t\treturn get_category(ch) == properties::control;\n\t}\n\n\tinline bool is_alphabetic(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::alphabetic) != 0;\n\t}\n\n\tinline bool is_alphanumeric(::boost::uint32_t ch)\n\t{\n\t\treturn is_decimal_number(ch) || is_alphabetic(ch);\n\t}\n\n\tinline bool is_uppercase(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::uppercase) != 0;\n\t}\n\n\tinline bool is_lowercase(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::lowercase) != 0;\n\t}\n\n\tinline bool is_white_space(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::white_space) != 0;\n\t}\n\n\tinline bool is_blank(::boost::uint32_t ch)\n\t{\n\t\tswitch (ch)\n\t\t{\n\t\t\tcase '\\n': case '\\v': case '\\f': case '\\r':\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\treturn is_white_space(ch)\n\t\t\t\t&& !(   get_category(ch) == properties::line_separator\n\t\t\t\t\t||  get_category(ch) == properties::paragraph_separator\n\t\t\t\t\t);\n\t\t}\n\t}\n\n\tinline bool is_graph(::boost::uint32_t ch)\n\t{\n\t\treturn !(   is_white_space(ch)\n\t\t\t\t||  get_category(ch) == properties::control\n\t\t\t\t||  get_category(ch) == properties::surrogate\n\t\t\t\t||  get_category(ch) == properties::unassigned\n\t\t\t\t);\n\t}\n\n\tinline bool is_print(::boost::uint32_t ch)\n\t{\n\t\treturn (is_graph(ch) || is_blank(ch)) && !is_control(ch);\n\t}\n\n\tinline bool is_noncharacter_code_point(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::noncharacter_code_point) != 0;\n\t}\n\n\tinline bool is_default_ignorable_code_point(::boost::uint32_t ch)\n\t{\n\t\treturn (detail::category_lookup(ch) & properties::default_ignorable_code_point) != 0;\n\t}\n\n\tinline properties::script get_script(::boost::uint32_t ch)\n\t{\n\t\treturn static_cast<properties::script>(detail::script_lookup(ch));\n\t}\n\n\tinline ::boost::uint32_t to_lowercase(::boost::uint32_t ch)\n\t{\n\t\t// The table returns 0 to signal that this code maps to itself\n\t\t::boost::uint32_t r = detail::lowercase_lookup(ch);\n\t\treturn (r == 0)? ch : r;\n\t}\n\n\tinline ::boost::uint32_t to_uppercase(::boost::uint32_t ch)\n\t{\n\t\t// The table returns 0 to signal that this code maps to itself\n\t\t::boost::uint32_t r = detail::uppercase_lookup(ch);\n\t\treturn (r == 0)? ch : r;\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode/script_table.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n\n\tAUTOGENERATED. DO NOT EDIT!!!\n==============================================================================*/\n#include <boost/cstdint.hpp>\n\nnamespace boost { namespace spirit { namespace ucd { namespace detail\n{\n\tstatic const ::boost::uint8_t script_stage1[] = {\n\n\t  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15, \n\t 16,  17,  18,  19,  20,  20,  21,  22,  23,  24,  25,  26,  27,  28,   1,  29, \n\t 30,  31,  32,  32,  33,  32,  32,  32,  34,  32,  32,  35,  36,  37,  38,  39, \n\t 40,  41,  42,  43,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  45,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 46,  46,  46,  46,  47,  48,  49,  50,  51,  52,  53,  54,  17,  17,  17,  17, \n\t 17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, \n\t 17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, \n\t 17,  17,  17,  17,  17,  17,  17,  55,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  44,  57,  58,  59,  60,  61,  62, \n\t 63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78, \n\t 79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94, \n\t 95,  95,  95,  96,  97,  98,  56,  56,  56,  56,  56,  56,  56,  56,  56,  99, \n\t100, 100, 100, 100, 101,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56, 102, 102, 103,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56, 104, 104, 105, 106,  56,  56, 107, 108, \n\t109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, \n\t109, 109, 109, 109, 109, 109, 109, 110, 109, 109, 109, 111, 112, 113,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, 114, \n\t115, 116, 117,  56,  56,  56,  56,  56,  56,  56,  56,  56, 118,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, 119, \n\t120, 121, 122, 123, 124, 125, 126, 127, 128, 128, 129,  56,  56,  56,  56, 130, \n\t131, 132, 133,  56, 134,  56,  56, 135, 136, 137,  56,  56, 138, 139, 140,  56, \n\t141, 142, 143,  32,  32,  32, 144, 145, 146,  32, 147, 148,  56,  56,  56,  56, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44, 149,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44, 150, 151,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, 152,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, 153,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  44,  44, 154,  56,  56,  56,  56,  56, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44, 155,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44, 156,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t157, 158,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56\n\t};\n\n\tstatic const ::boost::uint8_t script_stage2[] = {\n\n\t// block 0\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 163, 163, \n\t163,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163,  70, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163,  70, 163, 163, 163, 163, 163, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70, 163,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70, 163,  70,  70,  70,  70,  70,  70,  70,  70, \n\n\n\t// block 1\n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\n\n\t// block 2\n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 70,  70,  70,  70,  70, 163, 163, 163, 163, 163,  13,  13, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 3\n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t 43,  43,  43,  43, 163,  43,  43,  43, 164, 164,  43,  43,  43,  43, 163,  43, \n\t164, 164, 164, 164,  43, 163,  43, 163,  43,  43,  43, 164,  43, 164,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43, 164,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\n\n\t// block 4\n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27, 162, 162,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\n\n\t// block 5\n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t164,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5, \n\t  5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5, \n\t  5,   5,   5,   5,   5,   5,   5, 164, 164,   5,   5,   5,   5,   5,   5,   5, \n\t  5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5, \n\t  5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5, \n\t  5,   5,   5,   5,   5,   5,   5,   5,   5,   5,   5, 164, 164,   5,   5,   5, \n\t164,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50,  50, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, 164, 164, 164, 164,  50, \n\t 50,  50,  50,  50,  50, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 6\n\t  3,   3,   3,   3,   3, 163,   3,   3,   3,   3,   3,   3, 163,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 163,   3,   3,   3, 163, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t163,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t162,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 163,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\n\n\t// block 7\n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 164, 135, \n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, \n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, \n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, \n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 164, 164, 135, 135, 135, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, \n\t146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, \n\t146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, \n\t146, 146, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99, \n\t 99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99, \n\t 99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99, \n\t 99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99, 164, 164,  99,  99,  99, \n\n\n\t// block 8\n\t120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, \n\t120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, \n\t120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 164, 164, \n\t120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 164, \n\t 80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80, \n\t 80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80,  80, 164, 164,  80, 164, \n\t135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 164, 164, 164, 164, 164, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164, \n\t  3,   3, 164, 164, 164, 164, 164, 164,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3, 163,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\n\n\t// block 9\n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28, 162, 162, 162, 162,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28, 163, 163,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 11,  11,  11,  11, 164,  11,  11,  11,  11,  11,  11,  11,  11, 164, 164,  11, \n\t 11, 164, 164,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11, \n\t 11,  11,  11,  11,  11,  11,  11,  11,  11, 164,  11,  11,  11,  11,  11,  11, \n\t 11, 164,  11, 164, 164, 164,  11,  11,  11,  11, 164, 164,  11,  11,  11,  11, \n\t 11,  11,  11,  11,  11, 164, 164,  11,  11, 164, 164,  11,  11,  11,  11, 164, \n\t164, 164, 164, 164, 164, 164, 164,  11, 164, 164, 164, 164,  11,  11, 164,  11, \n\t 11,  11,  11,  11, 164, 164,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11, \n\t 11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11,  11, 164, \n\n\n\t// block 10\n\t164,  45,  45,  45, 164,  45,  45,  45,  45,  45,  45, 164, 164, 164, 164,  45, \n\t 45, 164, 164,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45, \n\t 45,  45,  45,  45,  45,  45,  45,  45,  45, 164,  45,  45,  45,  45,  45,  45, \n\t 45, 164,  45,  45, 164,  45,  45, 164,  45,  45, 164, 164,  45, 164,  45,  45, \n\t 45,  45,  45, 164, 164, 164, 164,  45,  45, 164, 164,  45,  45,  45, 164, 164, \n\t164,  45, 164, 164, 164, 164, 164, 164, 164,  45,  45,  45,  45, 164,  45, 164, \n\t164, 164, 164, 164, 164, 164,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45, \n\t 45,  45,  45,  45,  45,  45,  45, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164,  44,  44,  44, 164,  44,  44,  44,  44,  44,  44,  44,  44,  44, 164,  44, \n\t 44,  44, 164,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44,  44,  44,  44, 164,  44,  44,  44,  44,  44,  44, \n\t 44, 164,  44,  44, 164,  44,  44,  44,  44,  44, 164, 164,  44,  44,  44,  44, \n\t 44,  44,  44,  44,  44,  44, 164,  44,  44,  44, 164,  44,  44,  44, 164, 164, \n\t 44, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 44,  44,  44,  44, 164, 164,  44,  44,  44,  44,  44,  44,  44,  44,  44,  44, \n\t 44,  44, 164, 164, 164, 164, 164, 164, 164,  44,  44,  44,  44,  44,  44,  44, \n\n\n\t// block 11\n\t164, 104, 104, 104, 164, 104, 104, 104, 104, 104, 104, 104, 104, 164, 164, 104, \n\t104, 164, 164, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, \n\t104, 104, 104, 104, 104, 104, 104, 104, 104, 164, 104, 104, 104, 104, 104, 104, \n\t104, 164, 104, 104, 164, 104, 104, 104, 104, 104, 164, 164, 104, 104, 104, 104, \n\t104, 104, 104, 104, 104, 164, 164, 104, 104, 164, 164, 104, 104, 104, 164, 164, \n\t164, 164, 164, 164, 164, 104, 104, 104, 164, 164, 164, 164, 104, 104, 164, 104, \n\t104, 104, 104, 104, 164, 164, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, \n\t104, 104, 104, 104, 104, 104, 104, 104, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 140, 140, 164, 140, 140, 140, 140, 140, 140, 164, 164, 164, 140, 140, \n\t140, 164, 140, 140, 140, 140, 164, 164, 164, 140, 140, 164, 140, 164, 140, 140, \n\t164, 164, 164, 140, 140, 164, 164, 164, 140, 140, 140, 164, 164, 164, 140, 140, \n\t140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 164, 164, 164, 164, 140, 140, \n\t140, 140, 140, 164, 164, 164, 140, 140, 140, 164, 140, 140, 140, 140, 164, 164, \n\t140, 164, 164, 164, 164, 164, 164, 140, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, \n\t140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 164, 164, 164, 164, 164, \n\n\n\t// block 12\n\t143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 164, 143, 143, \n\t143, 164, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, \n\t143, 143, 143, 143, 143, 143, 143, 143, 143, 164, 143, 143, 143, 143, 143, 143, \n\t143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 164, 164, 143, 143, 143, 143, \n\t143, 143, 143, 143, 143, 164, 143, 143, 143, 164, 143, 143, 143, 143, 164, 164, \n\t164, 164, 164, 164, 164, 143, 143, 164, 143, 143, 143, 164, 164, 143, 164, 164, \n\t143, 143, 143, 143, 164, 164, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, \n\t164, 164, 164, 164, 164, 164, 164, 143, 143, 143, 143, 143, 143, 143, 143, 143, \n\t 66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66, 164,  66,  66, \n\t 66, 164,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66, \n\t 66,  66,  66,  66,  66,  66,  66,  66,  66, 164,  66,  66,  66,  66,  66,  66, \n\t 66,  66,  66,  66, 164,  66,  66,  66,  66,  66, 164, 164,  66,  66,  66,  66, \n\t 66,  66,  66,  66,  66, 164,  66,  66,  66, 164,  66,  66,  66,  66, 164, 164, \n\t164, 164, 164, 164, 164,  66,  66, 164, 164, 164, 164, 164, 164,  66,  66, 164, \n\t 66,  66,  66,  66, 164, 164,  66,  66,  66,  66,  66,  66,  66,  66,  66,  66, \n\t164,  66,  66,  66, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 13\n\t 87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, 164,  87,  87, \n\t 87, 164,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t 87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t 87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t 87,  87,  87,  87,  87, 164,  87,  87,  87, 164,  87,  87,  87,  87,  87,  87, \n\t164, 164, 164, 164,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t 87,  87,  87,  87, 164, 164,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t 87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87,  87, \n\t164, 128, 128, 128, 164, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, \n\t128, 128, 128, 128, 128, 128, 128, 164, 164, 164, 128, 128, 128, 128, 128, 128, \n\t128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, \n\t128, 128, 164, 128, 128, 128, 128, 128, 128, 128, 128, 128, 164, 128, 164, 164, \n\t128, 128, 128, 128, 128, 128, 128, 164, 164, 164, 128, 164, 164, 164, 164, 128, \n\t128, 128, 128, 128, 128, 164, 128, 164, 128, 128, 128, 128, 128, 128, 128, 128, \n\t164, 164, 164, 164, 164, 164, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, \n\t164, 164, 128, 128, 128, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 14\n\t164, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, \n\t147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, \n\t147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, \n\t147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 164, 164, 164, 164, 163, \n\t147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, \n\t147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164,  69,  69, 164,  69, 164,  69,  69,  69,  69,  69, 164,  69,  69,  69,  69, \n\t 69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69, \n\t 69,  69,  69,  69, 164,  69, 164,  69,  69,  69,  69,  69,  69,  69,  69,  69, \n\t 69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69,  69, 164, 164, \n\t 69,  69,  69,  69,  69, 164,  69, 164,  69,  69,  69,  69,  69,  69,  69, 164, \n\t 69,  69,  69,  69,  69,  69,  69,  69,  69,  69, 164, 164,  69,  69,  69,  69, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 15\n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 164, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 164, 164, 164, \n\t164, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 164, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 164, 148, 148, \n\t148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 164, 148, 148, \n\t148, 148, 148, 148, 148, 163, 163, 163, 163, 148, 148, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 16\n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37, 164,  37, 164, 164, 164, 164, 164,  37, 164, 164, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, 163,  37,  37,  37,  37, \n\n\n\t// block 17\n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\n\n\t// block 18\n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36, 164,  36,  36,  36,  36, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36, 164,  36,  36,  36,  36, 164, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 36, 164,  36,  36,  36,  36, 164, 164,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\n\n\t// block 19\n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36, 164,  36,  36,  36,  36, 164, 164,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, 164, 164,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, 164, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36, 164, 164, 164, 164, 164, 164, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22, 164, 164,  22,  22,  22,  22,  22,  22, 164, 164, \n\n\n\t// block 20\n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\n\n\t// block 21\n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, \n\t101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 164, 164, 164, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 163, 163, 163, 119, 119, \n\t119, 119, 119, 119, 119, 119, 119, 119, 119, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 22\n\t145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, \n\t145, 145, 145, 145, 145, 145, 164, 164, 164, 164, 164, 164, 164, 164, 164, 145, \n\t 48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, \n\t 48,  48,  48,  48,  48, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, \n\t 17,  17,  17,  17, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 164, 136, 136, \n\t136, 164, 136, 136, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, 164, 164, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63, 164, 164, 164, 164, 164, 164, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 23\n\t 89,  89, 163, 163,  89, 163,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89, 164, 164, 164, 164, 164, 164, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89, 164, 164, 164, 164, 164, 164, 164, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, 164, 164, 164, 164, 164, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t 19,  19,  19,  19,  19,  19, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 24\n\t 72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, \n\t 72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, 164, \n\t 72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, 164, 164, 164, 164, \n\t 72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, 164, 164, 164, 164, \n\t 72, 164, 164, 164,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, \n\t138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, \n\t138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 164, 164, \n\t138, 138, 138, 138, 138, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 164, 164, 164, 164, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 164, 164, 164, 164, 164, 164, \n\t139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 164, 164, 164, 139, 139, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\t 63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63,  63, \n\n\n\t// block 25\n\t 16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16, \n\t 16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16,  16, 164, 164,  16,  16, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, 164, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, 164, 164,  68, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68, 164, 164, 164, 164, 164, 164, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68, 164, 164, 164, 164, 164, 164, \n\t 68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68,  68, 164, 164, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 26\n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, 164, 164, 164, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, \n\t  7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7,   7, 164, \n\t133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, \n\t133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, \n\t133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, \n\t133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, \n\t 10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10, \n\t 10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10, \n\t 10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10,  10, \n\t 10,  10,  10,  10, 164, 164, 164, 164, 164, 164, 164, 164,  10,  10,  10,  10, \n\n\n\t// block 27\n\t 71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71, \n\t 71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71, \n\t 71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71,  71, \n\t 71,  71,  71,  71,  71,  71,  71,  71, 164, 164, 164,  71,  71,  71,  71,  71, \n\t 71,  71,  71,  71,  71,  71,  71,  71,  71,  71, 164, 164, 164,  71,  71,  71, \n\t102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, \n\t102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, \n\t102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27, 164, 164, 164, 164, 164, 164, 164, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, 164, 164,  37,  37,  37, \n\t133, 133, 133, 133, 133, 133, 133, 133, 164, 164, 164, 164, 164, 164, 164, 164, \n\t162, 162, 162, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 163, 162, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, 162, 163, 163, \n\t163, 163, 163, 163, 162, 163, 163, 163, 162, 162, 163, 164, 164, 164, 164, 164, \n\n\n\t// block 28\n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  43,  43,  43,  43,  43,  27,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  43,  43,  43, \n\t 43,  43,  70,  70,  70,  70,  43,  43,  43,  43,  43,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  27,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  43, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\n\n\t// block 29\n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43, 164, 164,  43,  43,  43,  43,  43,  43, 164, 164, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43, 164, 164,  43,  43,  43,  43,  43,  43, 164, 164, \n\t 43,  43,  43,  43,  43,  43,  43,  43, 164,  43, 164,  43, 164,  43, 164,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, 164, 164, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43, 164,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43, 164,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43, 164, 164,  43,  43,  43,  43,  43,  43, 164,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t164, 164,  43,  43,  43, 164,  43,  43,  43,  43,  43,  43,  43,  43,  43, 164, \n\n\n\t// block 30\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163,  70, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,  70, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 31\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163,  43, 163, 163, 163,  70,  70, 163, 163, 163, 163, \n\t163, 163,  70, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,  70, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 32\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 33\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 34\n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\t 15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15,  15, \n\n\n\t// block 35\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 36\n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24,  24, \n\t 24,  24,  24,  24, 164, 164, 164, 164, 164,  24,  24,  24,  24,  24,  24,  24, \n\n\n\t// block 37\n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37,  37, \n\t 37,  37,  37,  37,  37,  37, 164,  37, 164, 164, 164, 164, 164,  37, 164, 164, \n\t144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, \n\t144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, \n\t144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, \n\t144, 144, 144, 144, 144, 144, 144, 144, 164, 164, 164, 164, 164, 164, 164, 144, \n\t144, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 144, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, \n\t 36,  36,  36,  36,  36,  36,  36, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\n\n\t// block 38\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 39\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\n\n\t// block 40\n\t163, 163, 163, 163, 163,  47, 163,  47, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163,  47,  47,  47,  47,  47,  47,  47,  47,  47, 162, 162, 162, 162,  46,  46, \n\t163, 163, 163, 163, 163, 163, 163, 163,  47,  47,  47,  47, 163, 163, 163, 163, \n\t164,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51, 164, 164, 162, 162, 163, 163,  51,  51,  51, \n\t163,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, 163, 163,  60,  60,  60, \n\n\n\t// block 41\n\t164, 164, 164, 164, 164,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13, \n\t 13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13, \n\t 13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13, \n\t164,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13, \n\t 13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13,  13, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\n\n\t// block 42\n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, 163, \n\n\n\t// block 43\n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 44\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\n\n\t// block 45\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 46\n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\n\n\t// block 47\n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 164, 164, 164, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, \n\t160, 160, 160, 160, 160, 160, 160, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75, \n\t 75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75, \n\t 75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75,  75, \n\n\n\t// block 48\n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\n\n\t// block 49\n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, \n\t153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 50\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 164, 164, 164, 164, 164, \n\t 70,  70, 164,  70, 164,  70,  70,  70,  70,  70, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\n\n\t// block 51\n\t134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, \n\t134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, \n\t134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, \n\t111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, \n\t111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, \n\t111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, \n\t111, 111, 111, 111, 111, 111, 111, 111, 164, 164, 164, 164, 164, 164, 164, 164, \n\t122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, \n\t122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, \n\t122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, \n\t122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, \n\t122, 122, 122, 122, 122, 122, 164, 164, 164, 164, 164, 164, 164, 164, 122, 122, \n\t122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 164, 164, 164, 164, 164, 164, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28,  28, \n\n\n\t// block 52\n\t 59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59, \n\t 59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59, \n\t 59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59, 163,  59, \n\t117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, \n\t117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, \n\t117, 117, 117, 117, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 117, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 164, 164, 164, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58,  58, 164, 163, \n\t 58,  58,  58,  58,  58,  58,  58,  58,  58,  58, 164, 164, 164, 164,  58,  58, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, 164, \n\n\n\t// block 53\n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, \n\t 21,  21,  21,  21,  21,  21,  21, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21,  21, 164, 164, \n\t 21,  21,  21,  21,  21,  21,  21,  21,  21,  21, 164, 164,  21,  21,  21,  21, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t 93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93,  93, \n\t142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, \n\t142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, \n\t142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, \n\t142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, \n\t142, 142, 142, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 142, 142, 142, 142, 142, \n\t 91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91, \n\t 91,  91,  91,  91,  91,  91,  91, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 54\n\t164,  36,  36,  36,  36,  36,  36, 164, 164,  36,  36,  36,  36,  36,  36, 164, \n\t164,  36,  36,  36,  36,  36,  36, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36,  36,  36,  36, 164, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 163,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  43,  70,  70,  70,  70, 163, 163, 164, 164, 164, 164, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22,  22, \n\t 91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91, \n\t 91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91, \n\t 91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91,  91, 164, 164, \n\t 91,  91,  91,  91,  91,  91,  91,  91,  91,  91, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 55\n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46, 164, 164, 164, 164,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 164, 164, 164, 164, \n\n\n\t// block 56\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 57\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 58\n\t 70,  70,  70,  70,  70,  70,  70, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164,   5,   5,   5,   5,   5, 164, 164, 164, 164, 164,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t 50,  50,  50,  50,  50,  50,  50, 164,  50,  50,  50,  50,  50, 164,  50, 164, \n\t 50,  50, 164,  50,  50, 164,  50,  50,  50,  50,  50,  50,  50,  50,  50,  50, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\n\n\t// block 59\n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\n\n\t// block 60\n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 163, 163, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t164, 164,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3, 164, 164, 164, 164, 164, 164, 164,   3, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\n\n\t// block 61\n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,  27,  27, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 164, 164, 164, 164, \n\t  3,   3,   3,   3,   3, 164,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164, 164, 163, \n\n\n\t// block 62\n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 163, 163, \n\t163,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t163,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, \n\t 60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60,  60, 163, 163, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, \n\t 46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46,  46, 164, \n\t164, 164,  46,  46,  46,  46,  46,  46, 164, 164,  46,  46,  46,  46,  46,  46, \n\t164, 164,  46,  46,  46,  46,  46,  46, 164, 164,  46,  46,  46, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 163, 163, 163, 163, 163, 164, 164, \n\n\n\t// block 63\n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, 164,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74, 164,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, 164,  74,  74, 164,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, 164, 164, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, \n\t 74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74, 164, 164, 164, 164, 164, \n\n\n\t// block 64\n\t163, 163, 163, 164, 164, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, \n\t 43, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 164, 164, \n\n\n\t// block 65\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76, \n\t 76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76,  76, 164, 164, 164, \n\t 20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20, \n\t 20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20, \n\t 20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20, \n\t 20, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t162, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\n\n\t// block 66\n\t 57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57, \n\t 57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57,  57, \n\t 57,  57,  57,  57, 164, 164, 164, 164, 164, 164, 164, 164, 164,  57,  57,  57, \n\t 41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41, \n\t 41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41, 164, 164, 164, 164, 164, \n\t110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, \n\t110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, \n\t110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 164, 164, 164, 164, 164, \n\t152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, \n\t152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 164, 152, \n\t157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, \n\t157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, \n\t157, 157, 157, 157, 164, 164, 164, 164, 157, 157, 157, 157, 157, 157, 157, 157, \n\t157, 157, 157, 157, 157, 157, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 67\n\t 31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, \n\t 31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, \n\t 31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, \n\t 31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, \n\t 31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, \n\t124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, \n\t124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, \n\t124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, \n\t106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, \n\t106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 164, 164, \n\t106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 164, 164, 164, 164, 164, 164, \n\t105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, \n\t105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, \n\t105, 105, 105, 105, 164, 164, 164, 164, 105, 105, 105, 105, 105, 105, 105, 105, \n\t105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, \n\t105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 164, 164, 164, 164, \n\n\n\t// block 68\n\t 34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34, \n\t 34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34,  34, \n\t 34,  34,  34,  34,  34,  34,  34,  34, 164, 164, 164, 164, 164, 164, 164, 164, \n\t  1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1, \n\t  1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1, \n\t  1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1, \n\t  1,   1,   1,   1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,   1, \n\t154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 164, 154, 154, 154, 154, \n\t154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 164, 154, 154, 154, 154, \n\t154, 154, 154, 164, 154, 154, 164, 154, 154, 154, 154, 154, 154, 154, 154, 154, \n\t154, 154, 164, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, \n\t154, 154, 164, 154, 154, 154, 154, 154, 154, 154, 164, 154, 154, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 69\n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\n\n\t// block 70\n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73,  73, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73, \n\t 73,  73,  73,  73,  73,  73, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 73,  73,  73,  73,  73,  73,  73,  73, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 70,  70,  70,  70,  70,  70, 164,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70, 164,  70,  70,  70,  70,  70,  70,  70,  70,  70, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 71\n\t 26,  26,  26,  26,  26,  26, 164, 164,  26, 164,  26,  26,  26,  26,  26,  26, \n\t 26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, \n\t 26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, \n\t 26,  26,  26,  26,  26,  26, 164,  26,  26, 164, 164, 164,  26, 164, 164,  26, \n\t  4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4, \n\t  4,   4,   4,   4,   4,   4, 164,   4,   4,   4,   4,   4,   4,   4,   4,   4, \n\t108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, \n\t108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, \n\t 97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97, \n\t 97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97, 164, \n\t164, 164, 164, 164, 164, 164, 164,  97,  97,  97,  97,  97,  97,  97,  97,  97, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49,  49, \n\t 49,  49,  49, 164,  49,  49, 164, 164, 164, 164, 164,  49,  49,  49,  49,  49, \n\n\n\t// block 72\n\t114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, \n\t114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 164, 164, 164, 114, \n\t 77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77,  77, \n\t 77,  77,  77,  77,  77,  77,  77,  77,  77,  77, 164, 164, 164, 164, 164,  77, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86, \n\t 86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86,  86, \n\t 85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85, \n\t 85,  85,  85,  85,  85,  85,  85,  85, 164, 164, 164, 164,  85,  85,  85,  85, \n\t 85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85, \n\t164, 164,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85, \n\t 85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85, \n\t 85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85, \n\n\n\t// block 73\n\t 62,  62,  62,  62, 164,  62,  62, 164, 164, 164, 164, 164,  62,  62,  62,  62, \n\t 62,  62,  62,  62, 164,  62,  62,  62, 164,  62,  62,  62,  62,  62,  62,  62, \n\t 62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62,  62, \n\t 62,  62,  62,  62,  62,  62, 164, 164,  62,  62,  62, 164, 164, 164, 164,  62, \n\t 62,  62,  62,  62,  62,  62,  62,  62,  62, 164, 164, 164, 164, 164, 164, 164, \n\t 62,  62,  62,  62,  62,  62,  62,  62,  62, 164, 164, 164, 164, 164, 164, 164, \n\t121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, \n\t121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, \n\t 96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96, \n\t 96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81, \n\t 81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81, \n\t 81,  81,  81,  81,  81,  81,  81, 164, 164, 164, 164,  81,  81,  81,  81,  81, \n\t 81,  81,  81,  81,  81,  81,  81, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 74\n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6, 164, 164, 164,   6,   6,   6,   6,   6,   6,   6, \n\t116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, \n\t116, 116, 116, 116, 116, 116, 164, 164, 116, 116, 116, 116, 116, 116, 116, 116, \n\t112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, \n\t112, 112, 112, 164, 164, 164, 164, 164, 112, 112, 112, 112, 112, 112, 112, 112, \n\t113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, \n\t113, 113, 164, 164, 164, 164, 164, 164, 164, 113, 113, 113, 113, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 113, 113, 113, 113, 113, 113, 113, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 75\n\t103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, \n\t103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, \n\t103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, \n\t103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, \n\t103, 103, 103, 103, 103, 103, 103, 103, 103, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, \n\t 56,  56,  56, 164, 164, 164, 164, 164, 164, 164,  56,  56,  56,  56,  56,  56, \n\n\n\t// block 76\n\t118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, \n\t118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, \n\t118, 118, 118, 118, 118, 118, 118, 118, 164, 164, 164, 164, 164, 164, 164, 164, \n\t118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 77\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164, \n\t159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, \n\t159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, \n\t159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 164, 159, 159, 159, 164, 164, \n\t159, 159, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,   3,   3,   3, \n\n\n\t// block 78\n\t130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, \n\t130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, \n\t130, 130, 130, 130, 130, 130, 130, 130, 164, 164, 164, 164, 164, 164, 164, 164, \n\t129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, \n\t129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, \n\t129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, \n\t107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23, \n\t 23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23,  23, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35,  35, \n\t 35,  35,  35,  35,  35,  35,  35, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 79\n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, 164, 164, \n\t164, 164,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14, \n\t 14,  14,  14,  14,  14,  14, 164, 164, 164, 164, 164, 164, 164, 164, 164,  14, \n\t 67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67, \n\t 67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67, \n\t 67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67, \n\t 67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67,  67, \n\t 67,  67,  67, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,  67, 164, 164, \n\t131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, \n\t131, 131, 131, 131, 131, 131, 131, 131, 131, 164, 164, 164, 164, 164, 164, 164, \n\t131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 80\n\t 18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, \n\t 18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, \n\t 18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, \n\t 18,  18,  18,  18,  18, 164,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, \n\t 18,  18,  18,  18,  18,  18,  18,  18, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78, \n\t 78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78,  78, \n\t 78,  78,  78,  78,  78,  78,  78, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, \n\t164, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, \n\t128, 128, 128, 128, 128, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 81\n\t 64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64, \n\t 64,  64, 164,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64, \n\t 64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64, \n\t 64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64, \n\t 64,  64, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 92,  92,  92,  92,  92,  92,  92, 164,  92, 164,  92,  92,  92,  92, 164,  92, \n\t 92,  92,  92,  92,  92,  92,  92,  92,  92,  92,  92,  92,  92,  92, 164,  92, \n\t 92,  92,  92,  92,  92,  92,  92,  92,  92,  92, 164, 164, 164, 164, 164, 164, \n\t127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, \n\t127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, \n\t127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, \n\t127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 164, 164, 164, 164, 164, \n\t127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 82\n\t 42,  42,  42,  42, 164,  42,  42,  42,  42,  42,  42,  42,  42, 164, 164,  42, \n\t 42, 164, 164,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42, \n\t 42,  42,  42,  42,  42,  42,  42,  42,  42, 164,  42,  42,  42,  42,  42,  42, \n\t 42, 164,  42,  42, 164,  42,  42,  42,  42,  42, 164, 162,  42,  42,  42,  42, \n\t 42,  42,  42,  42,  42, 164, 164,  42,  42, 164, 164,  42,  42,  42, 164, 164, \n\t 42, 164, 164, 164, 164, 164, 164,  42, 164, 164, 164, 164, 164,  42,  42,  42, \n\t 42,  42,  42,  42, 164, 164,  42,  42,  42,  42,  42,  42,  42, 164, 164, 164, \n\t 42,  42,  42,  42,  42, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 83\n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, \n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, \n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, \n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, \n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, \n\t 98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98, 164,  98,  98,  98, \n\t 98,  98, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, \n\t149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, \n\t149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, \n\t149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, \n\t149, 149, 149, 149, 149, 149, 149, 149, 164, 164, 164, 164, 164, 164, 164, 164, \n\t149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 84\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, \n\t126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, \n\t126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, \n\t126, 126, 126, 126, 126, 126, 164, 164, 126, 126, 126, 126, 126, 126, 126, 126, \n\t126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, \n\t126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 85\n\t 88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88, \n\t 88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88, \n\t 88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88, \n\t 88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88,  88, \n\t 88,  88,  88,  88,  88, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 88,  88,  88,  88,  88,  88,  88,  88,  88,  88, 164, 164, 164, 164, 164, 164, \n\t 89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89,  89, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, \n\t137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, \n\t137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, \n\t137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 164, 164, 164, 164, 164, 164, \n\t137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 86\n\t  2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2, \n\t  2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2, 164, 164,   2,   2,   2, \n\t  2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2, 164, 164, 164, 164, \n\t  2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2, \n\t  2,   2,   2,   2,   2,   2,   2, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 87\n\t 30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30, \n\t 30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30, \n\t 30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30, \n\t 30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30,  30, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, \n\t155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, \n\t155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, \n\t155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, \n\t155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, \n\t155, 155, 155, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 155, \n\n\n\t// block 88\n\t 29,  29,  29,  29,  29,  29,  29, 164, 164,  29, 164, 164,  29,  29,  29,  29, \n\t 29,  29,  29,  29, 164,  29,  29, 164,  29,  29,  29,  29,  29,  29,  29,  29, \n\t 29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29,  29, \n\t 29,  29,  29,  29,  29,  29, 164,  29,  29, 164, 164,  29,  29,  29,  29,  29, \n\t 29,  29,  29,  29,  29,  29,  29, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 29,  29,  29,  29,  29,  29,  29,  29,  29,  29, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 95,  95,  95,  95,  95,  95,  95,  95, 164, 164,  95,  95,  95,  95,  95,  95, \n\t 95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95, \n\t 95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95, \n\t 95,  95,  95,  95,  95,  95,  95,  95, 164, 164,  95,  95,  95,  95,  95,  95, \n\t 95,  95,  95,  95,  95, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 89\n\t161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, \n\t161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, \n\t161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, \n\t161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, \n\t161, 161, 161, 161, 161, 161, 161, 161, 164, 164, 164, 164, 164, 164, 164, 164, \n\t132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, \n\t132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, \n\t132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, \n\t132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, \n\t132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, \n\t132, 132, 132, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19,  19, \n\t109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, \n\t109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, \n\t109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, \n\t109, 109, 109, 109, 109, 109, 109, 109, 109, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 90\n\t 28,  28,  28,  28,  28,  28,  28,  28,  28,  28, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 91\n\t 12,  12,  12,  12,  12,  12,  12,  12,  12, 164,  12,  12,  12,  12,  12,  12, \n\t 12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12, \n\t 12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12, \n\t 12,  12,  12,  12,  12,  12,  12, 164,  12,  12,  12,  12,  12,  12,  12,  12, \n\t 12,  12,  12,  12,  12,  12, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12, \n\t 12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,  12, 164, 164, 164, \n\t 82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82, \n\t 82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82, \n\t164, 164,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82,  82, \n\t 82,  82,  82,  82,  82,  82,  82,  82, 164,  82,  82,  82,  82,  82,  82,  82, \n\t 82,  82,  82,  82,  82,  82,  82, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 92\n\t 40,  40,  40,  40,  40,  40,  40, 164,  40,  40, 164,  40,  40,  40,  40,  40, \n\t 40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40, \n\t 40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40, \n\t 40,  40,  40,  40,  40,  40,  40, 164, 164, 164,  40, 164,  40,  40, 164,  40, \n\t 40,  40,  40,  40,  40,  40,  40,  40, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 40,  40,  40,  40,  40,  40,  40,  40,  40,  40, 164, 164, 164, 164, 164, 164, \n\t 39,  39,  39,  39,  39,  39, 164,  39,  39, 164,  39,  39,  39,  39,  39,  39, \n\t 39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39, \n\t 39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39,  39, 164, \n\t 39,  39, 164,  39,  39,  39,  39,  39,  39, 164, 164, 164, 164, 164, 164, 164, \n\t 39,  39,  39,  39,  39,  39,  39,  39,  39,  39, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 93\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79,  79, \n\t 79,  79,  79,  79,  79,  79,  79,  79,  79, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 94\n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61, 164,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, 164, 164, 164,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61,  61, \n\t 61,  61,  61,  61,  61,  61,  61,  61,  61,  61, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 75, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, \n\t140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, \n\t140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, \n\t140, 140, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 140, \n\n\n\t// block 95\n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\n\n\t// block 96\n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 97\n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 164, \n\t158, 158, 158, 158, 158, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\n\n\t// block 98\n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, \n\t158, 158, 158, 158, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 99\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25,  25, \n\t 25,  25,  25, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 100\n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\n\n\t// block 101\n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33,  33, \n\t 33,  33,  33,  33,  33,  33, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 102\n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\n\n\t// block 103\n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52,  52, \n\t 52,  52,  52,  52,  52,  52,  52, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 104\n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\n\n\t// block 105\n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8, \n\t  8,   8,   8,   8,   8,   8,   8,   8,   8, 164, 164, 164, 164, 164, 164, 164, \n\t 90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90, \n\t 90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90,  90, 164, \n\t 90,  90,  90,  90,  90,  90,  90,  90,  90,  90, 164, 164, 164, 164,  90,  90, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 164, \n\t150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 164, 164, 164, 164, 164, 164, \n\t  9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9, \n\t  9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9, 164, 164, \n\t  9,   9,   9,   9,   9,   9, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 106\n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53, 164,  53,  53,  53,  53,  53, \n\t 53,  53, 164,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53,  53,  53, 164, 164, 164, 164, 164,  53,  53,  53, \n\t 53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  53, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 107\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, \n\t 83,  83,  83,  83,  83,  83,  83,  83,  83,  83,  83, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 108\n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 164, 164, 164, 164, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 164, 164, 164, 164, 164, 164, 164, 115, \n\t115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t141, 100,  47,  47,  65, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 47,  47, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 109\n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\n\n\t// block 110\n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, \n\t141, 141, 141, 141, 141, 141, 141, 141, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 111\n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\n\n\t// block 112\n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65,  65, \n\t 65,  65,  65,  65,  65,  65, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 113\n\t141, 141, 141, 141, 141, 141, 141, 141, 141, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 114\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 60,  60,  60,  60, 164,  60,  60,  60,  60,  60,  60,  60, 164,  60,  60, 164, \n\n\n\t// block 115\n\t 60,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\n\n\t// block 116\n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51,  51, \n\t 60,  60,  60, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164,  51, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 51,  51,  51, 164, 164,  60, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164,  60,  60,  60,  60, 164, 164, 164, 164, 164, 164, 164, 164, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\n\n\t// block 117\n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, \n\t100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 164, 164, 164, 164, \n\n\n\t// block 118\n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 164, 164, 164, 164, 164, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 164, 164, 164, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32, 164, 164, 164, 164, 164, 164, 164, \n\t 32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 164, 164,  32,  32,  32,  32, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 119\n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 164, 164, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 120\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 121\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 164, 164, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, \n\t162, 162, 162, 163, 163, 162, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 122\n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43,  43, \n\t 43,  43,  43,  43,  43,  43, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 123\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 124\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 163, 163, \n\t164, 164, 163, 164, 164, 163, 163, 164, 164, 163, 163, 163, 163, 164, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 163, 164, 163, 163, 163, \n\t163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 125\n\t163, 163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 164, 164, 163, 163, 163, \n\t163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 164, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 163, 163, 163, 163, 164, \n\t163, 163, 163, 163, 163, 164, 163, 164, 164, 164, 163, 163, 163, 163, 163, 163, \n\t163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 126\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 127\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 128\n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\n\n\t// block 129\n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 123, 123, 123, 123, 123, \n\t164, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 130\n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, \n\t 70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70,  70, 164, \n\t164, 164, 164, 164, 164,  70,  70,  70,  70,  70,  70, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 131\n\t 38,  38,  38,  38,  38,  38,  38, 164,  38,  38,  38,  38,  38,  38,  38,  38, \n\t 38,  38,  38,  38,  38,  38,  38,  38,  38, 164, 164,  38,  38,  38,  38,  38, \n\t 38,  38, 164,  38,  38, 164,  38,  38,  38,  38,  38, 164, 164, 164, 164, 164, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, \n\t 27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,  27, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 132\n\t 54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54, \n\t 54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54, \n\t 54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54, 164, 164, 164, \n\t 54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  54, 164, 164, \n\t 54,  54,  54,  54,  54,  54,  54,  54,  54,  54, 164, 164, 164, 164,  54,  54, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 133\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, \n\t151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, \n\t156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, \n\t156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, \n\t156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 164, 164, 164, 164, 164, 156, \n\n\n\t// block 134\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94, \n\t 94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94,  94, \n\t 94,  94,  94,  94,  94,  94,  94,  94,  94,  94, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 135\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 36,  36,  36,  36,  36,  36,  36, 164,  36,  36,  36,  36, 164,  36,  36, 164, \n\t 36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,  36, 164, \n\n\n\t// block 136\n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84, 164, 164,  84,  84,  84,  84,  84,  84,  84,  84,  84, \n\t 84,  84,  84,  84,  84,  84,  84, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 137\n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, \n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 164, 164, 164, 164, \n\t  0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 164, 164, 164, 164,   0,   0, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 138\n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 139\n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 140\n\t  3,   3,   3,   3, 164,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, \n\t164,   3,   3, 164,   3, 164, 164,   3, 164,   3,   3,   3,   3,   3,   3,   3, \n\t  3,   3,   3, 164,   3,   3,   3,   3, 164,   3, 164,   3, 164, 164, 164, 164, \n\t164, 164,   3, 164, 164, 164, 164,   3, 164,   3, 164,   3, 164,   3,   3,   3, \n\t164,   3,   3, 164,   3, 164, 164,   3, 164,   3, 164,   3, 164,   3, 164,   3, \n\t164,   3,   3, 164,   3, 164, 164,   3,   3,   3,   3, 164,   3,   3,   3,   3, \n\t  3,   3,   3, 164,   3,   3,   3,   3, 164,   3,   3,   3,   3, 164,   3, 164, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164, 164, 164, 164, \n\t164,   3,   3,   3, 164,   3,   3,   3,   3,   3, 164,   3,   3,   3,   3,   3, \n\t  3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t  3,   3, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 141\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, \n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 142\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\n\n\t// block 143\n\t 51, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 144\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, \n\n\n\t// block 145\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\t163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 146\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, \n\t163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 147\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 163, \n\t163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 148\n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 149\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 150\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, 164, 164, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\n\n\t// block 151\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\n\n\t// block 152\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\n\n\t// block 153\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 154\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 155\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 164, 164, 164, 164, 164, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\n\n\t// block 156\n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t 47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 157\n\t164, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, \n\n\n\t// block 158\n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, \n\t164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164\n\t};\n\n\tinline ::boost::uint8_t script_lookup(::boost::uint32_t ch)\n\t{\n\t\t::boost::uint32_t block_offset = script_stage1[ch / 256] * 256;\n\t\treturn script_stage2[block_offset + ch % 256];\n\t}\n\n}}}} // namespace boost::spirit::unicode::detail\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode/uppercase_table.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n\n\tAUTOGENERATED. DO NOT EDIT!!!\n==============================================================================*/\n#include <boost/cstdint.hpp>\n\nnamespace boost { namespace spirit { namespace ucd { namespace detail\n{\n\tstatic const ::boost::uint8_t uppercase_stage1[] = {\n\n\t  0,   1,   2,   3,   4,   5,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  7,   6,   6,   8,   6,   6,   6,   6,   6,   6,   6,   6,   9,  10,  11,  12, \n\t  6,  13,   6,   6,  14,   6,   6,   6,   6,   6,   6,   6,  15,  16,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,  17,  18,   6,   6,   6,  19,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,  20, \n\t  6,   6,   6,   6,  21,  22,   6,   6,   6,   6,   6,   6,  23,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,  24,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,  25,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,  26,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, \n\t  6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6\n\t};\n\n\tstatic const ::boost::uint32_t uppercase_stage2[] = {\n\n\t// block 0\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,     65,     66,     67,     68,     69,     70,     71,     72,     73,     74,     75,     76,     77,     78,     79, \n\t\t80,     81,     82,     83,     84,     85,     86,     87,     88,     89,     90,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,    924,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t   192,    193,    194,    195,    196,    197,    198,    199,    200,    201,    202,    203,    204,    205,    206,    207, \n\t   208,    209,    210,    211,    212,    213,    214,      0,    216,    217,    218,    219,    220,    221,    222,    376, \n\n\n\t// block 1\n\t\t 0,    256,      0,    258,      0,    260,      0,    262,      0,    264,      0,    266,      0,    268,      0,    270, \n\t\t 0,    272,      0,    274,      0,    276,      0,    278,      0,    280,      0,    282,      0,    284,      0,    286, \n\t\t 0,    288,      0,    290,      0,    292,      0,    294,      0,    296,      0,    298,      0,    300,      0,    302, \n\t\t 0,     73,      0,    306,      0,    308,      0,    310,      0,      0,    313,      0,    315,      0,    317,      0, \n\t   319,      0,    321,      0,    323,      0,    325,      0,    327,      0,      0,    330,      0,    332,      0,    334, \n\t\t 0,    336,      0,    338,      0,    340,      0,    342,      0,    344,      0,    346,      0,    348,      0,    350, \n\t\t 0,    352,      0,    354,      0,    356,      0,    358,      0,    360,      0,    362,      0,    364,      0,    366, \n\t\t 0,    368,      0,    370,      0,    372,      0,    374,      0,      0,    377,      0,    379,      0,    381,     83, \n\t   579,      0,      0,    386,      0,    388,      0,      0,    391,      0,      0,      0,    395,      0,      0,      0, \n\t\t 0,      0,    401,      0,      0,    502,      0,      0,      0,    408,    573,      0,      0,      0,    544,      0, \n\t\t 0,    416,      0,    418,      0,    420,      0,      0,    423,      0,      0,      0,      0,    428,      0,      0, \n\t   431,      0,      0,      0,    435,      0,    437,      0,      0,    440,      0,      0,      0,    444,      0,    503, \n\t\t 0,      0,      0,      0,      0,    452,    452,      0,    455,    455,      0,    458,    458,      0,    461,      0, \n\t   463,      0,    465,      0,    467,      0,    469,      0,    471,      0,    473,      0,    475,    398,      0,    478, \n\t\t 0,    480,      0,    482,      0,    484,      0,    486,      0,    488,      0,    490,      0,    492,      0,    494, \n\t\t 0,      0,    497,    497,      0,    500,      0,      0,      0,    504,      0,    506,      0,    508,      0,    510, \n\n\n\t// block 2\n\t\t 0,    512,      0,    514,      0,    516,      0,    518,      0,    520,      0,    522,      0,    524,      0,    526, \n\t\t 0,    528,      0,    530,      0,    532,      0,    534,      0,    536,      0,    538,      0,    540,      0,    542, \n\t\t 0,      0,      0,    546,      0,    548,      0,    550,      0,    552,      0,    554,      0,    556,      0,    558, \n\t\t 0,    560,      0,    562,      0,      0,      0,      0,      0,      0,      0,      0,    571,      0,      0,  11390, \n\t 11391,      0,    577,      0,      0,      0,      0,    582,      0,    584,      0,    586,      0,    588,      0,    590, \n\t 11375,  11373,  11376,    385,    390,      0,    393,    394,      0,    399,      0,    400,  42923,      0,      0,      0, \n\t   403,  42924,      0,    404,      0,  42893,  42922,      0,    407,    406,  42926,  11362,  42925,      0,      0,    412, \n\t\t 0,  11374,    413,      0,      0,    415,      0,      0,      0,      0,      0,      0,      0,  11364,      0,      0, \n\t   422,      0,  42949,    425,      0,      0,      0,  42929,    430,    580,    433,    434,    581,      0,      0,      0, \n\t\t 0,      0,    439,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,  42930,  42928,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 3\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,    921,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,    880,      0,    882,      0,      0,      0,    886,      0,      0,      0,   1021,   1022,   1023,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,    902,    904,    905,    906, \n\t\t 0,    913,    914,    915,    916,    917,    918,    919,    920,    921,    922,    923,    924,    925,    926,    927, \n\t   928,    929,    931,    931,    932,    933,    934,    935,    936,    937,    938,    939,    908,    910,    911,      0, \n\t   914,    920,      0,      0,      0,    934,    928,    975,      0,    984,      0,    986,      0,    988,      0,    990, \n\t\t 0,    992,      0,    994,      0,    996,      0,    998,      0,   1000,      0,   1002,      0,   1004,      0,   1006, \n\t   922,    929,   1017,    895,      0,    917,      0,      0,   1015,      0,      0,   1018,      0,      0,      0,      0, \n\n\n\t// block 4\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  1040,   1041,   1042,   1043,   1044,   1045,   1046,   1047,   1048,   1049,   1050,   1051,   1052,   1053,   1054,   1055, \n\t  1056,   1057,   1058,   1059,   1060,   1061,   1062,   1063,   1064,   1065,   1066,   1067,   1068,   1069,   1070,   1071, \n\t  1024,   1025,   1026,   1027,   1028,   1029,   1030,   1031,   1032,   1033,   1034,   1035,   1036,   1037,   1038,   1039, \n\t\t 0,   1120,      0,   1122,      0,   1124,      0,   1126,      0,   1128,      0,   1130,      0,   1132,      0,   1134, \n\t\t 0,   1136,      0,   1138,      0,   1140,      0,   1142,      0,   1144,      0,   1146,      0,   1148,      0,   1150, \n\t\t 0,   1152,      0,      0,      0,      0,      0,      0,      0,      0,      0,   1162,      0,   1164,      0,   1166, \n\t\t 0,   1168,      0,   1170,      0,   1172,      0,   1174,      0,   1176,      0,   1178,      0,   1180,      0,   1182, \n\t\t 0,   1184,      0,   1186,      0,   1188,      0,   1190,      0,   1192,      0,   1194,      0,   1196,      0,   1198, \n\t\t 0,   1200,      0,   1202,      0,   1204,      0,   1206,      0,   1208,      0,   1210,      0,   1212,      0,   1214, \n\t\t 0,      0,   1217,      0,   1219,      0,   1221,      0,   1223,      0,   1225,      0,   1227,      0,   1229,   1216, \n\t\t 0,   1232,      0,   1234,      0,   1236,      0,   1238,      0,   1240,      0,   1242,      0,   1244,      0,   1246, \n\t\t 0,   1248,      0,   1250,      0,   1252,      0,   1254,      0,   1256,      0,   1258,      0,   1260,      0,   1262, \n\t\t 0,   1264,      0,   1266,      0,   1268,      0,   1270,      0,   1272,      0,   1274,      0,   1276,      0,   1278, \n\n\n\t// block 5\n\t\t 0,   1280,      0,   1282,      0,   1284,      0,   1286,      0,   1288,      0,   1290,      0,   1292,      0,   1294, \n\t\t 0,   1296,      0,   1298,      0,   1300,      0,   1302,      0,   1304,      0,   1306,      0,   1308,      0,   1310, \n\t\t 0,   1312,      0,   1314,      0,   1316,      0,   1318,      0,   1320,      0,   1322,      0,   1324,      0,   1326, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,   1329,   1330,   1331,   1332,   1333,   1334,   1335,   1336,   1337,   1338,   1339,   1340,   1341,   1342,   1343, \n\t  1344,   1345,   1346,   1347,   1348,   1349,   1350,   1351,   1352,   1353,   1354,   1355,   1356,   1357,   1358,   1359, \n\t  1360,   1361,   1362,   1363,   1364,   1365,   1366,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 6\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 7\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  7312,   7313,   7314,   7315,   7316,   7317,   7318,   7319,   7320,   7321,   7322,   7323,   7324,   7325,   7326,   7327, \n\t  7328,   7329,   7330,   7331,   7332,   7333,   7334,   7335,   7336,   7337,   7338,   7339,   7340,   7341,   7342,   7343, \n\t  7344,   7345,   7346,   7347,   7348,   7349,   7350,   7351,   7352,   7353,   7354,      0,      0,   7357,   7358,   7359, \n\n\n\t// block 8\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,   5104,   5105,   5106,   5107,   5108,   5109,      0,      0, \n\n\n\t// block 9\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  1042,   1044,   1054,   1057,   1058,   1058,   1066,   1122,  42570,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 10\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,  42877,      0,      0,      0,  11363,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,  42950,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 11\n\t\t 0,   7680,      0,   7682,      0,   7684,      0,   7686,      0,   7688,      0,   7690,      0,   7692,      0,   7694, \n\t\t 0,   7696,      0,   7698,      0,   7700,      0,   7702,      0,   7704,      0,   7706,      0,   7708,      0,   7710, \n\t\t 0,   7712,      0,   7714,      0,   7716,      0,   7718,      0,   7720,      0,   7722,      0,   7724,      0,   7726, \n\t\t 0,   7728,      0,   7730,      0,   7732,      0,   7734,      0,   7736,      0,   7738,      0,   7740,      0,   7742, \n\t\t 0,   7744,      0,   7746,      0,   7748,      0,   7750,      0,   7752,      0,   7754,      0,   7756,      0,   7758, \n\t\t 0,   7760,      0,   7762,      0,   7764,      0,   7766,      0,   7768,      0,   7770,      0,   7772,      0,   7774, \n\t\t 0,   7776,      0,   7778,      0,   7780,      0,   7782,      0,   7784,      0,   7786,      0,   7788,      0,   7790, \n\t\t 0,   7792,      0,   7794,      0,   7796,      0,   7798,      0,   7800,      0,   7802,      0,   7804,      0,   7806, \n\t\t 0,   7808,      0,   7810,      0,   7812,      0,   7814,      0,   7816,      0,   7818,      0,   7820,      0,   7822, \n\t\t 0,   7824,      0,   7826,      0,   7828,      0,      0,      0,      0,      0,   7776,      0,      0,      0,      0, \n\t\t 0,   7840,      0,   7842,      0,   7844,      0,   7846,      0,   7848,      0,   7850,      0,   7852,      0,   7854, \n\t\t 0,   7856,      0,   7858,      0,   7860,      0,   7862,      0,   7864,      0,   7866,      0,   7868,      0,   7870, \n\t\t 0,   7872,      0,   7874,      0,   7876,      0,   7878,      0,   7880,      0,   7882,      0,   7884,      0,   7886, \n\t\t 0,   7888,      0,   7890,      0,   7892,      0,   7894,      0,   7896,      0,   7898,      0,   7900,      0,   7902, \n\t\t 0,   7904,      0,   7906,      0,   7908,      0,   7910,      0,   7912,      0,   7914,      0,   7916,      0,   7918, \n\t\t 0,   7920,      0,   7922,      0,   7924,      0,   7926,      0,   7928,      0,   7930,      0,   7932,      0,   7934, \n\n\n\t// block 12\n\t  7944,   7945,   7946,   7947,   7948,   7949,   7950,   7951,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  7960,   7961,   7962,   7963,   7964,   7965,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  7976,   7977,   7978,   7979,   7980,   7981,   7982,   7983,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  7992,   7993,   7994,   7995,   7996,   7997,   7998,   7999,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8008,   8009,   8010,   8011,   8012,   8013,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,   8025,      0,   8027,      0,   8029,      0,   8031,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8040,   8041,   8042,   8043,   8044,   8045,   8046,   8047,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8122,   8123,   8136,   8137,   8138,   8139,   8154,   8155,   8184,   8185,   8170,   8171,   8186,   8187,      0,      0, \n\t  8072,   8073,   8074,   8075,   8076,   8077,   8078,   8079,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8088,   8089,   8090,   8091,   8092,   8093,   8094,   8095,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8104,   8105,   8106,   8107,   8108,   8109,   8110,   8111,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8120,   8121,      0,   8124,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,    921,      0, \n\t\t 0,      0,      0,   8140,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8152,   8153,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8168,   8169,      0,      0,      0,   8172,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,   8188,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 13\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,   8498,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  8544,   8545,   8546,   8547,   8548,   8549,   8550,   8551,   8552,   8553,   8554,   8555,   8556,   8557,   8558,   8559, \n\t\t 0,      0,      0,      0,   8579,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 14\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  9398,   9399,   9400,   9401,   9402,   9403,   9404,   9405,   9406,   9407,   9408,   9409,   9410,   9411,   9412,   9413, \n\t  9414,   9415,   9416,   9417,   9418,   9419,   9420,   9421,   9422,   9423,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 15\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 11264,  11265,  11266,  11267,  11268,  11269,  11270,  11271,  11272,  11273,  11274,  11275,  11276,  11277,  11278,  11279, \n\t 11280,  11281,  11282,  11283,  11284,  11285,  11286,  11287,  11288,  11289,  11290,  11291,  11292,  11293,  11294,  11295, \n\t 11296,  11297,  11298,  11299,  11300,  11301,  11302,  11303,  11304,  11305,  11306,  11307,  11308,  11309,  11310,  11311, \n\t\t 0,  11360,      0,      0,      0,    570,    574,      0,  11367,      0,  11369,      0,  11371,      0,      0,      0, \n\t\t 0,      0,      0,  11378,      0,      0,  11381,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,  11392,      0,  11394,      0,  11396,      0,  11398,      0,  11400,      0,  11402,      0,  11404,      0,  11406, \n\t\t 0,  11408,      0,  11410,      0,  11412,      0,  11414,      0,  11416,      0,  11418,      0,  11420,      0,  11422, \n\t\t 0,  11424,      0,  11426,      0,  11428,      0,  11430,      0,  11432,      0,  11434,      0,  11436,      0,  11438, \n\t\t 0,  11440,      0,  11442,      0,  11444,      0,  11446,      0,  11448,      0,  11450,      0,  11452,      0,  11454, \n\t\t 0,  11456,      0,  11458,      0,  11460,      0,  11462,      0,  11464,      0,  11466,      0,  11468,      0,  11470, \n\t\t 0,  11472,      0,  11474,      0,  11476,      0,  11478,      0,  11480,      0,  11482,      0,  11484,      0,  11486, \n\t\t 0,  11488,      0,  11490,      0,      0,      0,      0,      0,      0,      0,      0,  11499,      0,  11501,      0, \n\t\t 0,      0,      0,  11506,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 16\n\t  4256,   4257,   4258,   4259,   4260,   4261,   4262,   4263,   4264,   4265,   4266,   4267,   4268,   4269,   4270,   4271, \n\t  4272,   4273,   4274,   4275,   4276,   4277,   4278,   4279,   4280,   4281,   4282,   4283,   4284,   4285,   4286,   4287, \n\t  4288,   4289,   4290,   4291,   4292,   4293,      0,   4295,      0,      0,      0,      0,      0,   4301,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 17\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,  42560,      0,  42562,      0,  42564,      0,  42566,      0,  42568,      0,  42570,      0,  42572,      0,  42574, \n\t\t 0,  42576,      0,  42578,      0,  42580,      0,  42582,      0,  42584,      0,  42586,      0,  42588,      0,  42590, \n\t\t 0,  42592,      0,  42594,      0,  42596,      0,  42598,      0,  42600,      0,  42602,      0,  42604,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,  42624,      0,  42626,      0,  42628,      0,  42630,      0,  42632,      0,  42634,      0,  42636,      0,  42638, \n\t\t 0,  42640,      0,  42642,      0,  42644,      0,  42646,      0,  42648,      0,  42650,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 18\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,  42786,      0,  42788,      0,  42790,      0,  42792,      0,  42794,      0,  42796,      0,  42798, \n\t\t 0,      0,      0,  42802,      0,  42804,      0,  42806,      0,  42808,      0,  42810,      0,  42812,      0,  42814, \n\t\t 0,  42816,      0,  42818,      0,  42820,      0,  42822,      0,  42824,      0,  42826,      0,  42828,      0,  42830, \n\t\t 0,  42832,      0,  42834,      0,  42836,      0,  42838,      0,  42840,      0,  42842,      0,  42844,      0,  42846, \n\t\t 0,  42848,      0,  42850,      0,  42852,      0,  42854,      0,  42856,      0,  42858,      0,  42860,      0,  42862, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,  42873,      0,  42875,      0,      0,  42878, \n\t\t 0,  42880,      0,  42882,      0,  42884,      0,  42886,      0,      0,      0,      0,  42891,      0,      0,      0, \n\t\t 0,  42896,      0,  42898,  42948,      0,      0,  42902,      0,  42904,      0,  42906,      0,  42908,      0,  42910, \n\t\t 0,  42912,      0,  42914,      0,  42916,      0,  42918,      0,  42920,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,  42932,      0,  42934,      0,  42936,      0,  42938,      0,  42940,      0,  42942, \n\t\t 0,  42944,      0,  42946,      0,      0,      0,      0,  42951,      0,  42953,      0,      0,      0,      0,      0, \n\t\t 0,  42960,      0,      0,      0,      0,      0,  42966,      0,  42968,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,  42997,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 19\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,  42931,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t  5024,   5025,   5026,   5027,   5028,   5029,   5030,   5031,   5032,   5033,   5034,   5035,   5036,   5037,   5038,   5039, \n\t  5040,   5041,   5042,   5043,   5044,   5045,   5046,   5047,   5048,   5049,   5050,   5051,   5052,   5053,   5054,   5055, \n\t  5056,   5057,   5058,   5059,   5060,   5061,   5062,   5063,   5064,   5065,   5066,   5067,   5068,   5069,   5070,   5071, \n\t  5072,   5073,   5074,   5075,   5076,   5077,   5078,   5079,   5080,   5081,   5082,   5083,   5084,   5085,   5086,   5087, \n\t  5088,   5089,   5090,   5091,   5092,   5093,   5094,   5095,   5096,   5097,   5098,   5099,   5100,   5101,   5102,   5103, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 20\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,  65313,  65314,  65315,  65316,  65317,  65318,  65319,  65320,  65321,  65322,  65323,  65324,  65325,  65326,  65327, \n\t 65328,  65329,  65330,  65331,  65332,  65333,  65334,  65335,  65336,  65337,  65338,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 21\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,  66560,  66561,  66562,  66563,  66564,  66565,  66566,  66567, \n\t 66568,  66569,  66570,  66571,  66572,  66573,  66574,  66575,  66576,  66577,  66578,  66579,  66580,  66581,  66582,  66583, \n\t 66584,  66585,  66586,  66587,  66588,  66589,  66590,  66591,  66592,  66593,  66594,  66595,  66596,  66597,  66598,  66599, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,  66736,  66737,  66738,  66739,  66740,  66741,  66742,  66743, \n\t 66744,  66745,  66746,  66747,  66748,  66749,  66750,  66751,  66752,  66753,  66754,  66755,  66756,  66757,  66758,  66759, \n\t 66760,  66761,  66762,  66763,  66764,  66765,  66766,  66767,  66768,  66769,  66770,  66771,      0,      0,      0,      0, \n\n\n\t// block 22\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,  66928,  66929,  66930,  66931,  66932,  66933,  66934,  66935,  66936, \n\t 66937,  66938,      0,  66940,  66941,  66942,  66943,  66944,  66945,  66946,  66947,  66948,  66949,  66950,  66951,  66952, \n\t 66953,  66954,      0,  66956,  66957,  66958,  66959,  66960,  66961,  66962,      0,  66964,  66965,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 23\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 68736,  68737,  68738,  68739,  68740,  68741,  68742,  68743,  68744,  68745,  68746,  68747,  68748,  68749,  68750,  68751, \n\t 68752,  68753,  68754,  68755,  68756,  68757,  68758,  68759,  68760,  68761,  68762,  68763,  68764,  68765,  68766,  68767, \n\t 68768,  68769,  68770,  68771,  68772,  68773,  68774,  68775,  68776,  68777,  68778,  68779,  68780,  68781,  68782,  68783, \n\t 68784,  68785,  68786,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 24\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 71840,  71841,  71842,  71843,  71844,  71845,  71846,  71847,  71848,  71849,  71850,  71851,  71852,  71853,  71854,  71855, \n\t 71856,  71857,  71858,  71859,  71860,  71861,  71862,  71863,  71864,  71865,  71866,  71867,  71868,  71869,  71870,  71871, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 25\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t 93760,  93761,  93762,  93763,  93764,  93765,  93766,  93767,  93768,  93769,  93770,  93771,  93772,  93773,  93774,  93775, \n\t 93776,  93777,  93778,  93779,  93780,  93781,  93782,  93783,  93784,  93785,  93786,  93787,  93788,  93789,  93790,  93791, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\n\n\t// block 26\n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0, 125184, 125185, 125186, 125187, 125188, 125189, 125190, 125191, 125192, 125193, 125194, 125195, 125196, 125197, \n\t125198, 125199, 125200, 125201, 125202, 125203, 125204, 125205, 125206, 125207, 125208, 125209, 125210, 125211, 125212, 125213, \n\t125214, 125215, 125216, 125217,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, \n\t\t 0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0\n\t};\n\n\tinline ::boost::uint32_t uppercase_lookup(::boost::uint32_t ch)\n\t{\n\t\t::boost::uint32_t block_offset = uppercase_stage1[ch / 256] * 256;\n\t\treturn uppercase_stage2[block_offset + ch % 256];\n\t}\n\n}}}} // namespace boost::spirit::unicode::detail\n"
  },
  {
    "path": "tc/string/spirit/support/char_encoding/unicode.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_UNICODE_1_JANUARY_12_2010_0728PM)\n#define BOOST_SPIRIT_UNICODE_1_JANUARY_12_2010_0728PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <boost/cstdint.hpp>\n#include \"unicode/query.hpp\"\n\nnamespace boost { namespace spirit { namespace char_encoding\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Test characters for specified conditions (using iso8859-1)\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct unicode\n\t{\n#ifdef BOOST_NO_CXX11_CHAR32_T\n\t\ttypedef ::boost::uint32_t char_type;\n#else\n\t\ttypedef char32_t char_type;\n#endif\n\t\ttypedef ::boost::uint32_t classify_type;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Posix stuff\n\t///////////////////////////////////////////////////////////////////////////\n\t\tstatic bool\n\t\tisascii_(char_type ch)\n\t\t{\n\t\t\treturn 0 == (ch & ~0x7f);\n\t\t}\n\n\t\tstatic bool\n\t\tischar(char_type ch)\n\t\t{\n\t\t\t// unicode code points in the range 0x00 to 0x10FFFF\n\t\t\treturn ch <= 0x10FFFF;\n\t\t}\n\n\t\tstatic bool\n\t\tisalnum(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_alphanumeric(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisalpha(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_alphabetic(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisdigit(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_decimal_number(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisxdigit(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_hex_digit(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tiscntrl(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_control(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisgraph(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_graph(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tislower(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_lowercase(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisprint(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_print(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tispunct(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_punctuation(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisspace(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_white_space(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisblank BOOST_PREVENT_MACRO_SUBSTITUTION (char_type ch)\n\t\t{\n\t\t\treturn ucd::is_blank(ch);\n\t\t}\n\n\t\tstatic bool\n\t\tisupper(char_type ch)\n\t\t{\n\t\t\treturn ucd::is_uppercase(ch);\n\t\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Simple character conversions\n\t///////////////////////////////////////////////////////////////////////////\n\n\t\tstatic char_type\n\t\ttolower(char_type ch)\n\t\t{\n\t\t\treturn ucd::to_lowercase(ch);\n\t\t}\n\n\t\tstatic char_type\n\t\ttoupper(char_type ch)\n\t\t{\n\t\t\treturn ucd::to_uppercase(ch);\n\t\t}\n\n\t\tstatic ::boost::uint32_t\n\t\ttoucs4(char_type ch)\n\t\t{\n\t\t\treturn ch;\n\t\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n#define BOOST_SPIRIT_MAJOR_CATEGORY(name)                                       \\\n\t\tstatic bool                                                             \\\n\t\tis_##name(char_type ch)                                                 \\\n\t\t{                                                                       \\\n\t\t\treturn ucd::get_major_category(ch) == ucd::properties::name;        \\\n\t\t}                                                                       \\\n\t\t/***/\n\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(letter)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(mark)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(number)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(separator)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(other)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(punctuation)\n\t\tBOOST_SPIRIT_MAJOR_CATEGORY(symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  General Categories\n\t///////////////////////////////////////////////////////////////////////////\n#define BOOST_SPIRIT_CATEGORY(name)                                             \\\n\t\tstatic bool                                                             \\\n\t\tis_##name(char_type ch)                                                 \\\n\t\t{                                                                       \\\n\t\t\treturn ucd::get_category(ch) == ucd::properties::name;              \\\n\t\t}                                                                       \\\n\t\t/***/\n\n\t\tBOOST_SPIRIT_CATEGORY(uppercase_letter)\n\t\tBOOST_SPIRIT_CATEGORY(lowercase_letter)\n\t\tBOOST_SPIRIT_CATEGORY(titlecase_letter)\n\t\tBOOST_SPIRIT_CATEGORY(modifier_letter)\n\t\tBOOST_SPIRIT_CATEGORY(other_letter)\n\n\t\tBOOST_SPIRIT_CATEGORY(nonspacing_mark)\n\t\tBOOST_SPIRIT_CATEGORY(enclosing_mark)\n\t\tBOOST_SPIRIT_CATEGORY(spacing_mark)\n\n\t\tBOOST_SPIRIT_CATEGORY(decimal_number)\n\t\tBOOST_SPIRIT_CATEGORY(letter_number)\n\t\tBOOST_SPIRIT_CATEGORY(other_number)\n\n\t\tBOOST_SPIRIT_CATEGORY(space_separator)\n\t\tBOOST_SPIRIT_CATEGORY(line_separator)\n\t\tBOOST_SPIRIT_CATEGORY(paragraph_separator)\n\n\t\tBOOST_SPIRIT_CATEGORY(control)\n\t\tBOOST_SPIRIT_CATEGORY(format)\n\t\tBOOST_SPIRIT_CATEGORY(private_use)\n\t\tBOOST_SPIRIT_CATEGORY(surrogate)\n\t\tBOOST_SPIRIT_CATEGORY(unassigned)\n\n\t\tBOOST_SPIRIT_CATEGORY(dash_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(open_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(close_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(connector_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(other_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(initial_punctuation)\n\t\tBOOST_SPIRIT_CATEGORY(final_punctuation)\n\n\t\tBOOST_SPIRIT_CATEGORY(math_symbol)\n\t\tBOOST_SPIRIT_CATEGORY(currency_symbol)\n\t\tBOOST_SPIRIT_CATEGORY(modifier_symbol)\n\t\tBOOST_SPIRIT_CATEGORY(other_symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Derived Categories\n\t///////////////////////////////////////////////////////////////////////////\n#define BOOST_SPIRIT_DERIVED_CATEGORY(name)                                     \\\n\t\tstatic bool                                                             \\\n\t\tis_##name(char_type ch)                                                 \\\n\t\t{                                                                       \\\n\t\t\treturn ucd::is_##name(ch);                                          \\\n\t\t}                                                                       \\\n\t\t/***/\n\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(alphabetic)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(uppercase)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(lowercase)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(white_space)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(hex_digit)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(noncharacter_code_point)\n\t\tBOOST_SPIRIT_DERIVED_CATEGORY(default_ignorable_code_point)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Scripts\n\t///////////////////////////////////////////////////////////////////////////\n#define BOOST_SPIRIT_SCRIPT(name)                                               \\\n\t\tstatic bool                                                             \\\n\t\tis_##name(char_type ch)                                                 \\\n\t\t{                                                                       \\\n\t\t\treturn ucd::get_script(ch) == ucd::properties::name;                \\\n\t\t}                                                                       \\\n\t\t/***/\n\n\t\tBOOST_SPIRIT_SCRIPT(adlam)\n\t\tBOOST_SPIRIT_SCRIPT(caucasian_albanian)\n\t\tBOOST_SPIRIT_SCRIPT(ahom)\n\t\tBOOST_SPIRIT_SCRIPT(arabic)\n\t\tBOOST_SPIRIT_SCRIPT(imperial_aramaic)\n\t\tBOOST_SPIRIT_SCRIPT(armenian)\n\t\tBOOST_SPIRIT_SCRIPT(avestan)\n\t\tBOOST_SPIRIT_SCRIPT(balinese)\n\t\tBOOST_SPIRIT_SCRIPT(bamum)\n\t\tBOOST_SPIRIT_SCRIPT(bassa_vah)\n\t\tBOOST_SPIRIT_SCRIPT(batak)\n\t\tBOOST_SPIRIT_SCRIPT(bengali)\n\t\tBOOST_SPIRIT_SCRIPT(bhaiksuki)\n\t\tBOOST_SPIRIT_SCRIPT(bopomofo)\n\t\tBOOST_SPIRIT_SCRIPT(brahmi)\n\t\tBOOST_SPIRIT_SCRIPT(braille)\n\t\tBOOST_SPIRIT_SCRIPT(buginese)\n\t\tBOOST_SPIRIT_SCRIPT(buhid)\n\t\tBOOST_SPIRIT_SCRIPT(chakma)\n\t\tBOOST_SPIRIT_SCRIPT(canadian_aboriginal)\n\t\tBOOST_SPIRIT_SCRIPT(carian)\n\t\tBOOST_SPIRIT_SCRIPT(cham)\n\t\tBOOST_SPIRIT_SCRIPT(cherokee)\n\t\tBOOST_SPIRIT_SCRIPT(chorasmian)\n\t\tBOOST_SPIRIT_SCRIPT(coptic)\n\t\tBOOST_SPIRIT_SCRIPT(cypro_minoan)\n\t\tBOOST_SPIRIT_SCRIPT(cypriot)\n\t\tBOOST_SPIRIT_SCRIPT(cyrillic)\n\t\tBOOST_SPIRIT_SCRIPT(devanagari)\n\t\tBOOST_SPIRIT_SCRIPT(dives_akuru)\n\t\tBOOST_SPIRIT_SCRIPT(dogra)\n\t\tBOOST_SPIRIT_SCRIPT(deseret)\n\t\tBOOST_SPIRIT_SCRIPT(duployan)\n\t\tBOOST_SPIRIT_SCRIPT(egyptian_hieroglyphs)\n\t\tBOOST_SPIRIT_SCRIPT(elbasan)\n\t\tBOOST_SPIRIT_SCRIPT(elymaic)\n\t\tBOOST_SPIRIT_SCRIPT(ethiopic)\n\t\tBOOST_SPIRIT_SCRIPT(georgian)\n\t\tBOOST_SPIRIT_SCRIPT(glagolitic)\n\t\tBOOST_SPIRIT_SCRIPT(gunjala_gondi)\n\t\tBOOST_SPIRIT_SCRIPT(masaram_gondi)\n\t\tBOOST_SPIRIT_SCRIPT(gothic)\n\t\tBOOST_SPIRIT_SCRIPT(grantha)\n\t\tBOOST_SPIRIT_SCRIPT(greek)\n\t\tBOOST_SPIRIT_SCRIPT(gujarati)\n\t\tBOOST_SPIRIT_SCRIPT(gurmukhi)\n\t\tBOOST_SPIRIT_SCRIPT(hangul)\n\t\tBOOST_SPIRIT_SCRIPT(han)\n\t\tBOOST_SPIRIT_SCRIPT(hanunoo)\n\t\tBOOST_SPIRIT_SCRIPT(hatran)\n\t\tBOOST_SPIRIT_SCRIPT(hebrew)\n\t\tBOOST_SPIRIT_SCRIPT(hiragana)\n\t\tBOOST_SPIRIT_SCRIPT(anatolian_hieroglyphs)\n\t\tBOOST_SPIRIT_SCRIPT(pahawh_hmong)\n\t\tBOOST_SPIRIT_SCRIPT(nyiakeng_puachue_hmong)\n\t\tBOOST_SPIRIT_SCRIPT(katakana_or_hiragana)\n\t\tBOOST_SPIRIT_SCRIPT(old_hungarian)\n\t\tBOOST_SPIRIT_SCRIPT(old_italic)\n\t\tBOOST_SPIRIT_SCRIPT(javanese)\n\t\tBOOST_SPIRIT_SCRIPT(kayah_li)\n\t\tBOOST_SPIRIT_SCRIPT(katakana)\n\t\tBOOST_SPIRIT_SCRIPT(kawi)\n\t\tBOOST_SPIRIT_SCRIPT(kharoshthi)\n\t\tBOOST_SPIRIT_SCRIPT(khmer)\n\t\tBOOST_SPIRIT_SCRIPT(khojki)\n\t\tBOOST_SPIRIT_SCRIPT(khitan_small_script)\n\t\tBOOST_SPIRIT_SCRIPT(kannada)\n\t\tBOOST_SPIRIT_SCRIPT(kaithi)\n\t\tBOOST_SPIRIT_SCRIPT(tai_tham)\n\t\tBOOST_SPIRIT_SCRIPT(lao)\n\t\tBOOST_SPIRIT_SCRIPT(latin)\n\t\tBOOST_SPIRIT_SCRIPT(lepcha)\n\t\tBOOST_SPIRIT_SCRIPT(limbu)\n\t\tBOOST_SPIRIT_SCRIPT(linear_a)\n\t\tBOOST_SPIRIT_SCRIPT(linear_b)\n\t\tBOOST_SPIRIT_SCRIPT(lisu)\n\t\tBOOST_SPIRIT_SCRIPT(lycian)\n\t\tBOOST_SPIRIT_SCRIPT(lydian)\n\t\tBOOST_SPIRIT_SCRIPT(mahajani)\n\t\tBOOST_SPIRIT_SCRIPT(makasar)\n\t\tBOOST_SPIRIT_SCRIPT(mandaic)\n\t\tBOOST_SPIRIT_SCRIPT(manichaean)\n\t\tBOOST_SPIRIT_SCRIPT(marchen)\n\t\tBOOST_SPIRIT_SCRIPT(medefaidrin)\n\t\tBOOST_SPIRIT_SCRIPT(mende_kikakui)\n\t\tBOOST_SPIRIT_SCRIPT(meroitic_cursive)\n\t\tBOOST_SPIRIT_SCRIPT(meroitic_hieroglyphs)\n\t\tBOOST_SPIRIT_SCRIPT(malayalam)\n\t\tBOOST_SPIRIT_SCRIPT(modi)\n\t\tBOOST_SPIRIT_SCRIPT(mongolian)\n\t\tBOOST_SPIRIT_SCRIPT(mro)\n\t\tBOOST_SPIRIT_SCRIPT(meetei_mayek)\n\t\tBOOST_SPIRIT_SCRIPT(multani)\n\t\tBOOST_SPIRIT_SCRIPT(myanmar)\n\t\tBOOST_SPIRIT_SCRIPT(nag_mundari)\n\t\tBOOST_SPIRIT_SCRIPT(nandinagari)\n\t\tBOOST_SPIRIT_SCRIPT(old_north_arabian)\n\t\tBOOST_SPIRIT_SCRIPT(nabataean)\n\t\tBOOST_SPIRIT_SCRIPT(newa)\n\t\tBOOST_SPIRIT_SCRIPT(nko)\n\t\tBOOST_SPIRIT_SCRIPT(nushu)\n\t\tBOOST_SPIRIT_SCRIPT(ogham)\n\t\tBOOST_SPIRIT_SCRIPT(ol_chiki)\n\t\tBOOST_SPIRIT_SCRIPT(old_turkic)\n\t\tBOOST_SPIRIT_SCRIPT(oriya)\n\t\tBOOST_SPIRIT_SCRIPT(osage)\n\t\tBOOST_SPIRIT_SCRIPT(osmanya)\n\t\tBOOST_SPIRIT_SCRIPT(old_uyghur)\n\t\tBOOST_SPIRIT_SCRIPT(palmyrene)\n\t\tBOOST_SPIRIT_SCRIPT(pau_cin_hau)\n\t\tBOOST_SPIRIT_SCRIPT(old_permic)\n\t\tBOOST_SPIRIT_SCRIPT(phags_pa)\n\t\tBOOST_SPIRIT_SCRIPT(inscriptional_pahlavi)\n\t\tBOOST_SPIRIT_SCRIPT(psalter_pahlavi)\n\t\tBOOST_SPIRIT_SCRIPT(phoenician)\n\t\tBOOST_SPIRIT_SCRIPT(miao)\n\t\tBOOST_SPIRIT_SCRIPT(inscriptional_parthian)\n\t\tBOOST_SPIRIT_SCRIPT(rejang)\n\t\tBOOST_SPIRIT_SCRIPT(hanifi_rohingya)\n\t\tBOOST_SPIRIT_SCRIPT(runic)\n\t\tBOOST_SPIRIT_SCRIPT(samaritan)\n\t\tBOOST_SPIRIT_SCRIPT(old_south_arabian)\n\t\tBOOST_SPIRIT_SCRIPT(saurashtra)\n\t\tBOOST_SPIRIT_SCRIPT(signwriting)\n\t\tBOOST_SPIRIT_SCRIPT(shavian)\n\t\tBOOST_SPIRIT_SCRIPT(sharada)\n\t\tBOOST_SPIRIT_SCRIPT(siddham)\n\t\tBOOST_SPIRIT_SCRIPT(khudawadi)\n\t\tBOOST_SPIRIT_SCRIPT(sinhala)\n\t\tBOOST_SPIRIT_SCRIPT(sogdian)\n\t\tBOOST_SPIRIT_SCRIPT(old_sogdian)\n\t\tBOOST_SPIRIT_SCRIPT(sora_sompeng)\n\t\tBOOST_SPIRIT_SCRIPT(soyombo)\n\t\tBOOST_SPIRIT_SCRIPT(sundanese)\n\t\tBOOST_SPIRIT_SCRIPT(syloti_nagri)\n\t\tBOOST_SPIRIT_SCRIPT(syriac)\n\t\tBOOST_SPIRIT_SCRIPT(tagbanwa)\n\t\tBOOST_SPIRIT_SCRIPT(takri)\n\t\tBOOST_SPIRIT_SCRIPT(tai_le)\n\t\tBOOST_SPIRIT_SCRIPT(new_tai_lue)\n\t\tBOOST_SPIRIT_SCRIPT(tamil)\n\t\tBOOST_SPIRIT_SCRIPT(tangut)\n\t\tBOOST_SPIRIT_SCRIPT(tai_viet)\n\t\tBOOST_SPIRIT_SCRIPT(telugu)\n\t\tBOOST_SPIRIT_SCRIPT(tifinagh)\n\t\tBOOST_SPIRIT_SCRIPT(tagalog)\n\t\tBOOST_SPIRIT_SCRIPT(thaana)\n\t\tBOOST_SPIRIT_SCRIPT(thai)\n\t\tBOOST_SPIRIT_SCRIPT(tibetan)\n\t\tBOOST_SPIRIT_SCRIPT(tirhuta)\n\t\tBOOST_SPIRIT_SCRIPT(tangsa)\n\t\tBOOST_SPIRIT_SCRIPT(toto)\n\t\tBOOST_SPIRIT_SCRIPT(ugaritic)\n\t\tBOOST_SPIRIT_SCRIPT(vai)\n\t\tBOOST_SPIRIT_SCRIPT(vithkuqi)\n\t\tBOOST_SPIRIT_SCRIPT(warang_citi)\n\t\tBOOST_SPIRIT_SCRIPT(wancho)\n\t\tBOOST_SPIRIT_SCRIPT(old_persian)\n\t\tBOOST_SPIRIT_SCRIPT(cuneiform)\n\t\tBOOST_SPIRIT_SCRIPT(yezidi)\n\t\tBOOST_SPIRIT_SCRIPT(yi)\n\t\tBOOST_SPIRIT_SCRIPT(zanabazar_square)\n\t\tBOOST_SPIRIT_SCRIPT(inherited)\n\t\tBOOST_SPIRIT_SCRIPT(common)\n\t\tBOOST_SPIRIT_SCRIPT(unknown)\n\n#undef BOOST_SPIRIT_MAJOR_CATEGORY\n#undef BOOST_SPIRIT_CATEGORY\n#undef BOOST_SPIRIT_DERIVED_CATEGORY\n#undef BOOST_SPIRIT_SCRIPT\n\n\t};\n\n}}}\n\n#endif\n\n"
  },
  {
    "path": "tc/string/spirit/support/char_set/basic_chset.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\tCopyright (c) 2001-2009 Daniel Nuffer\n\thttp://spirit.sourceforge.net/\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 BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008\n#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n///////////////////////////////////////////////////////////////////////////////\n#include <bitset>\n#include <climits> \n#include \"range_run.hpp\"\n\nnamespace boost { namespace spirit { namespace support { namespace detail\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//\n\t//  basic_chset: basic character set implementation using range_run\n\t//\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Char>\n\tstruct basic_chset\n\t{\n\t\tbasic_chset() {}\n\t\tbasic_chset(basic_chset const& arg_)\n\t\t  : rr(arg_.rr) {}\n\n\t\tbool\n\t\ttest(Char v) const\n\t\t{\n\t\t\treturn rr.test(v);\n\t\t}\n\n\t\tvoid\n\t\tset(Char from, Char to)\n\t\t{\n\t\t\trr.set(range<Char>(from, to));\n\t\t}\n\n\t\tvoid\n\t\tset(Char c)\n\t\t{\n\t\t\trr.set(range<Char>(c, c));\n\t\t}\n\n\t\tvoid\n\t\tclear(Char from, Char to)\n\t\t{\n\t\t\trr.clear(range<Char>(from, to));\n\t\t}\n\n\t\tvoid\n\t\tclear(Char c)\n\t\t{\n\t\t\trr.clear(range<Char>(c, c));\n\t\t}\n\n\t\tvoid\n\t\tclear()\n\t\t{\n\t\t\trr.clear();\n\t\t}\n\n\t\tvoid\n\t\tinverse()\n\t\t{\n\t\t\tbasic_chset inv;\n\t\t\tinv.set(\n\t\t\t\t(std::numeric_limits<Char>::min)(),\n\t\t\t\t(std::numeric_limits<Char>::max)()\n\t\t\t);\n\t\t\tinv -= *this;\n\t\t\tswap(inv);\n\t\t}\n\n\t\tvoid\n\t\tswap(basic_chset& x)\n\t\t{\n\t\t\trr.swap(x.rr);\n\t\t}\n\n\n\t\tbasic_chset&\n\t\toperator|=(basic_chset const& x)\n\t\t{\n\t\t\ttypedef typename range_run<Char>::const_iterator const_iterator;\n\t\t\tfor (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)\n\t\t\t\trr.set(*iter);\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset&\n\t\toperator&=(basic_chset const& x)\n\t\t{\n\t\t\tbasic_chset inv;\n\t\t\tinv.set(\n\t\t\t\t(std::numeric_limits<Char>::min)(),\n\t\t\t\t(std::numeric_limits<Char>::max)()\n\t\t\t);\n\t\t\tinv -= x;\n\t\t\t*this -= inv;\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset&\n\t\toperator-=(basic_chset const& x)\n\t\t{\n\t\t\ttypedef typename range_run<Char>::const_iterator const_iterator;\n\t\t\tfor (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)\n\t\t\t\trr.clear(*iter);\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset&\n\t\toperator^=(basic_chset const& x)\n\t\t{\n\t\t\tbasic_chset bma = x;\n\t\t\tbma -= *this;\n\t\t\t*this -= x;\n\t\t\t*this |= bma;\n\t\t\treturn *this;\n\t\t}\n\n\t\tprivate: range_run<Char> rr;\n\t};\n\n#if (CHAR_BIT == 8)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\n\t//  basic_chset: specializations for 8 bit chars using std::bitset\n\t//\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Char>\n\tstruct basic_chset_8bit\n\t{\n\t\tbasic_chset_8bit() {}\n\t\tbasic_chset_8bit(basic_chset_8bit const& arg_)\n\t\t  : bset(arg_.bset) {}\n\n\t\tbool\n\t\ttest(Char v) const\n\t\t{\n\t\t\treturn bset.test((unsigned char)v);\n\t\t}\n\n\t\tvoid\n\t\tset(Char from, Char to)\n\t\t{\n\t\t\tfor (int i = from; i <= to; ++i)\n\t\t\t\tbset.set((unsigned char)i);\n\t\t}\n\n\t\tvoid\n\t\tset(Char c)\n\t\t{\n\t\t\tbset.set((unsigned char)c);\n\t\t}\n\n\t\tvoid\n\t\tclear(Char from, Char to)\n\t\t{\n\t\t\tfor (int i = from; i <= to; ++i)\n\t\t\t\tbset.reset((unsigned char)i);\n\t\t}\n\n\t\tvoid\n\t\tclear(Char c)\n\t\t{\n\t\t\tbset.reset((unsigned char)c);\n\t\t}\n\n\t\tvoid\n\t\tclear()\n\t\t{\n\t\t\tbset.reset();\n\t\t}\n\n\t\tvoid\n\t\tinverse()\n\t\t{\n\t\t\tbset.flip();\n\t\t}\n\n\t\tvoid\n\t\tswap(basic_chset_8bit& x)\n\t\t{\n\t\t\tstd::swap(bset, x.bset);\n\t\t}\n\n\t\tbasic_chset_8bit&\n\t\toperator|=(basic_chset_8bit const& x)\n\t\t{\n\t\t\tbset |= x.bset;\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset_8bit&\n\t\toperator&=(basic_chset_8bit const& x)\n\t\t{\n\t\t\tbset &= x.bset;\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset_8bit&\n\t\toperator-=(basic_chset_8bit const& x)\n\t\t{\n\t\t\tbset &= ~x.bset;\n\t\t\treturn *this;\n\t\t}\n\n\t\tbasic_chset_8bit&\n\t\toperator^=(basic_chset_8bit const& x)\n\t\t{\n\t\t\tbset ^= x.bset;\n\t\t\treturn *this;\n\t\t}\n\n\t\tprivate: std::bitset<256> bset;\n\t};\n\n\t/////////////////////////////////\n\ttemplate <>\n\tstruct basic_chset<char>\n\t  : basic_chset_8bit<char> {};\n\n\t/////////////////////////////////\n\ttemplate <>\n\tstruct basic_chset<signed char>\n\t  : basic_chset_8bit<signed char> {};\n\n\t/////////////////////////////////\n\ttemplate <>\n\tstruct basic_chset<unsigned char>\n\t  : basic_chset_8bit<unsigned char> {};\n\n#endif // #if (CHAR_BIT == 8)\n\n}}}}\n\n#endif\n\n"
  },
  {
    "path": "tc/string/spirit/support/char_set/range.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM)\n#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\nnamespace boost { namespace spirit { namespace support { namespace detail\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  A closed range (first, last)\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct range\n\t{\n\t\ttypedef T value_type;\n\n\t\trange() : first(), last() {}\n\t\trange(T first_, T last_) : first(first_), last(last_) {}\n\n\t\tT first;\n\t\tT last;\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_set/range_functions.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)\n#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include <limits>\n\nnamespace boost { namespace spirit { namespace support { namespace detail\n{\n\ttemplate <typename Range>\n\tinline bool\n\tis_valid(Range const& range)\n\t{\n\t\t// test for valid ranges\n\t\treturn range.first <= range.last;\n\t}\n\n\ttemplate <typename Range>\n\tinline bool\n\tincludes(Range const& range, Range const& other)\n\t{\n\t\t// see if two ranges intersect\n\t\treturn (range.first <= other.first) && (range.last >= other.last);\n\t}\n\n\ttemplate <typename Range>\n\tinline bool\n\tincludes(Range const& range, typename Range::value_type val)\n\t{\n\t\t// see if val is in range\n\t\treturn (range.first <= val) && (range.last >= val);\n\t}\n\n\ttemplate <typename Range>\n\tinline bool\n\tcan_merge(Range const& range, Range const& other)\n\t{\n\t\t// see if a 'range' overlaps, or is adjacent to\n\t\t// another range 'other', so we can merge them\n\n\t\ttypedef typename Range::value_type value_type;\n\t\ttypedef std::numeric_limits<value_type> limits;\n\n\t\tvalue_type decr_first =\n\t\t\trange.first == (limits::min)()\n\t\t\t? range.first : range.first-1;\n\n\t\tvalue_type incr_last =\n\t\t\trange.last == (limits::max)()\n\t\t\t? range.last : range.last+1;\n\n\t\treturn (decr_first <= other.last) && (incr_last >= other.first);\n\t}\n\n\ttemplate <typename Range>\n\tinline void\n\tmerge(Range& result, Range const& other)\n\t{\n\t\t// merge two ranges\n\t\tif (result.first > other.first)\n\t\t\tresult.first = other.first;\n\t\tif (result.last < other.last)\n\t\t\tresult.last = other.last;\n\t}\n\n\ttemplate <typename Range>\n\tstruct range_compare\n\t{\n\t\t// compare functor with a value or another range\n\n\t\ttypedef typename Range::value_type value_type;\n\n\t\tbool operator()(Range const& x, const value_type y) const\n\t\t{\n\t\t\treturn x.first < y;\n\t\t}\n\n\t\tbool operator()(value_type const x, Range const& y) const\n\t\t{\n\t\t\treturn x < y.first;\n\t\t}\n\n\t\tbool operator()(Range const& x, Range const& y) const\n\t\t{\n\t\t\treturn x.first < y.first;\n\t\t}\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_set/range_run.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM)\n#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include \"range.hpp\"\n#include <vector>\n\nnamespace boost { namespace spirit { namespace support { namespace detail\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  range_run\n\t//\n\t//      An implementation of a sparse bit (boolean) set. The set uses\n\t//      a sorted vector of disjoint ranges. This class implements the\n\t//      bare minimum essentials from which the full range of set\n\t//      operators can be implemented. The set is constructed from\n\t//      ranges. Internally, adjacent or overlapping ranges are\n\t//      coalesced.\n\t//\n\t//      range_runs are very space-economical in situations where there\n\t//      are lots of ranges and a few individual disjoint values.\n\t//      Searching is O(log n) where n is the number of ranges.\n\t//\n\t//      { Low level interface }\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Char>\n\tclass range_run\n\t{\n\tpublic:\n\n\t\ttypedef range<Char> range_type;\n\t\ttypedef std::vector<range_type> storage_type;\n\n\t\tvoid swap(range_run& other);\n\t\tbool test(Char v) const;\n\t\tvoid set(range_type const& range);\n\t\tvoid clear(range_type const& range);\n\t\tvoid clear();\n\n\tprivate:\n\n\t\tstorage_type run;\n\t};\n}}}}\n\n#include \"range_run_impl.hpp\"\n#endif\n"
  },
  {
    "path": "tc/string/spirit/support/char_set/range_run_impl.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM)\n#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include \"range_functions.hpp\"\n#include <boost/assert.hpp>\n#include <algorithm>\n\nnamespace boost { namespace spirit { namespace support { namespace detail\n{\n\ttemplate <typename Run, typename Iterator, typename Range>\n\tinline bool\n\ttry_merge(Run& run, Iterator iter, Range const& range)\n\t{\n\t\t// if *iter intersects with, or is adjacent to, 'range'...\n\t\tif (can_merge(*iter, range))\n\t\t{\n\t\t\t// merge range and *iter\n\t\t\tmerge(*iter, range);\n\n\t\t\t// collapse all subsequent ranges that can merge with *iter:\n\t\t\tIterator i = iter+1;\n\t\t\t// 1. skip subsequent ranges completely included in *iter\n\t\t\twhile (i != run.end() && i->last <= iter->last)\n\t\t\t\t++i;\n\t\t\t// 2. collapse next range if adjacent or overlapping with *iter\n\t\t\tif (i != run.end() && i->first-1 <= iter->last)\n\t\t\t{\n\t\t\t\titer->last = i->last;\n\t\t\t\t++i;\n\t\t\t}\n\n\t\t\t// erase all ranges that were collapsed\n\t\t\trun.erase(iter+1, i);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\ttemplate <typename Char>\n\tinline bool\n\trange_run<Char>::test(Char val) const\n\t{\n\t\tif (run.empty())\n\t\t\treturn false;\n\n\t\t// search the ranges for one that potentially includes val\n\t\ttypename storage_type::const_iterator iter =\n\t\t\tstd::upper_bound(\n\t\t\t\trun.begin(), run.end(), val,\n\t\t\t\trange_compare<range_type>()\n\t\t\t);\n\n\t\t// return true if *(iter-1) includes val\n\t\treturn iter != run.begin() && includes(*(--iter), val);\n\t}\n\n\ttemplate <typename Char>\n\tinline void\n\trange_run<Char>::swap(range_run& other)\n\t{\n\t\trun.swap(other.run);\n\t}\n\n\ttemplate <typename Char>\n\tvoid\n\trange_run<Char>::set(range_type const& range)\n\t{\n\t\tBOOST_ASSERT(is_valid(range));\n\t\tif (run.empty())\n\t\t{\n\t\t\t// the vector is empty, insert 'range'\n\t\t\trun.push_back(range);\n\t\t\treturn;\n\t\t}\n\n\t\t// search the ranges for one that potentially includes 'range'\n\t\ttypename storage_type::iterator iter =\n\t\t\tstd::upper_bound(\n\t\t\t\trun.begin(), run.end(), range,\n\t\t\t\trange_compare<range_type>()\n\t\t\t);\n\n\t\tif (iter != run.begin())\n\t\t{\n\t\t\t// if *(iter-1) includes 'range', return early\n\t\t\tif (includes(*(iter-1), range))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// if *(iter-1) can merge with 'range', merge them and return\n\t\t\tif (try_merge(run, iter-1, range))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// if *iter can merge with with 'range', merge them\n\t\tif (iter == run.end() || !try_merge(run, iter, range))\n\t\t{\n\t\t\t// no overlap, insert 'range'\n\t\t\trun.insert(iter, range);\n\t\t}\n\t}\n\n\ttemplate <typename Char>\n\tvoid\n\trange_run<Char>::clear(range_type const& range)\n\t{\n\t\tBOOST_ASSERT(is_valid(range));\n\t\tif (!run.empty())\n\t\t{\n\t\t\t// search the ranges for one that potentially includes 'range'\n\t\t\ttypename storage_type::iterator iter =\n\t\t\t\tstd::upper_bound(\n\t\t\t\t\trun.begin(), run.end(), range,\n\t\t\t\t\trange_compare<range_type>()\n\t\t\t\t);\n\n\t\t\t// 'range' starts with or after another range:\n\t\t\tif (iter != run.begin())\n\t\t\t{\n\t\t\t\ttypename storage_type::iterator const left_iter = iter-1;\n\n\t\t\t\t// 'range' starts after '*left_iter':\n\t\t\t\tif (left_iter->first < range.first)\n\t\t\t\t{\n\t\t\t\t\t// if 'range' is completely included inside '*left_iter':\n\t\t\t\t\t// need to break it apart into two ranges (punch a hole),\n\t\t\t\t\tif (left_iter->last > range.last)\n\t\t\t\t\t{\n\t\t\t\t\t\tChar save_last = left_iter->last;\n\t\t\t\t\t\tleft_iter->last = range.first-1;\n\t\t\t\t\t\trun.insert(iter, range_type(range.last+1, save_last));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// if 'range' contains 'left_iter->last':\n\t\t\t\t\t// truncate '*left_iter' (clip its right)\n\t\t\t\t\telse if (left_iter->last >= range.first)\n\t\t\t\t\t{\n\t\t\t\t\t\tleft_iter->last = range.first-1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// 'range' has the same left bound as '*left_iter': it\n\t\t\t\t// must be removed or truncated by the code below\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\titer = left_iter;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove or truncate subsequent ranges that overlap with 'range':\n\t\t\ttypename storage_type::iterator i = iter;\n\t\t\t// 1. skip subsequent ranges completely included in 'range'\n\t\t\twhile (i != run.end() && i->last <= range.last)\n\t\t\t\t++i;\n\t\t\t// 2. clip left of next range if overlapping with 'range'\n\t\t\tif (i != run.end() && i->first <= range.last)\n\t\t\t\ti->first = range.last+1;\n\n\t\t\t// erase all ranges that 'range' contained\n\t\t\trun.erase(iter, i);\n\t\t}\n\t}\n\n\ttemplate <typename Char>\n\tinline void\n\trange_run<Char>::clear()\n\t{\n\t\trun.clear();\n\t}\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/actions.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <cstring>\n#include <functional>\n\n#ifdef _MSC_VER\n// bogus https://developercommunity.visualstudio.com/t/buggy-warning-c4709/471956\n# pragma warning(disable: 4709) // comma operator within array index expression\n#endif\n\nnamespace x3 = boost::spirit::x3;\n\nint g_nTestAction = 0;\n\nauto fun1 =\n\t[](auto& ctx)\n\t{\n\t\tg_nTestAction += x3::_attr(ctx);\n\t}\n;\n\nstruct fun_action\n{\n\ttemplate <typename Context>\n\tvoid operator()(Context const& ctx) const\n\t{\n\t\tg_nTestAction += x3::_attr(ctx);\n\t}\n};\n\nauto fail =\n\t[](auto& ctx)\n\t{\n\t\tx3::_pass(ctx) = false;\n\t}\n;\n\nstruct setnext\n{\n\tsetnext(char& next) : next(next) {}\n\n\ttemplate <typename Context>\n\tvoid operator()(Context const& ctx) const\n\t{\n\t\tnext = x3::_attr(ctx);\n\t}\n\n\tchar& next;\n};\n\n\nstruct stationary : boost::noncopyable\n{\n\texplicit stationary(int i) : val{i} {}\n\tstationary& operator=(int i) { val = i; return *this; }\n\n\tint val;\n};\n\n\nUNITTESTDEF(x3_test_actions)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tusing x3::int_;\n\tusing x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::int_type{}[std::true_type{}]);\n\n\t{\n\t\tchar const *s1 = \"{42}\", *e1 = s1 + std::strlen(s1);\n\t\tx3::parse(s1, e1, lit('{') >> int_[fun1] >> lit('}'));\n\t}\n\n\n\t{\n\t\tchar const *s1 = \"{42}\", *e1 = s1 + std::strlen(s1);\n\t\tx3::parse(s1, e1, lit('{') >> int_[fun_action()] >> lit('}'));\n\t}\n\n\t{\n\t\tusing namespace std::placeholders;\n\t\tchar const *s1 = \"{42}\", *e1 = s1 + std::strlen(s1);\n\t\tx3::parse(s1, e1, lit('{') >> int_[std::bind(fun_action(), _1)] >> lit('}'));\n\t}\n\n\t_ASSERT(g_nTestAction == (42*3));\n\n\t{\n\t   std::string input(\"1234 6543\");\n\t   char next = '\\0';\n\t   _ASSERT(x3::phrase_parse(input.begin(), input.end(),\n\t\t  x3::int_[fail] | x3::digit[setnext(next)], x3::space));\n\t   _ASSERT(next == '1');\n\t}\n\n\t{ // ensure no unneeded synthesization, copying and moving occurred\n\t\tauto p = lit('{') >> int_ >> lit('}');\n\n\t\tstationary st { 0 };\n\t\t_ASSERT(test_attr(\"{42}\", p[([]{})], st));\n\t\t_ASSERTEQUAL(st.val, 42);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/alternative.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/adapt_struct.hpp>\n#include <boost/variant.hpp>\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/at.hpp>\n\n#include <string>\n#include <iostream>\n#include <vector>\n\nstruct di_ignore\n{\n\tstd::string text;\n};\n\nstruct di_include\n{\n\tstd::string FileName;\n};\n\nBOOST_FUSION_ADAPT_STRUCT(di_ignore,\n\ttext\n)\n\nBOOST_FUSION_ADAPT_STRUCT(di_include,\n\tFileName\n)\n\nstruct undefined {};\n\n\nstruct stationary : boost::noncopyable\n{\n\texplicit stationary(int i) : val{i} {}\n\tstationary& operator=(int i) { val = i; return *this; }\n\n\tint val;\n};\n\n\nUNITTESTDEF(x3_test_alternative)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tusing boost::spirit::x3::attr;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::unused_type;\n\tusing boost::spirit::x3::unused;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::eps;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ | char_);\n\n\t{\n\t\t_ASSERT((test(\"a\", char_ | char_)));\n\t\t_ASSERT((test(\"x\", lit('x') | lit('i'))));\n\t\t_ASSERT((test(\"i\", lit('x') | lit('i'))));\n\t\t_ASSERT((!test(\"z\", lit('x') | lit('o'))));\n\t\t_ASSERT((test(\"rock\", lit(\"rock\") | lit(\"roll\"))));\n\t\t_ASSERT((test(\"roll\", lit(\"rock\") | lit(\"roll\"))));\n\t\t_ASSERT((test(\"rock\", lit(\"rock\") | int_)));\n\t\t_ASSERT((test(\"12345\", lit(\"rock\") | int_)));\n\t}\n\n\t{\n\t\ttypedef boost::variant<undefined, int, char> attr_type;\n\t\tattr_type v;\n\n\t\t_ASSERT((test_attr(\"12345\", int_ | char_, v)));\n\t\t_ASSERT(boost::get<int>(v) == 12345);\n\n\t\t_ASSERT((test_attr(\"12345\", lit(\"rock\") | int_ | char_, v)));\n\t\t_ASSERT(boost::get<int>(v) == 12345);\n\n\t\tv = attr_type();\n\t\t_ASSERT((test_attr(\"rock\", lit(\"rock\") | int_ | char_, v)));\n\t\t_ASSERT(v.which() == 0);\n\n\t\t_ASSERT((test_attr(\"x\", lit(\"rock\") | int_ | char_, v)));\n\t\t_ASSERT(boost::get<char>(v) == 'x');\n\t}\n\n\t{   // Make sure that we are using the actual supplied attribute types\n\t\t// from the variant and not the expected type.\n\t\tboost::variant<int, std::string> v;\n\t\t_ASSERT((test_attr(\"12345\", int_ | +char_, v)));\n\t\t_ASSERT(boost::get<int>(v) == 12345);\n\n\t\t_ASSERT((test_attr(\"abc\", int_ | +char_, v)));\n\t\t_ASSERT(boost::get<std::string>(v) == \"abc\");\n\n\t\t_ASSERT((test_attr(\"12345\", +char_ | int_, v)));\n\t\t_ASSERT(boost::get<std::string>(v) == \"12345\");\n\t}\n\n\t{\n\t\tunused_type x;\n\t\t_ASSERT((test_attr(\"rock\", lit(\"rock\") | lit('x'), x)));\n\t}\n\n\t{\n\t\t// test if alternatives with all components having unused\n\t\t// attributes have an unused attribute\n\n\t\tusing boost::fusion::vector;\n\t\tusing boost::fusion::at_c;\n\n\t\tvector<char, char> v;\n\t\t_ASSERT((test_attr(\"abc\",\n\t\t\tchar_ >> (omit[char_] | omit[char_]) >> char_, v)));\n\t\t_ASSERT((at_c<0>(v) == 'a'));\n\t\t_ASSERT((at_c<1>(v) == 'c'));\n\t}\n\n\t{\n\t\t// Test that we can still pass a \"compatible\" attribute to\n\t\t// an alternate even if its \"expected\" attribute is unused type.\n\n\t\tstd::string s;\n\t\t_ASSERT((test_attr(\"...\", *(char_('.') | char_(',')), s)));\n\t\t_ASSERT(s == \"...\");\n\t}\n\n\t{   // make sure collapsing eps works as expected\n\t\t// (compile check only)\n\n\t\tusing boost::spirit::x3::rule;\n\t\tusing boost::spirit::x3::eps;\n\t\tusing boost::spirit::x3::_attr;\n\t\tusing boost::spirit::x3::_val;\n\n\t\trule<class r1, wchar_t> r1;\n\t\trule<class r2, wchar_t> r2;\n\t\trule<class r3, wchar_t> r3;\n\n\t\tauto f = [&](auto& ctx){ _val(ctx) = _attr(ctx); };\n\n\t\tr3  = ((eps >> r1))[f];\n\t\tr3  = ((r1) | r2)[f];\n\t\tr3 = ((eps >> r1) | r2);\n\t}\n\n\t{\n\t\tstd::string s;\n\t\tusing boost::spirit::x3::eps;\n\n\t\t// test having a variant<container, ...>\n\t\t_ASSERT( (test_attr(\"a,b\", (char_ % lit(',')) | eps, s )) );\n\t\t_ASSERT(s == \"ab\");\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::eps;\n\n\t\t// testing a sequence taking a container as attribute\n\t\tstd::string s;\n\t\t_ASSERT( (test_attr(\"abc,a,b,c\",\n\t\t\tchar_ >> char_ >> (char_ % lit(',')), s )) );\n\t\t_ASSERT(s == \"abcabc\");\n\n\t\t// test having an optional<container> inside a sequence\n\t\ts.erase();\n\t\t_ASSERT( (test_attr(\"ab\",\n\t\t\tchar_ >> char_ >> -(char_ % lit(',')), s )) );\n\t\t_ASSERT(s == \"ab\");\n\n\t\t// test having a variant<container, ...> inside a sequence\n\t\ts.erase();\n\t\t_ASSERT( (test_attr(\"ab\",\n\t\t\tchar_ >> char_ >> ((char_ % lit(',')) | eps), s )) );\n\t\t_ASSERT(s == \"ab\");\n\t\ts.erase();\n\t\t_ASSERT( (test_attr(\"abc\",\n\t\t\tchar_ >> char_ >> ((char_ % lit(',')) | eps), s )) );\n\t\t_ASSERT(s == \"abc\");\n\t}\n\n\t{\n\t\t//compile test only (bug_march_10_2011_8_35_am)\n\t\ttypedef boost::variant<double, std::string> value_type;\n\n\t\tusing boost::spirit::x3::rule;\n\t\tusing boost::spirit::x3::eps;\n\n\t\trule<class r1, value_type> r1;\n\t\tauto r1_ = r1 = r1 | eps; // left recursive!\n\n\t\tunused = r1_; // silence unused local warning\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::rule;\n\t\ttypedef boost::variant<di_ignore, di_include> d_line;\n\n\t\trule<class ignore, di_ignore> ignore;\n\t\trule<class include, di_include> include;\n\t\trule<class line, d_line> line;\n\n\t\tauto start =\n\t\t\tline = include | ignore;\n\n\t\tunused = start; // silence unused local warning\n\t}\n\n\t// single-element fusion vector tests\n\t{\n\t\tboost::fusion::vector<boost::variant<int, std::string>> fv;\n\t\t_ASSERT((test_attr(\"12345\", int_ | +char_, fv)));\n\t\t_ASSERT(boost::get<int>(boost::fusion::at_c<0>(fv)) == 12345);\n\n\t\tboost::fusion::vector<boost::variant<int, std::string>> fvi;\n\t\t_ASSERT((test_attr(\"12345\", int_ | int_, fvi)));\n\t\t_ASSERT(boost::get<int>(boost::fusion::at_c<0>(fvi)) == 12345);\n\t}\n\n\t// alternative over single element sequences as part of another sequence\n\t{\n\t\tauto  key1 = lit(\"long\") >> attr(long());\n\t\tauto  key2 = lit(\"char\") >> attr(char());\n\t\tauto  keys = key1 | key2;\n\t\tauto pair = keys >> lit(\"=\") >> +char_;\n\n\t\tboost::fusion::deque<boost::variant<long, char>, std::string> attr_;\n\n\t\t_ASSERT(test_attr(\"long=ABC\", pair, attr_));\n\t\t_ASSERT(boost::get<long>(&boost::fusion::front(attr_)) != nullptr);\n\t\t_ASSERT(boost::get<char>(&boost::fusion::front(attr_)) == nullptr);\n\t}\n\n\t{ // ensure no unneeded synthesization, copying and moving occurred\n\t\tauto p = lit('{') >> int_ >> lit('}');\n\n\t\tstationary st { 0 };\n\t\t_ASSERT(test_attr(\"{42}\", p | eps | p, st));\n\t\t_ASSERTEQUAL(st.val, 42);\n\t}\n\n\t{ // attributeless parsers must not insert values\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"1 2 3 - 5 - - 7 -\", (int_ | lit('-')) % lit(' '), v));\n\t\t_ASSERTEQUAL(v.size(), 5);\n\t\t_ASSERTEQUAL(v[0], 1);\n\t\t_ASSERTEQUAL(v[1], 2);\n\t\t_ASSERTEQUAL(v[2], 3);\n\t\t_ASSERTEQUAL(v[3], 5);\n\t\t_ASSERTEQUAL(v[4], 7);\n\t}\n\n\t{ // regressing test for #603\n\t\tusing boost::spirit::x3::attr;\n\t\tstruct X {};\n\t\tstd::vector<boost::variant<std::string, int, X>> v;\n\t\t_ASSERT(test_attr(\"xx42x9y\", *(int_ | +char_('x') | lit('y') >> attr(X{})), v));\n\t\t_ASSERTEQUAL(v.size(), 5);\n\t}\n\n\t{ // sequence parser in alternative into container\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"abcbbcd\",\n\t\t\t*(char_('a') >> *(*char_('b') >> char_('c')) | char_('d')), s));\n\t\t_ASSERTEQUAL(s, \"abcbbcd\");\n\t}\n\n\t{ // conversion between alternatives\n\t\tstruct X {};\n\t\tstruct Y {};\n\t\tstruct Z {};\n\t\tboost::variant<X, Y, Z> v;\n\t\tboost::variant<Y, X> x{X{}};\n\t\tv = x; // boost::variant supports that convertion\n\t\tauto const p = lit('x') >> attr(x) | lit('z') >> attr(Z{});\n\t\t_ASSERT(test_attr(\"z\", p, v));\n\t\t_ASSERT(boost::get<Z>(&v) != nullptr);\n\t\t_ASSERT(test_attr(\"x\", p, v));\n\t\t_ASSERT(boost::get<X>(&v) != nullptr);\n\t}\n\n\t{ // regression test for #679\n\t\tusing Qaz = std::vector<boost::variant<int>>;\n\t\tusing Foo = std::vector<boost::variant<Qaz, int>>;\n\t\tusing Bar = std::vector<boost::variant<Foo, int>>;\n\t\tBar x;\n\t\t_ASSERT(test_attr(\"abaabb\", +(lit('a') >> attr(Foo{}) | lit('b') >> attr(int{})), x));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/and_predicate.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_and_predicate)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::int_;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(&int_);\n\n\t{\n\t\t_ASSERT((test(\"1234\", &int_, false)));\n\t\t_ASSERT((!test(\"abcd\", &int_)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/attr.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <boost/fusion/include/std_pair.hpp>\n#include <vector>\n\nUNITTESTDEF(x3_test_attr)\n{\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::attr;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(attr);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(attr(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(attr(\"asd\"));\n\t{\n\t\tconstexpr char s[] = \"asd\";\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(attr(s));\n\t}\n\n\t{\n\t\tint d = 0;\n\t\t_ASSERT(test_attr(\"\", attr(1), d) && d == 1);\n\n\t\tint d1 = 1;\n\t\t_ASSERT(test_attr(\"\", attr(d1), d) && d == 1);\n\n\t\tstd::pair<int, int> p;\n\t\t_ASSERT(test_attr(\"1\", int_ >> attr(1), p) &&\n\t\t\tp.first == 1 && p.second == 1);\n\n\t\tchar c = '\\0';\n\t\t_ASSERT(test_attr(\"\", attr('a'), c) && c == 'a');\n\n\t\t// $$$ Needs some special is_convertible support, or\n\t\t// str ends up with an explicit null-terminator... $$$\n\t\tstd::string str;\n\t\t//~ _ASSERT(test_attr(\"\", attr(\"test\"), str) && str == \"test\");\n\n\t\tstr.clear();\n\t\t_ASSERT(test_attr(\"\", attr(std::string(\"test\")), str));\n\t\t_ASSERTEQUAL(str, \"test\");\n\n\t\tint array[] = {0, 1, 2};\n\t\tstd::vector<int> vec;\n\t\t_ASSERT(test_attr(\"\", attr(array), vec) && vec.size() == 3 &&\n\t\t\tvec[0] == 0 && vec[1] == 1 && vec[2] == 2);\n\t}\n\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"s\", lit(\"s\") >> attr(std::string(\"123\")), s) &&\n\t\t\ts == \"123\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"\", attr(std::string(\"123\")) >> attr(std::string(\"456\")), s));\n\t\t_ASSERTEQUAL(s, \"123456\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/attribute_type_check.t.cpp",
    "content": "#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/make_vector.hpp>\n#include <boost/fusion/include/equal_to.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include <boost/type_traits/decay.hpp>\n#include <string>\n#include <optional>\n\nnamespace x3 = boost::spirit::x3;\n\n// just an `attr` with added type checker\ntemplate <typename Value, typename Expected>\nstruct checked_attr_parser : x3::attr_parser<Value>\n{\n\tusing base_t = x3::attr_parser<Value>;\n\n\tchecked_attr_parser(Value const& value) : base_t(value) {}\n\tchecked_attr_parser(Value&& value) : base_t(std::move(value)) {}\n\n\ttemplate <typename Iterator, typename Context\n\t  , typename RuleContext, typename Attribute>\n\tbool parse(Iterator& first, Iterator const& last\n\t  , Context const& ctx, RuleContext& rctx, Attribute& attr_) const\n\t{\n\t\tstatic_assert(boost::is_same<Expected, Attribute>::value,\n\t\t\t\"attribute type check failed\");\n\t\treturn base_t::parse(first, last, ctx, rctx, attr_);\n\t}\n};\n\ntemplate <typename Expected, typename Value>\nstatic inline checked_attr_parser<boost::decay_t<Value>, Expected>\nchecked_attr(Value&& value) { return { std::forward<Value>(value) }; }\n\n// instantiate our type checker\n// (checks attribute value just to be sure we are ok)\ntemplate <typename Value, typename Expr>\nstatic void test_expr(Value const& v, Expr&& expr)\n{\n\tchar const* it = \"\";\n\tValue r=Value();\n\t_ASSERT((x3::parse(it, it, std::forward<Expr>(expr), r)));\n\t_ASSERT((r == v));\n}\n\ntemplate <typename Expr, typename Attribute>\nstatic void gen_sequence(Attribute const& attribute, Expr&& expr)\n{\n\ttest_expr(attribute, expr);\n\ttest_expr(attribute, expr >> x3::eps);\n}\n\ntemplate <typename Expected, typename... ExpectedTail, typename Attribute, typename Expr, typename Value, typename... Tail>\nstatic void gen_sequence(Attribute const& attribute, Expr&& expr, Value const& v, Tail const&... tail)\n{\n\tgen_sequence<ExpectedTail...>(attribute, expr >> checked_attr<Expected>(v), tail...);\n\tgen_sequence<ExpectedTail...>(attribute, expr >> x3::eps >> checked_attr<Expected>(v), tail...);\n\tgen_sequence<ExpectedTail...>(attribute, expr >> (x3::eps >> checked_attr<Expected>(v)), tail...);\n}\n\ntemplate <typename Expected, typename... ExpectedTail, typename Attribute, typename Value, typename... Tail>\nstatic void gen_sequence_tests(Attribute const& attribute, Value const& v, Tail const&... tail)\n{\n\tgen_sequence<ExpectedTail...>(attribute, checked_attr<Expected>(v), tail...);\n\tgen_sequence<ExpectedTail...>(attribute, x3::eps >> checked_attr<Expected>(v), tail...);\n}\n\ntemplate <typename Expected, typename Value>\nstatic void gen_single_item_tests(Value const& v)\n{\n\tExpected attribute(v);\n\tgen_sequence(attribute, checked_attr<Expected>(v));\n\tgen_sequence(attribute, x3::eps >> checked_attr<Expected>(v));\n}\n\ntemplate <typename Expected, typename... ExpectedTail, typename Value, typename... Tail>\nstatic void gen_single_item_tests(Value const& v, Tail const&... tail)\n{\n\tgen_single_item_tests<Expected>(v);\n\tgen_single_item_tests<ExpectedTail...>(tail...);\n}\n\ntemplate <typename... Expected, typename... Values>\nstatic void gen_tests(Values const&... values)\n{\n\tgen_single_item_tests<Expected...>(values...);\n\n\tboost::fusion::vector<Expected...> attribute = boost::fusion::make_vector(values...);\n\tgen_sequence_tests<Expected...>(attribute, values...);\n}\n\ntemplate <typename... Attributes>\nvoid make_test(Attributes const&... attrs)\n{\n\t// I would like to place all of this in a single call\n\t// but it requires tremendous amount of heap to compile\n\tgen_tests<Attributes...>(attrs...);\n\tgen_tests<\n\t\tstd::optional<Attributes>...\n\t  , boost::fusion::vector<Attributes>...\n\t>(attrs..., attrs...);\n\tgen_tests<\n\t\tstd::optional<boost::fusion::vector<Attributes>>...\n\t  , boost::fusion::vector<std::optional<Attributes>>...\n\t>(boost::fusion::vector<Attributes>(attrs)..., attrs...);\n}\n\nUNITTESTDEF(x3_test_attribute_type_check)\n{\n\tmake_test<int, std::string>(123, \"hello\");\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/binary.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#include \"test.hpp\"\n#include \"../x3/binary.hpp\"\n#include <boost/cstdint.hpp>\n#include <boost/predef/other/endian.h>\n\n///////////////////////////////////////////////////////////////////////////////\nUNITTESTDEF(x3_test_binary)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\tusing spirit_test::binary_test;\n\tusing spirit_test::binary_test_attr;\n\n\tusing boost::spirit::x3::byte_;\n\tusing boost::spirit::x3::word;\n\tusing boost::spirit::x3::dword;\n\tusing boost::spirit::x3::big_word;\n\tusing boost::spirit::x3::big_dword;\n\tusing boost::spirit::x3::little_word;\n\tusing boost::spirit::x3::little_dword;\n#ifdef BOOST_HAS_LONG_LONG\n\tusing boost::spirit::x3::qword;\n\tusing boost::spirit::x3::big_qword;\n\tusing boost::spirit::x3::little_qword;\n#endif\n\tusing boost::spirit::x3::bin_float;\n\tusing boost::spirit::x3::big_bin_float;\n\tusing boost::spirit::x3::little_bin_float;\n\tusing boost::spirit::x3::bin_double;\n\tusing boost::spirit::x3::big_bin_double;\n\tusing boost::spirit::x3::little_bin_double;\n\n\tboost::uint8_t uc;\n\tboost::uint16_t us;\n\tboost::uint32_t ui;\n#ifdef BOOST_HAS_LONG_LONG\n\tboost::uint64_t ul;\n#endif\n\tfloat f=0;\n\tdouble d=0;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(byte_);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(word);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(dword);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_word);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_dword);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_word);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_dword);\n#ifdef BOOST_HAS_LONG_LONG\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(qword);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_qword);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_qword);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bin_float);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_bin_float);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_bin_float);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bin_double);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_bin_double);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_bin_double);\n#endif\n\n// TODO: boost::endian::endian_arithmetic value constructor is not constexpr\n#if 0\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(byte_(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(word(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(dword(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_word(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_dword(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_word(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_dword(1));\n#ifdef BOOST_HAS_LONG_LONG\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(qword(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_qword(1));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_qword(1));\n#endif\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bin_float(1.0f));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_bin_float(1.0f));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_bin_float(1.0f));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bin_double(1.0));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(big_bin_double(1.0));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(little_bin_double(1.0));\n#endif\n\n\t{   // test native endian binaries\n#if BOOST_ENDIAN_LITTLE_BYTE\n\t\t_ASSERT(test_attr(\"\\x01\", byte_, uc) && uc == 0x01);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\", word, us) && us == 0x0201);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\", dword, ui) && ui == 0x04030201);\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\", qword, ul) &&\n\t\t\tul == 0x0807060504030201LL);\n#endif\n\t\t_ASSERT(binary_test_attr(\"\\x00\\x00\\x80\\x3f\", 4, bin_float, f) &&\n\t\t\tf == 1.0f);\n\t\t_ASSERT(binary_test_attr(\"\\x00\\x00\\x00\\x00\\x00\\x00\\xf0\\x3f\",\n\t\t\t8, bin_double, d) && f == 1.0);\n#else\n\t\t_ASSERT(test_attr(\"\\x01\", byte_, uc) && uc == 0x01);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\", word, us) && us ==  0x0102);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\", dword, ui) && ui == 0x01020304);\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\", qword, ul) &&\n\t\t\tul == 0x0102030405060708LL);\n#endif\n\t\t_ASSERT(binary_test_attr(\"\\x3f\\x80\\x00\\x00\", 4, bin_float, f) &&\n\t\t\tf == 1.0f);\n\t\t_ASSERT(binary_test_attr(\"\\x3f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\",\n\t\t\t8, bin_double, d) && f == 1.0);\n#endif\n\t}\n\n\t{   // test native endian binaries\n#if BOOST_ENDIAN_LITTLE_BYTE\n\t\t_ASSERT(test(\"\\x01\", byte_(0x01)));\n\t\t_ASSERT(test(\"\\x01\\x02\", word(0x0201)));\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\", dword(0x04030201)));\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\",\n\t\t\tqword(0x0807060504030201LL)));\n#endif\n\t\t_ASSERT(binary_test(\"\\x00\\x00\\x80\\x3f\", 4, bin_float(1.0f)));\n\t\t_ASSERT(binary_test(\"\\x00\\x00\\x00\\x00\\x00\\x00\\xf0\\x3f\", 8,\n\t\t\tbin_double(1.0)));\n#else\n\t\t_ASSERT(test(\"\\x01\", byte_(0x01)));\n\t\t_ASSERT(test(\"\\x01\\x02\", word(0x0102)));\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\", dword(0x01020304)));\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\",\n\t\t\tqword(0x0102030405060708LL)));\n#endif\n\t\t_ASSERT(binary_test(\"\\x3f\\x80\\x00\\x00\", 4, bin_float(1.0f)));\n\t\t_ASSERT(binary_test(\"\\x3f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\", 8,\n\t\t\tbin_double(1.0)));\n#endif\n\t}\n\n\t{   // test big endian binaries\n\t\t_ASSERT(test_attr(\"\\x01\\x02\", big_word, us) && us == 0x0102);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\", big_dword, ui) && ui == 0x01020304);\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\", big_qword, ul)\n\t\t\t&& ul == 0x0102030405060708LL);\n#endif\n\t\t_ASSERT(binary_test_attr(\"\\x3f\\x80\\x00\\x00\", 4, big_bin_float, f) &&\n\t\t\tf == 1.0f);\n\t\t_ASSERT(binary_test_attr(\"\\x3f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\",\n\t\t\t8, big_bin_double, d) && f == 1.0);\n\t}\n\n\t{\n\t\t_ASSERT(test(\"\\x01\\x02\", big_word(0x0102)));\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\", big_dword(0x01020304)));\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\",\n\t\t\tbig_qword(0x0102030405060708LL)));\n#endif\n\t\t_ASSERT(binary_test(\"\\x3f\\x80\\x00\\x00\", 4, big_bin_float(1.0f)));\n\t\t_ASSERT(binary_test(\"\\x3f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\", 8,\n\t\t\tbig_bin_double(1.0)));\n\t}\n\n\t{   // test little endian binaries\n\t\t_ASSERT(test_attr(\"\\x01\\x02\", little_word, us) && us == 0x0201);\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\", little_dword, ui) && ui == 0x04030201);\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test_attr(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\", little_qword, ul)\n\t\t\t&& ul == 0x0807060504030201LL);\n#endif\n\t\t_ASSERT(binary_test_attr(\"\\x00\\x00\\x80\\x3f\", 4,\n\t\t\tlittle_bin_float, f) && f == 1.0f);\n\t\t_ASSERT(binary_test_attr(\"\\x00\\x00\\x00\\x00\\x00\\x00\\xf0\\x3f\",\n\t\t\t8, little_bin_double, d) && f == 1.0);\n\t}\n\n\t{\n\t\t_ASSERT(test(\"\\x01\\x02\", little_word(0x0201)));\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\", little_dword(0x04030201)));\n#ifdef BOOST_HAS_LONG_LONG\n\t\t_ASSERT(test(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\",\n\t\t\tlittle_qword(0x0807060504030201LL)));\n#endif\n\t\t_ASSERT(binary_test(\"\\x00\\x00\\x80\\x3f\", 4, little_bin_float(1.0f)));\n\t\t_ASSERT(binary_test(\"\\x00\\x00\\x00\\x00\\x00\\x00\\xf0\\x3f\", 8,\n\t\t\tlittle_bin_double(1.0)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/bool.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_QI_BOOL)\n#define BOOST_SPIRIT_TEST_QI_BOOL\n\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n///////////////////////////////////////////////////////////////////////////////\nstruct backwards_bool_policies : boost::spirit::x3::bool_policies<>\n{\n\t// we want to interpret a 'true' spelled backwards as 'false'\n\ttemplate <typename Iterator, typename Attribute, typename CaseCompare>\n\tstatic bool\n\tparse_false(Iterator& first, Iterator const& last, Attribute& attr, CaseCompare const& case_compare)\n\t{\n\t\tnamespace spirit = boost::spirit;\n\t\tnamespace x3 = boost::spirit::x3;\n\t\tif (x3::detail::string_parse(\"eurt\", first, last, x3::unused, case_compare))\n\t\t{\n\t\t\tx3::traits::move_to(false, attr);   // result is false\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n};\n\n///////////////////////////////////////////////////////////////////////////////\nstruct test_bool_type\n{\n\ttest_bool_type(bool b = false) : b(b) {}    // provide conversion\n\tbool b;\n};\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/bool.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#include \"bool.hpp\"\n\nUNITTESTDEF(x3_test_bool)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::bool_;\n\n\t{\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bool_);\n\n\t\t_ASSERT(test(\"true\", bool_));\n\t\t_ASSERT(test(\"false\", bool_));\n\t\t_ASSERT(!test(\"fasle\", bool_));\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::true_;\n\t\tusing boost::spirit::x3::false_;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(true_);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(false_);\n\n\t\t_ASSERT(test(\"true\", true_));\n\t\t_ASSERT(!test(\"true\", false_));\n\t\t_ASSERT(test(\"false\", false_));\n\t\t_ASSERT(!test(\"false\", true_));\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::true_;\n\t\tusing boost::spirit::x3::false_;\n\t\tusing boost::spirit::x3::no_case;\n\n\t\t_ASSERT(test(\"True\", no_case[bool_]));\n\t\t_ASSERT(test(\"False\", no_case[bool_]));\n\t\t_ASSERT(test(\"True\", no_case[true_]));\n\t\t_ASSERT(test(\"False\", no_case[false_]));\n\t}\n\n\t{\n\t\tbool b = false;\n\t\t_ASSERT(test_attr(\"true\", bool_, b) && b);\n\t\t_ASSERT(test_attr(\"false\", bool_, b) && !b);\n\t\t_ASSERT(!test_attr(\"fasle\", bool_, b));\n\t}\n\n\t{\n\t\ttypedef boost::spirit::x3::bool_parser<bool, boost::spirit::char_encoding::standard, backwards_bool_policies>\n\t\t\tbackwards_bool_type;\n\t\tconstexpr backwards_bool_type backwards_bool{};\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(backwards_bool);\n\n\t\t_ASSERT(test(\"true\", backwards_bool));\n\t\t_ASSERT(test(\"eurt\", backwards_bool));\n\t\t_ASSERT(!test(\"false\", backwards_bool));\n\t\t_ASSERT(!test(\"fasle\", backwards_bool));\n\n\t\tbool b = false;\n\t\t_ASSERT(test_attr(\"true\", backwards_bool, b) && b);\n\t\t_ASSERT(test_attr(\"eurt\", backwards_bool, b) && !b);\n\t\t_ASSERT(!test_attr(\"false\", backwards_bool, b));\n\t\t_ASSERT(!test_attr(\"fasle\", backwards_bool, b));\n\t}\n\n\t{\n\t\ttypedef boost::spirit::x3::bool_parser<test_bool_type, boost::spirit::char_encoding::standard>\n\t\t\tbool_test_type;\n\t\tconstexpr bool_test_type test_bool{};\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(test_bool);\n\n\t\t_ASSERT(test(\"true\", test_bool));\n\t\t_ASSERT(test(\"false\", test_bool));\n\t\t_ASSERT(!test(\"fasle\", test_bool));\n\n\t\ttest_bool_type b = false;\n\t\t_ASSERT(test_attr(\"true\", test_bool, b) && b.b);\n\t\t_ASSERT(test_attr(\"false\", test_bool, b) && !b.b);\n\t\t_ASSERT(!test_attr(\"fasle\", test_bool, b));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/char1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c)      2019 Christian Mazakas\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#define BOOST_SPIRIT_X3_UNICODE\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../x3/char/unicode.hpp\"\n#include <boost/utility/string_view.hpp>\n\n#include <iostream>\n#include <vector>\n#include <algorithm>\n\nUNITTESTDEF(x3_test_char1)\n{\n\tusing spirit_test::test;\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_('x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_('a', 'z'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~char_('x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~char_('a', 'z'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~~char_('x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~~char_('a', 'z'));\n\n\t\t_ASSERT(test(\"x\", lit('x')));\n\t\t_ASSERT(test(L\"x\", lit(L'x')));\n\t\t_ASSERT(!test(\"y\", lit('x')));\n\t\t_ASSERT(!test(L\"y\", lit(L'x')));\n\n\t\t_ASSERT(test(\"x\", char_));\n\t\t_ASSERT(test(\"x\", char_('x')));\n\t\t_ASSERT(!test(\"x\", char_('y')));\n\t\t_ASSERT(test(\"x\", char_('a', 'z')));\n\t\t_ASSERT(!test(\"x\", char_('0', '9')));\n\n\t\t_ASSERT(test(\"0\", char_('0', '9')));\n\t\t_ASSERT(test(\"9\", char_('0', '9')));\n\t\t_ASSERT(!test(\"0\", ~char_('0', '9')));\n\t\t_ASSERT(!test(\"9\", ~char_('0', '9')));\n\n\t\t_ASSERT(!test(\"x\", ~char_));\n\t\t_ASSERT(!test(\"x\", ~char_('x')));\n\t\t_ASSERT(test(\" \", ~char_('x')));\n\t\t_ASSERT(test(\"X\", ~char_('x')));\n\t\t_ASSERT(!test(\"x\", ~char_('b', 'y')));\n\t\t_ASSERT(test(\"a\", ~char_('b', 'y')));\n\t\t_ASSERT(test(\"z\", ~char_('b', 'y')));\n\n\t\t_ASSERT(test(\"x\", ~~char_));\n\t\t_ASSERT(test(\"x\", ~~char_('x')));\n\t\t_ASSERT(!test(\" \", ~~char_('x')));\n\t\t_ASSERT(!test(\"X\", ~~char_('x')));\n\t\t_ASSERT(test(\"x\", ~~char_('b', 'y')));\n\t\t_ASSERT(!test(\"a\", ~~char_('b', 'y')));\n\t\t_ASSERT(!test(\"z\", ~~char_('b', 'y')));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\n\t\t_ASSERT(test(\"   x\", lit('x'), space));\n\t\t_ASSERT(test(L\"   x\", lit(L'x'), space));\n\n\t\t_ASSERT(test(\"   x\", char_, space));\n\t\t_ASSERT(test(\"   x\", char_('x'), space));\n\t\t_ASSERT(!test(\"   x\", char_('y'), space));\n\t\t_ASSERT(test(\"   x\", char_('a', 'z'), space));\n\t\t_ASSERT(!test(\"   x\", char_('0', '9'), space));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::standard_wide;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_(L'x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_(L'a', L'z'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~char_(L'x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~char_(L'a', L'z'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~~char_(L'x'));\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(~~char_(L'a', L'z'));\n\n\t\t_ASSERT(test(L\"x\", char_));\n\t\t_ASSERT(test(L\"x\", char_(L'x')));\n\t\t_ASSERT(!test(L\"x\", char_(L'y')));\n\t\t_ASSERT(test(L\"x\", char_(L'a', L'z')));\n\t\t_ASSERT(!test(L\"x\", char_(L'0', L'9')));\n\n\t\t_ASSERT(!test(L\"x\", ~char_));\n\t\t_ASSERT(!test(L\"x\", ~char_(L'x')));\n\t\t_ASSERT(test(L\" \", ~char_(L'x')));\n\t\t_ASSERT(test(L\"X\", ~char_(L'x')));\n\t\t_ASSERT(!test(L\"x\", ~char_(L'b', L'y')));\n\t\t_ASSERT(test(L\"a\", ~char_(L'b', L'y')));\n\t\t_ASSERT(test(L\"z\", ~char_(L'b', L'y')));\n\n\t\t_ASSERT(test(L\"x\", ~~char_));\n\t\t_ASSERT(test(L\"x\", ~~char_(L'x')));\n\t\t_ASSERT(!test(L\" \", ~~char_(L'x')));\n\t\t_ASSERT(!test(L\"X\", ~~char_(L'x')));\n\t\t_ASSERT(test(L\"x\", ~~char_(L'b', L'y')));\n\t\t_ASSERT(!test(L\"a\", ~~char_(L'b', L'y')));\n\t\t_ASSERT(!test(L\"z\", ~~char_(L'b', L'y')));\n\t}\n\n\t// unicode (normal ASCII)\n\t{\n\t\tusing namespace boost::spirit::x3::unicode;\n\n\t\t_ASSERT(test(U\"abcd\", +char_(U\"abcd\")));\n\t\t_ASSERT(!test(U\"abcd\", +char_(U\"qwer\")));\n\n\t\tauto const sub_delims = char_(U\"!$&'()*+,;=\");\n\n\t\tauto const delims =\n\t\t\tstd::vector<boost::u32string_view>{U\"!\", U\"$\", U\"&\", U\"'\", U\"(\", U\")\", U\"*\", U\"+\",\n\t\t\t\t\t\t\t\t\t\t\t   U\",\", U\";\", U\"=\"};\n\n\t\tauto const matched_all_sub_delims =\n\t\t\tstd::all_of(delims.begin(), delims.end(), [&](auto const delim) -> bool {\n\t\t\t\treturn test(delim, sub_delims);\n\t\t\t});\n\n\t\t_ASSERT(matched_all_sub_delims);\n\t}\n\n\t// unicode (escaped Unicode char literals)\n\t{\n\t\tusing namespace boost::spirit::x3::unicode;\n\n\t\tauto const chars = char_(U\"\\u0024\\u00a2\\u0939\\u20ac\\U00010348\");\n\n\t\tauto const test_strings =\n\t\t\tstd::vector<boost::u32string_view>{U\"\\u0024\", U\"\\u00a2\", U\"\\u0939\", U\"\\u20ac\",\n\t\t\t\t\t\t\t\t\t\t\t   U\"\\U00010348\"};\n\n\t\tauto const bad_test_strings = std::vector<boost::u32string_view>{U\"a\", U\"B\", U\"c\", U\"\\u0409\"};\n\n\t\tauto const all_matched =\n\t\t\tstd::all_of(test_strings.begin(), test_strings.end(), [&](auto const test_str) -> bool {\n\t\t\t\treturn test(test_str, chars);\n\t\t\t});\n\n\t\tauto const none_matched =\n\t\t\tstd::all_of(bad_test_strings.begin(), bad_test_strings.end(), [&](auto const bad_test_str) -> bool {\n\t\t\t\treturn !test(bad_test_str, chars);\n\t\t\t});\n\n\t\t_ASSERT(all_matched);\n\t\t_ASSERT(none_matched);\n\t}\n\n\n\t{   // single char strings!\n\t\tnamespace ascii = boost::spirit::x3::ascii;\n\t\t namespace wide = boost::spirit::x3::standard_wide;\n\n\t\t_ASSERT(test(\"x\", ascii::lit(\"x\")));\n\t\t_ASSERT(test(L\"x\", wide::lit(L\"x\")));\n\t\t_ASSERT(test(\"x\", ascii::char_(\"x\")));\n\t\t_ASSERT(test(L\"x\", wide::char_(L\"x\")));\n\n\t\t_ASSERT(test(\"x\", ascii::char_(\"a\", \"z\")));\n\t\t_ASSERT(test(L\"x\", wide::char_(L\"a\", L\"z\")));\n\t}\n\n\t{\n\t\t// chsets\n\t\tnamespace ascii = boost::spirit::x3::ascii;\n\t\tnamespace wide = boost::spirit::x3::standard_wide;\n\n\t\t_ASSERT(test(\"x\", ascii::char_(\"a-z\")));\n\t\t_ASSERT(!test(\"1\", ascii::char_(\"a-z\")));\n\t\t_ASSERT(test(\"1\", ascii::char_(\"a-z0-9\")));\n\n\t\t_ASSERT(test(\"x\", wide::char_(L\"a-z\")));\n\t\t_ASSERT(!test(\"1\", wide::char_(L\"a-z\")));\n\t\t_ASSERT(test(\"1\", wide::char_(L\"a-z0-9\")));\n\n\t\tstd::string set = \"a-z0-9\";\n\t\t_ASSERT(test(\"x\", ascii::char_(set)));\n\n#ifdef SPIRIT_NO_COMPILE_CHECK\n\t\ttest(\"\", ascii::char_(L\"a-z0-9\"));\n#endif\n\t}\n\n\t{\n\t\tnamespace ascii = boost::spirit::x3::ascii;\n\t\tchar const* input = \"\\x80\";\n\n\t\t// ascii > 7 bits (this should fail, not assert!)\n\t\t_ASSERT(!test(input, ascii::char_));\n\t\t_ASSERT(!test(input, ascii::char_('a')));\n\t\t_ASSERT(!test(input, ascii::alnum));\n\t\t_ASSERT(!test(input, ascii::char_(\"a-z\")));\n\t\t_ASSERT(!test(input, ascii::char_('0', '9')));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/char_class.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2010 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#define BOOST_SPIRIT_X3_UNICODE\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../x3/char/unicode.hpp\"\n#include <boost/type_traits/is_same.hpp>\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_char_class)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_failure;\n\tusing spirit_test::test_attr;\n\n\tusing boost::spirit::x3::unused_type;\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);\n\t\t_ASSERT(test(\"1\", alnum));\n\t\t_ASSERT(!test(\" \", alnum));\n\t\t_ASSERT(!test(\"1\", alpha));\n\t\t_ASSERT(test(\"x\", alpha));\n\t\t_ASSERT(test(\" \", blank));\n\t\t_ASSERT(!test(\"x\", blank));\n\t\t_ASSERT(test(\"1\", digit));\n\t\t_ASSERT(!test(\"x\", digit));\n\t\t_ASSERT(test(\"a\", lower));\n\t\t_ASSERT(!test(\"A\", lower));\n\t\t_ASSERT(test(\"!\", punct));\n\t\t_ASSERT(!test(\"x\", punct));\n\t\t_ASSERT(test(\" \", space));\n\t\t_ASSERT(test(\"\\n\", space));\n\t\t_ASSERT(test(\"\\r\", space));\n\t\t_ASSERT(test(\"\\t\", space));\n\t\t_ASSERT(test(\"A\", upper));\n\t\t_ASSERT(!test(\"a\", upper));\n\t\t_ASSERT(test(\"A\", xdigit));\n\t\t_ASSERT(test(\"0\", xdigit));\n\t\t_ASSERT(test(\"f\", xdigit));\n\t\t_ASSERT(!test(\"g\", xdigit));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(!test(\"1\", ~alnum));\n\t\t_ASSERT(test(\" \", ~alnum));\n\t\t_ASSERT(test(\"1\", ~alpha));\n\t\t_ASSERT(!test(\"x\", ~alpha));\n\t\t_ASSERT(!test(\" \", ~blank));\n\t\t_ASSERT(test(\"x\", ~blank));\n\t\t_ASSERT(!test(\"1\", ~digit));\n\t\t_ASSERT(test(\"x\", ~digit));\n\t\t_ASSERT(!test(\"a\", ~lower));\n\t\t_ASSERT(test(\"A\", ~lower));\n\t\t_ASSERT(!test(\"!\", ~punct));\n\t\t_ASSERT(test(\"x\", ~punct));\n\t\t_ASSERT(!test(\" \", ~space));\n\t\t_ASSERT(!test(\"\\n\", ~space));\n\t\t_ASSERT(!test(\"\\r\", ~space));\n\t\t_ASSERT(!test(\"\\t\", ~space));\n\t\t_ASSERT(!test(\"A\", ~upper));\n\t\t_ASSERT(test(\"a\", ~upper));\n\t\t_ASSERT(!test(\"A\", ~xdigit));\n\t\t_ASSERT(!test(\"0\", ~xdigit));\n\t\t_ASSERT(!test(\"f\", ~xdigit));\n\t\t_ASSERT(test(\"g\", ~xdigit));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::iso8859_1;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);\n\t\t_ASSERT(test(\"1\", alnum));\n\t\t_ASSERT(!test(\" \", alnum));\n\t\t_ASSERT(!test(\"1\", alpha));\n\t\t_ASSERT(test(\"x\", alpha));\n\t\t_ASSERT(test(\" \", blank));\n\t\t_ASSERT(!test(\"x\", blank));\n\t\t_ASSERT(test(\"1\", digit));\n\t\t_ASSERT(!test(\"x\", digit));\n\t\t_ASSERT(test(\"a\", lower));\n\t\t_ASSERT(!test(\"A\", lower));\n\t\t_ASSERT(test(\"!\", punct));\n\t\t_ASSERT(!test(\"x\", punct));\n\t\t_ASSERT(test(\" \", space));\n\t\t_ASSERT(test(\"\\n\", space));\n\t\t_ASSERT(test(\"\\r\", space));\n\t\t_ASSERT(test(\"\\t\", space));\n\t\t_ASSERT(test(\"A\", upper));\n\t\t_ASSERT(!test(\"a\", upper));\n\t\t_ASSERT(test(\"A\", xdigit));\n\t\t_ASSERT(test(\"0\", xdigit));\n\t\t_ASSERT(test(\"f\", xdigit));\n\t\t_ASSERT(!test(\"g\", xdigit));\n\n\t\t// test extended ASCII characters\n\t\t_ASSERT(test(\"\\xE9\", alpha));\n\t\t_ASSERT(test(\"\\xE9\", lower));\n\t\t_ASSERT(!test(\"\\xE9\", upper));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::standard;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);\n\t\t_ASSERT(test(\"1\", alnum));\n\t\t_ASSERT(!test(\" \", alnum));\n\t\t_ASSERT(!test(\"1\", alpha));\n\t\t_ASSERT(test(\"x\", alpha));\n\t\t_ASSERT(test(\" \", blank));\n\t\t_ASSERT(!test(\"x\", blank));\n\t\t_ASSERT(test(\"1\", digit));\n\t\t_ASSERT(!test(\"x\", digit));\n\t\t_ASSERT(test(\"a\", lower));\n\t\t_ASSERT(!test(\"A\", lower));\n\t\t_ASSERT(test(\"!\", punct));\n\t\t_ASSERT(!test(\"x\", punct));\n\t\t_ASSERT(test(\" \", space));\n\t\t_ASSERT(test(\"\\n\", space));\n\t\t_ASSERT(test(\"\\r\", space));\n\t\t_ASSERT(test(\"\\t\", space));\n\t\t_ASSERT(test(\"A\", upper));\n\t\t_ASSERT(!test(\"a\", upper));\n\t\t_ASSERT(test(\"A\", xdigit));\n\t\t_ASSERT(test(\"0\", xdigit));\n\t\t_ASSERT(test(\"f\", xdigit));\n\t\t_ASSERT(!test(\"g\", xdigit));\n\t\t_ASSERT(!test(\"\\xF1\", print));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::standard_wide;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);\n\t\t_ASSERT(test(L\"1\", alnum));\n\t\t_ASSERT(!test(L\" \", alnum));\n\t\t_ASSERT(!test(L\"1\", alpha));\n\t\t_ASSERT(test(L\"x\", alpha));\n\t\t_ASSERT(test(L\" \", blank));\n\t\t_ASSERT(!test(L\"x\", blank));\n\t\t_ASSERT(test(L\"1\", digit));\n\t\t_ASSERT(!test(L\"x\", digit));\n\t\t_ASSERT(test(L\"a\", lower));\n\t\t_ASSERT(!test(L\"A\", lower));\n\t\t_ASSERT(test(L\"!\", punct));\n\t\t_ASSERT(!test(L\"x\", punct));\n\t\t_ASSERT(test(L\" \", space));\n\t\t_ASSERT(test(L\"\\n\", space));\n\t\t_ASSERT(test(L\"\\r\", space));\n\t\t_ASSERT(test(L\"\\t\", space));\n\t\t_ASSERT(test(L\"A\", upper));\n\t\t_ASSERT(!test(L\"a\", upper));\n\t\t_ASSERT(test(L\"A\", xdigit));\n\t\t_ASSERT(test(L\"0\", xdigit));\n\t\t_ASSERT(test(L\"f\", xdigit));\n\t\t_ASSERT(!test(L\"g\", xdigit));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::unicode;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);\n\t\t_ASSERT(test(L\"1\", alnum));\n\t\t_ASSERT(!test(L\" \", alnum));\n\t\t_ASSERT(!test(L\"1\", alpha));\n\t\t_ASSERT(test(L\"x\", alpha));\n\t\t_ASSERT(test(L\" \", blank));\n\t\t_ASSERT(!test(L\"x\", blank));\n\t\t_ASSERT(test(L\"1\", digit));\n\t\t_ASSERT(!test(L\"x\", digit));\n\t\t_ASSERT(test(L\"a\", lower));\n\t\t_ASSERT(!test(L\"A\", lower));\n\t\t_ASSERT(test(L\"!\", punct));\n\t\t_ASSERT(!test(L\"x\", punct));\n\t\t_ASSERT(test(L\" \", space));\n\t\t_ASSERT(test(L\"\\n\", space));\n\t\t_ASSERT(test(L\"\\r\", space));\n\t\t_ASSERT(test(L\"\\t\", space));\n\t\t_ASSERT(test(L\"A\", upper));\n\t\t_ASSERT(!test(L\"a\", upper));\n\t\t_ASSERT(test(L\"A\", xdigit));\n\t\t_ASSERT(test(L\"0\", xdigit));\n\t\t_ASSERT(test(L\"f\", xdigit));\n\t\t_ASSERT(!test(L\"g\", xdigit));\n\n\t\t_ASSERT(test(L\"A\", alphabetic));\n\t\t_ASSERT(test(L\"9\", decimal_number));\n\t\t_ASSERT(test(L\"\\u2800\", braille));\n\t\t_ASSERT(!test(L\" \", braille));\n\t\t_ASSERT(test(L\" \", ~braille));\n\t\t// $$$ TODO $$$ Add more unicode tests\n\t}\n\n\t{   // test invalid unicode literals\n\t\tusing namespace boost::spirit::x3::unicode;\n\n\t\tauto const invalid_unicode = char32_t{0x7FFFFFFF};\n\t\tauto const input           = boost::u32string_view(&invalid_unicode, 1);\n\n\t\t_ASSERT(test_failure(input, char_));\n\n\t\t// force unicode category lookup\n\t\t// related issue: https://github.com/boostorg/spirit/issues/524\n\t\t_ASSERT(test_failure(input, alpha));\n\t\t_ASSERT(test_failure(input, upper));\n\t\t_ASSERT(test_failure(input, lower));\n\t}\n\n\t{   // test attribute extraction\n\t\tusing boost::spirit::x3::traits::attribute_of;\n\t\tusing boost::spirit::x3::iso8859_1::alpha;\n\t\tusing boost::spirit::x3::iso8859_1::alpha_type;\n\n\t\tstatic_assert(\n\t\t\tboost::is_same<\n\t\t\t\tattribute_of<alpha_type, unused_type>::type\n\t\t\t  , unsigned char>::value\n\t\t  , \"Wrong attribute type!\"\n\t\t);\n\n\t\tint attr = 0;\n\t\t_ASSERT(test_attr(\"a\", alpha, attr));\n\t\t_ASSERT(attr == 'a');\n\t}\n\n\t{   // test attribute extraction\n\t\tusing boost::spirit::x3::iso8859_1::alpha;\n\t\tusing boost::spirit::x3::iso8859_1::space;\n\t\tchar attr = 0;\n\t\t_ASSERT(test_attr(\"     a\", alpha, attr, space));\n\t\t_ASSERT(attr == 'a');\n\t}\n\n\t{   // test action\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\tusing boost::spirit::x3::_attr;\n\t\tchar ch;\n\t\tauto f = [&](auto& ctx){ ch = _attr(ctx); };\n\n\t\t_ASSERT(test(\"x\", alnum[f]));\n\t\t_ASSERT(ch == 'x');\n\t\t_ASSERT(test(\"   A\", alnum[f], space));\n\t\t_ASSERT(ch == 'A');\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/confix.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2009 Chris Hoeppler\n\tCopyright (c) 2014 Lee Clagett\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3/char.hpp\"\n#include \"../x3/core.hpp\"\n#include \"../x3/numeric.hpp\"\n#include \"../x3/operator.hpp\"\n#include \"../x3/string.hpp\"\n#include \"../x3/directive/confix.hpp\"\n\nUNITTESTDEF(x3_test_confix)\n{\n\tnamespace x3 = boost::spirit::x3;\n\tusing namespace spirit_test;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::confix(lit('('), lit(')')));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::confix(lit(\"[\"), lit(\"]\")));\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::confix(lit(\"/*\"), lit(\"*/\")));\n\n\t{\n\t\tconst auto comment = x3::confix(lit(\"/*\"), lit(\"*/\"));\n\n\t\t_ASSERT(test_failure(\"/abcdef*/\", comment[lit(\"abcdef\")]));\n\t\t_ASSERT(test_failure(\"/* abcdef*/\", comment[lit(\"abcdef\")]));\n\t\t_ASSERT(test_failure(\"/*abcdef */\", comment[lit(\"abcdef\")]));\n\t\t_ASSERT(test(\"/*abcdef*/\", comment[lit(\"abcdef\")]));\n\n\t\t{\n\t\t\tunsigned value = 0;\n\t\t\t_ASSERT(\n\t\t\t\ttest_attr(\" /* 123 */ \", comment[x3::uint_], value, x3::space));\n\t\t\t_ASSERT(value == 123);\n\n\t\t\tusing x3::_attr;\n\t\t\tvalue = 0;\n\t\t\tconst auto lambda = [&value](auto& ctx ){ value = _attr(ctx) + 1; };\n\t\t\t_ASSERT(test_attr(\"/*123*/\", comment[x3::uint_][lambda], value));\n\t\t\t_ASSERT(value == 124);\n\t\t}\n\t}\n\t{\n\t\tconst auto array = x3::confix(lit('['), lit(']'));\n\n\t\t{\n\t\t\tstd::vector<unsigned> values;\n\n\t\t\t_ASSERT(test(\"[0,2,4,6,8]\", array[x3::uint_ % lit(',')]));\n\t\t\t_ASSERT(test_attr(\"[0,2,4,6,8]\", array[x3::uint_ % lit(',')], values));\n\t\t\t_ASSERT(\n\t\t\t\tvalues.size() == 5 &&\n\t\t\t\tvalues[0] == 0 &&\n\t\t\t\tvalues[1] == 2 &&\n\t\t\t\tvalues[2] == 4 &&\n\t\t\t\tvalues[3] == 6 &&\n\t\t\t\tvalues[4] == 8);\n\t\t}\n\t\t{\n\t\t\tstd::vector<std::vector<unsigned>> values;\n\t\t\t_ASSERT(\n\t\t\t\ttest(\"[[1,3,5],[0,2,4]]\", array[array[x3::uint_ % lit(',')] % lit(',')]));\n\t\t\t_ASSERT(\n\t\t\t\ttest_attr(\n\t\t\t\t\t\"[[1,3,5],[0,2,4]]\",\n\t\t\t\t\tarray[array[x3::uint_ % lit(',')] % lit(',')],\n\t\t\t\t\tvalues));\n\t\t\t_ASSERT(\n\t\t\t\tvalues.size() == 2 &&\n\t\t\t\tvalues[0].size() == 3 &&\n\t\t\t\tvalues[0][0] == 1 &&\n\t\t\t\tvalues[0][1] == 3 &&\n\t\t\t\tvalues[0][2] == 5 &&\n\t\t\t\tvalues[1].size() == 3 &&\n\t\t\t\tvalues[1][0] == 0 &&\n\t\t\t\tvalues[1][1] == 2 &&\n\t\t\t\tvalues[1][2] == 4);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/container_support.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/std_pair.hpp>\n\n#include <map>\n#include <unordered_map>\n#include <boost/unordered_map.hpp>\n#include <vector>\n#include <list>\n#include <deque>\n#include <set>\n#include <unordered_set>\n#include <boost/unordered_set.hpp>\n#include <string>\n\nnamespace x3 = boost::spirit::x3;\nusing boost::spirit::x3::lit;\n\n\n// check if we did not break user defined specializations\nnamespace check_substitute {\ntemplate <typename T> struct foo {};\ntemplate <typename T> struct bar { using type = T; };\ntemplate <typename T> struct is_bar : std::false_type {};\ntemplate <typename T> struct is_bar<bar<T>> : std::true_type {};\n}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits {\nusing namespace check_substitute;\n\ntemplate <typename T, typename U>\nstruct is_substitute<foo<T>, foo<U>> : is_substitute<T, U> {};\n\ntemplate <typename T, typename U>\nstruct is_substitute<T, U, std::enable_if_t<is_bar<T>::value && is_bar<U>::value>>\n  : is_substitute<typename T::type, typename U::type> {};\n}}}}\n\nnamespace check_substitute {\nusing x3::traits::is_substitute;\nstatic_assert(is_substitute<foo<int>, foo<int>>::value, \"is_substitute problem\");\nstatic_assert(!is_substitute<foo<int>, foo<long>>::value, \"is_substitute problem\");\nstatic_assert(is_substitute<bar<int>, bar<int>>::value, \"is_substitute problem\");\nstatic_assert(!is_substitute<bar<int>, bar<long>>::value, \"is_substitute problem\");\n}\n\n\nx3::rule<class pair_rule, std::pair<std::string,std::string>> const pair_rule(\"pair\");\nx3::rule<class string_rule, std::string> const string_rule(\"string\");\n\nauto const pair_rule_def = string_rule > x3::lit('=') > string_rule;\nauto const string_rule_def = x3::lexeme[*x3::alnum];\n\nBOOST_SPIRIT_DEFINE(pair_rule, string_rule)\n\ntemplate <typename Container>\nvoid test_map_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {{\"k1\", \"v1\"}, {\"k2\", \"v2\"}};\n\tauto const rule = pair_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", rule, container));\n\t_ASSERT(container.size() == 2);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = pair_rule >> lit(',') >> pair_rule >> lit(',') >> pair_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = pair_rule >> +(lit(',') >> pair_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", cic_rule, container));\n}\n\ntemplate <typename Container>\nvoid test_multimap_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {{\"k1\", \"v1\"}, {\"k2\", \"v2\"}, {\"k2\", \"v3\"}};\n\tauto const rule = pair_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", rule, container));\n\t_ASSERT(container.size() == 3);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = pair_rule >> lit(',') >> pair_rule >> lit(',') >> pair_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = pair_rule >> +(lit(',') >> pair_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"k1=v1,k2=v2,k2=v3\", cic_rule, container));\n}\n\ntemplate <typename Container>\nvoid test_sequence_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {\"e1\", \"e2\", \"e2\"};\n\tauto const rule = string_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"e1,e2,e2\", rule, container));\n\t_ASSERT(container.size() == 3);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = string_rule >> lit(',') >> string_rule >> lit(',') >> string_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = string_rule >> +(lit(',') >> string_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", cic_rule, container));\n}\n\ntemplate <typename Container>\nvoid test_set_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {\"e1\", \"e2\"};\n\tauto const rule = string_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"e1,e2,e2\", rule, container));\n\t_ASSERT(container.size() == 2);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = string_rule >> lit(',') >> string_rule >> lit(',') >> string_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = string_rule >> +(lit(',') >> string_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", cic_rule, container));\n}\n\ntemplate <typename Container>\nvoid test_multiset_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {\"e1\", \"e2\", \"e2\"};\n\tauto const rule = string_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"e1,e2,e2\", rule, container));\n\t_ASSERT(container.size() == 3);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = string_rule >> lit(',') >> string_rule >> lit(',') >> string_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = string_rule >> +(lit(',') >> string_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", cic_rule, container));\n}\n\ntemplate <typename Container>\nvoid test_string_support()\n{\n\tusing spirit_test::test_attr;\n\n\tContainer container;\n\tContainer const compare {\"e1e2e2\"};\n\tauto const rule = string_rule % x3::lit(',');\n\n\t_ASSERT(test_attr(\"e1,e2,e2\", rule, container));\n\t_ASSERT(container.size() == 6);\n\t_ASSERT(container == compare);\n\n\t// test sequences parsing into containers\n\tauto const seq_rule = string_rule >> lit(',') >> string_rule >> lit(',') >> string_rule;\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", seq_rule, container));\n\n\t// test parsing container into container\n\tauto const cic_rule = string_rule >> +(lit(',') >> string_rule);\n\tcontainer.clear();\n\t_ASSERT(test_attr(\"e1,e2,e2\", cic_rule, container));\n}\n\nUNITTESTDEF(x3_test_container_support)\n{\n\tusing x3::traits::is_associative;\n\n\t// ------------------------------------------------------------------\n\n\tstatic_assert(is_associative<std::set<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::unordered_set<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<boost::unordered_set<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::multiset<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::unordered_multiset<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<boost::unordered_multiset<int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::map<int,int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::unordered_map<int,int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<boost::unordered_map<int,int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::multimap<int,int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<std::unordered_multimap<int,int>>::value, \"is_associative problem\");\n\tstatic_assert(is_associative<boost::unordered_multimap<int,int>>::value, \"is_associative problem\");\n\n\tstatic_assert(!is_associative<std::vector<int>>::value, \"is_associative problem\");\n\tstatic_assert(!is_associative<std::string>::value, \"is_associative problem\");\n\tstatic_assert(!is_associative<std::deque<int>>::value, \"is_associative problem\");\n\tstatic_assert(!is_associative<std::list<int>>::value, \"is_associative problem\");\n\n\t// ------------------------------------------------------------------\n\n\ttest_string_support<std::string>();\n\n\ttest_sequence_support<std::vector<std::string>>();\n\ttest_sequence_support<std::list<std::string>>();\n\ttest_sequence_support<std::deque<std::string>>();\n\n\ttest_set_support<std::set<std::string>>();\n\ttest_set_support<std::unordered_set<std::string>>();\n\ttest_set_support<boost::unordered_set<std::string>>();\n\n\ttest_multiset_support<std::multiset<std::string>>();\n\ttest_multiset_support<std::unordered_multiset<std::string>>();\n\ttest_multiset_support<boost::unordered_multiset<std::string>>();\n\n\ttest_map_support<std::map<std::string,std::string>>();\n\ttest_map_support<std::unordered_map<std::string,std::string>>();\n\ttest_map_support<boost::unordered_map<std::string,std::string>>();\n\n\ttest_multimap_support<std::multimap<std::string,std::string>>();\n\ttest_multimap_support<std::unordered_multimap<std::string,std::string>>();\n\ttest_multimap_support<boost::unordered_multimap<std::string,std::string>>();\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/difference.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <string>\n#include <iostream>\n\nUNITTESTDEF(x3_test_difference)\n{\n\tusing boost::spirit::x3::ascii::char_;\n\tusing boost::spirit::x3::ascii::space;\n\tusing boost::spirit::x3::lit;\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ - lit('a'));\n\n\t// Basic tests\n\t{\n\t\t_ASSERT(test(\"b\", char_ - lit('a')));\n\t\t_ASSERT(!test(\"a\", char_ - lit('a')));\n\t\t_ASSERT(test(\"/* abcdefghijk */\", lit(\"/*\") >> *(char_ - lit(\"*/\")) >> lit(\"*/\")));\n\t\t_ASSERT(!test(\"switch\", lit(\"switch\") - lit(\"switch\")));\n\t}\n\n\t// Test attributes\n\t{\n\t\tchar attr='\\0';\n\t\t_ASSERT(test_attr(\"xg\", (char_ - lit('g')) >> lit('g'), attr));\n\t\t_ASSERT(attr == 'x');\n\t}\n\n\t// Test handling of container attributes\n\t{\n\t\tstd::string attr;\n\t\t_ASSERT(test_attr(\"abcdefg\", *(char_ - lit('g')) >> lit('g'), attr));\n\t\t_ASSERT(attr == \"abcdef\");\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::_attr;\n\n\t\tstd::string s;\n\n\t\t_ASSERT(test(\n\t\t\t\"/*abcdefghijk*/\"\n\t\t  , lit(\"/*\") >> *(char_ - lit(\"*/\"))[([&](auto& ctx){ s += _attr(ctx); })] >> lit(\"*/\")\n\t\t));\n\t\t_ASSERT(s == \"abcdefghijk\");\n\t\ts.clear();\n\n\t\t_ASSERT(test(\n\t\t\t\"    /*abcdefghijk*/\"\n\t\t  , lit(\"/*\") >> *(char_ - lit(\"*/\"))[([&](auto& ctx){ s += _attr(ctx); })] >> lit(\"*/\")\n\t\t  , space\n\t\t));\n\t\t_ASSERT(s == \"abcdefghijk\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/eoi.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_eoi)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::eoi;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(eoi);\n\n\t{\n\t\t_ASSERT((test(\"\", eoi)));\n\t\t_ASSERT(!(test(\"x\", eoi)));\n\t}\n\n\t{\n\t\t_ASSERT(what(eoi) == \"eoi\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/eol.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_eol)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::eol;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(eol);\n\n\t{\n\t\t_ASSERT((test(\"\\r\\n\", eol)));\n\t\t_ASSERT((test(\"\\r\", eol)));\n\t\t_ASSERT((test(\"\\n\", eol)));\n\t\t_ASSERT((!test(\"\\n\\r\", eol)));\n\t\t_ASSERT((!test(\"\", eol)));\n\t}\n\n\t{\n\t\t_ASSERT(what(eol) == \"eol\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/eps.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_eps)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::eps;\n\tusing boost::spirit::x3::unused_type;\n\n\t{\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(eps);\n\t\t_ASSERT((test(\"\", eps)));\n\t\t_ASSERT((test(\"xxx\", eps, false)));\n\t\t//~ _ASSERT((!test(\"\", !eps))); // not predicate $$$ Implement me! $$$\n\t}\n\n\t{   // test non-lazy semantic predicate\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(eps(true));\n\t\t_ASSERT((test(\"\", eps(true))));\n\t\t_ASSERT((!test(\"\", eps(false))));\n\t\t_ASSERT((test(\"\", !eps(false))));\n\t}\n\n\t{   // test lazy semantic predicate\n\n\t\tauto true_ = [](unused_type) { return true; };\n\t\tauto false_ = [](unused_type) { return false; };\n\n\t\t// cannot use lambda in constant expression before C++17\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(eps(std::true_type{}));\n\t\t_ASSERT((test(\"\", eps(true_))));\n\t\t_ASSERT((!test(\"\", eps(false_))));\n\t\t_ASSERT((test(\"\", !eps(false_))));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/error_handler.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../x3/support/utility/annotate_on_success.hpp\"\n\n#include <string>\n#include <sstream>\n\nnamespace x3 = boost::spirit::x3;\n\nstruct error_handler_base\n{\n\ttemplate <typename Iterator, typename Exception, typename Context>\n\tx3::error_handler_result on_error(\n\t\tIterator&, Iterator const&\n\t  , Exception const& x, Context const& context) const\n\t{\n\t\tstd::string message = \"Error! Expecting: \" + x.which() + \" here:\";\n\t\tauto& error_handler = x3::get<x3::error_handler_tag>(context).get();\n\t\terror_handler(x.where(), message);\n\t\treturn x3::error_handler_result::fail;\n\t}\n};\n\nstruct test_inner_rule_class;\nstruct test_rule_class : x3::annotate_on_success, error_handler_base {};\n\nx3::rule<test_inner_rule_class> const test_inner_rule = \"\\\"bar\\\"\";\nx3::rule<test_rule_class> const test_rule;\nauto const test_inner_rule_def = x3::lit(\"bar\");\nauto const test_rule_def = x3::lit(\"foo\") > test_inner_rule > x3::lit(\"git\");\n\nBOOST_SPIRIT_DEFINE(test_inner_rule, test_rule)\n\nvoid test(std::string const& line_break) {\n\tstd::string const input(\"foo\" + line_break + \"  foo\" + line_break + \"git\");\n\tauto const begin = std::begin(input);\n\tauto const end = std::end(input);\n\n{\n\tstd::stringstream stream;\n\tx3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};\n\n\tauto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];\n\tx3::phrase_parse(begin, end, parser, x3::space);\n\n\t_ASSERTEQUAL(stream.str(), \"In line 2:\\nError! Expecting: \\\"bar\\\" here:\\n  foo\\n__^_\\n\");\n}\n\n{ // TODO: cleanup when error_handler is reenterable\n\tstd::stringstream stream;\n\tx3::error_handler<std::string::const_iterator> error_handler{ begin, end, stream };\n\n\tauto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];\n\tx3::parse(begin, end, parser);\n\n\t_ASSERT(tc::equal(stream.str().c_str(), \"In line 1:\\nError! Expecting: \\\"bar\\\" here:\\nfoo\\n___^_\\n\"));\n}\n}\n\nvoid test_line_break_first(std::string const& line_break) {\n\tstd::string const input(line_break + \"foo  foo\" + line_break + \"git\");\n\tauto const begin = std::begin(input);\n\tauto const end = std::end(input);\n\n\tstd::stringstream stream;\n\tx3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};\n\n\tauto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];\n\tx3::phrase_parse(begin, end, parser, x3::space);\n\n\t_ASSERTEQUAL(stream.str(), \"In line 2:\\nError! Expecting: \\\"bar\\\" here:\\nfoo  foo\\n_____^_\\n\");\n}\n\nUNITTESTDEF(x3_test_error_handler) {\n\ttest(\"\\n\");\n\ttest(\"\\r\");\n\ttest(\"\\r\\n\");\n\n\ttest_line_break_first(\"\\n\");\n\ttest_line_break_first(\"\\r\");\n\ttest_line_break_first(\"\\r\\n\");\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/expect.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2013 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../x3/binary.hpp\"\n#include \"../x3/directive/with.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/at.hpp>\n\n#include <string>\n#include <iostream>\n\nUNITTESTDEF(x3_test_expect)\n{\n\tusing namespace boost::spirit;\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::expect;\n\tusing boost::spirit::x3::lexeme;\n\tusing boost::spirit::x3::no_case;\n\tusing boost::spirit::x3::no_skip;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::raw;\n\tusing boost::spirit::x3::skip;\n\tusing boost::spirit::x3::seek;\n\tusing boost::spirit::x3::repeat;\n\tusing boost::spirit::x3::matches;\n\tusing boost::spirit::x3::eps;\n\tusing boost::spirit::x3::eoi;\n\tusing boost::spirit::x3::eol;\n\tusing boost::spirit::x3::attr;\n\tusing boost::spirit::x3::dword;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::symbols;\n\tusing boost::spirit::x3::confix;\n\tusing boost::spirit::x3::with;\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(expect[lit('x')]);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ > char_);\n\n\t{\n\t\t_ASSERT((test(\"aa\", char_ >> expect[char_])));\n\t\t_ASSERT((test(\"aaa\", char_ >> expect[char_ >> char_('a')])));\n\t\t_ASSERT((test(\"xi\", char_('x') >> expect[char_('i')])));\n\t\t_ASSERT((!test(\"xi\", char_('y') >> expect[char_('o')]))); // should not throw!\n\t\t_ASSERT((test(\"xin\", char_('x') >> expect[char_('i') >> char_('n')])));\n\t\t_ASSERT((!test(\"xi\", char_('x') >> expect[char_('o')])));\n\t}\n\n\t{\n\t\t_ASSERT((test(\"aa\", char_ > char_)));\n\t\t_ASSERT((test(\"aaa\", char_ > char_ > char_('a'))));\n\t\t_ASSERT((test(\"xi\", char_('x') > char_('i'))));\n\t\t_ASSERT((!test(\"xi\", char_('y') > char_('o')))); // should not throw!\n\t\t_ASSERT((test(\"xin\", char_('x') > char_('i') > char_('n'))));\n\t\t_ASSERT((!test(\"xi\", char_('x') > char_('o'))));\n\t}\n\n\t{\n\t\t_ASSERT((!test(\"ay:a\", char_ > char_('x') >> lit(':') > lit('a'))));\n\t}\n\n#if defined(BOOST_CLANG)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Woverloaded-shift-op-parentheses\"\n#endif\n\t{ // Test that attributes with > (sequences) work just like >> (sequences)\n\n\t\tusing boost::fusion::vector;\n\t\tusing boost::fusion::at_c;\n\n\t\t{\n\t\t\tvector<char, char, char> vecAttr;\n\t\t\t_ASSERT((test_attr(\" a\\n  b\\n  c\",\n\t\t\t\tchar_ > char_ > char_, vecAttr, space)));\n\t\t\t_ASSERT((at_c<0>(vecAttr) == 'a'));\n\t\t\t_ASSERT((at_c<1>(vecAttr) == 'b'));\n\t\t\t_ASSERT((at_c<2>(vecAttr) == 'c'));\n\t\t}\n\n\t\t{\n\t\t\tvector<char, char, char> vecAttr;\n\t\t\t_ASSERT((test_attr(\" a\\n  b\\n  c\",\n\t\t\t\tchar_ > char_ >> char_, vecAttr, space)));\n\t\t\t_ASSERT((at_c<0>(vecAttr) == 'a'));\n\t\t\t_ASSERT((at_c<1>(vecAttr) == 'b'));\n\t\t\t_ASSERT((at_c<2>(vecAttr) == 'c'));\n\t\t}\n\n\t\t{\n\t\t\tvector<char, char, char> vecAttr;\n\t\t\t_ASSERT((test_attr(\" a, b, c\",\n\t\t\t\tchar_ >> lit(',') > char_ >> lit(',') > char_, vecAttr, space)));\n\t\t\t_ASSERT((at_c<0>(vecAttr) == 'a'));\n\t\t\t_ASSERT((at_c<1>(vecAttr) == 'b'));\n\t\t\t_ASSERT((at_c<2>(vecAttr) == 'c'));\n\t\t}\n\n\t\t{\n\t\t\tstd::string strAttr;\n\t\t\t_ASSERT((test_attr(\"'azaaz'\",\n\t\t\t\tlit(\"'\") > *(char_(\"a\") | char_(\"z\")) > lit(\"'\"), strAttr, space)));\n\t\t\t_ASSERT(strAttr == \"azaaz\");\n\t\t}\n\t}\n#if defined(BOOST_CLANG)\n#pragma clang diagnostic pop\n#endif\n\n\t{\n\t\t_ASSERT((test(\" a a\", char_ > char_, space)));\n\t\t_ASSERT((test(\" x i\", char_('x') > char_('i'), space)));\n\t\t_ASSERT((!test(\" x i\", char_('x') > char_('o'), space)));\n\t}\n\n\t{\n\t\t_ASSERT((!test(\"bar\", expect[lit(\"foo\")])));\n\t}\n\n\t{ // Test expect in skipper\n\t\t_ASSERT((test(\"accbeabfcdg\", repeat(7)[alpha], lit('a') > lit('b') | lit('c') > lit('d'))));\n\t\tstd::string strAttr;\n\t\t_ASSERT((test_attr(\"accbeabfcdg\", repeat(7)[alpha], strAttr, lit('a') > lit('b') | lit('c') > lit('d'))));\n\t\t_ASSERT((strAttr == \"accbefg\"));\n\t}\n\n\t{ // Test expect in auxilary parsers\n\t\t_ASSERT((test(\"a12\", lit('a') > eps > +digit)));\n\t\t_ASSERT((!test(\"a12\", lit('a') > eps(false) > +digit)));\n\t\t_ASSERT((test(\"a12\", lit('a') > +digit > eoi)));\n\t\t_ASSERT((!test(\"a12\", lit('a') > eoi > +digit)));\n\t\t_ASSERT((test(\"a12\\n\", lit('a') > +digit > eol)));\n\t\t_ASSERT((!test(\"a12\\n\", lit('a') > eol > +digit)));\n\t\tint n = 0;\n\t\t_ASSERT((test_attr(\"abc\", lit(\"abc\") > attr(12) > eoi, n)));\n\t\t_ASSERT((12 == n));\n\t}\n\n\t{ // Test expect in binary, numeric, char, string parsers\n\t\t_ASSERT((test(\"12abcd\", +digit > dword)));\n\t\t_ASSERT((!test(\"12abc\", +digit > dword)));\n\t\t_ASSERT((test(\"abc12\", +alpha > int_)));\n\t\t_ASSERT((!test(\"abc\", +alpha > int_)));\n\t\t_ASSERT((test(\"12a\", +digit > lit('a'))));\n\t\t_ASSERT((!test(\"12a\", +digit > lit('b'))));\n\t\tsymbols<> s;\n\t\ts.add(\"cat\");\n\t\t_ASSERT((test(\"12cat\", +digit > s)));\n\t\t_ASSERT((!test(\"12dog\", +digit > s)));\n\t}\n\n\t{ // Test expect in confix\n\t\t_ASSERT((test(\"[12cat]\", confix(lit('['), lit(']'))[+digit > lit(\"cat\")])));\n\t\t_ASSERT((!test(\"[12dog]\", confix(lit('['), lit(']'))[+digit > lit(\"cat\")])));\n\t}\n\n\t{ // Test expect in expect\n\t\t_ASSERT((test(\"abc\", lit('a') >> expect[lit('b') >> lit('c')])));\n\t\t_ASSERT((!test(\"abc\", lit('a') >> expect[lit('b') >> lit('d')])));\n\t\t_ASSERT((!test(\"abc\", lit('a') >> expect[lit('b') > lit('d')])));\n\t}\n\n\t{ // Test expect in lexeme\n\t\t_ASSERT((test(\"12 ab\", int_ >> lexeme[lit('a') > lit('b')], space)));\n\t\t_ASSERT((!test(\"12 a b\", int_ >> lexeme[lit('a') > lit('b')], space)));\n\t}\n\n\t{ // Test expect in matches\n\t\t_ASSERT((test(\"ab\", matches[lit('a') >> lit('b')])));\n\t\t_ASSERT((test(\"ac\", matches[lit('a') >> lit('b')] >> lit(\"ac\"))));\n\t\t_ASSERT((test(\"ab\", matches[lit('a') > lit('b')])));\n\t\t_ASSERT((!test(\"ac\", matches[lit('a') > lit('b')] >> lit(\"ac\"))));\n\t\tbool bAttr = false;\n\t\t_ASSERT((test_attr(\"ab\", matches[lit('a') > lit('b')], bAttr)));\n\t\t_ASSERT((true == bAttr));\n\t}\n\n\t{ // Test expect in no_case\n\t\t_ASSERT((test(\"12 aB\", int_ >> no_case[lit('a') > lit('b')], space)));\n\t\t_ASSERT((!test(\"12 aB\", int_ >> no_case[lit('a') > lit('c')], space)));\n\t}\n\n\t{ // Test expect in no_skip\n\t\t_ASSERT((test(\"12 3ab\", int_ >> int_ >> no_skip[lit('a') > lit('b')], space)));\n\t\t_ASSERT((!test(\"12 3ab\", int_ >> int_ >> no_skip[lit('a') > lit('c')], space)));\n\t}\n\n\t{ // Test expect in omit\n\t\t_ASSERT((test(\"ab\", omit[lit('a') > lit('b')])));\n\t\t_ASSERT((!test(\"ab\", omit[lit('a') > lit('c')])));\n\t}\n\n\t{ // Test expect in raw\n\t\t_ASSERT((test(\"ab\", raw[lit('a') > lit('b')])));\n\t\t_ASSERT((!test(\"ab\", raw[lit('a') > lit('c')])));\n\t}\n\n\t{ // Test expect in repeat\n\t\t_ASSERT((test(\"ababac\", repeat(1, 3)[lit('a') >> lit('b')] >> lit(\"ac\") | +alpha)));\n\t\t_ASSERT((!test(\"ababac\", repeat(1, 3)[lit('a') > lit('b')] | +alpha)));\n\t\t_ASSERT((!test(\"acab\", repeat(2, 3)[lit('a') > lit('b')] | +alpha)));\n\t\t_ASSERT((test(\"bcab\", repeat(2, 3)[lit('a') > lit('b')] | +alpha)));\n\t}\n\n\t{ // Test expect in seek\n\t\t_ASSERT((test(\"a1b1c1\", seek[lit('c') > lit('1')])));\n\t\t_ASSERT((!test(\"a1b1c2c1\", seek[lit('c') > lit('1')])));\n\t}\n\n\t{ // Test expect in skip\n\t\t_ASSERT((test(\"ab[]c[]d\", skip(lit('[') > lit(']'))[+alpha])));\n\t\t_ASSERT((!test(\"ab[]c[5]d\", skip(lit('[') > lit(']'))[+alpha])));\n\t\t_ASSERT((test(\"a1[]b2c3[]d4\", skip(lit('[') > lit(']'))[+(alpha > digit)])));\n\t\t_ASSERT((!test(\"a1[]b2c3[]d\", skip(lit('[') > lit(']'))[+(alpha > digit)])));\n\t}\n\n\t{ // Test expect in alternative\n\t\t_ASSERT((test(\"ac\", lit('a') >> lit('b') | lit(\"ac\"))));\n\t\t_ASSERT((!test(\"ac\", (lit('a') > lit('b')) | lit(\"ac\"))));\n\t\t_ASSERT((test(\"ac\", lit('a') >> lit('b') | lit('a') >> lit('d') | lit(\"ac\"))));\n\t\t_ASSERT((!test(\"ac\", lit('a') >> lit('b') | (lit('a') > lit('d')) | lit(\"ac\"))));\n\t}\n\n\t{ // Test expect in and predicate\n\t\t_ASSERT((test(\"abc\", lit('a') >> &(lit('b') > lit('c')) >> lit(\"bc\"))));\n\t\t_ASSERT((!test(\"abc\", lit('a') >> &(lit('b') > lit('d')) >> lit(\"bc\"))));\n\t}\n\n\t{ // Test expect in difference\n\t\t_ASSERT((test(\"bcac\", *(char_ - (lit('a') >> lit('b'))))));\n\t\t_ASSERT((test(\"bcab\", *(char_ - (lit('a') > lit('b'))) >> lit(\"ab\"))));\n\t\t_ASSERT((!test(\"bcac\", *(char_ - (lit('a') > lit('b'))) >> lit(\"ab\"))));\n\t}\n\n\t{ // Test expect in kleene\n\t\t_ASSERT((test(\"abac\", *(lit('a') >> lit('b')) >> lit(\"ac\"))));\n\t\t_ASSERT((!test(\"abac\", *(lit('a') > lit('b')) >> lit(\"ac\"))));\n\t\t_ASSERT((test(\"abbc\", *(lit('a') > lit('b')) >> lit(\"bc\"))));\n\t}\n\n\t{ // Test expect in list\n\t\t_ASSERT((test(\"ab::ab::ac\", (lit('a') >> lit('b')) % (lit(':') >> lit(':')) >> lit(\"::ac\"))));\n\t\t_ASSERT((!test(\"ab::ab::ac\", (lit('a') > lit('b')) % (lit(':') >> lit(':')) >> lit(\"::ac\"))));\n\t\t_ASSERT((test(\"ab::ab:ac\", (lit('a') > lit('b')) % (lit(':') >> lit(':')) >> lit(\":ac\"))));\n\t\t_ASSERT((!test(\"ab::ab:ab\", (lit('a') >> lit('b')) % (lit(':') > lit(':')) >> lit(\":ab\"))));\n\t}\n\n\t{ // Test expect in not predicate\n\t\t_ASSERT((test(\"[ac]\", lit('[') >> !(lit('a') >> lit('b')) >> +alpha >> lit(']'))));\n\t\t_ASSERT((test(\"[bc]\", lit('[') >> !(lit('a') > lit('b')) >> +alpha >> lit(']'))));\n\t\t_ASSERT((!test(\"[ac]\", lit('[') >> !(lit('a') > lit('b')) >> +alpha >> lit(']'))));\n\t}\n\n\t{ // Test expect in optional\n\t\t_ASSERT((test(\"ac\", -(lit('a') >> lit('b')) >> lit(\"ac\"))));\n\t\t_ASSERT((test(\"ab\", -(lit('a') > lit('b')))));\n\t\t_ASSERT((!test(\"ac\", -(lit('a') > lit('b')) >> lit(\"ac\"))));\n\t}\n\n\t{ // Test expect in plus\n\t\t_ASSERT((test(\"abac\", +(lit('a') >> lit('b')) >> lit(\"ac\"))));\n\t\t_ASSERT((test(\"abbc\", +(lit('a') > lit('b')) >> lit(\"bc\"))));\n\t\t_ASSERT((!test(\"abac\", +(lit('a') > lit('b')) >> lit(\"ac\"))));\n\t}\n\n\t{ // Test fast expect (with bool injection)\n\t\tusing boost::spirit::x3::expectation_failure_tag;\n\t\t_ASSERT((test(\"ade\", with<expectation_failure_tag>(false)[lit('a') >> (lit('b') >> lit('c') | lit('d') >> lit('e'))])));\n\t\t_ASSERT((test(\"abc\", with<expectation_failure_tag>(false)[lit('a') >> (lit('b') > lit('c') | lit('d') > lit('e'))])));\n\t\t_ASSERT((test(\"ade\", with<expectation_failure_tag>(false)[lit('a') >> (lit('b') > lit('c') | lit('d') > lit('e'))])));\n\t\t_ASSERT((!test(\"abd\", with<expectation_failure_tag>(false)[lit('a') >> (lit('b') > lit('c') | lit('d') > lit('e'))])));\n\t\t_ASSERT((!test(\"adc\", with<expectation_failure_tag>(false)[lit('a') >> (lit('b') > lit('c') | lit('d') > lit('e'))])));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/extract_int.t.cpp",
    "content": "/*=============================================================================\n  Copyright (c) 2018 Nikita Kniazev\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\n#include \"test.hpp\"\n#include \"../x3/support/numeric_utils/extract_int.hpp\"\n\n#include <cmath> // for std::pow\n#include <cstdio>\n#include <iosfwd>\n#include <limits>\n\n#ifdef _MSC_VER\n# pragma warning(disable: 4127)   // conditional expression is constant\n#endif\n\ntemplate <int Min, int Max>\nstruct custom_int\n{\n\tcustom_int() = default;\n\tconstexpr custom_int(int value) : value_{value} {}\n\n\tcustom_int operator+(custom_int x) const { return value_ + x.value_; }\n\tcustom_int operator-(custom_int x) const { return value_ - x.value_; }\n\tcustom_int operator*(custom_int x) const { return value_ * x.value_; }\n\tcustom_int operator/(custom_int x) const { return value_ / x.value_; }\n\n\tcustom_int& operator+=(custom_int x) { value_ += x.value_; return *this; }\n\tcustom_int& operator-=(custom_int x) { value_ -= x.value_; return *this; }\n\tcustom_int& operator*=(custom_int x) { value_ *= x.value_; return *this; }\n\tcustom_int& operator/=(custom_int x) { value_ /= x.value_; return *this; }\n\tcustom_int& operator++() { ++value_; return *this; }\n\tcustom_int& operator--() { --value_; return *this; }\n\tcustom_int operator++(int) { return value_++; }\n\tcustom_int operator--(int) { return value_--; }\n\n\tcustom_int operator+() { return +value_; }\n\tcustom_int operator-() { return -value_; }\n\n\tbool operator< (custom_int x) const { return value_ <  x.value_; }\n\tbool operator> (custom_int x) const { return value_ >  x.value_; }\n\tbool operator<=(custom_int x) const { return value_ <= x.value_; }\n\tbool operator>=(custom_int x) const { return value_ >= x.value_; }\n\tbool operator==(custom_int x) const { return value_ == x.value_; }\n\tbool operator!=(custom_int x) const { return value_ != x.value_; }\n\n\ttemplate <typename Char, typename Traits>\n\tfriend std::basic_ostream<Char, Traits>&\n\toperator<<(std::basic_ostream<Char, Traits>& os, custom_int x) {\n\t\treturn os << x.value_;\n\t}\n\n\tstatic constexpr int max = Max;\n\tstatic constexpr int min = Min;\n\nprivate:\n\tint value_;\n};\n\nnamespace utils {\n\ntemplate <int Min, int Max> struct digits;\ntemplate <> struct digits<-9,  9>  { static constexpr int r2 = 3, r10 = 1; };\ntemplate <> struct digits<-10, 10> { static constexpr int r2 = 3, r10 = 1; };\ntemplate <> struct digits<-15, 15> { static constexpr int r2 = 3, r10 = 1; };\n\n}\n\nnamespace std {\n\ntemplate <int Min, int Max>\nclass numeric_limits<custom_int<Min, Max>> : public numeric_limits<int>\n{\npublic:\n\tstatic constexpr custom_int<Min, Max> max() noexcept { return Max; }\n\tstatic constexpr custom_int<Min, Max> min() noexcept { return Min; }\n\tstatic constexpr custom_int<Min, Max> lowest() noexcept { return min(); }\n\tstatic_assert(numeric_limits<int>::radix == 2, \"hardcoded for digits of radix 2\");\n\tstatic constexpr int digits = utils::digits<Min, Max>::r2;\n\tstatic constexpr int digits10 = utils::digits<Min, Max>::r10;\n};\n\n}\n\nnamespace x3 = boost::spirit::x3;\n\ntemplate <typename T, int Base, int MaxDigits>\nvoid test_overflow_handling(char const* begin, char const* end, int i)\n{\n\t// Check that parser fails on overflow\n\tstatic_assert(std::numeric_limits<T>::is_bounded, \"tests prerequest\");\n\tBOOST_ASSERT_MSG(MaxDigits == -1 || static_cast<int>(std::pow(float(Base), MaxDigits)) > T::max,\n\t\t\t\t\t \"test prerequest\");\n\tint initial = Base - i % Base; // just a 'random' non-equal to i number\n\tT x { initial };\n\tchar const* it = begin;\n\tbool r = x3::extract_int<T, Base, 1, MaxDigits>::call(it, end, x);\n\tif (T::min <= i && i <= T::max) {\n\t\t_ASSERT(r);\n\t\t_ASSERT(it == end);\n\t\t_ASSERTEQUAL(x, i);\n\t}\n\telse\n\t\tif (MaxDigits == -1) // TODO: Looks like a regression. See #430\n\t{\n\t\t_ASSERT(!r);\n\t\t_ASSERT(it == begin);\n\t}\n}\n\ntemplate <typename T, int Base>\nvoid test_unparsed_digits_are_not_consumed(char const* it, char const* end, int i)\n{\n\t// Check that unparsed digits are not consumed\n\tstatic_assert(T::min <= -Base+1, \"test prerequest\");\n\tstatic_assert(T::max >=  Base-1, \"test prerequest\");\n\tbool has_sign = *it == '+' || *it == '-';\n\tauto len = end - it;\n\tint initial = Base - i % Base; // just a 'random' non-equal to i number\n\tT x { initial };\n\tbool r = x3::extract_int<T, Base, 1, 1>::call(it, end, x);\n\t_ASSERT(r);\n\tif (-Base < i && i < Base) {\n\t\t_ASSERT(it == end);\n\t\t_ASSERTEQUAL(x, i);\n\t}\n\telse {\n\t\t_ASSERTEQUAL(end - it, len - 1 - has_sign);\n\t\t_ASSERTEQUAL(x, i / Base);\n\t}\n}\n\ntemplate <typename T, int Base>\nvoid run_tests(char const* begin, char const* end, int i)\n{\n\t// Check that parser fails on overflow\n\ttest_overflow_handling<T, Base, -1>(begin, end, i);\n\t// Check that MaxDigits > digits10 behave like MaxDigits=-1\n\ttest_overflow_handling<T, Base, 2>(begin, end, i);\n\t// Check that unparsed digits are not consumed\n\ttest_unparsed_digits_are_not_consumed<T, Base>(begin, end, i);\n}\n\nUNITTESTDEF(x3_test_extract_int)\n{\n\tfor (int i = -30; i <= 30; ++i) {\n\t\tchar s[4];\n\t\tstd::snprintf(s, 4, \"%d\", i);\n\t\tauto begin = &s[0], end = begin + std::strlen(begin);\n\n\t\t// log(Base, abs(MinOrMax) + 1) == digits\n\t\trun_tests<custom_int<-9, 9>, 10>(begin, end, i);\n\t\t// (MinOrMax % Base) == 0\n\t\trun_tests<custom_int<-10, 10>, 10>(begin, end, i);\n\t\t// (MinOrMax % Base) != 0\n\t\trun_tests<custom_int<-15, 15>, 10>(begin, end, i);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/fusion_map.t.cpp",
    "content": "/*=============================================================================\n  Copyright (c) 2001-2015 Joel de Guzman\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#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/at_key.hpp>\n#include <boost/fusion/include/make_map.hpp>\n#include <boost/fusion/adapted/struct.hpp>\n\n#include <string>\n#include <iostream>\n\nstruct AdaptedStruct {\n\tstd::string key1;\n\tstd::string key2;\n};\n\nclass key1_attr {};\nclass key2_attr {};\n\nBOOST_FUSION_ADAPT_ASSOC_STRUCT(\n\tAdaptedStruct,\n\t(std::string, key1, class key1_attr)\n\t(std::string, key2, class key2_attr)\n\t)\n\ntemplate <class Parser, class Attribute>\nbool test_attr(const std::string in,Parser const& p, Attribute& attr) {\n\tauto it = in.begin();\n\treturn boost::spirit::x3::parse(it,in.end(), p, attr);\n}\n\nUNITTESTDEF(x3_test_fusion_map)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::attr;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::eps;\n\tnamespace fusion = boost::fusion;\n\n\t{ // parsing sequence directly into fusion map\n\n\t\tauto const key1 = lit(\"key1\") >> attr(key1_attr());\n\t\tauto const kv1 = key1 >> lit(\"=\") >> +char_;\n\n\t\t{\n\t\t   auto attr_ =  fusion::make_map<key1_attr>(std::string());\n\t\t   _ASSERT(test_attr(\"key1=ABC\", kv1, attr_));\n\t\t   _ASSERT(fusion::at_key<key1_attr>(attr_) == \"ABC\");\n\t\t}\n\t\t{\n\t\t   AdaptedStruct attr_;\n\t\t   _ASSERT(test_attr(\"key1=ABC\", kv1, attr_));\n\t\t   _ASSERT(attr_.key1 == \"ABC\");\n\t\t   _ASSERT(attr_.key2 == \"\");\n\t\t}\n\t\t}\n\t\t{   // case when parser handling fusion assoc sequence\n\t\t\t// is on one side of another sequence\n\t\t\tauto const key1 = lit(\"key1\") >> attr(key1_attr());\n\t\t\tauto const kv1 = key1 >> lit(\"=\") >> +~char_(';');\n\n\t\t\tAdaptedStruct attr_;\n\t\t\t_ASSERT(test_attr(\"key1=ABC\", eps >>  (kv1 % lit(';')) , attr_));\n\t\t\t_ASSERT(attr_.key1 == \"ABC\");\n\t\t\t_ASSERT(attr_.key2 == \"\");\n\t\t}\n\t\t{ // parsing repeated sequence directly into fusion map (overwrite)\n\t\t  auto const key1 = lit(\"key1\") >> attr(key1_attr());\n\t\t  auto const kv1 = key1 >> lit(\"=\") >> +~char_(';');\n\n\t\t{\n\t\t   auto attr_ =  fusion::make_map<key1_attr>(std::string());\n\t\t   _ASSERT(test_attr(\"key1=ABC;key1=XYZ\", kv1 % lit(';'), attr_));\n\t\t   _ASSERT(fusion::at_key<key1_attr>(attr_) == \"XYZ\");\n\t\t}\n\t\t{\n\t\t   AdaptedStruct attr_;\n\t\t   _ASSERT(test_attr(\"key1=ABC;key1=XYZ\", kv1 % lit(';'), attr_));\n\t\t   _ASSERT(attr_.key1 == \"XYZ\");\n\t\t}\n\t}\n\n\t{   // parsing repeated sequence directly into fusion map (append)\n\n\t\t/* NOT IMPLEMENTED\n\t\tauto const key1 = lit(\"key1\") >> attr(key1_attr());\n\t\tauto const kv1 = key1 >> lit(\"=\") >> +char_;\n\t\tauto attr_ =  fusion::make_map<key1_attr>(std::vector<std::string>());\n\n\t\t_ASSERT(test_attr(\"key1=ABC;key1=XYZ\", kv1 % \";\", attr_));\n\t\t_ASSERT(fusion::at_key<key1_attr>(attr_) == {\"ABC\",\"XYZ\"});\n\t\t*/\n\t}\n\n\t{ // alternative over key-value pairs\n\n\t\tauto const key1 = lit(\"key1\") >> attr(key1_attr());\n\t\tauto const key2 = lit(\"key2\") >> attr(key2_attr());\n\t\tauto const kv1 = key1 >> lit(\"=\") >> +~char_(';');\n\t\tauto const kv2 = key2 >> lit(\"=\") >> +~char_(';');\n\n\t\tauto attr_ =  fusion::make_map<key1_attr, key2_attr>(std::string(),std::string());\n\t\t_ASSERT(test_attr(\"key2=XYZ;key1=ABC\", (kv1|kv2) % lit(';'), attr_));\n\t\t_ASSERT(fusion::at_key<key1_attr>(attr_) == \"ABC\");\n\t\t_ASSERT(fusion::at_key<key2_attr>(attr_) == \"XYZ\");\n\t}\n\n\t{ // parsing sequence where key is a variant\n\n\t\tnamespace x3 = boost::spirit::x3;\n\t\tauto  key1 = lit(\"key1\") >> attr(key1_attr());\n\t\tauto  key2 = lit(\"key2\") >> attr(key2_attr());\n\t\tauto  keys = key1 | key2;\n\t\tauto pair = keys >> lit(\"=\") >> +~char_(';');\n\n\t\t{\n\t\t\tauto attr_ =  fusion::make_map<key1_attr,key2_attr>(std::string(),std::string());\n\t\t\t_ASSERT(test_attr(\"key1=ABC;key2=XYZ\", pair % lit(';'), attr_));\n\t\t\t_ASSERT(fusion::at_key<key1_attr>(attr_) == \"ABC\");\n\t\t\t_ASSERT(fusion::at_key<key2_attr>(attr_) == \"XYZ\");\n\t\t}\n\t\t{\n\t\t\tAdaptedStruct attr_;\n\t\t\t_ASSERT(test_attr(\"key1=ABC;key2=XYZ\", pair % lit(';'), attr_));\n\t\t\t_ASSERT(fusion::at_key<key1_attr>(attr_) == \"ABC\");\n\t\t\t_ASSERT(fusion::at_key<key2_attr>(attr_) == \"XYZ\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/grammar.hpp",
    "content": "#include \"../x3.hpp\"\n\nnamespace x3 = boost::spirit::x3;\n\nx3::rule<struct grammar_r, int> const grammar;\nusing grammar_type = decltype(grammar);\nBOOST_SPIRIT_DECLARE(grammar_type)\n"
  },
  {
    "path": "tc/string/spirit/unittest/grammar.t.cpp",
    "content": "#include \"../../../base/assert_defs.h\"\n#include \"grammar.hpp\"\n\nauto const grammar_def = x3::int_;\n\nBOOST_SPIRIT_DEFINE(grammar)\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\n"
  },
  {
    "path": "tc/string/spirit/unittest/grammar_linker.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\tCopyright (c) 2019 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"grammar.hpp\"\n\nUNITTESTDEF(x3_test_grammar_linker)\n{\n\tchar const* s = \"123\", * e = s + std::strlen(s);\n#if 1\n\tauto r = parse(s, e, grammar);\n#else\n\tint i = 0;\n\tauto r = parse(s, e, grammar, i);\n#endif\n\n\t_ASSERT(r);\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/int.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2012 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_X3_INT_HPP)\n#define BOOST_SPIRIT_TEST_X3_INT_HPP\n\n#include \"test.hpp\"\n#include <climits>\n#include \"../x3/numeric/int.hpp\"\n\n///////////////////////////////////////////////////////////////////////////////\n//\n//  *** BEWARE PLATFORM DEPENDENT!!! ***\n//  *** The following assumes 32 bit or 64 bit integers and 64 bit long longs.\n//  *** Modify these constant strings when appropriate.\n//\n///////////////////////////////////////////////////////////////////////////////\n\n\tstatic_assert(sizeof(long long) == 8, \"unexpected long long size\");\n\n#if INT_MAX != LLONG_MAX\n\tstatic_assert(sizeof(int) == 4, \"unexpected int size\");\n\tinline char const* max_int = \"2147483647\";\n\tinline char const* int_overflow = \"2147483648\";\n\tinline char const* min_int = \"-2147483648\";\n\tinline char const* int_underflow = \"-2147483649\";\n#else\n\tstatic_assert(sizeof(int) == 8, \"unexpected int size\");\n\tinline char const* max_int = \"9223372036854775807\";\n\tinline char const* int_overflow = \"9223372036854775808\";\n\tinline char const* min_int = \"-9223372036854775808\";\n\tinline char const* int_underflow = \"-9223372036854775809\";\n#endif\n\n\tinline char const* max_long_long = \"9223372036854775807\";\n\tinline char const* long_long_overflow = \"9223372036854775808\";\n\tinline char const* min_long_long = \"-9223372036854775808\";\n\tinline char const* long_long_underflow = \"-9223372036854775809\";\n\n///////////////////////////////////////////////////////////////////////////////\n// A custom int type\nstruct custom_int\n{\n\tint n;\n\tcustom_int() : n(0) {}\n\texplicit custom_int(int n_) : n(n_) {}\n\tcustom_int& operator=(int n_) { n = n_; return *this; }\n\tfriend bool operator==(custom_int a, custom_int b) { return a.n == b.n; }\n\tfriend bool operator==(custom_int a, int b) { return a.n == b; }\n\tfriend custom_int operator*(custom_int a, custom_int b) { return custom_int(a.n * b.n); }\n\tfriend custom_int operator+(custom_int a, custom_int b) { return custom_int(a.n + b.n); }\n\tfriend custom_int operator-(custom_int a, custom_int b) { return custom_int(a.n - b.n); }\n};\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/int1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"int.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/at.hpp>\n\nUNITTESTDEF(x3_test_int1)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  signed integer tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::int_;\n\t\tint i=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(int_);\n\n\t\t_ASSERT(test(\"123456\", int_));\n\t\t_ASSERT(test_attr(\"123456\", int_, i));\n\t\t_ASSERT(i == 123456);\n\n\t\t_ASSERT(test(\"+123456\", int_));\n\t\t_ASSERT(test_attr(\"+123456\", int_, i));\n\t\t_ASSERT(i == 123456);\n\n\t\t_ASSERT(test(\"-123456\", int_));\n\t\t_ASSERT(test_attr(\"-123456\", int_, i));\n\t\t_ASSERT(i == -123456);\n\n\t\t_ASSERT(test(max_int, int_));\n\t\t_ASSERT(test_attr(max_int, int_, i));\n\t\t_ASSERT(i == INT_MAX);\n\n\t\t_ASSERT(test(min_int, int_));\n\t\t_ASSERT(test_attr(min_int, int_, i));\n\t\t_ASSERT(i == INT_MIN);\n\n\t\t_ASSERT(!test(int_overflow, int_));\n\t\t_ASSERT(!test_attr(int_overflow, int_, i));\n\t\t_ASSERT(!test(int_underflow, int_));\n\t\t_ASSERT(!test_attr(int_underflow, int_, i));\n\n\t\t_ASSERT(!test(\"-\", int_));\n\t\t_ASSERT(!test_attr(\"-\", int_, i));\n\n\t\t_ASSERT(!test(\"+\", int_));\n\t\t_ASSERT(!test_attr(\"+\", int_, i));\n\n\t\t// Bug report from Steve Nutt\n\t\t_ASSERT(!test_attr(\"5368709120\", int_, i));\n\n\t\t// with leading zeros\n\t\t_ASSERT(test(\"0000000000123456\", int_));\n\t\t_ASSERT(test_attr(\"0000000000123456\", int_, i));\n\t\t_ASSERT(i == 123456);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  long long tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::long_long;\n\t\tboost::long_long_type ll=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(long_long);\n\n\t\t_ASSERT(test(\"1234567890123456789\", long_long));\n\t\t_ASSERT(test_attr(\"1234567890123456789\", long_long, ll));\n\t\t_ASSERT(ll == 1234567890123456789LL);\n\n\t\t_ASSERT(test(\"-1234567890123456789\", long_long));\n\t\t_ASSERT(test_attr(\"-1234567890123456789\", long_long, ll));\n\t\t_ASSERT(ll == -1234567890123456789LL);\n\n\t\t_ASSERT(test(max_long_long, long_long));\n\t\t_ASSERT(test_attr(max_long_long, long_long, ll));\n\t\t_ASSERT(ll == LLONG_MAX);\n\n\t\t_ASSERT(test(min_long_long, long_long));\n\t\t_ASSERT(test_attr(min_long_long, long_long, ll));\n\t\t_ASSERT(ll == LLONG_MIN);\n\n\t\t_ASSERT(!test(long_long_overflow, long_long));\n\t\t_ASSERT(!test_attr(long_long_overflow, long_long, ll));\n\t\t_ASSERT(!test(long_long_underflow, long_long));\n\t\t_ASSERT(!test_attr(long_long_underflow, long_long, ll));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  short_ and long_ tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::short_;\n\t\tusing boost::spirit::x3::long_;\n\t\tint i=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(short_);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(long_);\n\n\t\t_ASSERT(test(\"12345\", short_));\n\t\t_ASSERT(test_attr(\"12345\", short_, i));\n\t\t_ASSERT(i == 12345);\n\n\t\t_ASSERT(test(\"1234567890\", long_));\n\t\t_ASSERT(test_attr(\"1234567890\", long_, i));\n\t\t_ASSERT(i == 1234567890);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Check overflow is parse error\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tconstexpr boost::spirit::x3::int_parser<boost::int8_t> int8_{};\n\t\tchar c=char();\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(int8_);\n\n\t\t_ASSERT(!test_attr(\"999\", int8_, c));\n\n\t\tint i;\n\t\tusing boost::spirit::x3::short_;\n\t\t_ASSERT(!test_attr(\"32769\", short_, i, false));\n\t\t_ASSERT(!test_attr(\"41234\", short_, i, false));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  int_parser<unused_type> tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::int_parser;\n\t\tusing boost::spirit::x3::unused_type;\n\t\tconstexpr int_parser<unused_type> any_int{};\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(any_int);\n\n\t\t_ASSERT(test(\"123456\", any_int));\n\t\t_ASSERT(test(\"-123456\", any_int));\n\t\t_ASSERT(test(\"-1234567890123456789\", any_int));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  action tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::_attr;\n\t\tusing boost::spirit::x3::ascii::space;\n\t\tusing boost::spirit::x3::int_;\n\t\tint n = 0, m = 0;\n\n\t\tauto f = [&](auto& ctx){ n = _attr(ctx); };\n\n\t\t_ASSERT(test(\"123\", int_[f]));\n\t\t_ASSERT(n == 123);\n\t\t_ASSERT(test_attr(\"789\", int_[f], m));\n\t\t_ASSERT(n == 789 && m == 789);\n\t\t_ASSERT(test(\"   456\", int_[f], space));\n\t\t_ASSERT(n == 456);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  custom int tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::int_;\n\t\tusing boost::spirit::x3::int_parser;\n\t\tcustom_int i;\n\n\t\t_ASSERT(test_attr(\"-123456\", int_, i));\n\t\tint_parser<custom_int, 10, 1, 2> int2;\n\t\t_ASSERT(test_attr(\"-12\", int2, i));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  single-element fusion vector tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::int_;\n\t\tusing boost::spirit::x3::int_parser;\n\t\tboost::fusion::vector<int> i;\n\n\t\t_ASSERT(test_attr(\"-123456\", int_, i));\n\t\t_ASSERT(boost::fusion::at_c<0>(i) == -123456);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/iterator_check.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2017 Joel de Guzman\n\tCopyright (c) 2017 think-cell GmbH\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <boost/range/adaptor/transformed.hpp>\n\n#include <iostream>\n#include <string>\n#include <functional>\n\nUNITTESTDEF(x3_test_iterator_check)\n{\n\tusing boost::adaptors::transform;\n\tusing boost::spirit::x3::raw;\n\tusing boost::spirit::x3::eps;\n\tusing boost::spirit::x3::eoi;\n\tusing boost::spirit::x3::upper;\n\tusing boost::spirit::x3::repeat;\n\tusing boost::spirit::x3::parse;\n\n\tstd::string input = \"abcde\";\n\tstd::function<char(char)> func = [](char c) {\n\t\treturn c < 'a' || 'z' < c ? c : static_cast<char>(c - 'a' + 'A');\n\t};\n\tauto const rng = transform(input, func);\n\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((parse(boost::begin(rng), boost::end(rng), +upper >> eoi, str)));\n\t\t_ASSERT((\"ABCDE\"==str));\n\t}\n\n\t{\n\t\tboost::iterator_range<decltype(boost::begin(rng))> str;\n\t\t_ASSERT((parse(boost::begin(rng), boost::end(rng), raw[+upper >> eoi], str)));\n\t\t_ASSERT((boost::equal(std::string(\"ABCDE\"), str)));\n\t}\n\n\t{\n\t\t_ASSERT((parse(boost::begin(rng), boost::end(rng), (repeat(6)[upper] | repeat(5)[upper]) >> eoi)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/kleene.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <string>\n#include <vector>\n#include <string>\n#include <iostream>\n\nstruct x_attr\n{\n};\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <>\n\tstruct container_value<x_attr>\n\t{\n\t\ttypedef char type; // value type of container\n\t};\n\n\ttemplate <>\n\tstruct push_back_container<x_attr>\n\t{\n\t\tstatic bool call(x_attr& /*c*/, char /*val*/)\n\t\t{\n\t\t\t// push back value type into container\n\t\t\treturn true;\n\t\t}\n\t};\n}}}}\n\nUNITTESTDEF(x3_test_kleene)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::alpha;\n\tusing boost::spirit::x3::upper;\n\tusing boost::spirit::x3::space;\n\tusing boost::spirit::x3::digit;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::lexeme;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(*char_);\n\n\t{\n\t\t_ASSERT(test(\"aaaaaaaa\", *char_));\n\t\t_ASSERT(test(\"a\", *char_));\n\t\t_ASSERT(test(\"\", *char_));\n\t\t_ASSERT(test(\"aaaaaaaa\", *alpha));\n\t\t_ASSERT(!test(\"aaaaaaaa\", *upper));\n\t}\n\n\t{\n\t\t_ASSERT(test(\" a a aaa aa\", *char_, space));\n\t\t_ASSERT(test(\"12345 678 9\", *digit, space));\n\t}\n\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"bbbb\", *char_, s) && 4 == s.size() && s == \"bbbb\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"b b b b \", *char_, s, space)  && s == \"bbbb\");\n\t}\n\n\t{\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"123 456 789 10\", *int_, v, space) && 4 == v.size() &&\n\t\t\tv[0] == 123 && v[1] == 456 && v[2] == 789 &&  v[3] == 10);\n\t}\n\n\t{\n\t\tstd::vector<std::string> v;\n\t\t_ASSERT(test_attr(\"a b c d\", *lexeme[+alpha], v, space) && 4 == v.size() &&\n\t\t\tv[0] == \"a\" && v[1] == \"b\" && v[2] == \"c\" &&  v[3] == \"d\");\n\t}\n\n\t{\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"123 456 789\", *int_, v, space) && 3 == v.size() &&\n\t\t\tv[0] == 123 && v[1] == 456 && v[2] == 789);\n\t}\n\n\t{ // actions\n\t\tusing boost::spirit::x3::_attr;\n\n\t\tstd::string v;\n\t\tauto f = [&](auto& ctx){ v = _attr(ctx); };\n\n\t\t_ASSERT(test(\"bbbb\", (*char_)[f]) && 4 == v.size() &&\n\t\t\tv[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');\n\t}\n\n\t{ // more actions\n\t\tusing boost::spirit::x3::_attr;\n\n\t\tstd::vector<int> v;\n\t\tauto f = [&](auto& ctx){ v = _attr(ctx); };\n\n\t\t_ASSERT(test(\"123 456 789\", (*int_)[f], space) && 3 == v.size() &&\n\t\t\tv[0] == 123 && v[1] == 456 && v[2] == 789);\n\t}\n\n\t{ // attribute customization\n\n\t\tx_attr x;\n\t\ttest_attr(\"abcde\", *char_, x);\n\t}\n\n\t{ // test move only types\n\t\tstd::vector<move_only> v;\n\t\t_ASSERT(test_attr(\"sss\", *synth_move_only, v));\n\t\t_ASSERTEQUAL(v.size(), 3);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/lexeme.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_lexeme)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::ascii::space;\n\tusing boost::spirit::x3::ascii::space_type;\n\tusing boost::spirit::x3::ascii::digit;\n\tusing boost::spirit::x3::lexeme;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lexeme[lit('x')]);\n\n\t{\n\t\t_ASSERT((test(\" 1 2 3 4 5\", +digit, space)));\n\t\t_ASSERT((!test(\" 1 2 3 4 5\", lexeme[+digit], space)));\n\t\t_ASSERT((test(\" 12345\", lexeme[+digit], space)));\n\t\t_ASSERT((test(\" 12345  \", lexeme[+digit], space, false)));\n\n\t\t// lexeme collapsing\n\t\t_ASSERT((!test(\" 1 2 3 4 5\", lexeme[lexeme[+digit]], space)));\n\t\t_ASSERT((test(\" 12345\", lexeme[lexeme[+digit]], space)));\n\t\t_ASSERT((test(\" 12345  \", lexeme[lexeme[+digit]], space, false)));\n\n\t\tauto r = +digit;\n\t\tauto rr = lexeme[r];\n\n\t\t_ASSERT((!test(\" 1 2 3 4 5\", rr, space)));\n\t\t_ASSERT((test(\" 12345\", rr, space)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/list.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2013 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <string>\n#include <vector>\n#include <set>\n#include <map>\n#include <string>\n#include <iostream>\n\nusing namespace spirit_test;\n\nUNITTESTDEF(x3_test_list)\n{\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ % lit(','));\n\n\t{\n\t\t_ASSERT(test(\"a,b,c,d,e,f,g,h\", char_ % lit(',')));\n\t\t_ASSERT(test(\"a,b,c,d,e,f,g,h,\", char_ % lit(','), false));\n\t}\n\n\t{\n\t\t_ASSERT(test(\"a, b, c, d, e, f, g, h\", char_ % lit(','), space));\n\t\t_ASSERT(test(\"a, b, c, d, e, f, g, h,\", char_ % lit(','), space, false));\n\t}\n\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"a,b,c,d,e,f,g,h\", char_ % lit(','), s));\n\t\t_ASSERT(s == \"abcdefgh\");\n\n\t\t_ASSERT(!test(\"a,b,c,d,e,f,g,h,\", char_ % lit(',')));\n\t}\n\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"ab,cd,ef,gh\", (char_ >> char_) % lit(','), s));\n\t\t_ASSERT(s == \"abcdefgh\");\n\n\t\t_ASSERT(!test(\"ab,cd,ef,gh,\", (char_ >> char_) % lit(',')));\n\t\t_ASSERT(!test(\"ab,cd,ef,g\", (char_ >> char_) % lit(',')));\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"ab,cd,efg\", (char_ >> char_) % lit(',') >> char_, s));\n\t\t_ASSERT(s == \"abcdefg\");\n\t}\n\n\t{ // regression test for has_attribute\n\t\tusing boost::spirit::x3::int_;\n\t\tusing boost::spirit::x3::omit;\n\n\t\tint i;\n\t\t_ASSERT(test_attr(\"1:2,3\", int_ >> lit(':') >> omit[int_] % lit(','), i));\n\t\t_ASSERTEQUAL(i, 1);\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::int_;\n\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"1,2\", int_ % lit(','), v));\n\t\t_ASSERT(2 == v.size() && 1 == v[0] && 2 == v[1]);\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::int_;\n\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"(1,2)\", lit('(') >> int_ % lit(',') >> lit(')'), v));\n\t\t_ASSERT(2 == v.size() && 1 == v[0] && 2 == v[1]);\n\t}\n\n\t{\n\t\tstd::vector<std::string> v;\n\t\t_ASSERT(test_attr(\"a,b,c,d\", +alpha % lit(','), v));\n\t\t_ASSERT(4 == v.size() && \"a\" == v[0] && \"b\" == v[1]\n\t\t\t&& \"c\" == v[2] && \"d\" == v[3]);\n\t}\n\n\t{\n\t\tstd::vector<std::optional<char> > v;\n\t\t_ASSERT(test_attr(\"#a,#\", (lit('#') >> -alpha) % lit(','), v));\n\t\t_ASSERT(2 == v.size() &&\n\t\t\t!!v[0] && 'a' == *v[0] && !v[1]);\n\n\t\tstd::vector<char> v2;\n\t\t_ASSERT(test_attr(\"#a,#\", (lit('#') >> -alpha) % lit(','), v2));\n\t\t_ASSERT(1 == v2.size() && 'a' == v2[0]);\n\t}\n\n\t{ // actions\n\t\tusing boost::spirit::x3::_attr;\n\n\t\tstd::string s;\n\t\tauto f = [&](auto& ctx){ s = std::string(_attr(ctx).begin(), _attr(ctx).end()); };\n\n\t\t_ASSERT(test(\"a,b,c,d,e,f,g,h\", (char_ % lit(','))[f]));\n\t\t_ASSERT(s == \"abcdefgh\");\n\t}\n\n\t{ // test move only types\n\t\tstd::vector<move_only> v;\n\t\t_ASSERT(test_attr(\"s.s.s.s\", synth_move_only % lit('.'), v));\n\t\t_ASSERTEQUAL(v.size(), 4);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/lit.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <string>\n\nUNITTESTDEF(x3_test_lit)\n{\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::char_;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lit(\"x\"));\n\n\t{\n\t\tstd::string attr;\n\t\tauto p = char_ >> lit(\"\\n\");\n\t\t_ASSERT(test_attr(\"A\\n\", p, attr));\n\t\t_ASSERT(attr == \"A\");\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\tstd::string attr;\n\t\tauto p = char_ >> lit(\"\\n\");\n\t\t_ASSERT(test_attr(\"A\\n\", p, attr));\n\t\t_ASSERT(attr == \"A\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/lit1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n\n#include <string>\n\nUNITTESTDEF(x3_test_lit1)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::string;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(string(\"x\"));\n\n\t{\n\t\t_ASSERT((test(\"kimpo\", lit(\"kimpo\"))));\n\t\t_ASSERT((test(\"kimpo\", string(\"kimpo\"))));\n\n\t\t_ASSERT((test(\"x\", string(\"x\"))));\n\t\t_ASSERT((test(L\"x\", string(L\"x\"))));\n\n\t\tstd::basic_string<char> s(\"kimpo\");\n\t\tstd::basic_string<wchar_t> ws(L\"kimpo\");\n\t\t_ASSERT((test(\"kimpo\", lit(s))));\n\t\t_ASSERT((test(L\"kimpo\", lit(ws))));\n\t\t_ASSERT((test(\"kimpo\", string(s))));\n\t\t_ASSERT((test(L\"kimpo\", string(ws))));\n\t}\n\n\t{\n\t\t_ASSERT((test(L\"kimpo\", lit(L\"kimpo\"))));\n\t\t_ASSERT((test(L\"kimpo\", string(L\"kimpo\"))));\n\t\t_ASSERT((test(L\"x\", string(L\"x\"))));\n\t}\n\n\t{\n\t\tstd::basic_string<char> s(\"kimpo\");\n\t\t_ASSERT((test(\"kimpo\", string(s))));\n\n\t\tstd::basic_string<wchar_t> ws(L\"kimpo\");\n\t\t_ASSERT((test(L\"kimpo\", string(ws))));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT((test(\"    kimpo\", string(\"kimpo\"), space)));\n\t\t_ASSERT((test(L\"    kimpo\", string(L\"kimpo\"), space)));\n\t\t_ASSERT((test(\"    x\", string(\"x\"), space)));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT((test(\"    kimpo\", string(\"kimpo\"), space)));\n\t\t_ASSERT((test(L\"    kimpo\", string(L\"kimpo\"), space)));\n\t\t_ASSERT((test(\"    x\", string(\"x\"), space)));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\tstd::string s;\n\t\t_ASSERT((test_attr(\"kimpo\", string(\"kimpo\"), s)));\n\t\t_ASSERT(s == \"kimpo\");\n\t\ts.clear();\n\t\t_ASSERT((test_attr(\"kimpo\", string(\"kim\") >> string(\"po\"), s)));\n\t\t_ASSERT(s == \"kimpo\");\n\t\ts.clear();\n\t\t_ASSERT((test_attr(\"x\", string(\"x\"), s)));\n\t\t_ASSERT(s == \"x\");\n\t}\n\n\t{ // single-element fusion vector tests\n\t\tboost::fusion::vector<std::string> s;\n\t\t_ASSERT(test_attr(\"kimpo\", string(\"kimpo\"), s));\n\t\t_ASSERT(boost::fusion::at_c<0>(s) == \"kimpo\");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/lit2.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_lit2)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::lit;\n\n\t{\n\t\t_ASSERT((test(\"kimpo\", lit(\"kimpo\"))));\n\n\t\tstd::basic_string<char> s(\"kimpo\");\n\t\tstd::basic_string<wchar_t> ws(L\"kimpo\");\n\t\t_ASSERT((test(\"kimpo\", lit(s))));\n\t\t_ASSERT((test(L\"kimpo\", lit(ws))));\n\t}\n\n\t{\n\t\tstd::basic_string<char> s(\"kimpo\");\n\t\t_ASSERT((test(\"kimpo\", lit(s))));\n\n\t\tstd::basic_string<wchar_t> ws(L\"kimpo\");\n\t\t_ASSERT((test(L\"kimpo\", lit(ws))));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT((test(\"    kimpo\", lit(\"kimpo\"), space)));\n\t\t_ASSERT((test(L\"    kimpo\", lit(L\"kimpo\"), space)));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::iso8859_1;\n\t\t_ASSERT((test(\"    kimpo\", lit(\"kimpo\"), space)));\n\t\t_ASSERT((test(L\"    kimpo\", lit(L\"kimpo\"), space)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/matches.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2010 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\nUNITTESTDEF(x3_test_matches)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::matches;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(matches[lit('x')]);\n\n\t{\n\t\t_ASSERT(test(\"x\", matches[char_]));\n\t\tbool result = false;\n\t\t_ASSERT(test_attr(\"x\", matches[char_], result) && result);\n\t}\n\n\t{\n\t\t_ASSERT(!test(\"y\", matches[char_('x')]));\n\t\t_ASSERT(!test(\"y\", matches[lit('x')]));\n\t\tbool result = true;\n\t\t_ASSERT(test_attr(\"y\", matches[char_('x')], result, false) && !result);\n\t\tresult = true;\n\t\t_ASSERT(test_attr(\"y\", matches[lit('x')], result, false) && !result);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/no_case.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\nUNITTESTDEF(x3_test_no_case)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::no_case;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(no_case[x3::lit('x')]);\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(test(\"x\", no_case[char_]));\n\t\t_ASSERT(test(\"X\", no_case[char_('x')]));\n\t\t_ASSERT(test(\"X\", no_case[char_('X')]));\n\t\t_ASSERT(test(\"x\", no_case[char_('X')]));\n\t\t_ASSERT(test(\"x\", no_case[char_('x')]));\n\t\t_ASSERT(!test(\"z\", no_case[char_('X')]));\n\t\t_ASSERT(!test(\"z\", no_case[char_('x')]));\n\t\t_ASSERT(test(\"x\", no_case[char_('a', 'z')]));\n\t\t_ASSERT(test(\"X\", no_case[char_('a', 'z')]));\n\t\t_ASSERT(!test(\"a\", no_case[char_('b', 'z')]));\n\t\t_ASSERT(!test(\"z\", no_case[char_('a', 'y')]));\n\t}\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(test(\"X\", no_case[lit('x')]));\n\t\t_ASSERT(test(\"X\", no_case[lit('X')]));\n\t\t_ASSERT(test(\"x\", no_case[lit('X')]));\n\t\t_ASSERT(test(\"x\", no_case[lit('x')]));\n\t\t_ASSERT(!test(\"z\", no_case[lit('X')]));\n\t\t_ASSERT(!test(\"z\", no_case[lit('x')]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::iso8859_1;\n\t\t_ASSERT(test(\"X\", no_case[char_(\"a-z\")]));\n\t\t_ASSERT(!test(\"1\", no_case[char_(\"a-z\")]));\n\t}\n\n\t{ // test extended ASCII characters\n\t\tusing namespace boost::spirit::x3::iso8859_1;\n\t\t_ASSERT(test(\"\\xC1\", no_case[char_('\\xE1')]));\n\n\t\t_ASSERT(test(\"\\xC9\", no_case[char_(\"\\xE5-\\xEF\")]));\n\t\t_ASSERT(!test(\"\\xFF\", no_case[char_(\"\\xE5-\\xEF\")]));\n\n\t\t_ASSERT(test(\"\\xC1\\xE1\", no_case[lit(\"\\xE1\\xC1\")]));\n\t\t_ASSERT(test(\"\\xE1\\xE1\", no_case[no_case[lit(\"\\xE1\\xC1\")]]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(test(\"Bochi Bochi\", no_case[lit(\"bochi bochi\")]));\n\t\t_ASSERT(test(\"BOCHI BOCHI\", no_case[lit(\"bochi bochi\")]));\n\t\t_ASSERT(!test(\"Vavoo\", no_case[lit(\"bochi bochi\")]));\n\t}\n\n\t{\n\t\t// should work!\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(test(\"x\", no_case[no_case[char_]]));\n\t\t_ASSERT(test(\"x\", no_case[no_case[char_('x')]]));\n\t\t_ASSERT(test(\"yabadabadoo\", no_case[no_case[lit(\"Yabadabadoo\")]]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::ascii;\n\t\t_ASSERT(test(\"X\", no_case[alnum]));\n\t\t_ASSERT(test(\"6\", no_case[alnum]));\n\t\t_ASSERT(!test(\":\", no_case[alnum]));\n\n\t\t_ASSERT(test(\"X\", no_case[lower]));\n\t\t_ASSERT(test(\"x\", no_case[lower]));\n\t\t_ASSERT(test(\"X\", no_case[upper]));\n\t\t_ASSERT(test(\"x\", no_case[upper]));\n\t\t_ASSERT(!test(\":\", no_case[lower]));\n\t\t_ASSERT(!test(\":\", no_case[upper]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::iso8859_1;\n\t\t_ASSERT(test(\"X\", no_case[alnum]));\n\t\t_ASSERT(test(\"6\", no_case[alnum]));\n\t\t_ASSERT(!test(\":\", no_case[alnum]));\n\n\t\t_ASSERT(test(\"X\", no_case[lower]));\n\t\t_ASSERT(test(\"x\", no_case[lower]));\n\t\t_ASSERT(test(\"X\", no_case[upper]));\n\t\t_ASSERT(test(\"x\", no_case[upper]));\n\t\t_ASSERT(!test(\":\", no_case[lower]));\n\t\t_ASSERT(!test(\":\", no_case[upper]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::standard;\n\t\t_ASSERT(test(\"X\", no_case[alnum]));\n\t\t_ASSERT(test(\"6\", no_case[alnum]));\n\t\t_ASSERT(!test(\":\", no_case[alnum]));\n\n\t\t_ASSERT(test(\"X\", no_case[lower]));\n\t\t_ASSERT(test(\"x\", no_case[lower]));\n\t\t_ASSERT(test(\"X\", no_case[upper]));\n\t\t_ASSERT(test(\"x\", no_case[upper]));\n\t\t_ASSERT(!test(\":\", no_case[lower]));\n\t\t_ASSERT(!test(\":\", no_case[upper]));\n\t}\n\n\t{\n\t\t// chsets\n\t\tnamespace standard = boost::spirit::x3::standard;\n\t\tnamespace standard_wide = boost::spirit::x3::standard_wide;\n\n\t\t_ASSERT(test(\"x\", no_case[standard::char_(\"a-z\")]));\n\t\t_ASSERT(test(\"X\", no_case[standard::char_(\"a-z\")]));\n\t\t_ASSERT(test(L\"X\", no_case[standard_wide::char_(L\"a-z\")]));\n\t\t_ASSERT(test(L\"X\", no_case[standard_wide::char_(L\"X\")]));\n\t}\n\n\t{\n\t\tusing namespace boost::spirit::x3::standard;\n\t\tstd::string s(\"bochi bochi\");\n\t\t_ASSERT(test(\"Bochi Bochi\", no_case[lit(s.c_str())]));\n\t\t_ASSERT(test(\"Bochi Bochi\", no_case[lit(s)]));\n\t\t_ASSERT(test(\"Bochi Bochi\", no_case[lit(s.c_str())]));\n\t\t_ASSERT(test(\"Bochi Bochi\", no_case[lit(s)]));\n\t}\n\n\t{\n\t\t{\n\t\t\tusing namespace boost::spirit::x3::standard;\n\t\t\t_ASSERT(!test(\"ą\", no_case[lit('a')]));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/no_skip.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\nUNITTESTDEF(x3_test_no_skip)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::ascii::space;\n\tusing boost::spirit::x3::ascii::space_type;\n\tusing boost::spirit::x3::ascii::char_;\n\tusing boost::spirit::x3::lexeme;\n\tusing boost::spirit::x3::no_skip;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(no_skip[lit('x')]);\n\n\t// without skipping no_skip is equivalent to lexeme\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"'  abc '\", lit('\\'') >> no_skip[+~char_('\\'')] >> lit('\\''), str)));\n\t\t_ASSERT(str == \"  abc \");\n\t}\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"'  abc '\", lit('\\'') >> lexeme[+~char_('\\'')] >> lit('\\''), str)));\n\t\t_ASSERT(str == \"  abc \");\n\t}\n\n\t// with skipping, no_skip allows to match a leading skipper\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"'  abc '\", lit('\\'') >> no_skip[+~char_('\\'')] >> lit('\\''), str, space)));\n\t\t_ASSERT(str == \"  abc \");\n\t}\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"'  abc '\", lit('\\'') >> lexeme[+~char_('\\'')] >> lit('\\''), str, space)));\n\t\t_ASSERT(str == \"abc \");\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/not_predicate.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\n#include <iostream>\n\nUNITTESTDEF(x3_test_not_predicate)\n{\n\tusing spirit_test::test;\n\tusing boost::spirit::x3::int_;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(!int_);\n\n\t{\n\t\t_ASSERT((!test(\"1234\", !int_)));\n\t\t_ASSERT((test(\"abcd\", !int_, false)));\n\t\t_ASSERT((!test(\"abcd\", !!int_, false)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/omit.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/at.hpp>\n\n#include <string>\n#include <iostream>\n\nusing boost::spirit::x3::rule;\n\nnamespace {\n\trule<class direct_rule, int> direct_rule = \"direct_rule\";\n\trule<class indirect_rule, int> indirect_rule = \"indirect_rule\";\n\n\tauto const direct_rule_def = boost::spirit::x3::int_;\n\tauto const indirect_rule_def = direct_rule;\n\n\tBOOST_SPIRIT_DEFINE(direct_rule, indirect_rule)\n}\n\nUNITTESTDEF(x3_test_omit)\n{\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::unused_type;\n\tusing boost::spirit::x3::unused;\n\tusing boost::spirit::x3::int_;\n\n\tusing boost::fusion::vector;\n\tusing boost::fusion::at_c;\n\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(omit[lit('x')]);\n\n\t{\n\t\t_ASSERT(test(\"a\", omit[lit('a')]));\n\t}\n\n\t{\n\t\t// omit[] means we don't receive the attribute\n\t\tchar attr=char();\n\t\t_ASSERT((test_attr(\"abc\", omit[char_] >> omit[lit('b')] >> char_, attr)));\n\t\t_ASSERT((attr == 'c'));\n\t}\n\n\t{\n\t\t// If all elements except 1 is omitted, the attribute is\n\t\t// a single-element sequence. For this case alone, we allow\n\t\t// naked attributes (unwrapped in a fusion sequence).\n\t\tchar attr=char();\n\t\t_ASSERT((test_attr(\"abc\", omit[char_] >> lit('b') >> char_, attr)));\n\t\t_ASSERT((attr == 'c'));\n\t}\n\n\t{\n\t\t// omit[] means we don't receive the attribute\n\t\tvector<> attr;\n\t\t_ASSERT((test_attr(\"abc\", omit[char_] >> omit[lit('b')] >> omit[char_], attr)));\n\t}\n\n\t{\n\t\t// omit[] means we don't receive the attribute\n\t\t// this test is merely a compile test, because using a unused as the\n\t\t// explicit attribute doesn't make any sense\n\t\tunused_type attr;\n\t\t_ASSERT((test_attr(\"abc\", omit[char_ >> lit('b') >> char_], attr)));\n\t}\n\n\t{\n\t\t// omit[] means we don't receive the attribute, if all elements of a\n\t\t// sequence have unused attributes, the whole sequence has an unused\n\t\t// attribute as well\n\t\tvector<char, char> attr;\n\t\t_ASSERT((test_attr(\"abcde\",\n\t\t\tchar_ >> (omit[char_] >> omit[lit('c')] >> omit[char_]) >> char_, attr)));\n\t\t_ASSERT((at_c<0>(attr) == 'a'));\n\t\t_ASSERT((at_c<1>(attr) == 'e'));\n\t}\n\n\t{\n\t\t// \"hello\" has an unused_type. unused attrubutes are not part of the sequence\n\t\tvector<char, char> attr;\n\t\t_ASSERT((test_attr(\"a hello c\", char_ >> lit(\"hello\") >> char_, attr, space)));\n\t\t_ASSERT((at_c<0>(attr) == 'a'));\n\t\t_ASSERT((at_c<1>(attr) == 'c'));\n\t}\n\n\t{\n\t\t// if only one node in a sequence is left (all the others are omitted),\n\t\t// then we need \"naked\" attributes (not wrapped in a tuple)\n\t\tint attr=0;\n\t\t_ASSERT((test_attr(\"a 123 c\", omit[lit('a')] >> int_ >> omit[lit('c')], attr, space)));\n\t\t_ASSERT((attr == 123));\n\t}\n\n\t{\n\t\t// unused means we don't care about the attribute\n\t\t_ASSERT((test_attr(\"abc\", char_ >> lit('b') >> char_, unused)));\n\t}\n\n\t{   // test action with omitted attribute\n\t\tchar c = 0;\n\t\tauto f = [&](auto& ctx){ c = _attr(ctx); };\n\n\t\t_ASSERT(test(\"x123\\\"a string\\\"\", (char_ >> omit[int_] >> lit(\"\\\"a string\\\"\"))[f]));\n\t\t_ASSERT(c == 'x');\n\t}\n\n\t{   // test action with omitted attribute\n\t\tint n = 0;\n\t\tauto f = [&](auto& ctx){ n = _attr(ctx); };\n\n\t\t_ASSERT(test(\"x 123 \\\"a string\\\"\", (omit[char_] >> int_ >> lit(\"\\\"a string\\\"\"))[f], space));\n\t\t_ASSERT(n == 123);\n\t}\n\n\t{\n\t\t// test with simple rule\n\t\t_ASSERT((test_attr(\"123\", omit[direct_rule], unused)));\n\t}\n\n\t{\n\t\t// test with complex rule\n\t\t_ASSERT((test_attr(\"123\", omit[indirect_rule], unused)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/optional_x3.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/adapted/struct.hpp>\n#include <boost/fusion/include/vector.hpp>\n#include <iostream>\n\n#ifdef _MSC_VER\n// bogus https://developercommunity.visualstudio.com/t/buggy-warning-c4709/471956\n# pragma warning(disable: 4709) // comma operator within array index expression\n#endif\n\nstruct adata\n{\n\tint a;\n\tstd::optional<int> b;\n};\n\nBOOST_FUSION_ADAPT_STRUCT(adata,\n\ta, b\n)\n\nstruct test_attribute_type\n{\n\ttemplate <typename Context>\n\tvoid operator()(Context& ctx) const\n\t{\n\t\t_ASSERT(typeid(decltype(_attr(ctx))).name() == typeid(std::optional<int>).name());\n\t}\n};\n\nUNITTESTDEF(x3_test_optional)\n{\n\tusing boost::spirit::x3::traits::is_optional;\n\n\tstatic_assert(is_optional<std::optional<int>>(), \"is_optional problem\");\n\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::ascii::char_;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(-int_);\n\n\t{\n\t\t_ASSERT((test(\"1234\", -int_)));\n\t\t_ASSERT((test(\"abcd\", -int_, false)));\n\n\t\tstd::optional<int> n;\n\t\t_ASSERT(test_attr(\"\", -int_, n));\n\t\t_ASSERT(!n);\n\t\t_ASSERT(test_attr(\"123\", -int_, n));\n\t\t_ASSERT(n);\n\t\t_ASSERTEQUAL(*n, 123);\n\n\t\tstd::optional<std::string> s;\n\t\t_ASSERT(test_attr(\"\", -+char_, s));\n\t\t_ASSERT(!s);\n\t\t_ASSERT(test_attr(\"abc\", -+char_, s));\n\t\t_ASSERT(s);\n\t\t_ASSERTEQUAL(*s, \"abc\");\n\t}\n\n\t{   // test propagation of unused\n\t\tusing boost::fusion::at_c;\n\t\tusing boost::fusion::vector;\n\n\t\tvector<char, char> v;\n\t\t_ASSERT((test_attr(\"a1234c\", char_ >> -omit[int_] >> char_, v)));\n\t\t_ASSERT((at_c<0>(v) == 'a'));\n\t\t_ASSERT((at_c<1>(v) == 'c'));\n\n\t\tv = boost::fusion::vector<char, char>();\n\t\t_ASSERT((test_attr(\"a1234c\", char_ >> omit[-int_] >> char_, v)));\n\t\t_ASSERT((at_c<0>(v) == 'a'));\n\t\t_ASSERT((at_c<1>(v) == 'c'));\n\n\t\tchar ch=0;\n\t\t_ASSERT((test_attr(\",c\", -(lit(',') >> char_), ch)));\n\t\t_ASSERT((ch == 'c'));\n\t}\n\n\t{   // test action\n\t\tstd::optional<int> n = 0;\n\t\t_ASSERT((test_attr(\"1234\", (-int_)[test_attribute_type()], n)));\n\t\t_ASSERT((n == 1234));\n\t}\n\n\t{\n\t\tstd::string s;\n\t\t_ASSERT((test_attr(\"abc\", char_ >> -(char_ >> char_), s)));\n\t\t_ASSERT(s == \"abc\");\n\t}\n\n\t{\n\t\tstd::optional<int> n = 0;\n\t\tauto f = [&](auto& ctx){ n = _attr(ctx); };\n\n\t\t_ASSERT((test(\"1234\", (-int_)[f])));\n\t\t_ASSERT(n == 1234);\n\n\t\tn = std::optional<int>();\n\t\t_ASSERT((test(\"abcd\", (-int_)[f], false)));\n\t\t_ASSERT(!n);\n\t}\n\n\t{\n\t\tstd::vector<adata> v;\n\t\t_ASSERT((test_attr(\"a 1 2 a 2\", *(lit('a') >> int_ >> -int_), v\n\t\t  , char_(' '))));\n\t\t_ASSERT(2 == v.size() &&\n\t\t\t1 == v[0].a && v[0].b && 2 == *(v[0].b) &&\n\t\t\t2 == v[1].a && !v[1].b);\n\t}\n\n\t{ // test move only types\n\t\tstd::optional<move_only> o;\n\t\t_ASSERT(test_attr(\"s\", -synth_move_only, o));\n\t\t_ASSERT(o);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/plus.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <string>\n#include <vector>\n#include <string>\n#include <iostream>\n\n\nstruct x_attr\n{\n};\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <>\n\tstruct container_value<x_attr>\n\t{\n\t\ttypedef char type; // value type of container\n\t};\n\n\ttemplate <>\n\tstruct push_back_container<x_attr>\n\t{\n\t\tstatic bool call(x_attr& /*c*/, char /*val*/)\n\t\t{\n\t\t\t// push back value type into container\n\t\t\treturn true;\n\t\t}\n\t};\n}}}}\n\nUNITTESTDEF(x3_test_plus)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::alpha;\n\tusing boost::spirit::x3::upper;\n\tusing boost::spirit::x3::space;\n\tusing boost::spirit::x3::digit;\n\t//~ using boost::spirit::x3::no_case;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::lit;\n\t//~ using boost::spirit::x3::_1;\n\tusing boost::spirit::x3::lexeme;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(+char_);\n\n\t{\n\t\t_ASSERT(test(\"aaaaaaaa\", +char_));\n\t\t_ASSERT(test(\"a\", +char_));\n\t\t_ASSERT(!test(\"\", +char_));\n\t\t_ASSERT(test(\"aaaaaaaa\", +alpha));\n\t\t_ASSERT(!test(\"aaaaaaaa\", +upper));\n\t}\n\n\t{\n\t\t_ASSERT(test(\" a a aaa aa\", +char_, space));\n\t\t_ASSERT(test(\"12345 678 9 \", +digit, space));\n\t}\n\n\t//~ {\n\t\t//~ _ASSERT(test(\"aBcdeFGH\", no_case[+char_]));\n\t\t//~ _ASSERT(test(\"a B cde FGH  \", no_case[+char_], space));\n\t//~ }\n\n\t{\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"123 456 789 10\", +int_, v, space) && 4 == v.size() &&\n\t\t\tv[0] == 123 && v[1] == 456 && v[2] == 789 &&  v[3] == 10);\n\t}\n\n\t{\n\t\tstd::vector<std::string> v;\n\t\t_ASSERT(test_attr(\"a b c d\", +lexeme[+alpha], v, space) && 4 == v.size() &&\n\t\t\tv[0] == \"a\" && v[1] == \"b\" && v[2] == \"c\" &&  v[3] == \"d\");\n\t}\n\n\t{\n\t\t_ASSERT(test(\"Kim Kim Kim\", +lit(\"Kim\"), space));\n\t}\n\n\t// $$$ Fixme $$$\n\t/*{\n\t\t// The following 2 tests show that omit does not inhibit explicit attributes\n\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"bbbb\", omit[+char_('b')], s) && s == \"bbbb\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"b b b b \", omit[+char_('b')], s, space) && s == \"bbbb\");\n\t}*/\n\n\t{ // actions\n\t\tstd::string v;\n\t\tauto f = [&](auto& ctx){ v = _attr(ctx); };\n\n\t\t_ASSERT(test(\"bbbb\", (+char_)[f]) && 4 == v.size() &&\n\t\t\tv[0] == 'b' && v[1] == 'b' && v[2] == 'b' &&  v[3] == 'b');\n\t}\n\n\t{ // more actions\n\t\tstd::vector<int> v;\n\t\tauto f = [&](auto& ctx){ v = _attr(ctx); };\n\n\t\t_ASSERT(test(\"1 2 3\", (+int_)[f], space) && 3 == v.size() &&\n\t\t\tv[0] == 1 && v[1] == 2 && v[2] == 3);\n\t}\n\n\t{ // attribute customization\n\n\t\tx_attr x;\n\t\ttest_attr(\"abcde\", +char_, x);\n\t}\n\n\t// single-element fusion vector tests\n\t{\n\t\tboost::fusion::vector<std::string> fs;\n\t\t_ASSERT((test_attr(\"12345\", +char_, fs))); // ok\n\t\t_ASSERT(boost::fusion::at_c<0>(fs) == \"12345\");\n\t}\n\n\t{ // test move only types\n\t\tstd::vector<move_only> v;\n\t\t_ASSERT(test_attr(\"sss\", +synth_move_only, v));\n\t\t_ASSERTEQUAL(v.size(), 3);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/raw.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/std_pair.hpp>\n#include <iostream>\n#include <string>\n\nusing boost::spirit::x3::rule;\n\nnamespace {\n\trule<class direct_rule, int> direct_rule = \"direct_rule\";\n\trule<class indirect_rule, int> indirect_rule = \"indirect_rule\";\n\n\tauto const direct_rule_def = boost::spirit::x3::int_;\n\tauto const indirect_rule_def = direct_rule;\n\n\tBOOST_SPIRIT_DEFINE(direct_rule, indirect_rule)\n}\n\nUNITTESTDEF(x3_test_raw)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::raw;\n\tusing boost::spirit::x3::eps;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::_attr;\n\tusing boost::spirit::x3::parse;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::char_;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(raw[lit('x')]);\n\n\t{\n\t\tboost::iterator_range<char const*> range;\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"spirit_test_123\", raw[alpha >> *(alnum | lit('_'))], range)));\n\t\t_ASSERT((std::string(range.begin(), range.end()) == \"spirit_test_123\"));\n\t\t_ASSERT((test_attr(\"  spirit\", raw[*alpha], range, space)));\n\t\t_ASSERT((range.size() == 6));\n\t}\n\n\t{\n\t\tstd::string str;\n\t\t_ASSERT((test_attr(\"spirit_test_123\", raw[alpha >> *(alnum | lit('_'))], str)));\n\t\t_ASSERT((str == \"spirit_test_123\"));\n\n\t\tstr.clear();\n\t\t_ASSERT((test_attr(\"x123\", alpha >> raw[+alnum], str)));\n\t\t_ASSERTEQUAL(str, \"x123\");\n\t}\n\n\t{\n\t\tboost::iterator_range<char const*> range;\n\t\t_ASSERT((test(\"x\", raw[alpha])));\n\t\t_ASSERT((test_attr(\"x\", raw[alpha], range)));\n\t\t_ASSERT((test_attr(\"x\", raw[alpha] >> eps, range)));\n\t}\n\n\t{\n\t\tboost::iterator_range<char const*> range;\n\t\t_ASSERT((test(\"x\", raw[alpha][ ([&](auto& ctx){ range = _attr(ctx); }) ])));\n\t\t_ASSERT(range.size() == 1 && *range.begin() == 'x');\n\t}\n\n\t{\n\t\tboost::iterator_range<char const*> range;\n\t\t_ASSERT((test(\"x123x\", lit('x') >> raw[+digit] >> lit('x'))));\n\t\t_ASSERT((test_attr(\"x123x\", lit('x') >> raw[+digit] >> lit('x'), range)));\n\t\t_ASSERT((std::string(range.begin(), range.end()) == \"123\"));\n\t}\n\n\t{\n\t\tusing range = boost::iterator_range<std::string::iterator>;\n\t\tboost::variant<int, range> attr;\n\n\t\tstd::string str(\"test\");\n\t\tparse(str.begin(), str.end(),  (int_ | raw[*char_]), attr);\n\n\t\tauto rng = boost::get<range>(attr);\n\t\t_ASSERT(std::string(rng.begin(), rng.end()) == \"test\");\n\t}\n\n\t{\n\t\tstd::vector<boost::iterator_range<std::string::iterator>> attr;\n\t\tstd::string str(\"123abcd\");\n\t\tparse(str.begin(), str.end()\n\t\t  , (raw[int_] >> raw[*char_])\n\t\t  , attr\n\t\t);\n\t\t_ASSERT(attr.size() == 2);\n\t\t_ASSERT(std::string(attr[0].begin(), attr[0].end()) == \"123\");\n\t\t_ASSERT(std::string(attr[1].begin(), attr[1].end()) == \"abcd\");\n\t}\n\n\t{\n\t\tstd::pair<int, boost::iterator_range<std::string::iterator>> attr;\n\t\tstd::string str(\"123abcd\");\n\t\tparse(str.begin(), str.end()\n\t\t  , (int_ >> raw[*char_])\n\t\t  , attr\n\t\t);\n\t\t_ASSERT(attr.first == 123);\n\t\t_ASSERT(std::string(attr.second.begin(), attr.second.end()) == \"abcd\");\n\t}\n\n\t{\n\t\t// test with simple rule\n\t\tboost::iterator_range<char const*> range;\n\t\t_ASSERT((test_attr(\"123\", raw[direct_rule], range)));\n\t\t_ASSERT((std::string(range.begin(), range.end()) == \"123\"));\n\t}\n\n\t{\n\t\t// test with complex rule\n\t\tboost::iterator_range<char const*> range;\n\t\t_ASSERT((test_attr(\"123\", raw[indirect_rule], range)));\n\t\t_ASSERT((std::string(range.begin(), range.end()) == \"123\"));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/real.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2010 Joel de Guzman\n\tCopyright (c) 2001-2010 Hartmut Kaiser\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_X3_REAL_HPP)\n#define BOOST_SPIRIT_TEST_X3_REAL_HPP\n\n#include \"test.hpp\"\n#include \"../x3/char.hpp\"\n#include \"../x3/numeric.hpp\"\n#include \"../x3/operator.hpp\"\n#include <boost/type_traits/type_identity.hpp>\n#include <climits>\n\n///////////////////////////////////////////////////////////////////////////////\n//  These policies can be used to parse thousand separated\n//  numbers with at most 2 decimal digits after the decimal\n//  point. e.g. 123,456,789.01\n///////////////////////////////////////////////////////////////////////////////\ntemplate <typename T>\nstruct ts_real_policies : boost::spirit::x3::ureal_policies<T>\n{\n\t//  2 decimal places Max\n\ttemplate <typename Iterator, typename Attribute>\n\tstatic bool\n\tparse_frac_n(Iterator& first, Iterator const& last, Attribute& attr)\n\t{\n\t\tnamespace x3 = boost::spirit::x3;\n\t\treturn boost::spirit::x3::extract_uint<T, 10, 1, 2, true>::call(first, last, attr);\n\t}\n\n\t//  No exponent\n\ttemplate <typename Iterator>\n\tstatic bool\n\tparse_exp(Iterator&, Iterator const&)\n\t{\n\t\treturn false;\n\t}\n\n\t//  No exponent\n\ttemplate <typename Iterator, typename Attribute>\n\tstatic bool\n\tparse_exp_n(Iterator&, Iterator const&, Attribute&)\n\t{\n\t\treturn false;\n\t}\n\n\t//  Thousands separated numbers\n\ttemplate <typename Iterator, typename Accumulator>\n\tstatic bool\n\tparse_n(Iterator& first, Iterator const& last, Accumulator& result)\n\t{\n\t\tusing boost::spirit::x3::uint_parser;\n\t\tusing boost::spirit::x3::lit;\n\t\tnamespace x3 = boost::spirit::x3;\n\n\t\tuint_parser<unsigned, 10, 1, 3> uint3;\n\t\tuint_parser<unsigned, 10, 3, 3> uint3_3;\n\n\t\tif (parse(first, last, uint3, result))\n\t\t{\n\t\t\tAccumulator n;\n\t\t\tIterator iter = first;\n\n\t\t\twhile (x3::parse(iter, last, lit(',')) && x3::parse(iter, last, uint3_3, n))\n\t\t\t{\n\t\t\t\tresult = result * 1000 + n;\n\t\t\t\tfirst = iter;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n};\n\ntemplate <typename T>\nstruct no_trailing_dot_policy : boost::spirit::x3::real_policies<T>\n{\n\tstatic bool const allow_trailing_dot = false;\n};\n\ntemplate <typename T>\nstruct no_leading_dot_policy : boost::spirit::x3::real_policies<T>\n{\n\tstatic bool const allow_leading_dot = false;\n};\n\ntemplate <typename T>\nbool compare(T n, boost::type_identity_t<T> expected)\n{\n\tusing std::abs;\n\tusing std::log10;\n\tusing std::pow;\n\tT const eps = pow(T(10), -std::numeric_limits<T>::digits10 + log10(abs(expected)));\n\tT delta = n - expected;\n\treturn (delta >= -eps) && (delta <= eps);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// A custom real type\nstruct custom_real\n{\n\tdouble n;\n\tcustom_real() : n(0) {}\n\tcustom_real(double n_) : n(n_) {}\n\tfriend bool operator==(custom_real a, custom_real b)\n\t\t{ return a.n == b.n; }\n\tfriend custom_real operator*(custom_real a, custom_real b)\n\t\t{ return custom_real(a.n * b.n); }\n\tfriend custom_real operator+(custom_real a, custom_real b)\n\t\t{ return custom_real(a.n + b.n); }\n\tfriend custom_real operator-(custom_real a, custom_real b)\n\t\t{ return custom_real(a.n - b.n); }\n};\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/real1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"real.hpp\"\n\nUNITTESTDEF(x3_test_real1)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::lit;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  thousand separated numbers\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::uint_parser;\n\t\tusing boost::spirit::x3::parse;\n\n\t\tuint_parser<unsigned, 10, 1, 3> uint3;\n\t\tuint_parser<unsigned, 10, 3, 3> uint3_3;\n\n\t#define r (uint3 >> *(lit(',') >> uint3_3))\n\n\t\t_ASSERT(test(\"1,234,567,890\", r));\n\t\t_ASSERT(test(\"12,345,678,900\", r));\n\t\t_ASSERT(test(\"123,456,789,000\", r));\n\t\t_ASSERT(!test(\"1000,234,567,890\", r));\n\t\t_ASSERT(!test(\"1,234,56,890\", r));\n\t\t_ASSERT(!test(\"1,66\", r));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  unsigned real number tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::real_parser;\n\t\tusing boost::spirit::x3::parse;\n\t\tusing boost::spirit::x3::ureal_policies;\n\n\t\tconstexpr real_parser<double, ureal_policies<double> > udouble;\n\t\tdouble d;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(udouble);\n\n\t\t_ASSERT(test(\"1234\", udouble));\n\t\t_ASSERT(test_attr(\"1234\", udouble, d) && compare(d, 1234));\n\n\t\t_ASSERT(test(\"1.2e3\", udouble));\n\t\t_ASSERT(test_attr(\"1.2e3\", udouble, d) && compare(d, 1.2e3));\n\n\t\t_ASSERT(test(\"1.2e-3\", udouble));\n\t\t_ASSERT(test_attr(\"1.2e-3\", udouble, d) && compare(d, 1.2e-3));\n\n\t\t_ASSERT(test(\"1.e2\", udouble));\n\t\t_ASSERT(test_attr(\"1.e2\", udouble, d) && compare(d, 1.e2));\n\n\t\t_ASSERT(test(\"1.\", udouble));\n\t\t_ASSERT(test_attr(\"1.\", udouble, d) && compare(d, 1.));\n\n\t\t_ASSERT(test(\".2e3\", udouble));\n\t\t_ASSERT(test_attr(\".2e3\", udouble, d) && compare(d, .2e3));\n\n\t\t_ASSERT(test(\"2e3\", udouble));\n\t\t_ASSERT(test_attr(\"2e3\", udouble, d) && compare(d, 2e3));\n\n\t\t_ASSERT(test(\"2\", udouble));\n\t\t_ASSERT(test_attr(\"2\", udouble, d) && compare(d, 2));\n\n\t\t_ASSERT(test(\"inf\", udouble));\n\t\t_ASSERT(test(\"infinity\", udouble));\n\t\t_ASSERT(test(\"INF\", udouble));\n\t\t_ASSERT(test(\"INFINITY\", udouble));\n\n\t\t_ASSERT(test_attr(\"inf\", udouble, d)\n\t\t\t\t&& std::isinf(d));\n\t\t_ASSERT(test_attr(\"INF\", udouble, d)\n\t\t\t\t&& std::isinf(d));\n\t\t_ASSERT(test_attr(\"infinity\", udouble, d)\n\t\t\t\t&& std::isinf(d));\n\t\t_ASSERT(test_attr(\"INFINITY\", udouble, d)\n\t\t\t\t&& std::isinf(d));\n\n\t\t_ASSERT(test(\"nan\", udouble));\n\t\t_ASSERT(test_attr(\"nan\", udouble, d)\n\t\t\t\t&& std::isnan(d));\n\t\t_ASSERT(test(\"NAN\", udouble));\n\t\t_ASSERT(test_attr(\"NAN\", udouble, d)\n\t\t\t\t&& std::isnan(d));\n\t\t_ASSERT(test(\"nan(...)\", udouble));\n\t\t_ASSERT(test_attr(\"nan(...)\", udouble, d)\n\t\t\t\t&& std::isnan(d));\n\t\t_ASSERT(test(\"NAN(...)\", udouble));\n\t\t_ASSERT(test_attr(\"NAN(...)\", udouble, d)\n\t\t\t\t&& std::isnan(d));\n\n\t\t_ASSERT(!test(\"e3\", udouble));\n\t\t_ASSERT(!test_attr(\"e3\", udouble, d));\n\n\t\t_ASSERT(!test(\"-1.2e3\", udouble));\n\t\t_ASSERT(!test_attr(\"-1.2e3\", udouble, d));\n\n\t\t_ASSERT(!test(\"+1.2e3\", udouble));\n\t\t_ASSERT(!test_attr(\"+1.2e3\", udouble, d));\n\n\t\t_ASSERT(!test(\"1.2e\", udouble));\n\t\t_ASSERT(!test_attr(\"1.2e\", udouble, d));\n\n\t\t_ASSERT(!test(\"-.3\", udouble));\n\t\t_ASSERT(!test_attr(\"-.3\", udouble, d));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/real2.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"real.hpp\"\n\ntemplate <typename T, typename P>\nvoid basic_real_parser_test(P parser)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tT attr;\n\n\t_ASSERT(test(\"-1234\", parser));\n\t_ASSERT(test_attr(\"-1234\", parser, attr) && compare(attr, T(-1234l)));\n\n\t_ASSERT(test(\"-1.2e3\", parser));\n\t_ASSERT(test_attr(\"-1.2e3\", parser, attr) && compare(attr, T(-1.2e3l)));\n\n\t_ASSERT(test(\"+1.2e3\", parser));\n\t_ASSERT(test_attr(\"+1.2e3\", parser, attr) && compare(attr, T(1.2e3l)));\n\n\t_ASSERT(test(\"-0.1\", parser));\n\t_ASSERT(test_attr(\"-0.1\", parser, attr) && compare(attr, T(-0.1l)));\n\n\t_ASSERT(test(\"-1.2e-3\", parser));\n\t_ASSERT(test_attr(\"-1.2e-3\", parser, attr) && compare(attr, T(-1.2e-3l)));\n\n\t_ASSERT(test(\"-1.e2\", parser));\n\t_ASSERT(test_attr(\"-1.e2\", parser, attr) && compare(attr, T(-1.e2l)));\n\n\t_ASSERT(test(\"-.2e3\", parser));\n\t_ASSERT(test_attr(\"-.2e3\", parser, attr) && compare(attr, T(-.2e3l)));\n\n\t_ASSERT(test(\"-2e3\", parser));\n\t_ASSERT(test_attr(\"-2e3\", parser, attr) && compare(attr, T(-2e3l)));\n\n\t_ASSERT(!test(\"-e3\", parser));\n\t_ASSERT(!test_attr(\"-e3\", parser, attr));\n\n\t_ASSERT(!test(\"-1.2e\", parser));\n\t_ASSERT(!test_attr(\"-1.2e\", parser, attr));\n}\n\nUNITTESTDEF(x3_test_real2)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(boost::spirit::x3::float_);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(boost::spirit::x3::double_);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(boost::spirit::x3::long_double);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  signed real number tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tbasic_real_parser_test<float>(boost::spirit::x3::float_);\n\t\tbasic_real_parser_test<double>(boost::spirit::x3::double_);\n\t\tbasic_real_parser_test<long double>(boost::spirit::x3::long_double);\n\t}\n\n\t{\n\t\tusing boost::spirit::x3::double_;\n\t\tdouble  d;\n\n#if defined(BOOST_SPIRIT_TEST_REAL_PRECISION)\n\t\t_ASSERT(test_attr(\"-5.7222349715140557e+307\", double_, d));\n\t\t_ASSERT(d == -5.7222349715140557e+307); // exact!\n\n\t\t_ASSERT(test_attr(\"2.0332938517515416e-308\", double_, d));\n\t\t_ASSERT(d == 2.0332938517515416e-308); // exact!\n\n\t\t_ASSERT(test_attr(\"20332938517515416e291\", double_, d));\n\t\t_ASSERT(d == 20332938517515416e291); // exact!\n\n\t\t_ASSERT(test_attr(\"2.0332938517515416e307\", double_, d));\n\t\t_ASSERT(d == 2.0332938517515416e307); // exact!\n#endif\n\n\t\t_ASSERT(test(\"-inf\", double_));\n\t\t_ASSERT(test(\"-infinity\", double_));\n\t\t_ASSERT(test_attr(\"-inf\", double_, d) &&\n\t\t\tstd::isinf(d) && std::signbit(d));\n\t\t_ASSERT(test_attr(\"-infinity\", double_, d) &&\n\t\t\tstd::isinf(d) && std::signbit(d));\n\t\t_ASSERT(test(\"-INF\", double_));\n\t\t_ASSERT(test(\"-INFINITY\", double_));\n\t\t_ASSERT(test_attr(\"-INF\", double_, d) &&\n\t\t\tstd::isinf(d) && std::signbit(d));\n\t\t_ASSERT(test_attr(\"-INFINITY\", double_, d) &&\n\t\t\tstd::isinf(d) && std::signbit(d));\n\n\t\t_ASSERT(test(\"-nan\", double_));\n\t\t_ASSERT(test_attr(\"-nan\", double_, d) &&\n\t\t\tstd::isnan(d) && std::signbit(d));\n\t\t_ASSERT(test(\"-NAN\", double_));\n\t\t_ASSERT(test_attr(\"-NAN\", double_, d) &&\n\t\t\tstd::isnan(d) && std::signbit(d));\n\n\t\t_ASSERT(test(\"-nan(...)\", double_));\n\t\t_ASSERT(test_attr(\"-nan(...)\", double_, d) &&\n\t\t\tstd::isnan(d) && std::signbit(d));\n\t\t_ASSERT(test(\"-NAN(...)\", double_));\n\t\t_ASSERT(test_attr(\"-NAN(...)\", double_, d) &&\n\t\t\tstd::isnan(d) && std::signbit(d));\n\n\t\t_ASSERT(!test(\"1e999\", double_));\n\t\t_ASSERT(!test(\"1e-999\", double_));\n\t\t_ASSERT(test_attr(\"2.1111111e-303\", double_, d) &&\n\t\t\tcompare(d, 2.1111111e-303));\n\t\t_ASSERT(!test_attr(\"1.1234e\", double_, d) && compare(d, 1.1234));\n\n\t\t// https://svn.boost.org/trac10/ticket/11608\n\t\t_ASSERT(test_attr(\"1267650600228229401496703205376\", double_, d) &&\n\t\t\tcompare(d, 1267650600228229401496703205376.));    // Note Qi has better precision\n\n\t\t_ASSERT(test_attr(\"12676506.00228229401496703205376\", double_, d) &&\n\t\t\tcompare(d, 12676506.00228229401496703205376));    // Note Qi has better precision\n\n\t\t_ASSERT(test_attr(\"12676506.00228229401496703205376E6\", double_, d) &&\n\t\t\tcompare(d, 12676506.00228229401496703205376E6));  // Note Qi has better precision\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/real3.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2010 Hartmut Kaiser\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"real.hpp\"\n\nUNITTESTDEF(x3_test_real3)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  strict real number tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::real_parser;\n\t\tusing boost::spirit::x3::parse;\n\t\tusing boost::spirit::x3::strict_ureal_policies;\n\t\tusing boost::spirit::x3::strict_real_policies;\n\n\t\tconstexpr real_parser<double, strict_ureal_policies<double> > strict_udouble;\n\t\tconstexpr real_parser<double, strict_real_policies<double> > strict_double;\n\t\tdouble  d;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(strict_udouble);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(strict_double);\n\n\t\t_ASSERT(!test(\"1234\", strict_udouble));\n\t\t_ASSERT(!test_attr(\"1234\", strict_udouble, d));\n\n\t\t_ASSERT(test(\"1.2\", strict_udouble));\n\t\t_ASSERT(test_attr(\"1.2\", strict_udouble, d) && compare(d, 1.2));\n\n\t\t_ASSERT(!test(\"-1234\", strict_double));\n\t\t_ASSERT(!test_attr(\"-1234\", strict_double, d));\n\n\t\t_ASSERT(test(\"123.\", strict_double));\n\t\t_ASSERT(test_attr(\"123.\", strict_double, d) && compare(d, 123));\n\n\t\t_ASSERT(test(\"3.E6\", strict_double));\n\t\t_ASSERT(test_attr(\"3.E6\", strict_double, d) && compare(d, 3e6));\n\n\t\tconstexpr real_parser<double, no_trailing_dot_policy<double> > notrdot_real;\n\t\tconstexpr real_parser<double, no_leading_dot_policy<double> > nolddot_real;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(notrdot_real);\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(nolddot_real);\n\n\t\t_ASSERT(!test(\"1234.\", notrdot_real));          //  Bad trailing dot\n\t\t_ASSERT(!test(\".1234\", nolddot_real));          //  Bad leading dot\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Special thousands separated numbers\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::real_parser;\n\t\tusing boost::spirit::x3::parse;\n\t\tconstexpr real_parser<double, ts_real_policies<double> > ts_real;\n\t\tdouble  d;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(ts_real);\n\n\t\t_ASSERT(test(\"123.01\", ts_real));\n\t\t_ASSERT(test_attr(\"123.01\", ts_real, d)\n\t\t\t\t&& compare(d, 123.01));\n\n\t\t_ASSERT(test(\"123,456,789.01\", ts_real));\n\t\t_ASSERT(test_attr(\"123,456,789.01\", ts_real, d)\n\t\t\t\t&& compare(d, 123456789.01));\n\n\t\t_ASSERT(test(\"12,345,678.90\", ts_real));\n\t\t_ASSERT(test_attr(\"12,345,678.90\", ts_real, d)\n\t\t\t\t&& compare(d, 12345678.90));\n\n\t\t_ASSERT(test(\"1,234,567.89\", ts_real));\n\t\t_ASSERT(test_attr(\"1,234,567.89\", ts_real, d)\n\t\t\t\t&& compare(d, 1234567.89));\n\n\t\t_ASSERT(!test(\"1234,567,890\", ts_real));\n\t\t_ASSERT(!test(\"1,234,5678,9\", ts_real));\n\t\t_ASSERT(!test(\"1,234,567.89e6\", ts_real));\n\t\t_ASSERT(!test(\"1,66\", ts_real));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/real4.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"real.hpp\"\n\n#include <boost/math/concepts/real_concept.hpp>\n\nUNITTESTDEF(x3_test_real4)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Custom data type\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::math::concepts::real_concept;\n\t\tusing boost::spirit::x3::real_parser;\n\t\tusing boost::spirit::x3::real_policies;\n\t\tusing boost::spirit::x3::parse;\n\n\t\tconstexpr real_parser<real_concept, real_policies<real_concept> > custom_real;\n\t\treal_concept d;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(custom_real);\n\n\t\t_ASSERT(test(\"-1234\", custom_real));\n\t\t_ASSERT(test_attr(\"-1234\", custom_real, d) && compare(d, -1234));\n\n\t\t_ASSERT(test(\"-1.2e3\", custom_real));\n\t\t_ASSERT(test_attr(\"-1.2e3\", custom_real, d) && compare(d, -1.2e3));\n\n\t\t_ASSERT(test(\"+1.2e3\", custom_real));\n\t\t_ASSERT(test_attr(\"+1.2e3\", custom_real, d) && compare(d, 1.2e3));\n\n\t\t_ASSERT(test(\"-0.1\", custom_real));\n\t\t_ASSERT(test_attr(\"-0.1\", custom_real, d) && compare(d, -0.1));\n\n\t\t_ASSERT(test(\"-1.2e-3\", custom_real));\n\t\t_ASSERT(test_attr(\"-1.2e-3\", custom_real, d) && compare(d, -1.2e-3));\n\n\t\t_ASSERT(test(\"-1.e2\", custom_real));\n\t\t_ASSERT(test_attr(\"-1.e2\", custom_real, d) && compare(d, -1.e2));\n\n\t\t_ASSERT(test(\"-.2e3\", custom_real));\n\t\t_ASSERT(test_attr(\"-.2e3\", custom_real, d) && compare(d, -.2e3));\n\n\t\t_ASSERT(test(\"-2e3\", custom_real));\n\t\t_ASSERT(test_attr(\"-2e3\", custom_real, d) && compare(d, -2e3));\n\n\t\t_ASSERT(!test(\"-e3\", custom_real));\n\t\t_ASSERT(!test_attr(\"-e3\", custom_real, d));\n\n\t\t_ASSERT(!test(\"-1.2e\", custom_real));\n\t\t_ASSERT(!test_attr(\"-1.2e\", custom_real, d));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  custom real tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::double_;\n\t\tcustom_real n;\n\n\t\t_ASSERT(test_attr(\"-123456e6\", double_, n));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/repeat.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <boost/utility/enable_if.hpp>\n#include <string>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#if defined(__GNUC__) && (__GNUC__ >= 8)\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92539\n# pragma GCC diagnostic ignored \"-Warray-bounds\"\n#endif\n\nUNITTESTDEF(x3_test_repeat)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::repeat;\n\tusing boost::spirit::x3::inf;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::lexeme;\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat[lit('x')]);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3)[lit('x')]);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3, 5)[lit('x')]);\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(repeat(3, inf)[lit('x')]);\n\n\t{\n\t\t_ASSERT(test(\"aaaaaaaa\", repeat[char_])); // kleene synonym\n\t\t_ASSERT(test(\"aaaaaaaa\", repeat(8)[char_]));\n\t\t_ASSERT(!test(\"aa\", repeat(3)[char_]));\n\t\t_ASSERT(test(\"aaa\", repeat(3, 5)[char_]));\n\t\t_ASSERT(test(\"aaaaa\", repeat(3, 5)[char_]));\n\t\t_ASSERT(!test(\"aaaaaa\", repeat(3, 5)[char_]));\n\t\t_ASSERT(!test(\"aa\", repeat(3, 5)[char_]));\n\n\t\t_ASSERT(test(\"aaa\", repeat(3, inf)[char_]));\n\t\t_ASSERT(test(\"aaaaa\", repeat(3, inf)[char_]));\n\t\t_ASSERT(test(\"aaaaaa\", repeat(3, inf)[char_]));\n\t\t_ASSERT(!test(\"aa\", repeat(3, inf)[char_]));\n\t}\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"aaaaaaaa\", repeat[char_ >> char_], s)); // kleene synonym\n\t\t_ASSERT(s == \"aaaaaaaa\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"aaaaaaaa\", repeat(4)[char_ >> char_], s));\n\t\t_ASSERT(s == \"aaaaaaaa\");\n\n\t\t_ASSERT(!test(\"aa\", repeat(3)[char_ >> char_]));\n\t\t_ASSERT(!test(\"a\", repeat(1)[char_ >> char_]));\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"aa\", repeat(1, 3)[char_ >> char_], s));\n\t\t_ASSERT(s == \"aa\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"aaaaaa\", repeat(1, 3)[char_ >> char_], s));\n\t\t_ASSERT(s == \"aaaaaa\");\n\n\t\t_ASSERT(!test(\"aaaaaaa\", repeat(1, 3)[char_ >> char_]));\n\t\t_ASSERT(!test(\"a\", repeat(1, 3)[char_ >> char_]));\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"aaaa\", repeat(2, inf)[char_ >> char_], s));\n\t\t_ASSERT(s == \"aaaa\");\n\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"aaaaaa\", repeat(2, inf)[char_ >> char_], s));\n\t\t_ASSERT(s == \"aaaaaa\");\n\n\t\t_ASSERT(!test(\"aa\", repeat(2, inf)[char_ >> char_]));\n\t}\n\n\t{ // from classic spirit tests\n\t\t_ASSERT(test(\"\", repeat(0, inf)[lit('x')]));\n\n\t\t//  repeat exact 8\n\t\t#define rep8 repeat(8)[alpha] >> lit('X')\n\t\t_ASSERT(!test(\"abcdefgX\", rep8, false));\n\t\t_ASSERT(test(\"abcdefghX\", rep8));\n\t\t_ASSERT(!test(\"abcdefghiX\", rep8, false));\n\t\t_ASSERT(!test(\"abcdefgX\", rep8, false));\n\t\t_ASSERT(!test(\"aX\", rep8, false));\n\n\t\t//  repeat 2 to 8\n\t\t#define rep28 repeat(2, 8)[alpha] >> lit('*')\n\t\t_ASSERT(test(\"abcdefg*\", rep28));\n\t\t_ASSERT(test(\"abcdefgh*\", rep28));\n\t\t_ASSERT(!test(\"abcdefghi*\", rep28, false));\n\t\t_ASSERT(!test(\"a*\", rep28, false));\n\n\t\t//  repeat 2 or more\n\t\t#define rep2_ repeat(2, inf)[alpha] >> lit('+')\n\t\t_ASSERT(test(\"abcdefg+\", rep2_));\n\t\t_ASSERT(test(\"abcdefgh+\", rep2_));\n\t\t_ASSERT(test(\"abcdefghi+\", rep2_));\n\t\t_ASSERT(test(\"abcdefg+\", rep2_));\n\t\t_ASSERT(!test(\"a+\", rep2_, false));\n\n\t\t//  repeat 0\n\t\t#define rep0 repeat(0)[alpha] >> lit('/')\n\t\t_ASSERT(test(\"/\", rep0));\n\t\t_ASSERT(!test(\"a/\", rep0, false));\n\n\t\t//  repeat 0 or 1\n\t\t#define rep01 repeat(0, 1)[alpha >> digit] >> lit('?')\n\t\t_ASSERT(!test(\"abcdefg?\", rep01, false));\n\t\t_ASSERT(!test(\"a?\", rep01, false));\n\t\t_ASSERT(!test(\"1?\", rep01, false));\n\t\t_ASSERT(!test(\"11?\", rep01, false));\n\t\t_ASSERT(!test(\"aa?\", rep01, false));\n\t\t_ASSERT(test(\"?\", rep01));\n\t\t_ASSERT(test(\"a1?\", rep01));\n\t}\n\n\t{\n\t\t_ASSERT(test(\" a a aaa aa\", repeat(7)[char_], space));\n\t\t_ASSERT(test(\"12345 678 9\", repeat(9)[digit], space));\n\t}\n\n\t{\n\t\tstd::vector<std::string> v;\n\t\t_ASSERT(test_attr(\"a b c d\", repeat(4)[lexeme[+alpha]], v, space) && 4 == v.size() &&\n\t\t\tv[0] == \"a\" && v[1] == \"b\" && v[2] == \"c\" &&  v[3] == \"d\");\n\t}\n\t{\n\t\t_ASSERT(test(\"1 2 3\", int_ >> repeat(2)[int_], space));\n\t\t_ASSERT(!test(\"1 2\", int_ >> repeat(2)[int_], space));\n\t}\n\n\t{\n\t\tstd::vector<int> v;\n\t\t_ASSERT(test_attr(\"1 2 3\", int_ >> repeat(2)[int_], v, space));\n\t\t_ASSERT(v.size() == 3 && v[0] == 1 && v[1] == 2 && v[2] == 3);\n\n\t\t_ASSERT(!test(\"1 2\", int_ >> repeat(2)[int_], space));\n\t}\n\n\t{ // test move only types\n\t\tstd::vector<move_only> v;\n\t\t_ASSERT(test_attr(\"sss\", repeat(3)[synth_move_only], v));\n\t\t_ASSERTEQUAL(v.size(), 3);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <string>\n#include <cstring>\n#include <iostream>\n\nUNITTESTDEF(x3_test_rule1)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::unused_type;\n\tusing boost::spirit::x3::phrase_parse;\n\tusing boost::spirit::x3::skip_flag;\n\tusing boost::spirit::x3::traits::has_attribute;\n\n#ifdef BOOST_SPIRIT_X3_NO_RTTI\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{});\n#endif\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{\"r\"});\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{\"r\"} = lit('x'));\n\n\t// check attribute advertising\n\tstatic_assert( has_attribute<rule<class r, int>, /*Context=*/unused_type>::value, \"\");\n\tstatic_assert(!has_attribute<rule<class r     >, /*Context=*/unused_type>::value, \"\");\n\tstatic_assert( has_attribute<decltype(rule<class r, int>{} = int_), /*Context=*/unused_type>::value, \"\");\n\tstatic_assert(!has_attribute<decltype(rule<class r     >{} = int_), /*Context=*/unused_type>::value, \"\");\n\n\n\t{ // basic tests\n\n\t\tauto a = lit('a');\n\t\tauto b = lit('b');\n\t\tauto c = lit('c');\n\t\trule<class r> r;\n\n\t\t{\n\t\t\tauto start =\n\t\t\t\tr = *(a | b | c);\n\n\t\t\t_ASSERT(test(\"abcabcacb\", start));\n\t\t}\n\n\t\t{\n\t\t\tauto start =\n\t\t\t\tr = (a | b) >> (r | b);\n\n\t\t\t_ASSERT(test(\"aaaabababaaabbb\", start));\n\t\t\t_ASSERT(test(\"aaaabababaaabba\", start, false));\n\n\t\t\t// ignore the skipper!\n\t\t\t_ASSERT(test(\"aaaabababaaabba\", start, space, false));\n\t\t}\n\t}\n\n\t{ // basic tests w/ skipper\n\n\t\tauto a = lit('a');\n\t\tauto b = lit('b');\n\t\tauto c = lit('c');\n\t\trule<class r> r;\n\n\t\t{\n\t\t\tauto start =\n\t\t\t\tr = *(a | b | c);\n\n\t\t\t_ASSERT(test(\" a b c a b c a c b \", start, space));\n\t\t}\n\n\t\t{\n\t\t\tauto start =\n\t\t\t\tr = (a | b) >> (r | b);\n\n\t\t\t_ASSERT(test(\" a a a a b a b a b a a a b b b \", start, space));\n\t\t\t_ASSERT(test(\" a a a a b a b a b a a a b b a \", start, space, false));\n\t\t}\n\t}\n\n\t{ // basic tests w/ skipper but no final post-skip\n\n\t\tauto a = rule<class a_id>()\n\t\t\t= lit('a');\n\n\t\tauto b = rule<class b_id>()\n\t\t\t= lit('b');\n\n\t\tauto c = rule<class c_id>()\n\t\t\t= lit('c');\n\n\t\t{\n\t\t\tauto start = rule<class start_id>() = *(a | b) >> c;\n\n\t\t\tchar const *s1 = \" a b a a b b a c ... \"\n\t\t\t  , *const e1 = s1 + std::strlen(s1);\n\t\t\t_ASSERT(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip)\n\t\t\t  && s1 == e1 - 5);\n\n\t\t}\n\n\t\t{\n\t\t\trule<class start> start;\n\n\t\t\tauto p =\n\t\t\t\tstart = (a | b) >> (start | c);\n\t\t\t{\n\t\t\t\tchar const *s1 = \" a a a a b a b a b a a a b b b c \"\n\t\t\t\t  , *const e1 = s1 + std::strlen(s1);\n\t\t\t\t_ASSERT(phrase_parse(s1, e1, p, space, skip_flag::post_skip)\n\t\t\t\t  && s1 == e1);\n\t\t\t}\n\t\t\t{\n\t\t\t\tchar const *s1 = \" a a a a b a b a b a a a b b b c \"\n\t\t\t\t  , *const e1 = s1 + std::strlen(s1);\n\t\t\t\t_ASSERT(phrase_parse(s1, e1, p, space, skip_flag::dont_post_skip)\n\t\t\t\t  && s1 == e1 - 1);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule2.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <string>\n#include <cstring>\n#include <iostream>\n\nnamespace x3 = boost::spirit::x3;\n\nnamespace {\n\ttemplate<typename Id>\n\tstruct check_no_rule_injection_parser\n\t\t: x3::parser<check_no_rule_injection_parser<Id>>\n\t{\n\t\ttypedef x3::unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator&, Iterator const&, Context const&,\n\t\t\tRuleContext&, Attribute&) const\n\t\t{\n\t\t\tstatic_assert(std::is_same<std::remove_cvref_t<decltype(x3::get<Id>(std::declval<Context const&>()))>, x3::unused_type>::value,\n\t\t\t\t\"no rule definition injection should occur\");\n\t\t\treturn true;\n\t\t}\n\t};\n\n\ttemplate<typename Id>\n\t[[maybe_unused]] auto const check_no_rule_injection = check_no_rule_injection_parser<Id>{};\n}\n\nUNITTESTDEF(x3_test_rule2)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::unused_type;\n\tusing boost::spirit::x3::_attr;\n\n\t{ // context tests\n\n\t\tchar ch;\n\t\tauto a = rule<class a_id, char>() = alpha;\n\n\t\t// this semantic action requires the context\n\t\tauto f = [&](auto& ctx){ ch = _attr(ctx); };\n\t\t_ASSERT(test(\"x\", a[f]));\n\t\t_ASSERT(ch == 'x');\n\n\t\t// this semantic action requires the (unused) context\n\t\tauto f2 = [&](auto&){ ch = 'y'; };\n\t\t_ASSERT(test(\"x\", a[f2]));\n\t\t_ASSERT(ch == 'y');\n\n\t\t// the semantic action may optionally not have any arguments at all\n\t\tauto f3 = [&]{ ch = 'z'; };\n\t\t_ASSERT(test(\"x\", a[f3]));\n\t\t_ASSERT(ch == 'z');\n\n\t\t_ASSERT(test_attr(\"z\", a, ch)); // attribute is given.\n\t\t_ASSERT(ch == 'z');\n\t}\n\n\t{ // auto rules tests\n\n\t\tchar ch = '\\0';\n\t\tauto a = rule<class a_id, char>() = alpha;\n\t\tauto f = [&](auto& ctx){ ch = _attr(ctx); };\n\n\t\t_ASSERT(test(\"x\", a[f]));\n\t\t_ASSERT(ch == 'x');\n\t\tch = '\\0';\n\t\t_ASSERT(test_attr(\"z\", a, ch)); // attribute is given.\n\t\t_ASSERT(ch == 'z');\n\n\t\tch = '\\0';\n\t\t_ASSERT(test(\"x\", a[f]));\n\t\t_ASSERT(ch == 'x');\n\t\tch = '\\0';\n\t\t_ASSERT(test_attr(\"z\", a, ch)); // attribute is given.\n\t\t_ASSERT(ch == 'z');\n\t}\n\n\t{ // auto rules tests: allow stl containers as attributes to\n\t  // sequences (in cases where attributes of the elements\n\t  // are convertible to the value_type of the container or if\n\t  // the element itself is an stl container with value_type\n\t  // that is convertible to the value_type of the attribute).\n\n\t\tstd::string s;\n\t\tauto f = [&](auto& ctx){ s = _attr(ctx); };\n\n\t\t{\n\t\t\tauto r = rule<class r_id, std::string>()\n\t\t\t\t= char_ >> *(lit(',') >> char_)\n\t\t\t\t;\n\n\t\t\t_ASSERT(test(\"a,b,c,d,e,f\", r[f]));\n\t\t\t_ASSERT(s == \"abcdef\");\n\t\t}\n\n\t\t{\n\t\t\tauto r = rule<class r_id, std::string>()\n\t\t\t\t= char_ >> *(lit(',') >> char_);\n\t\t\ts.clear();\n\t\t\t_ASSERT(test(\"a,b,c,d,e,f\", r[f]));\n\t\t\t_ASSERT(s == \"abcdef\");\n\t\t}\n\n\t\t{\n\t\t\tauto r = rule<class r_id, std::string>()\n\t\t\t\t= char_ >> char_ >> char_ >> char_ >> char_ >> char_;\n\t\t\ts.clear();\n\t\t\t_ASSERT(test(\"abcdef\", r[f]));\n\t\t\t_ASSERT(s == \"abcdef\");\n\t\t}\n\t}\n\n\t{\n\t\tstruct a;\n\t\t_ASSERT(test(\"\", rule<a>{} = check_no_rule_injection<a>));\n\t\t_ASSERT(test(\"\", rule<a>{} %= check_no_rule_injection<a>));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule3.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2012 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/adapt_struct.hpp>\n#include <boost/fusion/include/std_pair.hpp>\n#include <boost/variant.hpp>\n#include <string>\n#include <vector>\n#include <cstring>\n#include <iostream>\n\n#ifdef _MSC_VER\n// bogus https://developercommunity.visualstudio.com/t/buggy-warning-c4709/471956\n# pragma warning(disable: 4709) // comma operator within array index expression\n#endif\n\nusing boost::spirit::x3::_val;\nnamespace x3 = boost::spirit::x3;\nusing boost::spirit::x3::lit;\n\nstruct f\n{\n\ttemplate <typename Context>\n\tvoid operator()(Context const& ctx) const\n\t{\n\t\t_val(ctx) += _attr(ctx);\n\t}\n};\n\n\nstruct stationary : boost::noncopyable\n{\n\texplicit stationary(int i) : val{i} {}\n\tstationary& operator=(int i) { val = i; return *this; }\n\n\tint val;\n};\n\n\nnamespace check_stationary {\n\nboost::spirit::x3::rule<class a_r, stationary> const a;\nboost::spirit::x3::rule<class b_r, stationary> const b;\n\nauto const a_def = lit('{') >> boost::spirit::x3::int_ >> lit('}');\nauto const b_def = a;\n\nBOOST_SPIRIT_DEFINE(a, b)\n\n}\n\nnamespace check_recursive {\n\nusing node_t = boost::make_recursive_variant<\n\t\t\t\t   int,\n\t\t\t\t   std::vector<boost::recursive_variant_>\n\t\t\t   >::type;\n\nboost::spirit::x3::rule<class grammar_r, node_t> const grammar;\n\nauto const grammar_def = lit('[') >> grammar % lit(',') >> lit(']') | boost::spirit::x3::int_;\n\nBOOST_SPIRIT_DEFINE(grammar)\n\n}\n\nnamespace check_recursive_scoped {\n\nusing check_recursive::node_t;\n\nx3::rule<class intvec_r, node_t> const intvec;\nauto const grammar = intvec = lit('[') >> intvec % lit(',') >> lit(']') | x3::int_;\n\n}\n\nstruct recursive_tuple\n{\n\tint value;\n\tstd::vector<recursive_tuple> children;\n};\nBOOST_FUSION_ADAPT_STRUCT(recursive_tuple,\n\tvalue, children)\n\n// regression test for #461\nnamespace check_recursive_tuple {\n\nx3::rule<class grammar_r, recursive_tuple> const grammar;\nauto const grammar_def = x3::int_ >> (lit('{') >> grammar % lit(',') >> lit('}') | x3::eps);\nBOOST_SPIRIT_DEFINE(grammar)\n\nBOOST_SPIRIT_INSTANTIATE(decltype(grammar), char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\n\n}\n\n\nUNITTESTDEF(x3_test_rule3)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::eps;\n\tusing boost::spirit::x3::unused_type;\n\n\n\t{ // synth attribute value-init\n\n\t\tstd::string s;\n\t\ttypedef rule<class r, std::string> rule_type;\n\n\t\tauto rdef = rule_type()\n\t\t\t= alpha                 [f()]\n\t\t\t;\n\n\t\t_ASSERT(test_attr(\"abcdef\", +rdef, s));\n\t\t_ASSERT(s == \"abcdef\");\n\t}\n\n\t{ // synth attribute value-init\n\n\t\tstd::string s;\n\t\ttypedef rule<class r, std::string> rule_type;\n\n\t\tauto rdef = rule_type() =\n\t\t\talpha /\n\t\t\t   [](auto& ctx)\n\t\t\t   {\n\t\t\t\t  _val(ctx) += _attr(ctx);\n\t\t\t   }\n\t\t\t;\n\n\t\t_ASSERT(test_attr(\"abcdef\", +rdef, s));\n\t\t_ASSERT(s == \"abcdef\");\n\t}\n\n\t{\n\t\tauto r = rule<class r_id, int>{} = eps[([] (auto& ctx) {\n\t\t\tusing boost::spirit::x3::_val;\n\t\t\tstatic_assert(std::is_same<std::decay_t<decltype(_val(ctx))>, unused_type>::value,\n\t\t\t\t\"Attribute must not be synthesized\");\n\t\t})];\n\t\t_ASSERT(test(\"\", r));\n\t}\n\n\t{ // ensure no unneeded synthesization, copying and moving occurred\n\t\tstationary st { 0 };\n\t\t_ASSERT(test_attr(\"{42}\", check_stationary::b, st));\n\t\t_ASSERTEQUAL(st.val, 42);\n\t}\n\n\t{\n\t\tusing namespace check_recursive;\n\t\tnode_t v;\n\t\t_ASSERT(test_attr(\"[4,2]\", grammar, v));\n\t\t_ASSERT((node_t{std::vector<node_t>{{4}, {2}}} == v));\n\t}\n\t{\n\t\tusing namespace check_recursive_scoped;\n\t\tnode_t v;\n\t\t_ASSERT(test_attr(\"[4,2]\", grammar, v));\n\t\t_ASSERT((node_t{std::vector<node_t>{{4}, {2}}} == v));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule4.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/at.hpp>\n#include <string>\n#include <cstring>\n#include <iostream>\n\nnamespace x3 = boost::spirit::x3;\n\nint got_it = 0;\n\nstruct my_rule_class\n{\n\ttemplate <typename Iterator, typename Exception, typename Context>\n\tx3::error_handler_result\n\ton_error(Iterator&, Iterator const& last, Exception const& x, Context const&)\n\t{\n\t\treturn x3::error_handler_result::fail;\n\t}\n\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tinline void\n\ton_success(Iterator const&, Iterator const&, Attribute&, Context const&)\n\t{\n\t\t++got_it;\n\t}\n};\n\nstruct on_success_gets_preskipped_iterator\n{\n\tstatic bool ok;\n\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tvoid on_success(Iterator before, Iterator& after, Attribute&, Context const&)\n\t{\n\t\tok = ('b' == *before) && (++before == after);\n\t}\n};\nbool on_success_gets_preskipped_iterator::ok = false;\n\nstruct on_success_advance_iterator\n{\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tvoid on_success(Iterator const&, Iterator& after, Attribute&, Context const&)\n\t{\n\t\t++after;\n\t}\n};\nstruct on_success_advance_iterator_mutref\n{\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tvoid on_success(Iterator&, Iterator& after, Attribute&, Context const&)\n\t{\n\t\t++after;\n\t}\n};\nstruct on_success_advance_iterator_byval\n{\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tvoid on_success(Iterator, Iterator& after, Attribute&, Context const&)\n\t{\n\t\t++after;\n\t}\n};\n\nUNITTESTDEF(x3_test_rule4)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing namespace boost::spirit::x3::ascii;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::lit;\n\n\t{ // show that ra = rb and ra %= rb works as expected\n\t\trule<class a, int> ra;\n\t\trule<class b, int> rb;\n\t\tint attr=0;\n\n\t\tauto ra_def = (ra %= int_);\n\t\t_ASSERT(test_attr(\"123\", ra_def, attr));\n\t\t_ASSERT(attr == 123);\n\n\t\tauto rb_def = (rb %= ra_def);\n\t\t_ASSERT(test_attr(\"123\", rb_def, attr));\n\t\t_ASSERT(attr == 123);\n\n\t\tauto rb_def2 = (rb = ra_def);\n\t\t_ASSERT(test_attr(\"123\", rb_def2, attr));\n\t\t_ASSERT(attr == 123);\n\t}\n\n\t{ // show that ra %= rb works as expected with semantic actions\n\t\trule<class a, int> ra;\n\t\trule<class b, int> rb;\n\t\tint attr=0;\n\n\t\tauto f = [](auto&){};\n\t\tauto ra_def = (ra %= int_[f]);\n\t\t_ASSERT(test_attr(\"123\", ra_def, attr));\n\t\t_ASSERT(attr == 123);\n\n\t\tauto ra_def2 = (rb = (ra %= int_[f]));\n\t\t_ASSERT(test_attr(\"123\", ra_def2, attr));\n\t\t_ASSERT(attr == 123);\n\t}\n\n\n\t{ // std::string as container attribute with auto rules\n\n\t\tstd::string attr;\n\n\t\t// test deduced auto rule behavior\n\n\t\tauto text = rule<class text_id, std::string>()\n\t\t\t= +(!char_(')') >> !char_('>') >> char_);\n\n\t\tattr.clear();\n\t\t_ASSERT(test_attr(\"x\", text, attr));\n\t\t_ASSERT(attr == \"x\");\n\t}\n\n\t{ // error handling\n\n\t\tauto r = rule<my_rule_class, char const*>()\n\t\t\t= lit('(') > int_ > lit(',') > int_ > lit(')');\n\n\t\t_ASSERT(test(\"(123,456)\", r));\n\t\t_ASSERT(!test(\"(abc,def)\", r));\n\t\t_ASSERT(!test(\"(123,456]\", r));\n\t\t_ASSERT(!test(\"(123;456)\", r));\n\t\t_ASSERT(!test(\"[123,456]\", r));\n\n\t\t_ASSERT(got_it == 1);\n\t}\n\n\t{ // on_success gets pre-skipped iterator\n\t\tauto r = rule<on_success_gets_preskipped_iterator, char const*>()\n\t\t\t= lit(\"b\");\n\t\t_ASSERT(test(\"a b\", lit('a') >> r, lit(' ')));\n\t\t_ASSERT(on_success_gets_preskipped_iterator::ok);\n\t}\n\n\t{ // on_success handler mutable 'after' iterator\n\t\tauto r1 = rule<on_success_advance_iterator, char const*>()\n\t\t\t= lit(\"ab\");\n\t\t_ASSERT(test(\"abc\", r1));\n\t\tauto r2 = rule<on_success_advance_iterator_mutref, char const*>()\n\t\t\t= lit(\"ab\");\n\t\t_ASSERT(test(\"abc\", r2));\n\t\tauto r3 = rule<on_success_advance_iterator_byval, char const*>()\n\t\t\t= lit(\"ab\");\n\t\t_ASSERT(test(\"abc\", r3));\n\t}\n\n\t{\n\t\ttypedef boost::variant<double, int> v_type;\n\t\tauto r1 = rule<class r1_id, v_type>()\n\t\t\t= int_;\n\t\tv_type v;\n\t\t_ASSERT(test_attr(\"1\", r1, v) && v.which() == 1 &&\n\t\t\tboost::get<int>(v) == 1);\n\n\t\ttypedef std::optional<int> ov_type;\n\t\tauto r2 = rule<class r2_id, ov_type>()\n\t\t\t= int_;\n\t\tov_type ov;\n\t\t_ASSERT(test_attr(\"1\", r2, ov) && ov && ov == 1);\n\t}\n\n\t// test handling of single element fusion sequences\n\t{\n\t\tusing boost::fusion::vector;\n\t\tusing boost::fusion::at_c;\n\t\tauto r = rule<class r_id, vector<int>>()\n\t\t\t= int_;\n\n\t\tvector<int> v(0);\n\t\t_ASSERT(test_attr(\"1\", r, v) && at_c<0>(v) == 1);\n\t}\n\n\t{ // attribute compatibility test\n\t\tusing boost::spirit::x3::rule;\n\t\tusing boost::spirit::x3::int_;\n\n\t\tauto const expr = int_;\n\n\t\tlong long i;\n\t\t_ASSERT(test_attr(\"1\", expr, i) && i == 1); // ok\n\n\t\tconst rule< class int_rule, int > int_rule( \"int_rule\" );\n\t\tauto const int_rule_def = int_;\n\t\tauto const start  = int_rule = int_rule_def;\n\n\t\tlong long j;\n\t\t_ASSERT(test_attr(\"1\", start, j) && j == 1); // error\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule_separate_tu.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"test.hpp\"\n#include \"rule_separate_tu_grammar.hpp\"\n\nnamespace sem_act {\n\nnamespace x3 = boost::spirit::x3;\n\nauto nop = [](auto const&){};\n\nx3::rule<class used_attr1_r, int> used_attr1;\nauto const used_attr1_def = used_attr::grammar[nop];\nBOOST_SPIRIT_DEFINE(used_attr1);\n\nx3::rule<class used_attr2_r, int> used_attr2;\nauto const used_attr2_def = unused_attr::grammar[nop];\nBOOST_SPIRIT_DEFINE(used_attr2);\n\nx3::rule<class unused_attr1_r> unused_attr1;\nauto const unused_attr1_def = used_attr::grammar[nop];\nBOOST_SPIRIT_DEFINE(unused_attr1);\n\nx3::rule<class unused_attr2_r> unused_attr2;\nauto const unused_attr2_def = unused_attr::grammar[nop];\nBOOST_SPIRIT_DEFINE(unused_attr2);\n\n}\n\nUNITTESTDEF(x3_test_rule_separate_tu)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\t{\n\t\t_ASSERT(test(\"*\", unused_attr::skipper));\n\t\t_ASSERT(test(\"#\", unused_attr::skipper2));\n\t\t_ASSERT(test(\"==\", unused_attr::grammar));\n\t\t_ASSERT(test(\"*=*=\", unused_attr::grammar, unused_attr::skipper));\n\t\t_ASSERT(test(\"#=#=\", unused_attr::grammar, unused_attr::skipper2));\n\t}\n\n\t{\n\t\tlong i;\n\t\tstatic_assert(!std::is_same<decltype(i), used_attr::grammar_type::attribute_type>::value,\n\t\t\t\"ensure we have instantiated the rule with a different attribute type\");\n\t\t_ASSERT(test_attr(\"123\", used_attr::grammar, i));\n\t\t_ASSERTEQUAL(i, 123);\n\t\t_ASSERT(test_attr(\" 42\", used_attr::grammar, i, used_attr::skipper));\n\t\t_ASSERTEQUAL(i, 42);\n\t}\n\n\t{\n\t\tlong i;\n\t\t_ASSERT(test_attr(\"123\", sem_act::used_attr1, i));\n\t\t_ASSERT(test_attr(\"===\", sem_act::used_attr2, i));\n\t\t_ASSERT(test(\"123\", sem_act::unused_attr1));\n\t\t_ASSERT(test(\"===\", sem_act::unused_attr2));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule_separate_tu_grammar.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"../x3.hpp\"\n\n// Check that `BOOST_SPIRIT_INSTANTIATE` instantiates `parse_rule` with proper\n// types when a rule has no attribute.\n\nnamespace unused_attr {\n\nnamespace x3 = boost::spirit::x3;\n\n// skipper must has no attribute, checks `parse` and `skip_over`\nusing skipper_type = x3::rule<class skipper_r>;\nconst skipper_type skipper;\nBOOST_SPIRIT_DECLARE(skipper_type)\n\n// the `unused_type const` must have the same effect as no attribute\nusing skipper2_type = x3::rule<class skipper2_r, x3::unused_type const>;\nconst skipper2_type skipper2;\nBOOST_SPIRIT_DECLARE(skipper2_type)\n\n// grammar must has no attribute, checks `parse` and `phrase_parse`\nusing grammar_type = x3::rule<class grammar_r>;\nconst grammar_type grammar;\nBOOST_SPIRIT_DECLARE(grammar_type)\n\n}\n\n// Check instantiation when rule has an attribute.\n\nnamespace used_attr {\n\nnamespace x3 = boost::spirit::x3;\n\nusing skipper_type = x3::rule<class skipper_r>;\nconst skipper_type skipper;\nBOOST_SPIRIT_DECLARE(skipper_type)\n\nusing grammar_type = x3::rule<class grammar_r, int, true>;\nconst grammar_type grammar;\nBOOST_SPIRIT_DECLARE(grammar_type)\n\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/rule_separate_tu_grammar.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"../../../base/assert_defs.h\"\n#include \"rule_separate_tu_grammar.hpp\"\n\n#include \"../x3.hpp\"\n\nnamespace unused_attr {\n\nconst auto skipper_def = x3::lit('*');\nBOOST_SPIRIT_DEFINE(skipper)\nBOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\n\nconst auto skipper2_def = x3::lit('#');\nBOOST_SPIRIT_DEFINE(skipper2)\nBOOST_SPIRIT_INSTANTIATE(skipper2_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\n\nconst auto grammar_def = *x3::lit('=');\nBOOST_SPIRIT_DEFINE(grammar)\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(x3::phrase_parse_context<char const*, skipper_type>::type))\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(x3::phrase_parse_context<char const*, skipper2_type>::type))\n\n}\n\nnamespace used_attr {\n\nconst auto skipper_def = x3::space;\nBOOST_SPIRIT_DEFINE(skipper)\nBOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\n\nconst auto grammar_def = x3::int_;\nBOOST_SPIRIT_DEFINE(grammar)\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(\n\tx3::context<\n\t\tx3::expectation_failure_tag,\n\t\tstd::optional<x3::expectation_failure<char const*>>,\n\t\tx3::unused_type\n\t>\n))\nBOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, TC_FWD(x3::phrase_parse_context<char const*, skipper_type>::type))\n\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/seek.t.cpp",
    "content": "/*//////////////////////////////////////////////////////////////////////////////\n\tCopyright (c) 2011 Jamboree\n\tCopyright (c) 2014 Lee Clagett\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//////////////////////////////////////////////////////////////////////////////*/\n\n#include \"test.hpp\"\n#include \"../x3/auxiliary/eoi.hpp\"\n#include \"../x3/core.hpp\"\n#include \"../x3/char.hpp\"\n#include \"../x3/string.hpp\"\n#include \"../x3/numeric.hpp\"\n#include \"../x3/operator/plus.hpp\"\n#include \"../x3/operator/sequence.hpp\"\n#include \"../x3/directive/seek.hpp\"\n#include <vector>\n\n///////////////////////////////////////////////////////////////////////////////\nUNITTESTDEF(x3_test_seek)\n{\n\tusing namespace spirit_test;\n\tnamespace x3 = boost::spirit::x3;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::seek[lit('x')]);\n\n\t// test eoi\n\t{\n\t\t_ASSERT(test(\"\", x3::seek[x3::eoi]));\n\t\t_ASSERT(test(\" \", x3::seek[x3::eoi], x3::space));\n\t\t_ASSERT(test(\"a\", x3::seek[x3::eoi]));\n\t\t_ASSERT(test(\" a\", x3::seek[x3::eoi], x3::space));\n\t}\n\n\t// test literal finding\n\t{\n\t\tint i = 0;\n\n\t\t_ASSERT(\n\t\t\ttest_attr(\"!@#$%^&*KEY:123\", x3::seek[lit(\"KEY:\")] >> x3::int_, i)\n\t\t\t&& i == 123\n\t\t);\n\t}\n\t// test sequence finding\n\t{\n\t\tint i = 0;\n\n\t\t_ASSERT(\n\t\t\ttest_attr(\"!@#$%^&* KEY : 123\", x3::seek[x3::lit(\"KEY\") >> lit(':')] >> x3::int_, i, x3::space)\n\t\t\t&& i == 123\n\t\t);\n\t}\n\n\t// test attr finding\n\t{\n\t\tstd::vector<int> v;\n\n\t\t_ASSERT( // expect partial match\n\t\t\ttest_attr(\"a06b78c3d\", +x3::seek[x3::int_], v, false)\n\t\t\t&& v.size() == 3 && v[0] == 6 && v[1] == 78 && v[2] == 3\n\t\t);\n\t}\n\n\t// test action\n\t{\n\n\t   bool b = false;\n\t   auto const action = [&b]() { b = true; };\n\n\t   _ASSERT( // expect partial match\n\t\t   test(\"abcdefg\", x3::seek[lit(\"def\")][action], false)\n\t\t   && b\n\t   );\n\t}\n\n\t// test container\n\t{\n\t\tstd::vector<int> v;\n\n\t\t_ASSERT(\n\t\t\ttest_attr(\"abcInt:100Int:95Int:44\", x3::seek[+(lit(\"Int:\") >> x3::int_)], v)\n\t\t\t&& v.size() == 3 && v[0] == 100 && v[1] == 95 && v[2] == 44\n\t\t);\n\t}\n\n\t// test failure rollback\n\t{\n\t\t_ASSERT(test_failure(\"abcdefg\", x3::seek[x3::int_]));\n\t}\n\n\t// past the end regression GH#658\n\t_ASSERT(!test(\" \", x3::seek[lit('x')], x3::space));\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/sequence.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"utils.hpp\"\n#include \"../x3.hpp\"\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/deque.hpp>\n#include <boost/fusion/include/at.hpp>\n#include <boost/fusion/include/comparison.hpp>\n#include <string>\n#include <iostream>\n\nUNITTESTDEF(x3_test_sequence)\n{\n\tusing boost::spirit::x3::unused_type;\n\n\tusing boost::spirit::x3::char_;\n\tusing boost::spirit::x3::space;\n\tusing boost::spirit::x3::string;\n\tusing boost::spirit::x3::attr;\n\tusing boost::spirit::x3::omit;\n\tusing boost::spirit::x3::lit;\n\tusing boost::spirit::x3::unused;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::float_;\n\tusing boost::spirit::x3::no_case;\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::alnum;\n\n\tusing boost::spirit::x3::traits::attribute_of;\n\n\tusing boost::fusion::vector;\n\tusing boost::fusion::deque;\n\tusing boost::fusion::at_c;\n\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ >> char_);\n\n\t{\n\t\t_ASSERT((test(\"aa\", char_ >> char_)));\n\t\t_ASSERT((test(\"aa\", char_ >> lit('a'))));\n\t\t_ASSERT((test(\"aaa\", char_ >> char_ >> char_('a'))));\n\t\t_ASSERT((test(\"xi\", char_('x') >> char_('i'))));\n\t\t_ASSERT((!test(\"xi\", char_('x') >> char_('o'))));\n\t\t_ASSERT((test(\"xin\", char_('x') >> char_('i') >> char_('n'))));\n\t}\n\n#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK\n\t{\n\t\t// Compile check only\n\t\tstruct x {};\n\t\tchar_ >> x(); // this should give a reasonable error message\n\t}\n#endif\n\n\t{\n\t\t_ASSERT((test(\" a a\", char_ >> char_, space)));\n\t\t_ASSERT((test(\" x i\", char_('x') >> char_('i'), space)));\n\t\t_ASSERT((!test(\" x i\", char_('x') >> char_('o'), space)));\n\t}\n\n\n\t{\n\t\t_ASSERT((test(\" Hello, World\", lit(\"Hello\") >> lit(',') >> lit(\"World\"), space)));\n\t}\n\n\n\t{\n\t\tvector<char, char> attr_;\n\t\t_ASSERT((test_attr(\"ab\", char_ >> char_, attr_)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t\t_ASSERT((at_c<1>(attr_) == 'b'));\n\t}\n\n#ifdef BOOST_SPIRIT_COMPILE_ERROR_CHECK\n\t{\n\t\t// Compile check only\n\t\tvector<char, char> attr_;\n\n\t\t// error: attr does not have enough elements\n\t\ttest_attr(\"abc\", char_ >> char_ >> char_, attr_);\n\t}\n#endif\n\n\t{\n\t\tvector<char, char, char> attr_;\n\t\t_ASSERT((test_attr(\" a\\n  b\\n  c\", char_ >> char_ >> char_, attr_, space)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t\t_ASSERT((at_c<1>(attr_) == 'b'));\n\t\t_ASSERT((at_c<2>(attr_) == 'c'));\n\t}\n\n\t{\n\t\t// 'b' has an unused_type. unused attributes are not part of the sequence\n\t\tvector<char, char> attr_;\n\t\t_ASSERT((test_attr(\"abc\", char_ >> lit('b') >> char_, attr_)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t\t_ASSERT((at_c<1>(attr_) == 'c'));\n\t}\n\n\t{\n\t\t// 'b' has an unused_type. unused attributes are not part of the sequence\n\t\tvector<char, char> attr_;\n\t\t_ASSERT((test_attr(\"acb\", char_ >> char_ >> lit('b'), attr_)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t\t_ASSERT((at_c<1>(attr_) == 'c'));\n\t}\n\n\t{\n\t\t// \"hello\" has an unused_type. unused attributes are not part of the sequence\n\t\tvector<char, char> attr_;\n\t\t_ASSERT((test_attr(\"a hello c\", char_ >> lit(\"hello\") >> char_, attr_, space)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t\t_ASSERT((at_c<1>(attr_) == 'c'));\n\t}\n\n\t{\n\t\t// a single element\n\t\tchar attr_=0;\n\t\t_ASSERT((test_attr(\"ab\", char_ >> lit('b'), attr_)));\n\t\t_ASSERT((attr_ == 'a'));\n\t}\n\n\t{\n\t\t// a single element fusion sequence\n\t\tvector<char> attr_;\n\t\t_ASSERT((test_attr(\"ab\", char_ >> lit('b'), attr_)));\n\t\t_ASSERT((at_c<0>(attr_) == 'a'));\n\t}\n\n\t{\n\t\t// make sure single element tuples get passed through if the rhs\n\t\t// has a single element tuple as its attribute. Edit JDG 2014:\n\t\t// actually he issue here is that if the rhs in this case a rule\n\t\t// (r), it should get it (i.e. the sequence parser should not\n\t\t// unwrap it). It's odd that the RHS (r) does not really have a\n\t\t// single element tuple (it's a deque<char, int>), so the original\n\t\t// comment is not accurate.\n\n\t\ttypedef deque<char, int> attr_type;\n\t\tattr_type fv;\n\n\t\tauto r = rule<class r_id, attr_type>()\n\t\t\t= char_ >> lit(',') >> int_;\n\n\t\t_ASSERT((test_attr(\"test:x,1\", lit(\"test:\") >> r, fv) &&\n\t\t\tfv == attr_type('x', 1)));\n\t}\n\n\t{\n\t\t// make sure single element tuples get passed through if the rhs\n\t\t// has a single element tuple as its attribute. This is a correction\n\t\t// of the test above.\n\n\t\ttypedef deque<int> attr_type;\n\t\tattr_type fv;\n\n\t\tauto r = rule<class r_id, attr_type>()\n\t\t\t= int_;\n\n\t\t_ASSERT((test_attr(\"test:1\", lit(\"test:\") >> r, fv) &&\n\t\t\tfv == attr_type(1)));\n\t}\n\n\t{\n\t\t// unused means we don't care about the attribute\n\t\t_ASSERT((test_attr(\"abc\", char_ >> lit('b') >> char_, unused)));\n\t}\n\n\t{\n\t\t_ASSERT((test(\"aA\", no_case[char_('a') >> lit('a')])));\n\t\t_ASSERT((test(\"BEGIN END\", no_case[lit(\"begin\") >> lit(\"end\")], space)));\n\t\t_ASSERT((!test(\"BEGIN END\", no_case[lit(\"begin\") >> lit(\"nend\")], space)));\n\t}\n\n\t{ // check attribute is passed through unary to another sequence\n\t\tusing boost::spirit::x3::eps;\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"ab\", eps >> no_case[char_ >> char_], s));\n\t\t_ASSERT(\"ab\" == s);\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"ab\", no_case[char_ >> char_] >> eps, s));\n\t\t_ASSERT(\"ab\" == s);\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"abc\", char_ >> no_case[char_ >> char_], s));\n\t\t_ASSERT(\"abc\" == s);\n\t\ts.clear();\n\t\t_ASSERT(test_attr(\"abc\", no_case[char_ >> char_] >> char_, s));\n\t\t_ASSERT(\"abc\" == s);\n\t}\n\n\t{\n#ifdef SPIRIT_NO_COMPILE_CHECK\n\t\tchar_ >> char_ = char_ >> char_; // disallow this!\n#endif\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"abc\", char_ >> char_ >> char_, v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"a,b,c\", char_ >> *(lit(',') >> char_), v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"abc\", char_ >> *char_, v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\t\t//~ using boost::spirit::x3::hold;\n\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"abc\", char_ >> *(char_ >> char_), v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\n\t\tv.clear();\n\t\t_ASSERT(!test_attr(\"abcd\", char_ >> *(char_ >> char_), v));\n\n\t\t// $$$ hold not yet implemented $$$\n\t\t//~ v.clear();\n\t\t//~ _ASSERT(test_attr(\"abcdef\", char_ >> *hold[char_ >> char_] >> char_, v));\n\t\t//~ _ASSERT(v.size() == 6);\n\t\t//~ _ASSERT(v[0] == 'a');\n\t\t//~ _ASSERT(v[1] == 'b');\n\t\t//~ _ASSERT(v[2] == 'c');\n\t\t//~ _ASSERT(v[3] == 'd');\n\t\t//~ _ASSERT(v[4] == 'e');\n\t\t//~ _ASSERT(v[5] == 'f');\n\n\t\tv.clear();\n\t\t_ASSERT(test_attr(\"abc\", char_ >> +(char_ >> char_), v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"abc\", char_ >> -(+char_), v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t\t_ASSERT(v[2] == 'c');\n\t}\n\n\t{ // alternative forms of attributes. Allow sequences to take in\n\t  // stl containers.\n\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"foobar\", string(\"foo\") >> string(\"bar\"), s));\n\t\t_ASSERT(s == \"foobar\");\n\n\t\ts.clear();\n\n\t\t// $$$ hold not yet implemented $$$\n\t\t//~ using boost::spirit::x3::hold;\n\n\t\t\t\t//~ rule<char const*, std::string()> word = +char_(\"abc\");\n\t\t\t\t//~ _ASSERT(test_attr(\"ab.bc.ca\", *hold[word >> string(\".\")] >> word, s));\n\t\t\t\t//~ _ASSERT(s == \"ab.bc.ca\");\n\t}\n\n\t// Make sure get_sequence_types works for sequences of sequences.\n\t{\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\" a b\", (lit(' ') >> char_) >> (lit(' ') >> char_), v));\n\t\t_ASSERT(v.size() == 2);\n\t\t_ASSERT(v[0] == 'a');\n\t\t_ASSERT(v[1] == 'b');\n\t}\n\n\t// alternative forms of attributes. Allow sequences to take in\n\t// stl containers of stl containers.\n\t{\n\t\tstd::vector<std::string> v;\n\t\t_ASSERT(test_attr(\"abc1,abc2\",\n\t\t\t*~char_(',') >> *(lit(',') >> *~char_(',')), v));\n\t\t_ASSERT(v.size() == 2 && v[0] == \"abc1\" && v[1] == \"abc2\");\n\t}\n\n\t{\n\t\tstd::vector<std::string> v;\n\n\t\tauto e = rule<class e_id, std::string>()\n\t\t\t= *~char_(',');\n\n\t\tauto l = rule<class l_id, std::vector<std::string>>()\n\t\t\t= e >> *(lit(',') >> e);\n\n\t\t_ASSERT(test_attr(\"abc1,abc2,abc3\", l, v));\n\t\t_ASSERT(v.size() == 3);\n\t\t_ASSERT(v[0] == \"abc1\");\n\t\t_ASSERT(v[1] == \"abc2\");\n\t\t_ASSERT(v[2] == \"abc3\");\n\t}\n\n\t// do the same with a plain string object\n\t{\n\t\tstd::string s;\n\t\t_ASSERT(test_attr(\"abc1,abc2\",\n\t\t\t*~char_(',') >> *(lit(',') >> *~char_(',')), s));\n\t\t_ASSERT(s == \"abc1abc2\");\n\t}\n\n\t{\n\t\tstd::string s;\n\t\tauto e = rule<class e_id, std::string>()\n\t\t\t= *~char_(',');\n\n\t\tauto l = rule<class l_id, std::string>()\n\t\t\t= e >> *(lit(',') >> e);\n\n\t\t_ASSERT(test_attr(\"abc1,abc2,abc3\", l, s));\n\t\t_ASSERT(s == \"abc1abc2abc3\");\n\t}\n\n\t{\n\t\tstd::vector<char> v;\n\t\t_ASSERT(test_attr(\"ab\", char_ >> -char_, v));\n\t\t_ASSERT(v.size() == 2 && v[0] == 'a' && v[1] == 'b');\n\n\t\tv.clear();\n\t\t_ASSERT(test_attr(\"a\", char_ >> -char_, v));\n\t\t_ASSERT(v.size() == 1 && v[0] == 'a');\n\n\t\t// $$$ should this be allowed? I don't think so... $$$\n\t\t//~ v.clear();\n\t\t//~ _ASSERT(test_attr(\"a\", char_, v));\n\t\t//~ _ASSERT(v.size() == 1 && v[0] == 'a');\n\t}\n\n\t{\n\t\tstd::vector<std::optional<char>> v;\n\t\t_ASSERT(test_attr(\"ab\", char_ >> -char_, v));\n\t\t_ASSERT(v.size() == 2 && v[0] == 'a' && v[1] == 'b');\n\n\t\tv.clear();\n\t\t_ASSERT(test_attr(\"a\", char_ >> -char_, v));\n\t\t_ASSERT(v.size() == 2 && v[0] == 'a' && !v[1]);\n\n\t\t// $$$ should this be allowed? I don't think so... $$$\n\t\t//~ v.clear();\n\t\t//~ _ASSERT(test_attr(\"a\", char_, v));\n\t\t//~ _ASSERT(v.size() == 1 && v[0] == 'a');\n\t}\n\n\t// test from spirit mailing list\n\t// \"Error with container within sequence\"\n\t{\n\t\ttypedef vector<std::string> attr_type;\n\t\tattr_type vecstr;\n\n\t\tauto r = *alnum;\n\n\t\t_ASSERT(test_attr(\"abcdef\", r, vecstr));\n\t\t_ASSERT(at_c<0>(vecstr) == \"abcdef\");\n\t}\n\n\t// test from spirit mailing list (variation of above)\n\t// \"Error with container within sequence\"\n\t{\n\t\ttypedef vector<std::vector<int>> attr_type;\n\t\tattr_type vecvecn;\n\n\t\tauto r = *int_;\n\n\t\t_ASSERT(test_attr(\"123 456\", r, vecvecn, space));\n\t\t_ASSERT(at_c<0>(vecvecn).size() == 2);\n\t\t_ASSERT(at_c<0>(vecvecn)[0] == 123);\n\t\t_ASSERT(at_c<0>(vecvecn)[1] == 456);\n\t}\n\n\t{ // non-flat optional\n\t\tvector<int, std::optional<vector<int, int>>> v;\n\t\tauto const p = int_ >> -(lit(':') >> int_ >> lit('-') >> int_);\n\t\t_ASSERT(test_attr(\"1:2-3\", p, v));\n\t\t_ASSERT(at_c<1>(v));\n\t\t_ASSERTEQUAL(at_c<0>(*at_c<1>(v)), 2);\n\t}\n\n\t{ // optional with container attribute\n\t\tvector<char, std::optional<std::string>> v;\n\t\tauto const p = char_ >> -(lit(':') >> +char_);\n\t\t_ASSERT(test_attr(\"x\", p, v));\n\t\t_ASSERT(!at_c<1>(v));\n\t\tv = {};\n\t\t_ASSERT(test_attr(\"x:abc\", p, v));\n\t\t_ASSERT(at_c<1>(v));\n\t\t_ASSERT(*at_c<1>(v) == \"abc\");\n\t}\n\n\t{\n\t\tusing Attr = boost::variant<int, float>;\n\t\tAttr varnf;\n\t\tauto const term = rule<class term_id, Attr>(\"term\") = int_ | float_;\n\t\tauto const expr = rule<class expr_id, Attr>(\"expr\") = term | (lit('(') > term > lit(')'));\n\t\t_ASSERT((test_attr(\"(1)\", expr, varnf, space)));\n\t}\n\n\t// test that failing sequence leaves attribute consistent\n\t{\n\tstd::string str;\n\t//no need to use omit[], but lit() is buggy ATM\n\t_ASSERT(test_attr(\"A\\nB\\nC\", *(char_ >> omit[lit(\"\\n\")]), str, false));\n\t_ASSERT(str == \"AB\");\n\t}\n\n\t// test that sequence with only one parser producing attribute\n\t// makes it unwrapped\n\t{\n\t_ASSERT((boost::is_same<\n\t\t    typename attribute_of<decltype(lit(\"abc\") >> attr(long())), unused_type>::type,\n\t\t    long>() ));\n\t}\n\n\t{   // test action\n\t\tusing boost::fusion::at_c;\n\n\t\tchar c = 0;\n\t\tint n = 0;\n\t\tauto f = [&](auto& ctx)\n\t\t\t{\n\t\t\t\tc = at_c<0>(_attr(ctx));\n\t\t\t\tn = at_c<1>(_attr(ctx));\n\t\t\t};\n\n\t\t_ASSERT(test(\"x123\\\"a string\\\"\", (char_ >> int_ >> lit(\"\\\"a string\\\"\"))[f]));\n\t\t_ASSERT(c == 'x');\n\t\t_ASSERT(n == 123);\n\t}\n\n\t{   // test action\n\t\tchar c = 0;\n\t\tint n = 0;\n\t\tauto f = [&](auto& ctx)\n\t\t\t{\n\t\t\t\tc = at_c<0>(_attr(ctx));\n\t\t\t\tn = at_c<1>(_attr(ctx));\n\t\t\t};\n\n\t\t_ASSERT(test(\"x 123 \\\"a string\\\"\", (char_ >> int_ >> lit(\"\\\"a string\\\"\"))[f], space));\n\t\t_ASSERT(c == 'x');\n\t\t_ASSERT(n == 123);\n\t}\n\n\t{\n#ifdef SPIRIT_NO_COMPILE_CHECK\n\t\tchar const* const s = \"\";\n\t\tint i;\n\t\tparse(s, s, int_ >> int_, i);\n#endif\n\t}\n\n\t{ // test move only types\n\t\tusing boost::spirit::x3::eps;\n\t\tstd::vector<move_only> v;\n\t\t_ASSERT(test_attr(\"ssszs\", *synth_move_only >> lit('z') >> synth_move_only, v));\n\t\t_ASSERTEQUAL(v.size(), 4);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/skip.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\nUNITTESTDEF(x3_test_skip)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::ascii::space;\n\tusing boost::spirit::x3::ascii::space_type;\n\tusing boost::spirit::x3::ascii::char_;\n\tusing boost::spirit::x3::ascii::alpha;\n\tusing boost::spirit::x3::lexeme;\n\tusing boost::spirit::x3::skip;\n\tusing boost::spirit::x3::lit;\n\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(skip('x')[lit('y')]);\n\n\t{\n\t\t_ASSERT((test(\"a b c d\", skip(space)[*char_])));\n\t}\n\n\t{ // test attribute\n\t\tstd::string s;\n\t\t_ASSERT((test_attr(\"a b c d\", skip(space)[*char_], s)));\n\t\t_ASSERT(s == \"abcd\");\n\t}\n\n\t{ // reskip\n\t\t_ASSERT((test(\"ab c d\", lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]], space)));\n\t\t_ASSERT((test(\"abcd\", lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]], space)));\n\t\t_ASSERT(!(test(\"a bcd\", lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]], space)));\n\n\t\t_ASSERT((test(\"ab c d\", lexeme[lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]]], space)));\n\t\t_ASSERT((test(\"abcd\", lexeme[lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]]], space)));\n\t\t_ASSERT(!(test(\"a bcd\", lexeme[lexeme[lit('a') >> lit('b') >> skip[lit('c') >> lit('d')]]], space)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/symbols1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\n// Custom string type with a C-style string conversion.\nstruct custom_string_c\n{\n\tcustom_string_c(char c) { str[0] = c; str[1] = '\\0'; }\n\n\toperator char*() { return str; }\n\toperator char const*() const { return str; }\n\nprivate:\n\tchar str[2];\n};\n\nUNITTESTDEF(x3_test_symbols1)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::symbols;\n\tusing boost::spirit::x3::no_case;\n\tusing boost::spirit::x3::lit;\n\n\t{ // basics\n\t\tsymbols<int> sym;\n\n\t\tsym.add\n\t\t\t(\"Joel\")\n\t\t\t(\"Ruby\")\n\t\t\t(\"Tenji\")\n\t\t\t(\"Tutit\")\n\t\t\t(\"Kim\")\n\t\t\t(\"Joey\")\n\t\t\t(\"Joeyboy\")\n\t\t;\n\n\t\t_ASSERT((test(\"Joel\", sym)));\n\t\t_ASSERT((test(\"Ruby\", sym)));\n\t\t_ASSERT((test(\"Tenji\", sym)));\n\t\t_ASSERT((test(\"Tutit\", sym)));\n\t\t_ASSERT((test(\"Kim\", sym)));\n\t\t_ASSERT((test(\"Joey\", sym)));\n\t\t_ASSERT((test(\"Joeyboy\", sym)));\n\t\t_ASSERT((!test(\"XXX\", sym)));\n\n\t\t// test copy\n\t\tsymbols<int> sym2;\n\t\tsym2 = sym;\n\t\t_ASSERT((test(\"Joel\", sym2)));\n\t\t_ASSERT((test(\"Ruby\", sym2)));\n\t\t_ASSERT((test(\"Tenji\", sym2)));\n\t\t_ASSERT((test(\"Tutit\", sym2)));\n\t\t_ASSERT((test(\"Kim\", sym2)));\n\t\t_ASSERT((test(\"Joey\", sym2)));\n\t\t_ASSERT((!test(\"XXX\", sym2)));\n\n\t\t// make sure it plays well with other parsers\n\t\t_ASSERT((test(\"Joelyo\", sym >> lit(\"yo\"))));\n\n\t\tsym.remove\n\t\t\t(\"Joel\")\n\t\t\t(\"Ruby\")\n\t\t;\n\n\t\t_ASSERT((!test(\"Joel\", sym)));\n\t\t_ASSERT((!test(\"Ruby\", sym)));\n\t}\n\n\t{ // comma syntax\n\t\tsymbols<int> sym;\n\t\tsym += \"Joel\", \"Ruby\", \"Tenji\", \"Tutit\", \"Kim\", \"Joey\";\n\n\t\t_ASSERT((test(\"Joel\", sym)));\n\t\t_ASSERT((test(\"Ruby\", sym)));\n\t\t_ASSERT((test(\"Tenji\", sym)));\n\t\t_ASSERT((test(\"Tutit\", sym)));\n\t\t_ASSERT((test(\"Kim\", sym)));\n\t\t_ASSERT((test(\"Joey\", sym)));\n\t\t_ASSERT((!test(\"XXX\", sym)));\n\n\t\tsym -= \"Joel\", \"Ruby\";\n\n\t\t_ASSERT((!test(\"Joel\", sym)));\n\t\t_ASSERT((!test(\"Ruby\", sym)));\n\t}\n\n\t{ // no-case handling\n\t\tusing namespace boost::spirit::x3::ascii;\n\n\t\tsymbols<int> sym;\n\t\t// NOTE: make sure all entries are in lower-case!!!\n\t\tsym = \"joel\", \"ruby\", \"tenji\", \"tutit\", \"kim\", \"joey\";\n\n\t\t_ASSERT((test(\"joel\", no_case[sym])));\n\t\t_ASSERT((test(\"ruby\", no_case[sym])));\n\t\t_ASSERT((test(\"tenji\", no_case[sym])));\n\t\t_ASSERT((test(\"tutit\", no_case[sym])));\n\t\t_ASSERT((test(\"kim\", no_case[sym])));\n\t\t_ASSERT((test(\"joey\", no_case[sym])));\n\n\t\t_ASSERT((test(\"JOEL\", no_case[sym])));\n\t\t_ASSERT((test(\"RUBY\", no_case[sym])));\n\t\t_ASSERT((test(\"TENJI\", no_case[sym])));\n\t\t_ASSERT((test(\"TUTIT\", no_case[sym])));\n\t\t_ASSERT((test(\"KIM\", no_case[sym])));\n\t\t_ASSERT((test(\"JOEY\", no_case[sym])));\n\n\t\t// make sure it plays well with other parsers\n\t\t_ASSERT((test(\"Joelyo\", no_case[sym] >> lit(\"yo\"))));\n\t}\n\n\t{ // attributes\n\t\tsymbols<int> sym;\n\n\t\tsym.add\n\t\t\t(\"Joel\", 1)\n\t\t\t(\"Ruby\", 2)\n\t\t\t(\"Tenji\", 3)\n\t\t\t(\"Tutit\", 4)\n\t\t\t(\"Kim\", 5)\n\t\t\t(\"Joey\", 6)\n\t\t;\n\n\t\tint i=0;\n\t\t_ASSERT((test_attr(\"Joel\", sym, i)));\n\t\t_ASSERT(i == 1);\n\t\t_ASSERT((test_attr(\"Ruby\", sym, i)));\n\t\t_ASSERT(i == 2);\n\t\t_ASSERT((test_attr(\"Tenji\", sym, i)));\n\t\t_ASSERT(i == 3);\n\t\t_ASSERT((test_attr(\"Tutit\", sym, i)));\n\t\t_ASSERT(i == 4);\n\t\t_ASSERT((test_attr(\"Kim\", sym, i)));\n\t\t_ASSERT(i == 5);\n\t\t_ASSERT((test_attr(\"Joey\", sym, i)));\n\t\t_ASSERT(i == 6);\n\t\t_ASSERT((!test_attr(\"XXX\", sym, i)));\n\n\t\t// double add:\n\n\t\tsym.add(\"Joel\", 265);\n\t\t_ASSERT((test_attr(\"Joel\", sym, i)));\n\t\t_ASSERT(i == 1);\n\t}\n\n\t{ // actions\n\t\tusing boost::spirit::x3::_attr;\n\n\t\tsymbols<int> sym;\n\t\tsym.add\n\t\t\t(\"Joel\", 1)\n\t\t\t(\"Ruby\", 2)\n\t\t\t(\"Tenji\", 3)\n\t\t\t(\"Tutit\", 4)\n\t\t\t(\"Kim\", 5)\n\t\t\t(\"Joey\", 6)\n\t\t;\n\n\t\tint i;\n\t\tauto f = [&](auto& ctx){ i = _attr(ctx); };\n\n\t\t_ASSERT((test(\"Joel\", sym[f])));\n\t\t_ASSERT(i == 1);\n\t\t_ASSERT((test(\"Ruby\", sym[f])));\n\t\t_ASSERT(i == 2);\n\t\t_ASSERT((test(\"Tenji\", sym[f])));\n\t\t_ASSERT(i == 3);\n\t\t_ASSERT((test(\"Tutit\", sym[f])));\n\t\t_ASSERT(i == 4);\n\t\t_ASSERT((test(\"Kim\", sym[f])));\n\t\t_ASSERT(i == 5);\n\t\t_ASSERT((test(\"Joey\", sym[f])));\n\t\t_ASSERT(i == 6);\n\t\t_ASSERT((!test(\"XXX\", sym[f])));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/symbols2.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <iostream>\n\n// Custom string type with a C-style string conversion.\nstruct custom_string_c\n{\n\tcustom_string_c(char c) { str[0] = c; str[1] = '\\0'; }\n\n\toperator char*() { return str; }\n\toperator char const*() const { return str; }\n\nprivate:\n\tchar str[2];\n};\n\nstd::string get_str(char const* str)\n{\n\treturn std::string(str);\n}\n\nUNITTESTDEF(x3_test_symbols2)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::symbols;\n\tusing boost::spirit::x3::rule;\n\n\t{ // construction from symbol array\n\t\tchar const* syms[] = {\"Joel\",\"Ruby\",\"Tenji\",\"Tutit\",\"Kim\",\"Joey\"};\n\t\tsymbols<int> sym(syms);\n\n\t\t_ASSERT((test(\"Joel\", sym)));\n\t\t_ASSERT((test(\"Ruby\", sym)));\n\t\t_ASSERT((test(\"Tenji\", sym)));\n\t\t_ASSERT((test(\"Tutit\", sym)));\n\t\t_ASSERT((test(\"Kim\", sym)));\n\t\t_ASSERT((test(\"Joey\", sym)));\n\t\t_ASSERT((!test(\"XXX\", sym)));\n\t}\n\n\t{ // construction from 2 arrays\n\n\t\tchar const* syms[] = {\"Joel\",\"Ruby\",\"Tenji\",\"Tutit\",\"Kim\",\"Joey\"};\n\t\tint data[] = {1,2,3,4,5,6};\n\t\tsymbols<int> sym(syms, data);\n\n\t\tint i=0;\n\t\t_ASSERT((test_attr(\"Joel\", sym, i)));\n\t\t_ASSERT(i == 1);\n\t\t_ASSERT((test_attr(\"Ruby\", sym, i)));\n\t\t_ASSERT(i == 2);\n\t\t_ASSERT((test_attr(\"Tenji\", sym, i)));\n\t\t_ASSERT(i == 3);\n\t\t_ASSERT((test_attr(\"Tutit\", sym, i)));\n\t\t_ASSERT(i == 4);\n\t\t_ASSERT((test_attr(\"Kim\", sym, i)));\n\t\t_ASSERT(i == 5);\n\t\t_ASSERT((test_attr(\"Joey\", sym, i)));\n\t\t_ASSERT(i == 6);\n\t\t_ASSERT((!test_attr(\"XXX\", sym, i)));\n\t}\n\n\t{ // allow std::string and other string types\n\t\tsymbols<> sym;\n\n\t\t// const and non-const std::string\n\t\tstd::string a(\"abc\");\n\t\tstd::string const b(\"def\");\n\t\tsym += a;\n\t\tsym += b;\n\t\t_ASSERT((test(\"abc\", sym)));\n\t\t_ASSERT((test(\"def\", sym)));\n\t\tsym = a;\n\t\t_ASSERT((test(\"abc\", sym)));\n\t\t_ASSERT((!test(\"def\", sym)));\n\n\t\t// non-const C-style string\n\t\tchar arr[2]; arr[0] = 'a'; arr[1] = '\\0';\n\t\tsym = arr;\n\t\t_ASSERT((test(\"a\", sym)));\n\t\t_ASSERT((!test(\"b\", sym)));\n\n\t\t// const and non-const custom string type\n\t\tcustom_string_c c('x');\n\t\tcustom_string_c const cc('y');\n\t\tsym = c, cc;\n\t\t_ASSERT((test(\"x\", sym)));\n\t\t_ASSERT((test(\"y\", sym)));\n\t\t_ASSERT((!test(\"z\", sym)));\n\t}\n\n\t{ // find\n\n\t\tsymbols<int> sym;\n\t\tsym.add(\"a\", 1)(\"b\", 2);\n\n\t\t_ASSERT(!sym.find(\"c\"));\n\n\t\t_ASSERT(sym.find(\"a\") && *sym.find(\"a\") == 1);\n\t\t_ASSERT(sym.find(\"b\") && *sym.find(\"b\") == 2);\n\n\t\t_ASSERT(sym.at(\"a\") == 1);\n\t\t_ASSERT(sym.at(\"b\") == 2);\n\t\t_ASSERT(sym.at(\"c\") == 0);\n\n\t\t_ASSERT(sym.find(\"a\") && *sym.find(\"a\") == 1);\n\t\t_ASSERT(sym.find(\"b\") && *sym.find(\"b\") == 2);\n\t\t_ASSERT(sym.find(\"c\") && *sym.find(\"c\") == 0);\n\n\t\tsymbols<int> const_sym(sym);\n\n\t\t_ASSERT(const_sym.find(\"a\") && *const_sym.find(\"a\") == 1);\n\t\t_ASSERT(const_sym.find(\"b\") && *const_sym.find(\"b\") == 2);\n\t\t_ASSERT(const_sym.find(\"c\") && *const_sym.find(\"c\") == 0);\n\t\t_ASSERT(!const_sym.find(\"d\"));\n\n\t\tchar const *str1 = \"all\";\n\t\tchar const *first = str1, *last = str1 + 3;\n\t\t_ASSERT(*sym.prefix_find(first, last) == 1 && first == str1 + 1);\n\n\t\tchar const *str2 = \"dart\";\n\t\tfirst = str2; last = str2 + 4;\n\t\t_ASSERT(!sym.prefix_find(first, last) && first == str2);\n\t}\n\n\t{ // name\n\t\tsymbols <int> sym,sym2;\n\t\tsym.name(\"test\");\n\t\t_ASSERT(sym.name()==\"test\");\n\t\tsym2 = sym;\n\t\t_ASSERT(sym2.name()==\"test\");\n\n\t\tsymbols <int> sym3(sym);\n\t\t_ASSERT(sym3.name()==\"test\");\n\t}\n\n\t{ // Substrings\n\n\t\tsymbols<int> sym;\n\t\t_ASSERT(sym.at(\"foo\") == 0);\n\t\tsym.at(\"foo\") = 1;\n\t\t_ASSERT(sym.at(\"foo\") == 1);\n\t\t_ASSERT(sym.at(\"fool\") == 0);\n\t\tsym.at(\"fool\") = 2;\n\t\t_ASSERT(sym.find(\"foo\") && *sym.find(\"foo\") == 1);\n\t\t_ASSERT(sym.find(\"fool\") && *sym.find(\"fool\") == 2);\n\t\t_ASSERT(!sym.find(\"foolish\"));\n\t\t_ASSERT(!sym.find(\"foot\"));\n\t\t_ASSERT(!sym.find(\"afoot\"));\n\n\t\tchar const *str, *first, *last;\n\t\tstr = \"foolish\"; first = str; last = str + 7;\n\t\t_ASSERT(*sym.prefix_find(first, last) == 2 && first == str + 4);\n\n\t\tfirst = str; last = str + 4;\n\t\t_ASSERT(*sym.prefix_find(first, last) == 2 && first == str + 4);\n\n\t\tstr = \"food\"; first = str; last = str + 4;\n\t\t_ASSERT(*sym.prefix_find(first, last) == 1 && first == str + 3);\n\n\t\tfirst = str; last = str + 3;\n\t\t_ASSERT(*sym.prefix_find(first, last) == 1 && first == str + 3);\n\n\t\tfirst = str; last = str + 2;\n\t\t_ASSERT(!sym.prefix_find(first, last) && first == str);\n\t}\n\n\t{\n\t\t// remove bug\n\n\t\tstd::string s;\n\t\tsymbols<double> vars;\n\n\t\tvars.add(\"l1\", 12.0);\n\t\tvars.add(\"l2\", 0.0);\n\t\tvars.remove(\"l2\");\n\t\tvars.find(\"l1\");\n\t\tdouble* d = vars.find(\"l1\");\n\t\t_ASSERT(d != 0);\n\t}\n\n\t{ // test for proto problem with rvalue references (10-11-2011)\n\t\tsymbols<int> sym;\n\t\tsym += get_str(\"Joel\");\n\t\tsym += get_str(\"Ruby\");\n\n\t\t_ASSERT((test(\"Joel\", sym)));\n\t\t_ASSERT((test(\"Ruby\", sym)));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/symbols3.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2013 Carl Barron\n\tCopyright (c) 2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#define BOOST_SPIRIT_X3_DEBUG\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../support/char_encoding/unicode.hpp\"\n#include <boost/fusion/include/at.hpp>\n#include <boost/fusion/include/vector.hpp>\n#include <boost/fusion/include/adapt_struct.hpp>\n#include <boost/mpl/int.hpp>\n#include <iostream>\n#include <numeric>\n#include <vector>\n#include <optional>\n\nstruct roman\n{\n\tstd::optional<int> a;\n\tstd::optional<int> b;\n\tstd::optional<int> c;\n};\n\nBOOST_FUSION_ADAPT_STRUCT(roman,\n\ta, b, c\n)\n\nint eval(roman const & c)\n{\n\treturn c.a.value_or(0) + c.b.value_or(0) + c.c.value_or(0);\n}\n\nUNITTESTDEF(x3_test_symbols3)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\tusing boost::spirit::x3::symbols;\n\n\t{ // construction from initializer-list\n\t\tsymbols<int> const ones =\n\t\t{\n\t\t\t{\"I\", 1}, {\"II\", 2}, {\"III\", 3}, {\"IV\", 4},\n\t\t\t{\"V\", 5}, {\"VI\", 6}, {\"VII\", 7}, {\"VIII\", 8},\n\t\t\t{\"IX\", 9}\n\t\t};\n\t\tsymbols<int> const tens =\n\t\t{\n\t\t\t{\"X\", 10}, {\"XX\", 20}, {\"XXX\", 30}, {\"XL\", 40},\n\t\t\t{\"L\", 50}, {\"LX\", 60}, {\"LXX\", 70}, {\"LXXX\", 80},\n\t\t\t{\"XC\", 90}\n\t\t};\n\t\tsymbols<int> const hundreds\n\t\t{\n\t\t\t{\"C\", 100}, {\"CC\", 200}, {\"CCC\", 300}, {\"CD\", 400},\n\t\t\t{\"D\", 500}, {\"DC\", 600}, {\"DCC\", 700}, {\"DCCC\", 800},\n\t\t\t{\"CM\", 900}\n\t\t};\n\n\t\tauto number = -hundreds >> -tens >> -ones;\n\n\t\troman r;\n\t\t_ASSERT((test_attr(\"CDXLII\", number, r)));\n\t\t_ASSERT(eval(r) == 442);\n\t}\n\n\t{ // construction from initializer-list without attribute\n\t\tsymbols<> foo = {\"a1\", \"a2\", \"a3\"};\n\n\t\t_ASSERT((test(\"a3\", foo)));\n\t}\n\n\t{ // assignment from initializer-list\n\t\tsymbols<> foo;\n\t\tfoo = {\"a1\", \"a2\", \"a3\"};\n\n\t\t_ASSERT((test(\"a3\", foo)));\n\t}\n\n\t{ // unicode | construction from initializer-list\n\t\tusing namespace boost::spirit;\n\t\tx3::symbols_parser<char_encoding::unicode, int> foo = {{U\"a1\", 1}, {U\"a2\", 2}, {U\"a3\", 3}};\n\n\t\tint r=0;\n\t\t_ASSERT((test_attr(U\"a3\", foo, r)));\n\t\t_ASSERT(r == 3);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/test.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2013 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM)\n#define BOOST_SPIRIT_TEST_FEBRUARY_01_2007_0605PM\n\n#include \"../../../base/assert_defs.h\"\n#include \"../../../unittest.h\"\n#include \"../../spirit.h\"\n#include <boost/utility/string_view.hpp>\n#include <iostream>\n\nnamespace spirit_test\n{\n\ttemplate <typename Char, typename Parser>\n\tbool test(Char const* in, Parser const& p, bool full_match = true)\n\t{\n\t\tChar const* last = in;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn boost::spirit::x3::parse(in, last, p)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser>\n\tbool test(boost::basic_string_view<Char, std::char_traits<Char>> in,\n\t\t\t  Parser const& p, bool full_match = true)\n\t{\n\t\tauto const last = in.end();\n\t\tauto pos        = in.begin();\n\n\t\treturn boost::spirit::x3::parse(pos, last, p) && (!full_match || (pos == last));\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Skipper>\n\tbool test(Char const* in, Parser const& p\n\t\t, Skipper const& s, bool full_match = true)\n\t{\n\t\tChar const* last = in;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn boost::spirit::x3::phrase_parse(in, last, p, s)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser>\n\tbool test_failure(Char const* in, Parser const& p)\n\t{\n\t\tChar const * const start = in;\n\t\tChar const* last = in;\n\t\twhile (*last)\n\t\t\tlast++;\n\n\t\treturn !boost::spirit::x3::parse(in, last, p) && (in == start);\n\t}\n\n\ttemplate <typename Char, typename Parser>\n\tbool test_failure(boost::basic_string_view<Char, std::char_traits<Char>> const in,\n\t\t\t\t\t  Parser const& p)\n\t{\n\t\tauto pos = in.begin();\n\t\treturn !boost::spirit::x3::parse(pos, in.end(), p) && (pos == in.begin());\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Attr>\n\tbool test_attr(Char const* in, Parser const& p\n\t\t, Attr& attr, bool full_match = true)\n\t{\n\t\tChar const* last = in;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn boost::spirit::x3::parse(in, last, p, attr)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Attr, typename Skipper>\n\tbool test_attr(Char const* in, Parser const& p\n\t\t, Attr& attr, Skipper const& s, bool full_match = true)\n\t{\n\t\tChar const* last = in;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn boost::spirit::x3::phrase_parse(in, last, p, s, attr)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser>\n\tbool binary_test(Char const* in, std::size_t size, Parser const& p,\n\t\tbool full_match = true)\n\t{\n\t\tChar const* last = in + size;\n\t\treturn boost::spirit::x3::parse(in, last, p)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Skipper>\n\tbool binary_test(Char const* in, std::size_t size, Parser const& p,\n\t\tSkipper const& s, bool full_match = true)\n\t{\n\t\tChar const* last = in + size;\n\t\treturn boost::spirit::x3::phrase_parse(in, last, p, s)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Attr>\n\tbool binary_test_attr(Char const* in, std::size_t size, Parser const& p,\n\t\tAttr& attr, bool full_match = true)\n\t{\n\t\tChar const* last = in + size;\n\t\treturn boost::spirit::x3::parse(in, last, p, attr)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\ttemplate <typename Char, typename Parser, typename Attr, typename Skipper>\n\tbool binary_test_attr(Char const* in, std::size_t size, Parser const& p,\n\t\tAttr& attr, Skipper const& s, bool full_match = true)\n\t{\n\t\tChar const* last = in + size;\n\t\treturn boost::spirit::x3::phrase_parse(in, last, p, s, attr)\n\t\t\t&& (!full_match || (in == last));\n\t}\n\n\n\ttemplate <typename... T>\n\tconstexpr bool always_true(T&&...) { return true; }\n\n\ttemplate <typename Parser>\n\tconstexpr bool test_ctors(Parser const& p)\n\t{\n\t\treturn always_true(\n\t\t\t\t   static_cast<Parser>(static_cast<Parser&&>(  // test move ctor\n\t\t\t\t\t   static_cast<Parser>(p))));              // test copy ctor\n\t}\n}\n\n# define BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(...) \\\n\tstatic_assert(::spirit_test::test_ctors(__VA_ARGS__), \"\")\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/to_utf8.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2018-2023 Nikita Kniazev\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3/support/utility/utf8.hpp\"\n#include <string>\n\nstatic bool nowarn_constexpr(bool x) { return x; }\n\nUNITTESTDEF(x3_test_to_utf8)\n{\n\tusing boost::spirit::x3::to_utf8;\n\tusing namespace std::string_literals;\n\n\t_ASSERT(tc::equal(\"\\xED\\x9F\\xBF\", to_utf8(0xD7FFul).c_str()));\n\t_ASSERT(tc::equal(\"\\xEE\\x80\\x80\", to_utf8(0xE000ul).c_str()));\n\n\tif (nowarn_constexpr(sizeof(L\"\\u00FF\") == 2))\n\t\t_ASSERT(tc::equal(\"\\xC3\\xBF\", to_utf8(L\"\\u00FF\"[0]).c_str()));\n\t_ASSERT(tc::equal(\"\\xC3\\xBF\", to_utf8(U'\\u00FF').c_str()));\n\tif (nowarn_constexpr(sizeof(L\"\\uFFE1\") == 2))\n\t\t_ASSERT(tc::equal(\"\\xEF\\xBF\\xA1\", to_utf8(L\"\\uFFE1\"[0]).c_str()));\n\t_ASSERT(tc::equal(\"\\xEF\\xBF\\xA1\", to_utf8(U'\\uFFE1').c_str()));\n\tif (nowarn_constexpr(sizeof(L\"\\U0001F9D0\") == 2))\n\t\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\", to_utf8(L\"\\U0001F9D0\"[0]).c_str()));\n\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\", to_utf8(U'\\U0001F9D0').c_str()));\n\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\\xF0\\x9F\\xA7\\xA0\", to_utf8(L\"\\U0001F9D0\\U0001F9E0\").c_str()));\n\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\\xF0\\x9F\\xA7\\xA0\", to_utf8(U\"\\U0001F9D0\\U0001F9E0\").c_str()));\n\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\\xF0\\x9F\\xA7\\xA0\", to_utf8(L\"\\U0001F9D0\\U0001F9E0\"s).c_str()));\n\t_ASSERT(tc::equal(\"\\xF0\\x9F\\xA7\\x90\\xF0\\x9F\\xA7\\xA0\", to_utf8(U\"\\U0001F9D0\\U0001F9E0\"s).c_str()));\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/tst.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3/string/tst.hpp\"\n#include \"../x3/string/tst_map.hpp\"\n#include \"../x3/support/no_case.hpp\"\n#include \"../support/char_encoding/standard.hpp\"\n#include \"../support/char_encoding/standard_wide.hpp\"\n\n#include <string>\n#include <cctype>\n#include <iostream>\n\nnamespace\n{\n\ttemplate <typename TST, typename Char>\n\tvoid add(TST& tst, Char const* s, int data)\n\t{\n\t\tChar const* last = s;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\ttst.add(s, last, data);\n\t}\n\n\ttemplate <typename TST, typename Char>\n\tvoid remove(TST& tst, Char const* s)\n\t{\n\t\tChar const* last = s;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\ttst.remove(s, last);\n\t}\n\n\ttemplate <typename TST, typename Char, typename CaseCompare>\n\tvoid docheck(TST const& tst, CaseCompare const& comp, Char const* s, bool expected, int N = 0, int val = -1)\n\t{\n\t\tChar const* first = s;\n\t\tChar const* last = s;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\tint* r = tst.find(s, last,comp);\n\t\t_ASSERT((r != 0) == expected);\n\t\tif (r != 0)\n\t\t\t_ASSERT((s-first) == N);\n\t\tif (r)\n\t\t\t_ASSERT(*r == val);\n\t}\n\n\tstruct printer\n\t{\n\t\ttemplate <typename String, typename Data>\n\t\tvoid operator()(String const& s, Data const& data)\n\t\t{\n\t\t\tstd::cout << \"    \" << s << \": \" << data << std::endl;\n\t\t}\n\t};\n\n\ttemplate <typename TST>\n\tvoid print(TST const& tst)\n\t{\n\t\tstd::cout << '[' << std::endl;\n\t\ttst.for_each(printer());\n\t\tstd::cout << ']' << std::endl;\n\t}\n\n}\n\nboost::spirit::x3::case_compare<boost::spirit::char_encoding::standard> ncomp;\nboost::spirit::x3::case_compare<boost::spirit::char_encoding::standard_wide> wcomp;\nboost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard> nc_ncomp;\nboost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard_wide> nc_wcomp;\n\ntemplate <typename Lookup, typename WideLookup>\nvoid tests()\n{\n\t{ // basic tests\n\t\tLookup lookup;\n\n\t\tdocheck(lookup, ncomp, \"not-yet-there\", false);\n\t\tdocheck(lookup, ncomp, \"\", false);\n\n\t\tadd(lookup, \"apple\", 123);\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 123); // full match\n\t\tdocheck(lookup, ncomp, \"banana\", false); // no-match\n\t\tdocheck(lookup, ncomp, \"applexxx\", true, 5, 123); // partial match\n\n\t\tadd(lookup, \"applepie\", 456);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 456); // full match\n\t\tdocheck(lookup, ncomp, \"banana\", false); // no-match\n\t\tdocheck(lookup, ncomp, \"applepiexxx\", true, 8, 456); // partial match\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 123); // full match\n\t\tdocheck(lookup, ncomp, \"applexxx\", true, 5, 123); // partial match\n\t}\n\n\t{ // variation of above\n\t\tLookup lookup;\n\n\t\tadd(lookup, \"applepie\", 456);\n\t\tadd(lookup, \"apple\", 123);\n\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 456); // full match\n\t\tdocheck(lookup, ncomp, \"banana\", false); // no-match\n\t\tdocheck(lookup, ncomp, \"applepiexxx\", true, 8, 456); // partial match\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 123); // full match\n\t\tdocheck(lookup, ncomp, \"applexxx\", true, 5, 123); // partial match\n\t}\n\t{ // variation of above\n\t\tLookup lookup;\n\n\t\tadd(lookup, \"applepie\", 456);\n\t\tadd(lookup, \"apple\", 123);\n\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 456); // full match\n\t\tdocheck(lookup, ncomp, \"banana\", false); // no-match\n\t\tdocheck(lookup, ncomp, \"applepiexxx\", true, 8, 456); // partial match\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 123); // full match\n\t\tdocheck(lookup, ncomp, \"applexxx\", true, 5, 123); // partial match\n\t}\n\n\t{ // narrow char tests\n\t\tLookup lookup;\n\t\tadd(lookup, \"pineapple\", 1);\n\t\tadd(lookup, \"orange\", 2);\n\t\tadd(lookup, \"banana\", 3);\n\t\tadd(lookup, \"applepie\", 4);\n\t\tadd(lookup, \"apple\", 5);\n\n\t\tdocheck(lookup, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookup, ncomp, \"banana\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"pizza\", false);\n\t\tdocheck(lookup, ncomp, \"steak\", false);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookup, ncomp, \"bananarama\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"applet\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepi\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"appl\", false);\n\n\t\tdocheck(lookup, ncomp, \"pineapplez\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orangez\", true, 6, 2);\n\t\tdocheck(lookup, ncomp, \"bananaz\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"applez\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"pizzaz\", false);\n\t\tdocheck(lookup, ncomp, \"steakz\", false);\n\t\tdocheck(lookup, ncomp, \"applepiez\", true, 8, 4);\n\t\tdocheck(lookup, ncomp, \"bananaramaz\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"appletz\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepix\", true, 5, 5);\n\t}\n\n\t{ // wide char tests\n\t\tWideLookup lookup;\n\t\tadd(lookup, L\"pineapple\", 1);\n\t\tadd(lookup, L\"orange\", 2);\n\t\tadd(lookup, L\"banana\", 3);\n\t\tadd(lookup, L\"applepie\", 4);\n\t\tadd(lookup, L\"apple\", 5);\n\n\t\tdocheck(lookup, wcomp, L\"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, wcomp, L\"orange\", true, 6, 2);\n\t\tdocheck(lookup, wcomp, L\"banana\", true, 6, 3);\n\t\tdocheck(lookup, wcomp, L\"apple\", true, 5, 5);\n\t\tdocheck(lookup, wcomp, L\"pizza\", false);\n\t\tdocheck(lookup, wcomp, L\"steak\", false);\n\t\tdocheck(lookup, wcomp, L\"applepie\", true, 8, 4);\n\t\tdocheck(lookup, wcomp, L\"bananarama\", true, 6, 3);\n\t\tdocheck(lookup, wcomp, L\"applet\", true, 5, 5);\n\t\tdocheck(lookup, wcomp, L\"applepi\", true, 5, 5);\n\t\tdocheck(lookup, wcomp, L\"appl\", false);\n\n\t\tdocheck(lookup, wcomp, L\"pineapplez\", true, 9, 1);\n\t\tdocheck(lookup, wcomp, L\"orangez\", true, 6, 2);\n\t\tdocheck(lookup, wcomp, L\"bananaz\", true, 6, 3);\n\t\tdocheck(lookup, wcomp, L\"applez\", true, 5, 5);\n\t\tdocheck(lookup, wcomp, L\"pizzaz\", false);\n\t\tdocheck(lookup, wcomp, L\"steakz\", false);\n\t\tdocheck(lookup, wcomp, L\"applepiez\", true, 8, 4);\n\t\tdocheck(lookup, wcomp, L\"bananaramaz\", true, 6, 3);\n\t\tdocheck(lookup, wcomp, L\"appletz\", true, 5, 5);\n\t\tdocheck(lookup, wcomp, L\"applepix\", true, 5, 5);\n\t}\n\n\t{ // test remove\n\t\tLookup lookup;\n\t\tadd(lookup, \"pineapple\", 1);\n\t\tadd(lookup, \"orange\", 2);\n\t\tadd(lookup, \"banana\", 3);\n\t\tadd(lookup, \"applepie\", 4);\n\t\tadd(lookup, \"apple\", 5);\n\n\t\tdocheck(lookup, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookup, ncomp, \"banana\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookup, ncomp, \"bananarama\", true, 6, 3);\n\t\tdocheck(lookup, ncomp, \"applet\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepi\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"appl\", false);\n\n\t\tremove(lookup, \"banana\");\n\t\tdocheck(lookup, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookup, ncomp, \"banana\", false);\n\t\tdocheck(lookup, ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookup, ncomp, \"bananarama\", false);\n\t\tdocheck(lookup, ncomp, \"applet\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"applepi\", true, 5, 5);\n\t\tdocheck(lookup, ncomp, \"appl\", false);\n\n\t\tremove(lookup, \"apple\");\n\t\tdocheck(lookup, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookup, ncomp, \"apple\", false);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookup, ncomp, \"applet\", false);\n\t\tdocheck(lookup, ncomp, \"applepi\", false);\n\t\tdocheck(lookup, ncomp, \"appl\", false);\n\n\t\tremove(lookup, \"orange\");\n\t\tdocheck(lookup, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, ncomp, \"orange\", false);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\n\t\tremove(lookup, \"pineapple\");\n\t\tdocheck(lookup, ncomp, \"pineapple\", false);\n\t\tdocheck(lookup, ncomp, \"orange\", false);\n\t\tdocheck(lookup, ncomp, \"applepie\", true, 8, 4);\n\n\t\tremove(lookup, \"applepie\");\n\t\tdocheck(lookup, ncomp, \"applepie\", false);\n\t}\n\n\t{ // copy/assign/clear test\n\t\tLookup lookupa;\n\t\tadd(lookupa, \"pineapple\", 1);\n\t\tadd(lookupa, \"orange\", 2);\n\t\tadd(lookupa, \"banana\", 3);\n\t\tadd(lookupa, \"applepie\", 4);\n\t\tadd(lookupa, \"apple\", 5);\n\n\t\tLookup lookupb(lookupa); // copy ctor\n\t\tdocheck(lookupb, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookupb, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookupb, ncomp, \"banana\", true, 6, 3);\n\t\tdocheck(lookupb, ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"pizza\", false);\n\t\tdocheck(lookupb, ncomp, \"steak\", false);\n\t\tdocheck(lookupb, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookupb, ncomp, \"bananarama\", true, 6, 3);\n\t\tdocheck(lookupb, ncomp, \"applet\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"applepi\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"appl\", false);\n\n\t\tlookupb.clear(); // clear\n\t\tdocheck(lookupb, ncomp, \"pineapple\", false);\n\t\tdocheck(lookupb, ncomp, \"orange\", false);\n\t\tdocheck(lookupb, ncomp, \"banana\", false);\n\t\tdocheck(lookupb, ncomp, \"apple\", false);\n\t\tdocheck(lookupb, ncomp, \"applepie\", false);\n\t\tdocheck(lookupb, ncomp, \"bananarama\", false);\n\t\tdocheck(lookupb, ncomp, \"applet\", false);\n\t\tdocheck(lookupb, ncomp, \"applepi\", false);\n\t\tdocheck(lookupb, ncomp, \"appl\", false);\n\n\t\tlookupb = lookupa; // assign\n\t\tdocheck(lookupb, ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookupb, ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookupb, ncomp, \"banana\", true, 6, 3);\n\t\tdocheck(lookupb, ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"pizza\", false);\n\t\tdocheck(lookupb, ncomp, \"steak\", false);\n\t\tdocheck(lookupb, ncomp, \"applepie\", true, 8, 4);\n\t\tdocheck(lookupb, ncomp, \"bananarama\", true, 6, 3);\n\t\tdocheck(lookupb, ncomp, \"applet\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"applepi\", true, 5, 5);\n\t\tdocheck(lookupb, ncomp, \"appl\", false);\n\t}\n\n\t{ // test for_each\n\t\tLookup lookup;\n\t\tadd(lookup, \"pineapple\", 1);\n\t\tadd(lookup, \"orange\", 2);\n\t\tadd(lookup, \"banana\", 3);\n\t\tadd(lookup, \"applepie\", 4);\n\t\tadd(lookup, \"apple\", 5);\n\n\t\t//print(lookup);\n\t}\n\n\t{ // case insensitive tests\n\t\tLookup lookup;\n\n\t\t// NOTE: make sure all entries are in lower-case!!!\n\t\tadd(lookup, \"pineapple\", 1);\n\t\tadd(lookup, \"orange\", 2);\n\t\tadd(lookup, \"banana\", 3);\n\t\tadd(lookup, \"applepie\", 4);\n\t\tadd(lookup, \"apple\", 5);\n\n\t\tdocheck(lookup, nc_ncomp, \"pineapple\", true, 9, 1);\n\t\tdocheck(lookup, nc_ncomp, \"orange\", true, 6, 2);\n\t\tdocheck(lookup, nc_ncomp, \"banana\", true, 6, 3);\n\t\tdocheck(lookup, nc_ncomp, \"apple\", true, 5, 5);\n\t\tdocheck(lookup, nc_ncomp, \"applepie\", true, 8, 4);\n\n\t\tdocheck(lookup, nc_ncomp, \"PINEAPPLE\", true, 9, 1);\n\t\tdocheck(lookup, nc_ncomp, \"ORANGE\", true, 6, 2);\n\t\tdocheck(lookup, nc_ncomp, \"BANANA\", true, 6, 3);\n\t\tdocheck(lookup, nc_ncomp, \"APPLE\", true, 5, 5);\n\t\tdocheck(lookup, nc_ncomp, \"APPLEPIE\", true, 8, 4);\n\n\t\tdocheck(lookup, nc_ncomp, \"pineApple\", true, 9, 1);\n\t\tdocheck(lookup, nc_ncomp, \"orangE\", true, 6, 2);\n\t\tdocheck(lookup, nc_ncomp, \"Banana\", true, 6, 3);\n\t\tdocheck(lookup, nc_ncomp, \"aPPLe\", true, 5, 5);\n\t\tdocheck(lookup, nc_ncomp, \"ApplePie\", true, 8, 4);\n\n\t\t//print(lookup);\n\t}\n}\n\nUNITTESTDEF(x3_test_tst)\n{\n\tusing boost::spirit::x3::tst;\n\tusing boost::spirit::x3::tst_map;\n\n\ttests<tst<char, int>, tst<wchar_t, int> >();\n//~    tests<tst_map<char, int>, tst_map<wchar_t, int> >();\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/uint.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2012 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_QI_UINT_HPP)\n#define BOOST_SPIRIT_TEST_QI_UINT_HPP\n\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include <climits>\n#include <cstring>\n\n///////////////////////////////////////////////////////////////////////////////\n//\n//  *** BEWARE PLATFORM DEPENDENT!!! ***\n//  *** The following assumes 32 bit integers and 64 bit long longs.\n//  *** Modify these constant strings when appropriate.\n//\n///////////////////////////////////////////////////////////////////////////////\n\ninline char const* max_unsigned = \"4294967295\";\ninline char const* unsigned_overflow = \"4294967296\";\ninline char const* max_binary = \"11111111111111111111111111111111\";\ninline char const* binary_overflow = \"100000000000000000000000000000000\";\ninline char const* max_octal = \"37777777777\";\ninline char const* octal_overflow = \"100000000000\";\ninline char const* max_hex = \"FFFFFFFF\";\ninline char const* hex_overflow = \"100000000\";\n\n///////////////////////////////////////////////////////////////////////////////\n// A custom int type\nstruct custom_uint\n{\n\tunsigned n;\n\tcustom_uint() : n(0) {}\n\texplicit custom_uint(unsigned n_) : n(n_) {}\n\tcustom_uint& operator=(unsigned n_) { n = n_; return *this; }\n\tfriend bool operator==(custom_uint a, custom_uint b)\n\t\t{ return a.n == b.n; }\n\tfriend bool operator==(custom_uint a, unsigned b)\n\t\t{ return a.n == b; }\n\tfriend custom_uint operator*(custom_uint a, custom_uint b)\n\t\t{ return custom_uint(a.n * b.n); }\n\tfriend custom_uint operator+(custom_uint a, custom_uint b)\n\t\t{ return custom_uint(a.n + b.n); }\n};\n\n#endif\n\n"
  },
  {
    "path": "tc/string/spirit/unittest/uint1.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011      Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"uint.hpp\"\n#include \"../x3.hpp\"\n\nUNITTESTDEF(x3_test_uint1)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\t///////////////////////////////////////////////////////////////////////////\n\t//  unsigned tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::uint_;\n\t\tunsigned u=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(uint_);\n\n\t\t_ASSERT(test(\"123456\", uint_));\n\t\t_ASSERT(test_attr(\"123456\", uint_, u));\n\t\t_ASSERT(u == 123456);\n\n\t\t_ASSERT(test(max_unsigned, uint_));\n\t\t_ASSERT(test_attr(max_unsigned, uint_, u));\n\t\t_ASSERT(u == UINT_MAX);\n\n\t\t_ASSERT(!test(unsigned_overflow, uint_));\n\t\t_ASSERT(!test_attr(unsigned_overflow, uint_, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  binary tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::bin;\n\t\tunsigned u=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(bin);\n\n\t\t_ASSERT(test(\"11111110\", bin));\n\t\t_ASSERT(test_attr(\"11111110\", bin, u));\n\t\t_ASSERT(u == 0xFE);\n\n\t\t_ASSERT(test(max_binary, bin));\n\t\t_ASSERT(test_attr(max_binary, bin, u));\n\t\t_ASSERT(u == UINT_MAX);\n\n\t\t_ASSERT(!test(binary_overflow, bin));\n\t\t_ASSERT(!test_attr(binary_overflow, bin, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  octal tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::oct;\n\t\tunsigned u=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(oct);\n\n\t\t_ASSERT(test(\"12545674515\", oct));\n\t\t_ASSERT(test_attr(\"12545674515\", oct, u));\n\t\t_ASSERT(u == 012545674515);\n\n\t\t_ASSERT(test(max_octal, oct));\n\t\t_ASSERT(test_attr(max_octal, oct, u));\n\t\t_ASSERT(u == UINT_MAX);\n\n\t\t_ASSERT(!test(octal_overflow, oct));\n\t\t_ASSERT(!test_attr(octal_overflow, oct, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  hex tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::hex;\n\t\tunsigned u=0;\n\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(hex);\n\n\t\t_ASSERT(test(\"95BC8DF\", hex));\n\t\t_ASSERT(test_attr(\"95BC8DF\", hex, u));\n\t\t_ASSERT(u == 0x95BC8DF);\n\n\t\t_ASSERT(test(\"abcdef12\", hex));\n\t\t_ASSERT(test_attr(\"abcdef12\", hex, u));\n\t\t_ASSERT(u == 0xabcdef12);\n\n\t\t_ASSERT(test(max_hex, hex));\n\t\t_ASSERT(test_attr(max_hex, hex, u));\n\t\t_ASSERT(u == UINT_MAX);\n\n\t\t_ASSERT(!test(hex_overflow, hex));\n\t\t_ASSERT(!test_attr(hex_overflow, hex, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  limited fieldwidth\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned u=0;\n\t\tusing boost::spirit::x3::uint_parser;\n\n\t\tconstexpr uint_parser<unsigned, 10, 1, 3> uint3{};\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(uint3);\n\t\t_ASSERT(test(\"123456\", uint3, false));\n\t\t_ASSERT(test_attr(\"123456\", uint3, u, false));\n\t\t_ASSERT(u == 123);\n\n\t\tconstexpr uint_parser<unsigned, 10, 2, 4> uint4{};\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(uint4);\n\t\t_ASSERT(test(\"123456\", uint4, false));\n\t\t_ASSERT(test_attr(\"123456\", uint4, u, false));\n\t\t_ASSERT(u == 1234);\n\n\t\tchar const * first = \"0000000\";\n\t\tchar const * last  = first + std::strlen(first);\n\t\tconstexpr uint_parser<unsigned, 10, 4, 4> uint_exact4{};\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(uint_exact4);\n\t\t_ASSERT(boost::spirit::x3::parse(first, last, uint_exact4, u)\n\t\t\t&& first != last && (last-first == 3) && u == 0);\n\n\t\tfirst = \"0001400\";\n\t\tlast  = first + std::strlen(first);\n\t\t_ASSERT(boost::spirit::x3::parse(first, last, uint_exact4, u)\n\t\t\t&& first != last && (last-first == 3) && u == 1);\n\n\t\t_ASSERT(!test(\"1\", uint4));\n\t\t_ASSERT(!test_attr(\"1\", uint4, u));\n\t\t_ASSERT(test_attr(\"014567\", uint4, u, false) && u == 145);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  action tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::_attr;\n\t\tusing boost::spirit::x3::uint_;\n\t\tusing boost::spirit::x3::ascii::space;\n\t\tint n;\n\n\t\tauto f = [&](auto& ctx){ n = _attr(ctx); };\n\n\t\t_ASSERT(test(\"123\", uint_[f]));\n\t\t_ASSERT(n == 123);\n\t\t_ASSERT(test(\"   456\", uint_[f], space));\n\t\t_ASSERT(n == 456);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Check overflow is parse error\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tboost::spirit::x3::uint_parser<boost::uint8_t> uint8_;\n\t\tboost::uint8_t u8;\n\n\t\t_ASSERT(!test_attr(\"999\", uint8_, u8));\n\t\t_ASSERT(!test_attr(\"256\", uint8_, u8));\n\t\t_ASSERT(test_attr(\"255\", uint8_, u8));\n\n\t\tboost::spirit::x3::uint_parser<boost::uint16_t> uint16_;\n\t\tboost::uint16_t u16;\n\n\t\t_ASSERT(!test_attr(\"99999\", uint16_, u16));\n\t\t_ASSERT(!test_attr(\"65536\", uint16_, u16));\n\t\t_ASSERT(test_attr(\"65535\", uint16_, u16));\n\n\t\tboost::spirit::x3::uint_parser<boost::uint32_t> uint32_;\n\t\tboost::uint32_t u32;\n\n\t\t_ASSERT(!test_attr(\"9999999999\", uint32_, u32));\n\t\t_ASSERT(!test_attr(\"4294967296\", uint32_, u32));\n\t\t_ASSERT(test_attr(\"4294967295\", uint32_, u32));\n\n\t\tboost::spirit::x3::uint_parser<boost::int8_t> u_int8_;\n\n\t\t_ASSERT(!test_attr(\"999\", u_int8_, u8));\n\t\t_ASSERT(!test_attr(\"-1\", u_int8_, u8));\n\t\t_ASSERT(!test_attr(\"128\", u_int8_, u8));\n\t\t_ASSERT(test_attr(\"127\", u_int8_, u8));\n\t\t_ASSERT(test_attr(\"0\", u_int8_, u8));\n\n\t\tboost::spirit::x3::uint_parser<boost::int16_t> u_int16_;\n\n\t\t_ASSERT(!test_attr(\"99999\", u_int16_, u16));\n\t\t_ASSERT(!test_attr(\"-1\", u_int16_, u16));\n\t\t_ASSERT(!test_attr(\"32768\", u_int16_, u16));\n\t\t_ASSERT(test_attr(\"32767\", u_int16_, u16));\n\t\t_ASSERT(test_attr(\"0\", u_int16_, u16));\n\n\t\tboost::spirit::x3::uint_parser<boost::int32_t> u_int32_;\n\n\t\t_ASSERT(!test_attr(\"9999999999\", u_int32_, u32));\n\t\t_ASSERT(!test_attr(\"-1\", u_int32_, u32));\n\t\t_ASSERT(!test_attr(\"2147483648\", u_int32_, u32));\n\t\t_ASSERT(test_attr(\"2147483647\", u_int32_, u32));\n\t\t_ASSERT(test_attr(\"0\", u_int32_, u32));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  custom uint tests\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tusing boost::spirit::x3::uint_;\n\t\tusing boost::spirit::x3::uint_parser;\n\t\tcustom_uint u;\n\n\t\t_ASSERT(test_attr(\"123456\", uint_, u));\n\t\tuint_parser<custom_uint, 10, 1, 2> uint2;\n\t\t_ASSERT(test_attr(\"12\", uint2, u));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/uint_radix.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2011 Jan Frederick Eick\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#if !defined(BOOST_SPIRIT_TEST_X3_UINT4_HPP)\n#define BOOST_SPIRIT_TEST_X3_UINT4_HPP\n\n///////////////////////////////////////////////////////////////////////////////\n//\n//  *** BEWARE PLATFORM DEPENDENT!!! ***\n//  *** The following assumes 32 bit integers and 64 bit long longs.\n//  *** Modify these constant strings when appropriate.\n//\n///////////////////////////////////////////////////////////////////////////////\n\nchar const* max_unsigned_base3 =                \"102002022201221111210\";\nchar const* unsigned_overflow_base3 =           \"102002022201221111211\";\nchar const* digit_overflow_base3 =              \"1020020222012211112100\";\n\nchar const* max_unsigned_base4 =                \"3333333333333333\";\nchar const* digit_overflow_base4 =              \"33333333333333330\";\n\nchar const* max_unsigned_base5 =                \"32244002423140\";\nchar const* unsigned_overflow_base5 =           \"32244002423141\";\nchar const* digit_overflow_base5 =              \"322440024231400\";\n\nchar const* max_unsigned_base6 =                \"1550104015503\";\nchar const* unsigned_overflow_base6 =           \"1550104015504\";\nchar const* digit_overflow_base6 =              \"15501040155030\";\n\nchar const* max_unsigned_base7 =                \"211301422353\";\nchar const* unsigned_overflow_base7 =           \"211301422354\";\nchar const* digit_overflow_base7 =              \"2113014223530\";\n\nchar const* max_unsigned_base9 =                \"12068657453\";\nchar const* unsigned_overflow_base9 =           \"12068657454\";\nchar const* digit_overflow_base9 =              \"120686574530\";\n\nchar const* max_unsigned_base11 =               \"1904440553\";\nchar const* unsigned_overflow_base11 =          \"1904440554\";\nchar const* digit_overflow_base11 =             \"19044405530\";\n\nchar const* max_unsigned_base12 =               \"9BA461593\";\nchar const* unsigned_overflow_base12 =          \"9BA461594\";\nchar const* digit_overflow_base12 =             \"9BA4615930\";\n\nchar const* max_unsigned_base13 =               \"535A79888\";\nchar const* unsigned_overflow_base13 =          \"535A79889\";\nchar const* digit_overflow_base13 =             \"535A798880\";\n\nchar const* max_unsigned_base14 =               \"2CA5B7463\";\nchar const* unsigned_overflow_base14 =          \"2CA5B7464\";\nchar const* digit_overflow_base14 =             \"2CA5B74630\";\n\nchar const* max_unsigned_base15 =               \"1A20DCD80\";\nchar const* unsigned_overflow_base15 =          \"1A20DCD81\";\nchar const* digit_overflow_base15 =             \"1A20DCD800\";\n\nchar const* max_unsigned_base17 =               \"A7FFDA90\";\nchar const* unsigned_overflow_base17 =          \"A7FFDA91\";\nchar const* digit_overflow_base17 =             \"A7FFDA900\";\n\nchar const* max_unsigned_base18 =               \"704HE7G3\";\nchar const* unsigned_overflow_base18 =          \"704HE7G4\";\nchar const* digit_overflow_base18 =             \"704HE7G30\";\n\nchar const* max_unsigned_base19 =               \"4F5AFF65\";\nchar const* unsigned_overflow_base19 =          \"4F5AFF66\";\nchar const* digit_overflow_base19 =             \"4F5AFF650\";\n\nchar const* max_unsigned_base20 =               \"3723AI4F\";\nchar const* unsigned_overflow_base20 =          \"3723AI4G\";\nchar const* digit_overflow_base20 =             \"3723AI4G0\";\n\nchar const* max_unsigned_base21 =               \"281D55I3\";\nchar const* unsigned_overflow_base21 =          \"281D55I4\";\nchar const* digit_overflow_base21 =             \"281D55I30\";\n\nchar const* max_unsigned_base22 =               \"1FJ8B183\";\nchar const* unsigned_overflow_base22 =          \"1FJ8B184\";\nchar const* digit_overflow_base22 =             \"1FJ8B1830\";\n\nchar const* max_unsigned_base23 =               \"1606K7IB\";\nchar const* unsigned_overflow_base23 =          \"1606K7IC\";\nchar const* digit_overflow_base23 =             \"1606K7IB0\";\n\nchar const* max_unsigned_base24 =               \"MB994AF\";\nchar const* unsigned_overflow_base24 =          \"MB994AG\";\nchar const* digit_overflow_base24 =             \"MB994AF0\";\n\nchar const* max_unsigned_base25 =               \"HEK2MGK\";\nchar const* unsigned_overflow_base25 =          \"HEK2MGL\";\nchar const* digit_overflow_base25 =             \"HEK2MGK0\";\n\nchar const* max_unsigned_base26 =               \"DNCHBNL\";\nchar const* unsigned_overflow_base26 =          \"DNCHBNM\";\nchar const* digit_overflow_base26 =             \"DNCHBNL0\";\n\nchar const* max_unsigned_base27 =               \"B28JPDL\";\nchar const* unsigned_overflow_base27 =          \"B28JPDM\";\nchar const* digit_overflow_base27 =             \"B28JPDL0\";\n\nchar const* max_unsigned_base28 =               \"8PFGIH3\";\nchar const* unsigned_overflow_base28 =          \"8PFGIH4\";\nchar const* digit_overflow_base28 =             \"8PFGIH30\";\n\nchar const* max_unsigned_base29 =               \"76BEIGF\";\nchar const* unsigned_overflow_base29 =          \"76BEIGH\";\nchar const* digit_overflow_base29 =             \"76BEIGF0\";\n\nchar const* max_unsigned_base30 =               \"5QMCPQF\";\nchar const* unsigned_overflow_base30 =          \"5QMCPQG\";\nchar const* digit_overflow_base30 =             \"5QMCPQF0\";\n\nchar const* max_unsigned_base31 =               \"4Q0JTO3\";\nchar const* unsigned_overflow_base31 =          \"4Q0JTO4\";\nchar const* digit_overflow_base31 =             \"4Q0JTO30\";\n\nchar const* max_unsigned_base32 =               \"3VVVVVV\";\nchar const* unsigned_overflow_base32 =          \"3VVVVVW\";\nchar const* digit_overflow_base32 =             \"3VVVVVV0\";\n\nchar const* max_unsigned_base33 =               \"3AOKQ93\";\nchar const* unsigned_overflow_base33 =          \"3AOKQ94\";\nchar const* digit_overflow_base33 =             \"3AOKQ930\";\n\nchar const* max_unsigned_base34 =               \"2QHXJLH\";\nchar const* unsigned_overflow_base34 =          \"2QHXJLI\";\nchar const* digit_overflow_base34 =             \"2QHXJLH0\";\n\nchar const* max_unsigned_base35 =               \"2BR45QA\";\nchar const* unsigned_overflow_base35 =          \"2BR45QB\";\nchar const* digit_overflow_base35 =             \"2BR45QA0\";\n\nchar const* max_unsigned_base36 =               \"1Z141Z3\";\nchar const* unsigned_overflow_base36 =          \"1Z141Z4\";\nchar const* digit_overflow_base36 =             \"1Z141Z30\";\n\n#endif"
  },
  {
    "path": "tc/string/spirit/unittest/uint_radix.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2011 Jan Frederick Eick\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n\n#include \"test.hpp\"\n#include \"uint_radix.hpp\"\n#include \"../x3.hpp\"\n#include <climits>\n#include <cstring>\n\nUNITTESTDEF(x3_test_uint_radix)\n{\n\tusing spirit_test::test;\n\tusing spirit_test::test_attr;\n\n\tusing boost::spirit::x3::uint_parser;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 3)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 3, 1, -1>             base3_parser;\n\n\t\t_ASSERT(test(\"210112221200\",                 base3_parser));\n\t\t_ASSERT(test_attr(\"210112221200\",            base3_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"1231\",                        base3_parser));\n\t\t_ASSERT(!test_attr(\"1231\",                   base3_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base3,             base3_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base3,        base3_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base3,       base3_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base3,  base3_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base3,          base3_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base3,     base3_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 4)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 4, 1, -1>             base4_parser;\n\n\t\t_ASSERT(test(\"1213210302\",                   base4_parser));\n\t\t_ASSERT(test_attr(\"1213210302\",              base4_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"1234\",                        base4_parser));\n\t\t_ASSERT(!test_attr(\"1234\",                   base4_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base4,             base4_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base4,        base4_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base4,          base4_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base4,     base4_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 5)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 5, 1, -1>             base5_parser;\n\n\t\t_ASSERT(test(\"102033432\",                    base5_parser));\n\t\t_ASSERT(test_attr(\"102033432\",               base5_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"2345\",                        base5_parser));\n\t\t_ASSERT(!test_attr(\"2345\",                   base5_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base5,             base5_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base5,        base5_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base5,       base5_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base5,  base5_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base5,          base5_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base5,     base5_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 6)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 6, 1, -1>             base6_parser;\n\n\t\t_ASSERT(test(\"13032030\",                     base6_parser));\n\t\t_ASSERT(test_attr(\"13032030\",                base6_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"3456\",                        base6_parser));\n\t\t_ASSERT(!test_attr(\"3456\",                   base6_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base6,             base6_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base6,        base6_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base6,       base6_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base6,  base6_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base6,          base6_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base6,     base6_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 7)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 7, 1, -1>             base7_parser;\n\n\t\t_ASSERT(test(\"3414600\",                      base7_parser));\n\t\t_ASSERT(test_attr(\"3414600\",                 base7_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"4567\",                        base7_parser));\n\t\t_ASSERT(!test_attr(\"4567\",                   base7_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base7,             base7_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base7,        base7_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base7,       base7_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base7,  base7_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base7,          base7_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base7,     base7_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 9)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 9, 1, -1>             base9_parser;\n\n\t\t_ASSERT(test(\"715850\",                       base9_parser));\n\t\t_ASSERT(test_attr(\"715850\",                  base9_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"6789\",                        base9_parser));\n\t\t_ASSERT(!test_attr(\"6789\",                   base9_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base9,             base9_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base9,        base9_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base9,       base9_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base9,  base9_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base9,          base9_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base9,     base9_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 11)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\n\t\tuint_parser<unsigned int, 11, 1, -1>            base11_parser;\n\n\t\t_ASSERT(test(\"26a815\",                       base11_parser));\n\t\t_ASSERT(test_attr(\"26a815\",                  base11_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"90ab\",                        base11_parser));\n\t\t_ASSERT(!test_attr(\"90AB\",                   base11_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base11,            base11_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base11,       base11_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base11,      base11_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base11, base11_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base11,         base11_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base11,    base11_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 12)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 12, 1, -1>            base12_parser;\n\n\t\t_ASSERT(test(\"185616\",                       base12_parser));\n\t\t_ASSERT(test_attr(\"185616\",                  base12_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"9abc\",                        base12_parser));\n\t\t_ASSERT(!test_attr(\"9ABC\",                   base12_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base12,            base12_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base12,       base12_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base12,      base12_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base12, base12_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base12,         base12_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base12,    base12_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 13)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 13, 1, -1>            base13_parser;\n\n\t\t_ASSERT(test(\"11b140\",                       base13_parser));\n\t\t_ASSERT(test_attr(\"11b140\",                  base13_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"abcd\",                        base13_parser));\n\t\t_ASSERT(!test_attr(\"ABCD\",                   base13_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base13,            base13_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base13,       base13_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base13,      base13_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base13, base13_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base13,         base13_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base13,    base13_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 14)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 14, 1, -1>            base14_parser;\n\n\t\t_ASSERT(test(\"b0870\",                        base14_parser));\n\t\t_ASSERT(test_attr(\"b0870\",                   base14_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"bcde\",                        base14_parser));\n\t\t_ASSERT(!test_attr(\"BCDE\",                   base14_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base14,            base14_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base14,       base14_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base14,      base14_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base14, base14_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base14,         base14_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base14,    base14_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 15)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 15, 1, -1>            base15_parser;\n\n\t\t_ASSERT(test(\"85a7c\",                        base15_parser));\n\t\t_ASSERT(test_attr(\"85a7c\",                   base15_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"cdef\",                        base15_parser));\n\t\t_ASSERT(!test_attr(\"CDEF\",                   base15_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base15,            base15_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base15,       base15_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base15,      base15_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base15, base15_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base15,         base15_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base15,    base15_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 17)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 17, 1, -1>            base17_parser;\n\n\t\t_ASSERT(test(\"515g7\",                        base17_parser));\n\t\t_ASSERT(test_attr(\"515g7\",                   base17_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"efgh\",                        base17_parser));\n\t\t_ASSERT(!test_attr(\"EFGH\",                   base17_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base17,            base17_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base17,       base17_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base17,      base17_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base17, base17_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base17,         base17_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base17,    base17_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 18)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 18, 1, -1>            base18_parser;\n\n\t\t_ASSERT(test(\"40d70\",                        base18_parser));\n\t\t_ASSERT(test_attr(\"40d70\",                   base18_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"fghi\",                        base18_parser));\n\t\t_ASSERT(!test_attr(\"FGHI\",                   base18_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base18,            base18_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base18,       base18_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base18,      base18_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base18, base18_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base18,         base18_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base18,    base18_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 19)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 19, 1, -1>            base19_parser;\n\n\t\t_ASSERT(test(\"34g3a\",                        base19_parser));\n\t\t_ASSERT(test_attr(\"34g3a\",                   base19_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"ghij\",                        base19_parser));\n\t\t_ASSERT(!test_attr(\"GHIJ\",                   base19_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base19,            base19_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base19,       base19_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base19,      base19_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base19, base19_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base19,         base19_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base19,    base19_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 20)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 20, 1, -1>            base20_parser;\n\n\t\t_ASSERT(test(\"2d0c2\",                        base20_parser));\n\t\t_ASSERT(test_attr(\"2d0c2\",                   base20_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"hijk\",                        base20_parser));\n\t\t_ASSERT(!test_attr(\"HIJK\",                   base20_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base20,            base20_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base20,       base20_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base20,      base20_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base20, base20_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base20,         base20_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base20,    base20_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 21)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 21, 1, -1>            base21_parser;\n\n\t\t_ASSERT(test(\"23h00\",                        base21_parser));\n\t\t_ASSERT(test_attr(\"23h00\",                   base21_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"ijkl\",                        base21_parser));\n\t\t_ASSERT(!test_attr(\"IJKL\",                   base21_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base21,            base21_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base21,       base21_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base21,      base21_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base21, base21_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base21,         base21_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base21,    base21_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 22)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 22, 1, -1>            base22_parser;\n\n\t\t_ASSERT(test(\"1hibg\",                        base22_parser));\n\t\t_ASSERT(test_attr(\"1hibg\",                   base22_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"jklm\",                        base22_parser));\n\t\t_ASSERT(!test_attr(\"JKLM\",                   base22_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base22,            base22_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base22,       base22_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base22,      base22_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base22, base22_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base22,         base22_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base22,    base22_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 23)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 23, 1, -1>            base23_parser;\n\n\t\t_ASSERT(test(\"1bjm7\",                        base23_parser));\n\t\t_ASSERT(test_attr(\"1bjm7\",                   base23_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"klmn\",                        base23_parser));\n\t\t_ASSERT(!test_attr(\"KLMN\",                   base23_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base23,            base23_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base23,       base23_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base23,      base23_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base23, base23_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base23,         base23_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base23,    base23_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 24)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 24, 1, -1>            base24_parser;\n\n\t\t_ASSERT(test(\"16gci\",                        base24_parser));\n\t\t_ASSERT(test_attr(\"16gci\",                   base24_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"lmno\",                        base24_parser));\n\t\t_ASSERT(!test_attr(\"LMNO\",                   base24_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base24,            base24_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base24,       base24_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base24,      base24_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base24, base24_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base24,         base24_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base24,    base24_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 25)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 25, 1, -1>            base25_parser;\n\n\t\t_ASSERT(test(\"123jh\",                        base25_parser));\n\t\t_ASSERT(test_attr(\"123jh\",                   base25_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"mnop\",                        base25_parser));\n\t\t_ASSERT(!test_attr(\"MNOP\",                   base25_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base25,            base25_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base25,       base25_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base25,      base25_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base25, base25_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base25,         base25_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base25,    base25_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 26)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 26, 1, -1>            base26_parser;\n\n\t\t_ASSERT(test(\"o3f0\",                         base26_parser));\n\t\t_ASSERT(test_attr(\"o3f0\",                    base26_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"nopq\",                        base26_parser));\n\t\t_ASSERT(!test_attr(\"NOPQ\",                   base26_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base26,            base26_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base26,       base26_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base26,      base26_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base26, base26_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base26,         base26_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base26,    base26_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 27)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 27, 1, -1>            base27_parser;\n\n\t\t_ASSERT(test(\"lepi\",                         base27_parser));\n\t\t_ASSERT(test_attr(\"lepi\",                    base27_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"opqr\",                        base27_parser));\n\t\t_ASSERT(!test_attr(\"OPQR\",                   base27_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base27,            base27_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base27,       base27_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base27,      base27_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base27, base27_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base27,         base27_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base27,    base27_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 28)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 28, 1, -1>            base28_parser;\n\n\t\t_ASSERT(test(\"j93e\",                         base28_parser));\n\t\t_ASSERT(test_attr(\"j93e\",                    base28_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"pqrs\",                        base28_parser));\n\t\t_ASSERT(!test_attr(\"PQRS\",                   base28_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base28,            base28_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base28,       base28_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base28,      base28_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base28, base28_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base28,         base28_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base28,    base28_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 29)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 29, 1, -1>            base29_parser;\n\n\t\t_ASSERT(test(\"hbd1\",                         base29_parser));\n\t\t_ASSERT(test_attr(\"hbd1\",                    base29_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"qrst\",                        base29_parser));\n\t\t_ASSERT(!test_attr(\"QRST\",                   base29_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base29,            base29_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base29,       base29_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base29,      base29_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base29, base29_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base29,         base29_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base29,    base29_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 30)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 30, 1, -1>            base30_parser;\n\n\t\t_ASSERT(test(\"flbc\",                         base30_parser));\n\t\t_ASSERT(test_attr(\"flbc\",                    base30_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"rstu\",                        base30_parser));\n\t\t_ASSERT(!test_attr(\"RSTU\",                   base30_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base30,            base30_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base30,       base30_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base30,      base30_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base30, base30_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base30,         base30_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base30,    base30_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 31)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 31, 1, -1>            base31_parser;\n\n\t\t_ASSERT(test(\"e7e7\",                         base31_parser));\n\t\t_ASSERT(test_attr(\"e7e7\",                    base31_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"stuv\",                        base31_parser));\n\t\t_ASSERT(!test_attr(\"STUV\",                   base31_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base31,            base31_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base31,       base31_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base31,      base31_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base31, base31_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base31,         base31_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base31,    base31_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 32)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 32, 1, -1>            base32_parser;\n\n\t\t_ASSERT(test(\"cu9i\",                         base32_parser));\n\t\t_ASSERT(test_attr(\"cu9i\",                    base32_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"tuvw\",                        base32_parser));\n\t\t_ASSERT(!test_attr(\"TUVW\",                   base32_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base32,            base32_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base32,       base32_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base32,      base32_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base32, base32_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base32,         base32_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base32,    base32_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 33)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 33, 1, -1>            base33_parser;\n\n\t\t_ASSERT(test(\"bqir\",                         base33_parser));\n\t\t_ASSERT(test_attr(\"bqir\",                    base33_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"uvwx\",                        base33_parser));\n\t\t_ASSERT(!test_attr(\"UVWX\",                   base33_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base33,            base33_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base33,       base33_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base33,      base33_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base33, base33_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base33,         base33_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base33,    base33_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 34)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 34, 1, -1>            base34_parser;\n\n\t\t_ASSERT(test(\"aqxo\",                         base34_parser));\n\t\t_ASSERT(test_attr(\"aqxo\",                    base34_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"vwxy\",                        base34_parser));\n\t\t_ASSERT(!test_attr(\"VWXY\",                   base34_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base34,            base34_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base34,       base34_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base34,      base34_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base34, base34_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base34,         base34_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base34,    base34_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 35)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 35, 1, -1>            base35_parser;\n\n\t\t_ASSERT(test(\"9vb7\",                         base35_parser));\n\t\t_ASSERT(test_attr(\"9vb7\",                    base35_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(!test(\"wxyz\",                        base35_parser));\n\t\t_ASSERT(!test_attr(\"WXYZ\",                   base35_parser, u));\n\n\t\t_ASSERT(test(max_unsigned_base35,            base35_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base35,       base35_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base35,      base35_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base35, base35_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base35,         base35_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base35,    base35_parser, u));\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  arbitrary radix test (base 36)\n\t///////////////////////////////////////////////////////////////////////////\n\t{\n\t\tunsigned int u=0;\n\t\tuint_parser<unsigned int, 36, 1, -1>            base36_parser;\n\n\t\t_ASSERT(test(\"93ci\",                         base36_parser));\n\t\t_ASSERT(test_attr(\"93ci\",                    base36_parser, u));\n\t\t_ASSERT(424242 == u);\n\n\t\t_ASSERT(test(max_unsigned_base36,            base36_parser));\n\t\t_ASSERT(test_attr(max_unsigned_base36,       base36_parser, u));\n\n\t\t_ASSERT(!test(unsigned_overflow_base36,      base36_parser));\n\t\t_ASSERT(!test_attr(unsigned_overflow_base36, base36_parser, u));\n\t\t_ASSERT(!test(digit_overflow_base36,         base36_parser));\n\t\t_ASSERT(!test_attr(digit_overflow_base36,    base36_parser, u));\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/unused_type.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3/support/unused.hpp\"\n#include <type_traits>\n#include <iostream>\n\nvoid test_use(boost::spirit::x3::unused_type) {}\n\nUNITTESTDEF(x3_test_unused_type)\n{\n\tusing boost::spirit::x3::unused;\n\tusing boost::spirit::x3::unused_type;\n\n\tstatic_assert(std::is_trivial<unused_type>::value, \"\");\n\n\tunused_type unused_mut;\n\tstatic_assert(std::is_same<decltype((unused)), unused_type const&>::value, \"\");\n\tstatic_assert(std::is_same<decltype((unused_mut)), unused_type&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused = 123), unused_type const&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused = unused), unused_type const&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused = unused_mut), unused_type const&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused_mut = 123), unused_type&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused_mut = unused), unused_type&>::value, \"\");\n\tstatic_assert(std::is_same<decltype(unused_mut = unused_mut), unused_type&>::value, \"\");\n\n\ttest_use(0);\n\ttest_use(unused);\n\ttest_use(unused_mut);\n\n\tstd::cout << unused;\n\tstd::cout << unused_mut;\n\tstd::cin >> unused_mut;\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/utils.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Nikita Kniazev\n\n\tUse, modification and distribution is subject to the Boost Software\n\tLicense, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at\n\thttp://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_TEST_X3_UTILS_HPP)\n#define BOOST_SPIRIT_TEST_X3_UTILS_HPP\n\n#include \"../x3/core/parser.hpp\"\n\nstruct move_only\n{\n\tmove_only() = default;\n\tmove_only(move_only&&) = default;\n\tmove_only& operator=(move_only&&) = default;\n};\n\n\ntemplate <typename T>\nstruct synth_parser : boost::spirit::x3::parser<synth_parser<T>>\n{\n\ttypedef T attribute_type;\n\n\tstatic bool const has_attribute = true;\n\tstatic bool const handles_container = false;\n\n\ttemplate <typename Iterator, typename Context,\n\t\ttypename RuleContext, typename Attribute>\n\tbool parse(Iterator& iter, Iterator const& last, Context const&,\n\t\tRuleContext&, Attribute& attr) const\n\t{\n\t\tif (iter != last && *iter == 's') {\n\t\t\t++iter;\n\t\t\tboost::spirit::x3::traits::move_to(attribute_type{}, attr);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n};\n\ntemplate <typename T>\nsynth_parser<T> synth{};\n\nsynth_parser<move_only> const synth_move_only{};\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/unittest/with.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n\nnamespace x3 = boost::spirit::x3;\n\nstruct my_tag;\n\nstruct my_rule_class\n{\n\ttemplate <typename Iterator, typename Exception, typename Context>\n\tx3::error_handler_result\n\ton_error(Iterator&, Iterator const&, Exception const&, Context const& context)\n\t{\n\t\tx3::get<my_tag>(context)++;\n\t\treturn x3::error_handler_result::fail;\n\t}\n\n\ttemplate <typename Iterator, typename Attribute, typename Context>\n\tinline void\n\ton_success(Iterator const&, Iterator const&, Attribute&, Context const& context)\n\t{\n\t\tx3::get<my_tag>(context)++;\n\t}\n};\n\nUNITTESTDEF(x3_test_with)\n{\n\tusing spirit_test::test_attr;\n\tusing spirit_test::test;\n\n\tusing boost::spirit::x3::rule;\n\tusing boost::spirit::x3::int_;\n\tusing boost::spirit::x3::with;\n\tusing boost::spirit::x3::lit;\n\n// read from a mutable field is not allowed on these compilers\n#if (!defined(_MSC_VER) || _MSC_VER >= 1910) && \\\n\t(!defined(__clang__) || __clang_major__ >= 7)\n\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(with<my_tag>(0)[lit('x')]);\n#endif\n\t{\n\t\tconstexpr int i = 0;\n\t\tBOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(with<my_tag>(i)[lit('x')]);\n\t}\n\n\t{ // injecting data into the context in the grammar\n\n\t\tint val = 0;\n\t\tauto r = rule<my_rule_class, char const*>() =\n\t\t\tlit('(') > int_ > lit(',') > int_ > lit(')')\n\t\t\t;\n\n\t\tauto start =\n\t\t\twith<my_tag>(std::ref(val)) [ r ]\n\t\t\t;\n\n\t\t_ASSERT(test(\"(123,456)\", start));\n\t\t_ASSERT(!test(\"(abc,def)\", start));\n\t\t_ASSERT(val == 2);\n\t}\n\n\t{ // injecting non-const lvalue into the context\n\t\tint val = 0;\n\t\tauto const r  = int_[([](auto& ctx){\n\t\t\tx3::get<my_tag>(ctx) += x3::_attr(ctx);\n\t\t})];\n\t\t_ASSERT(test(\"123,456\", with<my_tag>(val)[r % lit(',')]));\n\t\t_ASSERT(579 == val);\n\t}\n\n\t{ // injecting rvalue into the context\n\t\tauto const r1 = int_[([](auto& ctx){\n\t\t\tx3::get<my_tag>(ctx) += x3::_attr(ctx);\n\t\t})];\n\t\tauto const r2 = rule<struct my_rvalue_rule_class, int>() =\n\t\t\tx3::lit('(') >> (r1 % lit(',')) >> x3::lit(')')[([](auto& ctx){\n\t\t\t\tx3::_val(ctx) = x3::get<my_tag>(ctx);\n\t\t\t})];\n\t\tint attr = 0;\n\t\t_ASSERT(test_attr(\"(1,2,3)\", with<my_tag>(100)[r2], attr));\n\t\t_ASSERT(106 == attr);\n\t}\n\n\t{ // injecting const/non-const lvalue and rvalue into the context\n\t\tstruct functor {\n\t\t\tint operator()(int& val) {\n\t\t\t\treturn val * 10; // non-const ref returns 10 * injected val\n\t\t\t}\n\t\t\tint operator()(int const& val) {\n\t\t\t\treturn val; // const ref returns injected val\n\t\t\t}\n\t\t};\n\n\t\tauto f = [](auto& ctx){\n\t\t\tx3::_val(ctx) = x3::_attr(ctx) + functor()(x3::get<my_tag>(ctx));\n\t\t};\n\t\tauto const r = rule<struct my_rule_class2, int>() = int_[f];\n\n\t\tint attr = 0;\n\t\tint const cval = 10;\n\t\t_ASSERT(test_attr(\"5\", with<my_tag>(cval)[r], attr));\n\t\t_ASSERT(15 == attr); // x3::get returns const ref to cval\n\n\t\tattr = 0;\n\t\tint val = 10;\n\t\t_ASSERT(test_attr(\"5\", with<my_tag>(val)[r], attr));\n\t\t_ASSERT(105 == attr); // x3::get returns ref to val\n\n\t\tattr = 0;\n\n\t\t_ASSERT(test_attr(\"5\", with<my_tag>(10)[r], attr));\n\t\t// x3::get returns ref to member variable of with_directive\n\t\t_ASSERT(105 == attr);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/unittest/x3_variant.t.cpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2016 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#include \"test.hpp\"\n#include \"../x3.hpp\"\n#include \"../x3/support/ast/variant.hpp\"\n#include <string>\n#include <iostream>\n\nnamespace x3 = boost::spirit::x3;\n\nstruct none {};\n\nusing variant = x3::variant<\n\t\tnone\n\t  , bool\n\t  , std::string\n\t  , int\n\t  , double\n\t>;\n\nstruct ast : variant\n{\n\tusing variant::variant;\n\tusing variant::operator=;\n\n\tast(char const* s)\n\t  : variant(std::string{s})\n\t{}\n\n\tast& operator=(char const* s)\n\t{\n\t\tvariant::operator=(std::string{s});\n\t\treturn *this;\n\t}\n};\n\nUNITTESTDEF(x3_test_x3_variant)\n{\n\t{\n\t\tast v{123};\n\t\t_ASSERT(boost::get<int>(v) == 123);\n\n\t\tv = \"test\";\n\t\t_ASSERT(boost::get<std::string>(v) == \"test\");\n\n\t\tv = true;\n\t\t_ASSERT(boost::get<bool>(v) == true);\n\t}\n}\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary/attr.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM\n#define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM\n\n#include \"../core/parser.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../support/traits/container_traits.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include <boost/type_traits/is_same.hpp>\n#include <boost/type_traits/remove_cv.hpp>\n#include <boost/type_traits/remove_reference.hpp>\n#include <cstddef>\n#include <string>\n#include <utility>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\nnamespace detail\n{\n\ttemplate <typename Value, std::size_t N\n\t  , typename = std::make_index_sequence<N>>\n\tstruct array_helper;\n\n\ttemplate <typename Value, std::size_t N, std::size_t... Is>\n\tstruct array_helper<Value, N, std::index_sequence<Is...>>\n\t{\n\t\tconstexpr array_helper(Value const (&value)[N])\n\t\t\t: value_{ value[Is]... } {}\n\n\t\tconstexpr array_helper(Value (&&value)[N])\n\t\t\t: value_{ static_cast<Value&&>(value[Is])... } {}\n\n\t\tValue value_[N];\n\t};\n}\n\n\ttemplate <typename Value>\n\tstruct attr_parser : parser<attr_parser<Value>>\n\t{\n\t\ttypedef Value attribute_type;\n\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\t\tstatic bool const handles_container =\n\t\t\ttraits::is_container<attribute_type>::value;\n\n\t\tconstexpr attr_parser(Value const& value)\n\t\t  : value_(value) {}\n\t\tconstexpr attr_parser(Value&& value)\n\t\t  : value_(std::move(value)) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& /* first */, Iterator const& /* last */\n\t\t  , Context const& /* context */, RuleContext&, Attribute& attr_) const\n\t\t{\n\t\t\t// $$$ Change to copy_to once we have it $$$\n\t\t\ttraits::move_to(value_, attr_);\n\t\t\treturn true;\n\t\t}\n\n\t\tValue value_;\n\t};\n\n\ttemplate <typename Value, std::size_t N>\n\tstruct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>\n\t  , detail::array_helper<Value, N>\n\t{\n\t\tusing detail::array_helper<Value, N>::array_helper;\n\n\t\ttypedef Value attribute_type[N];\n\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\t\tstatic bool const handles_container = true;\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& /* first */, Iterator const& /* last */\n\t\t  , Context const& /* context */, RuleContext&, Attribute& attr_) const\n\t\t{\n\t\t\t// $$$ Change to copy_to once we have it $$$\n\t\t\ttraits::move_to(this->value_ + 0, this->value_ + N, attr_);\n\t\t\treturn true;\n\t\t}\n\t};\n\n\ttemplate <typename Value>\n\tstruct get_info<attr_parser<Value>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(attr_parser<Value> const& /*p*/) const\n\t\t{\n\t\t\treturn \"attr\";\n\t\t}\n\t};\n\n\tstruct attr_gen\n\t{\n\t\ttemplate <typename Value>\n\t\tconstexpr attr_parser<typename remove_cv<\n\t\t\ttypename remove_reference<Value>::type>::type>\n\t\toperator()(Value&& value) const\n\t\t{\n\t\t\treturn { std::forward<Value>(value) };\n\t\t}\n\t};\n\n\tconstexpr auto attr = attr_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary/eoi.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM)\n#define BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM\n\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../support/unused.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct eoi_parser : parser<eoi_parser>\n\t{\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute&) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn first == last;\n\t\t}\n\t};\n\n\ttemplate<>\n\tstruct get_info<eoi_parser>\n\t{\n\t\ttypedef std::string result_type;\n\t\tresult_type operator()(eoi_parser const &) const { return \"eoi\"; }\n\t};\n\n\tconstexpr auto eoi = eoi_parser{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary/eol.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM)\n#define BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM\n\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../support/unused.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct eol_parser : parser<eol_parser>\n\t{\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t , Context const& context, unused_type, Attribute& /*attr*/) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\tIterator iter = first;\n\t\t\tbool matched = false;\n\t\t\tif (iter != last && *iter == '\\r')  // CR\n\t\t\t{\n\t\t\t\tmatched = true;\n\t\t\t\t++iter;\n\t\t\t}\n\t\t\tif (iter != last && *iter == '\\n')  // LF\n\t\t\t{\n\t\t\t\tmatched = true;\n\t\t\t\t++iter;\n\t\t\t}\n\n\t\t\tif (matched) first = iter;\n\t\t\treturn matched;\n\t\t}\n\t};\n\n\ttemplate<>\n\tstruct get_info<eol_parser>\n\t{\n\t\ttypedef std::string result_type;\n\t\tresult_type operator()(eol_parser const &) const { return \"eol\"; }\n\t};\n\n\tconstexpr auto eol = eol_parser{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary/eps.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM)\n#define BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM\n\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../support/unused.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct rule_context_tag;\n\n\tstruct semantic_predicate : parser<semantic_predicate>\n\t{\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\tconstexpr semantic_predicate(bool predicate)\n\t\t  : predicate(predicate) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute&) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn predicate;\n\t\t}\n\n\t\tbool predicate;\n\t};\n\n\ttemplate <typename F>\n\tstruct lazy_semantic_predicate : parser<lazy_semantic_predicate<F>>\n\t{\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\tconstexpr lazy_semantic_predicate(F f)\n\t\t  : f(f) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& /* attr */) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn f(x3::get<rule_context_tag>(context));\n\t\t}\n\n\t\tF f;\n\t};\n\n\tstruct eps_parser : parser<eps_parser>\n\t{\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext&, Attribute&) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn true;\n\t\t}\n\n\t\tconstexpr semantic_predicate operator()(bool predicate) const\n\t\t{\n\t\t\treturn { predicate };\n\t\t}\n\n\t\ttemplate <typename F>\n\t\tconstexpr lazy_semantic_predicate<F> operator()(F f) const\n\t\t{\n\t\t\treturn { f };\n\t\t}\n\t};\n\n\tconstexpr auto eps = eps_parser{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary/guard.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM)\n#define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM\n\n#include \"../support/context.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tenum class error_handler_result\n\t{\n\t\tfail\n\t  , retry\n\t  , accept\n\t  , rethrow\n\t};\n\n\ttemplate <typename Subject, typename Handler>\n\tstruct guard : unary_parser<Subject, guard<Subject, Handler>>\n\t{\n\t\ttypedef unary_parser<Subject, guard<Subject, Handler>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\n\t\tconstexpr guard(Subject const& subject, Handler handler)\n\t\t  : base_type(subject), handler(handler) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tIterator i = first;\n\t\t\t\tif (this->subject.parse(i, last, context, rcontext, attr))\n\t\t\t\t{\n\t\t\t\t\tfirst = i;\n\t\t\t\t\treturn true;\n\t\t\t\t} else if (has_expectation_failure(context)) {\n\t\t\t\t\tswitch (handler(first, last, get_expectation_failure(first, context), context))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase error_handler_result::fail:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tcase error_handler_result::retry:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcase error_handler_result::accept:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase error_handler_result::rethrow:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tHandler handler;\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/auxiliary.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM)\n#define BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM\n\n#include \"auxiliary/eps.hpp\"\n#include \"auxiliary/guard.hpp\"\n#include \"auxiliary/eol.hpp\"\n#include \"auxiliary/eoi.hpp\"\n#include \"auxiliary/attr.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/binary/binary.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2001-2011 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM)\n#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include <cstdint>\n\n#include <boost/endian/conversion.hpp>\n#include <boost/endian/arithmetic.hpp>\n#include <boost/mpl/or.hpp>\n#include <boost/type_traits/is_integral.hpp>\n#include <boost/type_traits/is_enum.hpp>\n#include <boost/type_traits/is_floating_point.hpp>\n#include <boost/config.hpp>\n#include <climits>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename T, boost::endian::order endian, std::size_t bits>\n\tstruct binary_lit_parser\n\t  : parser<binary_lit_parser<T, endian, bits> >\n\t{\n\t\tstatic bool const has_attribute = false;\n\t\ttypedef unused_type attribute_type;\n\n\t\tconstexpr binary_lit_parser(T n_)\n\t\t  : n(n_) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr_param) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\n\t\t\tunsigned char const* bytes = n.data();\n\n\t\t\tIterator it = first;\n\t\t\tfor (unsigned int i = 0; i < sizeof(n); ++i)\n\t\t\t{\n\t\t\t\tif (it == last || *bytes++ != static_cast<unsigned char>(*it++))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfirst = it;\n\t\t\tx3::traits::move_to(n, attr_param);\n\t\t\treturn true;\n\t\t}\n\n\t\tboost::endian::endian_arithmetic<endian, T, bits> n;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, boost::endian::order endian, std::size_t bits>\n\tstruct any_binary_parser : parser<any_binary_parser<T, endian, bits > >\n\t{\n\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr_param) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\n\t\t\t// Properly align the buffer for performance reasons\n\t\t\talignas(T) unsigned char buf[sizeof(T)];\n\t\t\tunsigned char * bytes = buf;\n\n\t\t\tIterator it = first;\n\t\t\tfor (unsigned int i = 0; i < sizeof(T); ++i)\n\t\t\t{\n\t\t\t\tif (it == last)\n\t\t\t\t\treturn false;\n\t\t\t\t*bytes++ = *it++;\n\t\t\t}\n\n\t\t\tfirst = it;\n\n\t\t\tstatic_assert(bits % CHAR_BIT == 0,\n\t\t\t\t\t\t  \"Boost.Endian supports only multiples of CHAR_BIT\");\n\t\t\tx3::traits::move_to(\n\t\t\t\tendian::endian_load<T, bits / CHAR_BIT, endian>(buf),\n\t\t\t\tattr_param);\n\t\t\treturn true;\n\t\t}\n\n\t\tconstexpr binary_lit_parser<T, endian, bits> operator()(T n) const\n\t\t{\n\t\t\treturn {n};\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits)                  \\\n\ttypedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \\\n\tconstexpr name##type name = name##type();\n\n\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)\n#ifdef BOOST_HAS_LONG_LONG\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)\n#endif\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, sizeof(float) * CHAR_BIT)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, sizeof(float) * CHAR_BIT)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, sizeof(float) * CHAR_BIT)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, sizeof(double) * CHAR_BIT)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, sizeof(double) * CHAR_BIT)\n\tBOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, sizeof(double) * CHAR_BIT)\n\n#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, std::size_t bits>\n\tstruct get_info<any_binary_parser<T, endian::order::little, bits>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(any_binary_parser<T, endian::order::little, bits> const&) const\n\t\t{\n\t\t\treturn \"little-endian binary\";\n\t\t}\n\t};\n\n\ttemplate <typename T, std::size_t bits>\n\tstruct get_info<any_binary_parser<T, endian::order::big, bits>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(any_binary_parser<T, endian::order::big, bits> const&) const\n\t\t{\n\t\t\treturn \"big-endian binary\";\n\t\t}\n\t};\n\n\ttemplate <typename T, std::size_t bits>\n\tstruct get_info<binary_lit_parser<T, endian::order::little, bits>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(binary_lit_parser<T, endian::order::little, bits> const&) const\n\t\t{\n\t\t\treturn \"little-endian binary\";\n\t\t}\n\t};\n\n\ttemplate <typename T, std::size_t bits>\n\tstruct get_info<binary_lit_parser<T, endian::order::big, bits>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(binary_lit_parser<T, endian::order::big, bits> const&) const\n\t\t{\n\t\t\treturn \"big-endian binary\";\n\t\t}\n\t};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/binary.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0906AM)\n#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0906AM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#include \"binary/binary.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/any_char.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM)\n#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM\n\n#include <boost/type_traits/extent.hpp>\n#include \"literal_char.hpp\"\n#include \"char_set.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Encoding>\n\tstruct any_char : char_parser<any_char<Encoding>>\n\t{\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef Encoding encoding;\n\t\ttypedef char_type attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch_, Context const&) const\n\t\t{\n\t\t\treturn encoding::ischar(ch_);\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tconstexpr literal_char<Encoding> operator()(Char ch) const\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tconstexpr literal_char<Encoding> operator()(const Char (&ch)[2]) const\n\t\t{\n\t\t\treturn { ch[0] };\n\t\t}\n\n\t\ttemplate <typename Char, std::size_t N>\n\t\tconstexpr char_set<Encoding> operator()(const Char (&ch)[N]) const\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tconstexpr char_range<Encoding> operator()(Char from, Char to) const\n\t\t{\n\t\t\treturn { from, to };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tconstexpr char_range<Encoding> operator()(Char (&from)[2], Char (&to)[2]) const\n\t\t{\n\t\t\treturn { static_cast<char_type>(from[0]), static_cast<char_type>(to[0]) };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tchar_set<Encoding> operator()(std::basic_string<Char> const& s) const\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/char.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM)\n#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM\n\n#include \"any_char.hpp\"\n#include \"../../support/char_encoding/ascii.hpp\"\n#include \"../../support/char_encoding/iso8859_1.hpp\"\n#include \"../../support/char_encoding/standard.hpp\"\n#include \"../../support/char_encoding/standard_wide.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tnamespace standard\n\t{\n\t\ttypedef any_char<char_encoding::standard> char_type;\n\t\tconstexpr auto char_ = char_type{};\n\n\t\tconstexpr literal_char<char_encoding::standard, unused_type>\n\t\tlit(char ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t\tconstexpr literal_char<char_encoding::standard, unused_type>\n\t\tlit(wchar_t ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t}\n\n\tusing standard::char_type;\n\tusing standard::char_;\n\tusing standard::lit;\n\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tnamespace standard_wide\n\t{\n\t\ttypedef any_char<char_encoding::standard_wide> char_type;\n\t\tconstexpr auto char_ = char_type{};\n\n\t\tconstexpr literal_char<char_encoding::standard_wide, unused_type>\n\t\tlit(wchar_t ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\t}\n#endif\n\n\tnamespace ascii\n\t{\n\t\ttypedef any_char<char_encoding::ascii> char_type;\n\t\tconstexpr auto char_ = char_type{};\n\n\t\tconstexpr literal_char<char_encoding::ascii, unused_type>\n\t\tlit(char ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t\tconstexpr literal_char<char_encoding::ascii, unused_type>\n\t\tlit(wchar_t ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\t}\n\n\tnamespace iso8859_1\n\t{\n\t\ttypedef any_char<char_encoding::iso8859_1> char_type;\n\t\tconstexpr auto char_ = char_type{};\n\n\t\tconstexpr literal_char<char_encoding::iso8859_1, unused_type>\n\t\tlit(char ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\n\t\tconstexpr literal_char<char_encoding::iso8859_1, unused_type>\n\t\tlit(wchar_t ch)\n\t\t{\n\t\t\treturn { ch };\n\t\t}\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/char_class.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM)\n#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM\n\n#include \"char_parser.hpp\"\n#include \"detail/cast_char.hpp\"\n#include \"../../support/char_encoding/standard.hpp\"\n#include \"../../support/char_encoding/standard_wide.hpp\"\n#include \"../../support/char_encoding/ascii.hpp\"\n#include \"../../support/char_encoding/iso8859_1.hpp\"\n#include \"char_class_tags.hpp\"\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Encoding>\n\tstruct char_class_base\n\t{\n\t\ttypedef typename Encoding::classify_type char_type;\n\n#define BOOST_SPIRIT_X3_CLASSIFY(name)                                          \\\n\t\ttemplate <typename Char>                                                \\\n\t\tstatic bool                                                             \\\n\t\tis(name##_tag, Char ch)                                                 \\\n\t\t{                                                                       \\\n\t\t\treturn Encoding::is##name                                           \\\n\t\t\t\tBOOST_PREVENT_MACRO_SUBSTITUTION                                \\\n\t\t\t\t\t(detail::cast_char<char_type>(ch));                         \\\n\t\t}                                                                       \\\n\t\t/***/\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(char)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(alnum)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(alpha)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(digit)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(xdigit)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cntrl)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(graph)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lower)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(print)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(punct)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(space)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(blank)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(upper)\n\n#undef BOOST_SPIRIT_X3_CLASSIFY\n\t};\n\n\ttemplate <typename Encoding, typename Tag>\n\tstruct char_class\n\t  : char_parser<char_class<Encoding, Tag>>\n\t{\n\t\ttypedef Encoding encoding;\n\t\ttypedef Tag tag;\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef char_type attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch, Context const& context) const\n\t\t{\n\t\t\treturn encoding::ischar(ch)\n\t\t\t\t&& char_class_base<Encoding>::is(\n\t\t\t\t\tget_case_compare<Encoding>(context).get_char_class_tag(tag()), ch);\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_X3_CHAR_CLASS(encoding, name)                                 \\\n\ttypedef char_class<char_encoding::encoding, name##_tag> name##_type;           \\\n\tconstexpr name##_type name = name##_type();                                    \\\n\t/***/\n\n#define BOOST_SPIRIT_X3_CHAR_CLASSES(encoding)                                     \\\n\tnamespace encoding                                                             \\\n\t{                                                                              \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, alnum)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, alpha)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, digit)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, xdigit)                               \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, cntrl)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, graph)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, lower)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, print)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, punct)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, space)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, blank)                                \\\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(encoding, upper)                                \\\n\t}                                                                              \\\n\t/***/\n\n\tBOOST_SPIRIT_X3_CHAR_CLASSES(standard)\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tBOOST_SPIRIT_X3_CHAR_CLASSES(standard_wide)\n#endif\n\tBOOST_SPIRIT_X3_CHAR_CLASSES(ascii)\n\tBOOST_SPIRIT_X3_CHAR_CLASSES(iso8859_1)\n\n#undef BOOST_SPIRIT_X3_CHAR_CLASS\n#undef BOOST_SPIRIT_X3_CHAR_CLASSES\n\n\tusing standard::alnum_type;\n\tusing standard::alpha_type;\n\tusing standard::digit_type;\n\tusing standard::xdigit_type;\n\tusing standard::cntrl_type;\n\tusing standard::graph_type;\n\tusing standard::lower_type;\n\tusing standard::print_type;\n\tusing standard::punct_type;\n\tusing standard::space_type;\n\tusing standard::blank_type;\n\tusing standard::upper_type;\n\n\tusing standard::alnum;\n\tusing standard::alpha;\n\tusing standard::digit;\n\tusing standard::xdigit;\n\tusing standard::cntrl;\n\tusing standard::graph;\n\tusing standard::lower;\n\tusing standard::print;\n\tusing standard::punct;\n\tusing standard::space;\n\tusing standard::blank;\n\tusing standard::upper;\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/char_class_tags.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM)\n#define BOOST_SPIRIT_X3_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM\n\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct char_tag {};\n\tstruct alnum_tag {};\n\tstruct alpha_tag {};\n\tstruct blank_tag {};\n\tstruct cntrl_tag {};\n\tstruct digit_tag {};\n\tstruct graph_tag {};\n\tstruct print_tag {};\n\tstruct punct_tag {};\n\tstruct space_tag {};\n\tstruct xdigit_tag {};\n\tstruct lower_tag {};\n\tstruct upper_tag {};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/char_parser.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM)\n#define BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include \"../support/no_case.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// The base char_parser\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Derived>\n\tstruct char_parser : parser<Derived>\n\t{\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\tif (first != last && this->derived().test(*first, context))\n\t\t\t{\n\t\t\t\tx3::traits::move_to(*first, attr);\n\t\t\t\t++first;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/char_set.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM)\n#define BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM\n\n#include \"char_parser.hpp\"\n#include \"detail/cast_char.hpp\"\n#include \"../support/traits/string_traits.hpp\"\n#include \"../support/utility/utf8.hpp\"\n#include \"../support/no_case.hpp\"\n#include \"../../support/char_set/basic_chset.hpp\"\n\n#include <boost/type_traits/is_same.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Parser for a character range\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Encoding, typename Attribute = typename Encoding::char_type>\n\tstruct char_range\n\t  : char_parser< char_range<Encoding, Attribute> >\n\t{\n\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef Encoding encoding;\n\t\ttypedef Attribute attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\n\n\t\tconstexpr char_range(char_type from_, char_type to_)\n\t\t  : from(from_), to(to_) {}\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch_, Context const& context) const\n\t\t{\n\n\t\t\tchar_type ch = char_type(ch_);  // optimize for token based parsing\n\t\t\treturn (get_case_compare<encoding>(context)(ch, from) >= 0)\n\t\t\t   && (get_case_compare<encoding>(context)(ch , to) <= 0);\n\t\t}\n\n\t\tchar_type from, to;\n\t};\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Parser for a character set\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Encoding, typename Attribute = typename Encoding::char_type>\n\tstruct char_set : char_parser<char_set<Encoding, Attribute>>\n\t{\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef Encoding encoding;\n\t\ttypedef Attribute attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\n\t\ttemplate <typename String>\n\t\tchar_set(String const& str)\n\t\t{\n\t\t\tusing spirit::x3::detail::cast_char;\n\n\t\t\tauto* definition = traits::get_c_string(str);\n\t\t\tauto ch = *definition++;\n\t\t\twhile (ch)\n\t\t\t{\n\t\t\t\tauto next = *definition++;\n\t\t\t\tif (next == '-')\n\t\t\t\t{\n\t\t\t\t\tnext = *definition++;\n\t\t\t\t\tif (next == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tchset.set(cast_char<char_type>(ch));\n\t\t\t\t\t\tchset.set('-');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tchset.set(\n\t\t\t\t\t\tcast_char<char_type>(ch),\n\t\t\t\t\t\tcast_char<char_type>(next)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tchset.set(cast_char<char_type>(ch));\n\t\t\t\t}\n\t\t\t\tch = next;\n\t\t\t}\n\t\t}\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch_, Context const& context) const\n\t\t{\n\t\t\treturn get_case_compare<encoding>(context).in_set(ch_, chset);\n\t\t}\n\n\t\tsupport::detail::basic_chset<char_type> chset;\n\t};\n\n\ttemplate <typename Encoding, typename Attribute>\n\tstruct get_info<char_set<Encoding, Attribute>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(char_set<Encoding, Attribute> const& /* p */) const\n\t\t{\n\t\t\treturn \"char-set\";\n\t\t}\n\t};\n\n\ttemplate <typename Encoding, typename Attribute>\n\tstruct get_info<char_range<Encoding, Attribute>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(char_range<Encoding, Attribute> const& p) const\n\t\t{\n\t\t\treturn \"char_range \\\"\" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '\"';\n\t\t}\n\t};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/detail/cast_char.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)\n#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM\n\n#include <boost/type_traits/is_signed.hpp>\n#include <boost/type_traits/make_unsigned.hpp>\n#include <boost/type_traits/make_signed.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\t// Here's the thing... typical encodings (except ASCII) deal with unsigned\n\t// integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.\n\t// Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you\n\t// cast this to an unsigned int with 32 bits, you get 4294967273!\n\t//\n\t// The trick is to cast to an unsigned version of the source char first\n\t// before casting to the target. {P.S. Don't worry about the code, the\n\t// optimizer will optimize the if-else branches}\n\n\ttemplate <typename TargetChar, typename SourceChar>\n\tTargetChar cast_char(SourceChar ch)\n\t{\n#if defined(_MSC_VER)\n# pragma warning(push)\n# pragma warning(disable: 4127) // conditional expression is constant\n#endif\n\t\tif (is_signed<TargetChar>::value != is_signed<SourceChar>::value)\n\t\t{\n\t\t\tif (is_signed<SourceChar>::value)\n\t\t\t{\n\t\t\t\t // source is signed, target is unsigned\n\t\t\t\ttypedef typename make_unsigned<SourceChar>::type USourceChar;\n\t\t\t\treturn TargetChar(USourceChar(ch));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t // source is unsigned, target is signed\n\t\t\t\ttypedef typename make_signed<SourceChar>::type SSourceChar;\n\t\t\t\treturn TargetChar(SSourceChar(ch));\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// source and target has same signedness\n\t\t\treturn TargetChar(ch); // just cast\n\t\t}\n#if defined(_MSC_VER)\n# pragma warning(pop)\n#endif\n\t}\n}}}}\n\n#endif\n\n\n"
  },
  {
    "path": "tc/string/spirit/x3/char/literal_char.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM)\n#define BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM\n\n#include \"char_parser.hpp\"\n#include \"../support/utility/utf8.hpp\"\n#include <boost/type_traits/is_same.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Encoding, typename Attribute = typename Encoding::char_type>\n\tstruct literal_char : char_parser<literal_char<Encoding, Attribute>>\n\t{\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef Encoding encoding;\n\t\ttypedef Attribute attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\n\t\ttemplate <typename Char>\n\t\tconstexpr literal_char(Char ch)\n\t\t  : ch(static_cast<char_type>(ch)) {}\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch_, Context const& context) const\n\t\t{\n\t\t\treturn get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0;\n\t\t}\n\n\t\tchar_type ch;\n\t};\n\n\ttemplate <typename Encoding, typename Attribute>\n\tstruct get_info<literal_char<Encoding, Attribute>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(literal_char<Encoding, Attribute> const& p) const\n\t\t{\n\t\t\treturn '\\'' + to_utf8(Encoding::toucs4(p.ch)) + '\\'';\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/negated_char_parser.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM)\n#define BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM\n\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../support/traits/has_attribute.hpp\"\n#include \"char_parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// negated_char_parser handles ~cp expressions (cp is a char_parser)\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Positive>\n\tstruct negated_char_parser :\n\t\tchar_parser<negated_char_parser<Positive>>\n\t{\n\t\tconstexpr negated_char_parser(Positive const& positive)\n\t\t  : positive(positive) {}\n\n\t\ttemplate <typename CharParam, typename Context>\n\t\tbool test(CharParam ch, Context const& context) const\n\t\t{\n\t\t\treturn !positive.test(ch, context);\n\t\t}\n\n\t\tPositive positive;\n\t};\n\n\ttemplate <typename Positive>\n\tconstexpr negated_char_parser<Positive>\n\toperator~(char_parser<Positive> const& cp)\n\t{\n\t\treturn { cp.derived() };\n\t}\n\n\ttemplate <typename Positive>\n\tconstexpr Positive const&\n\toperator~(negated_char_parser<Positive> const& cp)\n\t{\n\t\treturn cp.positive;\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Positive, typename Context>\n\tstruct attribute_of<x3::negated_char_parser<Positive>, Context>\n\t\t: attribute_of<Positive, Context> {};\n\n\ttemplate <typename Positive, typename Context>\n\tstruct has_attribute<x3::negated_char_parser<Positive>, Context>\n\t\t: has_attribute<Positive, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char/unicode.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM)\n#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM\n\n#include \"char_parser.hpp\"\n#include \"char.hpp\"\n#include \"detail/cast_char.hpp\"\n#include \"../../support/char_encoding/unicode.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct char_tag;\n\tstruct alnum_tag;\n\tstruct alpha_tag;\n\tstruct blank_tag;\n\tstruct cntrl_tag;\n\tstruct digit_tag;\n\tstruct graph_tag;\n\tstruct print_tag;\n\tstruct punct_tag;\n\tstruct space_tag;\n\tstruct xdigit_tag;\n\tstruct lower_tag;\n\tstruct upper_tag;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct letter_tag {};\n\tstruct mark_tag {};\n\tstruct number_tag {};\n\tstruct separator_tag {};\n\tstruct other_tag {};\n\tstruct punctuation_tag {};\n\tstruct symbol_tag {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode General Categories\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct uppercase_letter_tag {};\n\tstruct lowercase_letter_tag {};\n\tstruct titlecase_letter_tag {};\n\tstruct modifier_letter_tag {};\n\tstruct other_letter_tag {};\n\n\tstruct nonspacing_mark_tag {};\n\tstruct enclosing_mark_tag {};\n\tstruct spacing_mark_tag {};\n\n\tstruct decimal_number_tag {};\n\tstruct letter_number_tag {};\n\tstruct other_number_tag {};\n\n\tstruct space_separator_tag {};\n\tstruct line_separator_tag {};\n\tstruct paragraph_separator_tag {};\n\n\tstruct control_tag {};\n\tstruct format_tag {};\n\tstruct private_use_tag {};\n\tstruct surrogate_tag {};\n\tstruct unassigned_tag {};\n\n\tstruct dash_punctuation_tag {};\n\tstruct open_punctuation_tag {};\n\tstruct close_punctuation_tag {};\n\tstruct connector_punctuation_tag {};\n\tstruct other_punctuation_tag {};\n\tstruct initial_punctuation_tag {};\n\tstruct final_punctuation_tag {};\n\n\tstruct math_symbol_tag {};\n\tstruct currency_symbol_tag {};\n\tstruct modifier_symbol_tag {};\n\tstruct other_symbol_tag {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Derived Categories\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct alphabetic_tag {};\n\tstruct uppercase_tag {};\n\tstruct lowercase_tag {};\n\tstruct white_space_tag {};\n\tstruct hex_digit_tag {};\n\tstruct noncharacter_code_point_tag {};\n\tstruct default_ignorable_code_point_tag {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Scripts\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct adlam_tag {};\n\tstruct caucasian_albanian_tag {};\n\tstruct ahom_tag {};\n\tstruct arabic_tag {};\n\tstruct imperial_aramaic_tag {};\n\tstruct armenian_tag {};\n\tstruct avestan_tag {};\n\tstruct balinese_tag {};\n\tstruct bamum_tag {};\n\tstruct bassa_vah_tag {};\n\tstruct batak_tag {};\n\tstruct bengali_tag {};\n\tstruct bhaiksuki_tag {};\n\tstruct bopomofo_tag {};\n\tstruct brahmi_tag {};\n\tstruct braille_tag {};\n\tstruct buginese_tag {};\n\tstruct buhid_tag {};\n\tstruct chakma_tag {};\n\tstruct canadian_aboriginal_tag {};\n\tstruct carian_tag {};\n\tstruct cham_tag {};\n\tstruct cherokee_tag {};\n\tstruct chorasmian_tag {};\n\tstruct coptic_tag {};\n\tstruct cypro_minoan_tag {};\n\tstruct cypriot_tag {};\n\tstruct cyrillic_tag {};\n\tstruct devanagari_tag {};\n\tstruct dives_akuru_tag {};\n\tstruct dogra_tag {};\n\tstruct deseret_tag {};\n\tstruct duployan_tag {};\n\tstruct egyptian_hieroglyphs_tag {};\n\tstruct elbasan_tag {};\n\tstruct elymaic_tag {};\n\tstruct ethiopic_tag {};\n\tstruct georgian_tag {};\n\tstruct glagolitic_tag {};\n\tstruct gunjala_gondi_tag {};\n\tstruct masaram_gondi_tag {};\n\tstruct gothic_tag {};\n\tstruct grantha_tag {};\n\tstruct greek_tag {};\n\tstruct gujarati_tag {};\n\tstruct gurmukhi_tag {};\n\tstruct hangul_tag {};\n\tstruct han_tag {};\n\tstruct hanunoo_tag {};\n\tstruct hatran_tag {};\n\tstruct hebrew_tag {};\n\tstruct hiragana_tag {};\n\tstruct anatolian_hieroglyphs_tag {};\n\tstruct pahawh_hmong_tag {};\n\tstruct nyiakeng_puachue_hmong_tag {};\n\tstruct katakana_or_hiragana_tag {};\n\tstruct old_hungarian_tag {};\n\tstruct old_italic_tag {};\n\tstruct javanese_tag {};\n\tstruct kayah_li_tag {};\n\tstruct katakana_tag {};\n\tstruct kawi_tag {};\n\tstruct kharoshthi_tag {};\n\tstruct khmer_tag {};\n\tstruct khojki_tag {};\n\tstruct khitan_small_script_tag {};\n\tstruct kannada_tag {};\n\tstruct kaithi_tag {};\n\tstruct tai_tham_tag {};\n\tstruct lao_tag {};\n\tstruct latin_tag {};\n\tstruct lepcha_tag {};\n\tstruct limbu_tag {};\n\tstruct linear_a_tag {};\n\tstruct linear_b_tag {};\n\tstruct lisu_tag {};\n\tstruct lycian_tag {};\n\tstruct lydian_tag {};\n\tstruct mahajani_tag {};\n\tstruct makasar_tag {};\n\tstruct mandaic_tag {};\n\tstruct manichaean_tag {};\n\tstruct marchen_tag {};\n\tstruct medefaidrin_tag {};\n\tstruct mende_kikakui_tag {};\n\tstruct meroitic_cursive_tag {};\n\tstruct meroitic_hieroglyphs_tag {};\n\tstruct malayalam_tag {};\n\tstruct modi_tag {};\n\tstruct mongolian_tag {};\n\tstruct mro_tag {};\n\tstruct meetei_mayek_tag {};\n\tstruct multani_tag {};\n\tstruct myanmar_tag {};\n\tstruct nag_mundari_tag {};\n\tstruct nandinagari_tag {};\n\tstruct old_north_arabian_tag {};\n\tstruct nabataean_tag {};\n\tstruct newa_tag {};\n\tstruct nko_tag {};\n\tstruct nushu_tag {};\n\tstruct ogham_tag {};\n\tstruct ol_chiki_tag {};\n\tstruct old_turkic_tag {};\n\tstruct oriya_tag {};\n\tstruct osage_tag {};\n\tstruct osmanya_tag {};\n\tstruct old_uyghur_tag {};\n\tstruct palmyrene_tag {};\n\tstruct pau_cin_hau_tag {};\n\tstruct old_permic_tag {};\n\tstruct phags_pa_tag {};\n\tstruct inscriptional_pahlavi_tag {};\n\tstruct psalter_pahlavi_tag {};\n\tstruct phoenician_tag {};\n\tstruct miao_tag {};\n\tstruct inscriptional_parthian_tag {};\n\tstruct rejang_tag {};\n\tstruct hanifi_rohingya_tag {};\n\tstruct runic_tag {};\n\tstruct samaritan_tag {};\n\tstruct old_south_arabian_tag {};\n\tstruct saurashtra_tag {};\n\tstruct signwriting_tag {};\n\tstruct shavian_tag {};\n\tstruct sharada_tag {};\n\tstruct siddham_tag {};\n\tstruct khudawadi_tag {};\n\tstruct sinhala_tag {};\n\tstruct sogdian_tag {};\n\tstruct old_sogdian_tag {};\n\tstruct sora_sompeng_tag {};\n\tstruct soyombo_tag {};\n\tstruct sundanese_tag {};\n\tstruct syloti_nagri_tag {};\n\tstruct syriac_tag {};\n\tstruct tagbanwa_tag {};\n\tstruct takri_tag {};\n\tstruct tai_le_tag {};\n\tstruct new_tai_lue_tag {};\n\tstruct tamil_tag {};\n\tstruct tangut_tag {};\n\tstruct tai_viet_tag {};\n\tstruct telugu_tag {};\n\tstruct tifinagh_tag {};\n\tstruct tagalog_tag {};\n\tstruct thaana_tag {};\n\tstruct thai_tag {};\n\tstruct tibetan_tag {};\n\tstruct tirhuta_tag {};\n\tstruct tangsa_tag {};\n\tstruct toto_tag {};\n\tstruct ugaritic_tag {};\n\tstruct vai_tag {};\n\tstruct vithkuqi_tag {};\n\tstruct warang_citi_tag {};\n\tstruct wancho_tag {};\n\tstruct old_persian_tag {};\n\tstruct cuneiform_tag {};\n\tstruct yezidi_tag {};\n\tstruct yi_tag {};\n\tstruct zanabazar_square_tag {};\n\tstruct inherited_tag {};\n\tstruct common_tag {};\n\tstruct unknown_tag {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\tstruct unicode_char_class_base\n\t{\n\t\ttypedef char_encoding::unicode encoding;\n\t\ttypedef char_encoding::unicode::char_type char_type;\n\n#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name)                                     \\\n\t\ttemplate <typename Char>                                                 \\\n\t\tstatic bool                                                              \\\n\t\tis(name##_tag, Char ch)                                                  \\\n\t\t{                                                                        \\\n\t\t\treturn encoding::is ##name                                           \\\n\t\t\t\tBOOST_PREVENT_MACRO_SUBSTITUTION                                 \\\n\t\t\t\t\t(detail::cast_char<char_type>(ch));                          \\\n\t\t}                                                                        \\\n\t\t/***/\n\n#define BOOST_SPIRIT_X3_CLASSIFY(name)                                           \\\n\t\ttemplate <typename Char>                                                 \\\n\t\tstatic bool                                                              \\\n\t\tis(name##_tag, Char ch)                                                  \\\n\t\t{                                                                        \\\n\t\t\treturn encoding::is_##name                                           \\\n\t\t\t\tBOOST_PREVENT_MACRO_SUBSTITUTION                                 \\\n\t\t\t\t\t(detail::cast_char<char_type>(ch));                          \\\n\t\t}                                                                        \\\n\t\t/***/\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(char)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(alnum)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(alpha)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(digit)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(xdigit)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(cntrl)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(graph)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(lower)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(print)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(punct)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(space)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(blank)\n\t\tBOOST_SPIRIT_X3_BASIC_CLASSIFY(upper)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CLASSIFY(letter)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mark)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(number)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(separator)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(other)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode General Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CLASSIFY(uppercase_letter)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lowercase_letter)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(titlecase_letter)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(modifier_letter)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(other_letter)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nonspacing_mark)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(enclosing_mark)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(spacing_mark)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(decimal_number)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(letter_number)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(other_number)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(space_separator)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(line_separator)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(paragraph_separator)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(control)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(format)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(private_use)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(surrogate)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(unassigned)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(dash_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(open_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(close_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(connector_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(other_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(initial_punctuation)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(final_punctuation)\n\n\t\tBOOST_SPIRIT_X3_CLASSIFY(math_symbol)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(currency_symbol)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(modifier_symbol)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(other_symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Derived Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CLASSIFY(alphabetic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(uppercase)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lowercase)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(white_space)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hex_digit)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(noncharacter_code_point)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(default_ignorable_code_point)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Scripts\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CLASSIFY(adlam)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(caucasian_albanian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(ahom)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(arabic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(imperial_aramaic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(armenian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(avestan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(balinese)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(bamum)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(bassa_vah)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(batak)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(bengali)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(bhaiksuki)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(bopomofo)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(brahmi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(braille)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(buginese)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(buhid)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(chakma)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(canadian_aboriginal)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(carian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cham)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cherokee)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(chorasmian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(coptic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cypro_minoan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cypriot)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cyrillic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(devanagari)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(dives_akuru)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(dogra)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(deseret)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(duployan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(egyptian_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(elbasan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(elymaic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(ethiopic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(georgian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(glagolitic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(gunjala_gondi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(masaram_gondi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(gothic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(grantha)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(greek)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(gujarati)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(gurmukhi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hangul)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(han)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hanunoo)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hatran)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hebrew)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hiragana)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(anatolian_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(pahawh_hmong)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nyiakeng_puachue_hmong)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(katakana_or_hiragana)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_hungarian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_italic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(javanese)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(kayah_li)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(katakana)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(kawi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(kharoshthi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(khmer)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(khojki)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(khitan_small_script)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(kannada)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(kaithi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tai_tham)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lao)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(latin)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lepcha)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(limbu)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(linear_a)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(linear_b)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lisu)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lycian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(lydian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mahajani)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(makasar)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mandaic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(manichaean)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(marchen)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(medefaidrin)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mende_kikakui)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(meroitic_cursive)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(meroitic_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(malayalam)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(modi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mongolian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(mro)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(meetei_mayek)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(multani)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(myanmar)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nag_mundari)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nandinagari)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_north_arabian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nabataean)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(newa)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nko)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(nushu)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(ogham)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(ol_chiki)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_turkic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(oriya)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(osage)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(osmanya)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_uyghur)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(palmyrene)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(pau_cin_hau)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_permic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(phags_pa)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(inscriptional_pahlavi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(psalter_pahlavi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(phoenician)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(miao)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(inscriptional_parthian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(rejang)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(hanifi_rohingya)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(runic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(samaritan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_south_arabian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(saurashtra)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(signwriting)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(shavian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(sharada)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(siddham)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(khudawadi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(sinhala)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(sogdian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_sogdian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(sora_sompeng)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(soyombo)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(sundanese)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(syloti_nagri)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(syriac)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tagbanwa)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(takri)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tai_le)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(new_tai_lue)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tamil)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tangut)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tai_viet)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(telugu)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tifinagh)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tagalog)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(thaana)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(thai)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tibetan)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tirhuta)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(tangsa)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(toto)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(ugaritic)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(vai)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(vithkuqi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(warang_citi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(wancho)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(old_persian)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(cuneiform)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(yezidi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(yi)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(zanabazar_square)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(inherited)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(common)\n\t\tBOOST_SPIRIT_X3_CLASSIFY(unknown)\n\n#undef BOOST_SPIRIT_X3_BASIC_CLASSIFY\n#undef BOOST_SPIRIT_X3_CLASSIFY\n\t};\n\n\ttemplate <typename Tag>\n\tstruct unicode_char_class\n\t  : char_parser<unicode_char_class<Tag>>\n\t{\n\t\ttypedef char_encoding::unicode encoding;\n\t\ttypedef Tag tag;\n\t\ttypedef typename encoding::char_type char_type;\n\t\ttypedef char_type attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Char, typename Context>\n\t\tbool test(Char ch, Context const&) const\n\t\t{\n\t\t\treturn encoding::ischar(ch) && unicode_char_class_base::is(tag(), ch);\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_X3_CHAR_CLASS(name)                                         \\\n\ttypedef unicode_char_class<name##_tag> name##_type;                          \\\n\tconstexpr name##_type name = name##_type();                                  \\\n\t/***/\n\n\tnamespace unicode\n\t{\n\t\ttypedef any_char<char_encoding::unicode> char_type;\n\t\tconstexpr auto char_ = char_type{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(alnum)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(alpha)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(digit)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(xdigit)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cntrl)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(graph)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lower)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(print)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(punct)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(space)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(blank)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(upper)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Major Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(letter)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mark)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(number)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(separator)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(other)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode General Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(uppercase_letter)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lowercase_letter)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(titlecase_letter)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(modifier_letter)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(other_letter)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nonspacing_mark)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(enclosing_mark)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(spacing_mark)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(decimal_number)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(letter_number)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(other_number)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(space_separator)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(line_separator)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(paragraph_separator)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(control)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(format)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(private_use)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(surrogate)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(unassigned)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(dash_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(open_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(close_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(connector_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(other_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(initial_punctuation)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(final_punctuation)\n\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(math_symbol)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(currency_symbol)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(modifier_symbol)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(other_symbol)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Derived Categories\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(alphabetic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(uppercase)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lowercase)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(white_space)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hex_digit)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(noncharacter_code_point)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(default_ignorable_code_point)\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Unicode Scripts\n\t///////////////////////////////////////////////////////////////////////////\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(adlam)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(caucasian_albanian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(ahom)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(arabic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(imperial_aramaic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(armenian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(avestan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(balinese)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(bamum)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(bassa_vah)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(batak)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(bengali)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(bhaiksuki)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(bopomofo)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(brahmi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(braille)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(buginese)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(buhid)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(chakma)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(canadian_aboriginal)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(carian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cham)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cherokee)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(chorasmian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(coptic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cypro_minoan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cypriot)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cyrillic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(devanagari)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(dives_akuru)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(dogra)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(deseret)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(duployan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(egyptian_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(elbasan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(elymaic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(ethiopic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(georgian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(glagolitic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(gunjala_gondi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(masaram_gondi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(gothic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(grantha)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(greek)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(gujarati)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(gurmukhi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hangul)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(han)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hanunoo)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hatran)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hebrew)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hiragana)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(anatolian_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(pahawh_hmong)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nyiakeng_puachue_hmong)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(katakana_or_hiragana)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_hungarian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_italic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(javanese)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(kayah_li)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(katakana)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(kawi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(kharoshthi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(khmer)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(khojki)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(khitan_small_script)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(kannada)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(kaithi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tai_tham)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lao)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(latin)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lepcha)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(limbu)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(linear_a)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(linear_b)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lisu)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lycian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(lydian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mahajani)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(makasar)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mandaic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(manichaean)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(marchen)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(medefaidrin)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mende_kikakui)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(meroitic_cursive)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(meroitic_hieroglyphs)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(malayalam)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(modi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mongolian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(mro)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(meetei_mayek)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(multani)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(myanmar)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nag_mundari)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nandinagari)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_north_arabian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nabataean)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(newa)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nko)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(nushu)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(ogham)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(ol_chiki)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_turkic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(oriya)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(osage)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(osmanya)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_uyghur)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(palmyrene)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(pau_cin_hau)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_permic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(phags_pa)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_pahlavi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(psalter_pahlavi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(phoenician)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(miao)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_parthian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(rejang)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(hanifi_rohingya)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(runic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(samaritan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_south_arabian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(saurashtra)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(signwriting)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(shavian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(sharada)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(siddham)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(khudawadi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(sinhala)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(sogdian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_sogdian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(sora_sompeng)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(soyombo)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(sundanese)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(syloti_nagri)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(syriac)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tagbanwa)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(takri)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tai_le)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(new_tai_lue)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tamil)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tangut)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tai_viet)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(telugu)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tifinagh)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tagalog)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(thaana)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(thai)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tibetan)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tirhuta)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(tangsa)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(toto)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(ugaritic)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(vai)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(vithkuqi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(warang_citi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(wancho)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(old_persian)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(cuneiform)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(yezidi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(yi)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(zanabazar_square)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(inherited)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(common)\n\t\tBOOST_SPIRIT_X3_CHAR_CLASS(unknown)\n\t}\n\n#undef BOOST_SPIRIT_X3_CHAR_CLASS\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/char.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM)\n#define BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM\n\n#include \"char/char_parser.hpp\"\n#include \"char/negated_char_parser.hpp\"\n#include \"char/char.hpp\"\n#include \"char/char_class.hpp\"\n#include \"char/char_set.hpp\"\n\n#if defined(BOOST_SPIRIT_X3_UNICODE)\n#include \"char/unicode.hpp\"\n#endif\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/action.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ACTION_JANUARY_07_2007_1128AM)\n#define BOOST_SPIRIT_X3_ACTION_JANUARY_07_2007_1128AM\n\n#include \"../support/context.hpp\"\n#include \"../support/traits/attribute_of.hpp\"\n#include \"call.hpp\"\n#include \"../nonterminal/detail/transform_attribute.hpp\"\n#include <boost/range/iterator_range_core.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct raw_attribute_type;\n\tstruct parse_pass_context_tag;\n\n\ttemplate <typename Context>\n\tinline bool& _pass(Context const& context)\n\t{\n\t\treturn x3::get<parse_pass_context_tag>(context);\n\t}\n\n\ttemplate <typename Subject, typename Action>\n\tstruct action : unary_parser<Subject, action<Subject, Action>>\n\t{\n\t\ttypedef unary_parser<Subject, action<Subject, Action>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const has_action = true;\n\n\t\tconstexpr action(Subject const& subject, Action f)\n\t\t  : base_type(subject), f(f) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename RuleContext, typename Attribute>\n\t\tbool call_action(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tbool pass = true;\n\t\t\tauto action_context = make_context<parse_pass_context_tag>(pass, context);\n\t\t\tcall(f, first, last, action_context, rcontext, attr);\n\t\t\treturn pass;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse_main(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tIterator save = first;\n\t\t\tif (this->subject.parse(first, last, context, rcontext, attr))\n\t\t\t{\n\t\t\t\tif (call_action(first, last, context, rcontext, attr))\n\t\t\t\t\treturn true;\n\n\t\t\t\t// reset iterators if semantic action failed the match\n\t\t\t\t// retrospectively\n\t\t\t\tfirst = save;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// attr==raw_attribute_type, action wants iterator_range (see raw.hpp)\n\t\ttemplate <typename Iterator, typename Context, typename RuleContext>\n\t\tbool parse_main(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, raw_attribute_type&) const\n\t\t{\n\t\t\tboost::iterator_range<Iterator> rng;\n\t\t\t// synthesize the attribute since one is not supplied\n\t\t\treturn parse_main(first, last, context, rcontext, rng);\n\t\t}\n\n\t\t// attr==unused, action wants attribute\n\t\ttemplate <typename Iterator, typename Context, typename RuleContext>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, unused_type) const\n\t\t{\n\t\t\ttypedef typename\n\t\t\t\ttraits::attribute_of<action<Subject, Action>, Context>::type\n\t\t\tattribute_type;\n\n\t\t\t// synthesize the attribute since one is not supplied\n\t\t\tattribute_type attribute{};\n\t\t\treturn parse_main(first, last, context, rcontext, attribute);\n\t\t}\n\n\t\t// main parse function\n\t\ttemplate <typename Iterator, typename Context\n\t\t\t, typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn parse_main(first, last, context, rcontext, attr);\n\t\t}\n\n\t\tAction f;\n\t};\n\n\ttemplate <spirit_parser P, typename Action>\n\tconstexpr action<P, Action>\n\toperator/(P const& p, Action f)\n\t{\n\t\treturn { p, f };\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/call.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CALL_CONTEXT_MAY_26_2014_0234PM)\n#define BOOST_SPIRIT_X3_CALL_CONTEXT_MAY_26_2014_0234PM\n\n#include <type_traits>\n\n#include \"../support/context.hpp\"\n#include \"../support/utility/is_callable.hpp\"\n#include <boost/range/iterator_range_core.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t////////////////////////////////////////////////////////////////////////////\n\tstruct rule_val_context_tag;\n\n\ttemplate <typename Context>\n\tinline decltype(auto) _val(Context const& context)\n\t{\n\t\treturn x3::get<rule_val_context_tag>(context);\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////\n\tstruct where_context_tag;\n\n\ttemplate <typename Context>\n\tinline decltype(auto) _where(Context const& context)\n\t{\n\t\treturn x3::get<where_context_tag>(context);\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////\n\tstruct attr_context_tag;\n\n\ttemplate <typename Context>\n\tinline decltype(auto) _attr(Context const& context)\n\t{\n\t\treturn x3::get<attr_context_tag>(context);\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////\n\tnamespace detail\n\t{\n\t\ttemplate <typename F, typename Context>\n\t\tauto call(F f, Context const& context, mpl::true_)\n\t\t{\n\t\t\treturn f(context);\n\t\t}\n\n\t\ttemplate <typename F, typename Context>\n\t\tauto call(F f, Context const& /* context */, mpl::false_)\n\t\t{\n\t\t\treturn f();\n\t\t}\n\t}\n\n\ttemplate <\n\t\ttypename F, typename Iterator\n\t  , typename Context, typename RuleContext, typename Attribute>\n\tauto call(\n\t\tF f, Iterator& first, Iterator const& last\n\t  , Context const& context, RuleContext& rcontext, Attribute& attr)\n\t{\n\t\tboost::iterator_range<Iterator> rng(first, last);\n\t\tauto val_context = make_context<rule_val_context_tag>(rcontext, context);\n\t\tauto where_context = make_context<where_context_tag>(rng, val_context);\n\t\tauto attr_context = make_context<attr_context_tag>(attr, where_context);\n\t\treturn detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/detail/parse_into_container.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM)\n#define BOOST_SPIRIT_X3_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM\n\n#include <type_traits>\n\n#include \"../../support/traits/container_traits.hpp\"\n#include \"../../support/traits/attribute_of.hpp\"\n#include \"../../support/traits/pseudo_attribute.hpp\"\n#include \"../../support/traits/handles_container.hpp\"\n#include \"../../support/traits/has_attribute.hpp\"\n#include \"../../support/traits/is_substitute.hpp\"\n#include \"../../support/traits/move_to.hpp\"\n#include <boost/mpl/and.hpp>\n#include <boost/fusion/include/at_key.hpp>\n#include <boost/fusion/include/front.hpp>\n#include <boost/fusion/include/back.hpp>\n#include <boost/variant/apply_visitor.hpp>\n#include <iterator> // for std::make_move_iterator\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename Attribute, typename Value>\n\tstruct saver_visitor;\n\n\t// save to associative fusion container where Key is simple type\n\ttemplate <typename Key, typename Enable = void>\n\tstruct save_to_assoc_attr\n\t{\n\t\ttemplate <typename Value, typename Attribute>\n\t\tstatic void call(const Key, Value& value, Attribute& attr)\n\t\t{\n\t\t\ttraits::move_to(value, fusion::at_key<Key>(attr));\n\t\t}\n\t};\n\n\t// save to associative fusion container where Key\n\t// is variant over possible keys\n\ttemplate <typename ...T>\n\tstruct save_to_assoc_attr<variant<T...> >\n\t{\n\t\ttypedef variant<T...> variant_t;\n\n\t\ttemplate <typename Value, typename Attribute>\n\t\tstatic void call(const variant_t key, Value& value, Attribute& attr)\n\t\t{\n\t\t\tapply_visitor(saver_visitor<Attribute, Value>(attr, value), key);\n\t\t}\n\t};\n\n\ttemplate <typename Attribute, typename Value>\n\tstruct saver_visitor  : boost::static_visitor<void>\n\t{\n\t\tsaver_visitor(Attribute& attr, Value& value)\n\t\t\t: attr(attr), value(value) {};\n\n\t\tAttribute& attr;\n\t\tValue& value;\n\n\t\ttemplate <typename Key>\n\t\tvoid operator()(Key) const\n\t\t{\n\t\t\tsave_to_assoc_attr<Key>::call(Key(), value,attr);\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Container, typename Context>\n\tstruct parser_accepts_container\n\t\t: traits::is_substitute<\n\t\t\t\ttypename traits::attribute_of<Parser, Context>::type\n\t\t\t  , Container\n\t\t\t>\n\t{};\n\n\ttemplate <typename Parser>\n\tstruct parse_into_container_base_impl\n\t{\n\tprivate:\n\n\t\t// Parser has attribute (synthesize; Attribute is a container)\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_x(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)\n\t\t{\n\t\t\t// synthesized attribute needs to be value initialized\n\t\t\tusing value_type = typename traits::container_value<Attribute>::type;\n\t\t\tvalue_type val{};\n\n\t\t\tif (!parser.parse(first, last, context, rcontext, val))\n\t\t\t\treturn false;\n\n\t\t\t// push the parsed value into our attribute\n\t\t\ttraits::push_back(attr, static_cast<value_type&&>(val));\n\t\t\treturn true;\n\t\t}\n\n\t\t// Parser has attribute (synthesize; Attribute is a container)\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_x(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)\n\t\t{\n\t\t\treturn parser.parse(first, last, context, rcontext, attr);\n\t\t}\n\n\t\t// Parser has attribute (synthesize; Attribute is a container)\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr)\n\t\t{\n\t\t\ttypedef\n\t\t\t\tparser_accepts_container<Parser, Attribute, Context>\n\t\t\tparser_accepts_container;\n\n\t\t\treturn call_synthesize_x(parser, first, last, context, rcontext, attr\n\t\t\t\t, parser_accepts_container());\n\t\t}\n\n\t\t// Parser has attribute (synthesize; Attribute is a single element fusion sequence)\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_into_fusion_seq(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr, mpl::false_ /* is_associative */)\n\t\t{\n\t\t\tstatic_assert(traits::has_size<Attribute, 1>::value,\n\t\t\t\t\"Expecting a single element fusion sequence\");\n\t\t\treturn call_synthesize(parser, first, last, context, rcontext,\n\t\t\t\tfusion::front(attr));\n\t\t}\n\n\t\t// Parser has attribute (synthesize; Attribute is fusion map sequence)\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_into_fusion_seq(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr, mpl::true_ /*is_associative*/)\n\t\t{\n\t\t\tusing attribute_type = typename traits::attribute_of<Parser, Context>::type;\n\t\t\tstatic_assert(traits::has_size<attribute_type, 2>::value,\n\t\t\t\t\"To parse directly into fusion map parser must produce 2 element attr\");\n\n\t\t\t// use type of  first element of attribute as key\n\t\t\tusing key = typename std::remove_reference<\n\t\t\ttypename fusion::result_of::front<attribute_type>::type>::type;\n\n\t\t\tattribute_type attr_;\n\t\t\tif (!parser.parse(first, last, context, rcontext, attr_))\n\t\t\t\treturn false;\n\n\t\t\tsave_to_assoc_attr<key>::call(fusion::front(attr_), fusion::back(attr_), attr);\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_dispatch_by_seq(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr, mpl::true_ /*is_sequence*/)\n\t\t{\n\t\t\treturn call_synthesize_into_fusion_seq(\n\t\t\t\tparser, first, last, context, rcontext, attr\n\t\t\t  , fusion::traits::is_associative<Attribute>());\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call_synthesize_dispatch_by_seq(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr, mpl::false_ /*is_sequence*/)\n\t\t{\n\t\t\treturn call_synthesize(parser, first, last, context, rcontext, attr);\n\t\t}\n\n\t\t// Parser has attribute (synthesize)\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr, mpl::true_)\n\t\t{\n\t\t\treturn call_synthesize_dispatch_by_seq(parser, first, last, context, rcontext, attr\n\t\t\t\t, fusion::traits::is_sequence<Attribute>());\n\t\t}\n\n\t\t// Parser has no attribute (pass unused)\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& /* attr */, mpl::false_)\n\t\t{\n\t\t\treturn parser.parse(first, last, context, rcontext, unused);\n\t\t}\n\n\n\tpublic:\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tstatic bool call(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last, Context const& context\n\t\t  , RContext& rcontext, Attribute& attr)\n\t\t{\n\t\t\treturn call(parser, first, last, context, rcontext, attr\n\t\t\t  , mpl::bool_<traits::has_attribute<Parser, Context>::value>());\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Context, typename RContext, typename Enable = void>\n\tstruct parse_into_container_impl : parse_into_container_base_impl<Parser> {};\n\n\ttemplate <typename Parser, typename Iterator, typename Container, typename Context>\n\tstruct parser_attr_is_substitute_for_container_value\n\t\t: traits::is_substitute<\n\t\t\ttypename traits::pseudo_attribute<\n\t\t\t\tContext\n\t\t\t  , typename traits::attribute_of<Parser, Context>::type\n\t\t\t  , Iterator\n\t\t\t>::type\n\t\t  , typename traits::container_value<Container>::type\n\t\t>\n\t{};\n\n\ttemplate <typename Parser, typename Context, typename RContext>\n\tstruct parse_into_container_impl<Parser, Context, RContext,\n\t\ttypename enable_if<traits::handles_container<Parser, Context>>::type>\n\t{\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)\n\t\t{\n\t\t\treturn parse_into_container_base_impl<Parser>::call(\n\t\t\t\tparser, first, last, context, rcontext, attr);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tstatic bool call(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, unused_type attr, mpl::true_)\n\t\t{\n\t\t\treturn parser.parse(first, last, context, rcontext, attr);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tParser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)\n\t\t{\n\t\t\tif (traits::is_empty(attr))\n\t\t\t\treturn parser.parse(first, last, context, rcontext, attr);\n\t\t\tAttribute rest;\n\t\t\tbool r = parser.parse(first, last, context, rcontext, rest);\n\t\t\tif (r)\n\t\t\t\ttraits::append(attr, std::make_move_iterator(rest.begin()),\n\t\t\t\t\t\t\t\t\t std::make_move_iterator(rest.end()));\n\t\t\treturn r;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(Parser const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr)\n\t\t{\n\t\t\ttypedef parser_accepts_container<\n\t\t\t\t\tParser, Attribute, Context>\n\t\t\tparser_accepts_container;\n\n\t\t\ttypedef parser_attr_is_substitute_for_container_value<\n\t\t\t\t\tParser, Iterator, Attribute, Context>\n\t\t\tparser_attr_is_substitute_for_container_value;\n\n\t\t\ttypedef mpl::or_<\n\t\t\t\tparser_accepts_container\n\t\t\t  , mpl::not_<parser_attr_is_substitute_for_container_value>>\n\t\t\tpass_attibute_as_is;\n\n\t\t\treturn call(parser, first, last, context, rcontext, attr,\n\t\t\t\tpass_attibute_as_is());\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_into_container(\n\t\tParser const& parser\n\t  , Iterator& first, Iterator const& last, Context const& context\n\t  , RContext& rcontext, Attribute& attr)\n\t{\n\t\treturn parse_into_container_impl<Parser, Context, RContext>::call(\n\t\t\tparser, first, last, context, rcontext, attr);\n\t}\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/parse.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM)\n#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM\n\n#include \"../support/context.hpp\"\n#include \"parser.hpp\"\n#include \"skip_over.hpp\"\n#include <boost/iterator/iterator_concepts.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, spirit_parser Parser, typename Attribute>\n\tinline bool\n\tparse_main(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Attribute& attr)\n\t{\n\t\t// Make sure the iterator is at least a readable forward traversal iterator.\n\t\t// If you got a compilation error here, then you are using a weaker iterator\n\t\t// while calling this function, you need to supply a readable forward traversal\n\t\t// iterator instead.\n\t\tBOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));\n\t\tBOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));\n\n\t\tstd::optional<expectation_failure<Iterator>> failure;\n\t\treturn p.parse(first, last, make_context<expectation_failure_tag>(failure), unused, attr);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Attribute>\n\tinline bool\n\tparse(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Attribute& attr)\n\t{\n\t\treturn parse_main(first, last, p, attr);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Attribute>\n\tinline bool\n\tparse(\n\t\tIterator const& first_\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Attribute& attr)\n\t{\n\t\tIterator first = first_;\n\t\treturn parse_main(first, last, p, attr);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser>\n\tinline bool\n\tparse(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p)\n\t{\n\t\treturn parse_main(first, last, p, unused);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser>\n\tinline bool\n\tparse(\n\t\tIterator const& first_\n\t  , Iterator last\n\t  , Parser const& p)\n\t{\n\t\tIterator first = first_;\n\t\treturn parse_main(first, last, p, unused);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\tenum class skip_flag\n\t{\n\t\tpost_skip,      // force post-skipping in phrase_parse()\n\t\tdont_post_skip  // inhibit post-skipping in phrase_parse()\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, spirit_parser Parser, spirit_parser Skipper, typename Attribute>\n\tinline bool\n\tphrase_parse_main(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Skipper const& s\n\t  , Attribute& attr\n\t  , skip_flag post_skip = skip_flag::post_skip)\n\t{\n\t\t// Make sure the iterator is at least a readable forward traversal iterator.\n\t\t// If you got a compilation error here, then you are using a weaker iterator\n\t\t// while calling this function, you need to supply a readable forward traversal\n\t\t// iterator instead.\n\t\tBOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));\n\t\tBOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));\n\n\t\tstatic_assert(!std::is_same<Skipper, unused_type>::value,\n\t\t\t\"Error! Skipper cannot be unused_type.\");\n\n\t\tauto skipper_ctx = make_context<skipper_tag>(s);\n\t\tstd::optional<expectation_failure<Iterator>> failure;\n\t\tbool r = p.parse(first, last, make_context<expectation_failure_tag>(failure, skipper_ctx), unused, attr);\n\t\tif (post_skip == skip_flag::post_skip)\n\t\t\tx3::skip_over(first, last, skipper_ctx);\n\t\treturn r;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Skipper, typename Attribute>\n\tinline bool\n\tphrase_parse(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Skipper const& s\n\t  , Attribute& attr\n\t  , skip_flag post_skip = skip_flag::post_skip)\n\t{\n\t\treturn phrase_parse_main(first, last, p, s, attr, post_skip);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Skipper, typename Attribute>\n\tinline bool\n\tphrase_parse(\n\t\tIterator const& first_\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Skipper const& s\n\t  , Attribute& attr\n\t  , skip_flag post_skip = skip_flag::post_skip)\n\t{\n\t\tIterator first = first_;\n\t\treturn phrase_parse_main(first, last, p, s, attr, post_skip);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Skipper>\n\tinline bool\n\tphrase_parse(\n\t\tIterator& first\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Skipper const& s\n\t  , skip_flag post_skip = skip_flag::post_skip)\n\t{\n\t\treturn phrase_parse_main(first, last, p, s, unused, post_skip);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Parser, typename Skipper>\n\tinline bool\n\tphrase_parse(\n\t\tIterator const& first_\n\t  , Iterator last\n\t  , Parser const& p\n\t  , Skipper const& s\n\t  , skip_flag post_skip = skip_flag::post_skip)\n\t{\n\t\tIterator first = first_;\n\t\treturn phrase_parse_main(first, last, p, s, unused, post_skip);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Skipper>\n\tstruct phrase_parse_context\n\t{\n\t\ttypedef decltype(\n\t\t\tmake_context<expectation_failure_tag>(\n\t\t\t\tstd::declval<\n\t\t\t\t\tstd::optional<expectation_failure<Iterator>>&\n\t\t\t\t>(),\n\t\t\t\tmake_context<skipper_tag>(std::declval<Skipper const&>())\n\t\t\t)\n\t\t)\n\t\ttype;\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/parser.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)\n#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM\n\n#include <boost/mpl/bool.hpp>\n#include <boost/type_traits/is_base_of.hpp>\n#include <boost/type_traits/remove_cv.hpp>\n#include <boost/type_traits/remove_reference.hpp>\n#include <boost/utility/declval.hpp>\n#include <boost/utility/enable_if.hpp>\n#include \"../support/unused.hpp\"\n#include \"../support/context.hpp\"\n#include \"../support/traits/has_attribute.hpp\"\n#include <boost/core/ignore_unused.hpp>\n#include <boost/assert.hpp>\n#include <string>\n\n#if !defined(BOOST_SPIRIT_X3_NO_RTTI)\n#include <typeinfo>\n#endif\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject, typename Action>\n\tstruct action;\n\n\ttemplate <typename Subject, typename Handler>\n\tstruct guard;\n\n\tstruct parser_base {};\n\tstruct parser_id;\n\n\ttemplate<typename Parser>\n\tconcept spirit_parser = std::is_base_of<parser_base, Parser>::value;\n\n\ttemplate <typename Derived>\n\tstruct parser : parser_base\n\t{\n\t\ttypedef Derived derived_type;\n\t\tstatic bool const handles_container = false;\n\t\tstatic bool const is_pass_through_unary = false;\n\t\tstatic bool const has_action = false;\n\n\t\tconstexpr Derived const& derived() const\n\t\t{\n\t\t\treturn *static_cast<Derived const*>(this);\n\t\t}\n\n\t\ttemplate <typename Action>\n\t\tconstexpr action<Derived, Action> operator[](Action f) const\n\t\t{\n\t\t\treturn { this->derived(), f };\n\t\t}\n\n\t\ttemplate <typename Handler>\n\t\tconstexpr guard<Derived, Handler> on_error(Handler f) const\n\t\t{\n\t\t\treturn { this->derived(), f };\n\t\t}\n\t};\n\n\tstruct unary_category;\n\tstruct binary_category;\n\n\ttemplate <typename Subject, typename Derived>\n\tstruct unary_parser : parser<Derived>\n\t{\n\t\ttypedef unary_category category;\n\t\ttypedef Subject subject_type;\n\t\tstatic bool const has_action = Subject::has_action;\n\n\t\tconstexpr unary_parser(Subject const& subject)\n\t\t\t: subject(subject) {}\n\n\t\tunary_parser const& get_unary() const { return *this; }\n\n\t\tSubject subject;\n\t};\n\n\ttemplate <typename Left, typename Right, typename Derived>\n\tstruct binary_parser : parser<Derived>\n\t{\n\t\ttypedef binary_category category;\n\t\ttypedef Left left_type;\n\t\ttypedef Right right_type;\n\t\tstatic bool const has_action =\n\t\t\tleft_type::has_action || right_type::has_action;\n\n\t\tconstexpr binary_parser(Left const& left, Right const& right)\n\t\t\t: left(left), right(right) {}\n\n\t\tbinary_parser const& get_binary() const { return *this; }\n\n\t\tLeft left;\n\t\tRight right;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The main what function\n\t//\n\t// Note: unlike Spirit2, spirit parsers are no longer required to have a\n\t// \"what\" member function. In X3, we specialize the get_info struct\n\t// below where needed. If a specialization is not provided, the default\n\t// below will be used. The default \"what\" result will be the typeid\n\t// name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise\n\t// \"undefined\"\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Parser, typename Enable = void>\n\tstruct get_info\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(Parser const&) const\n\t\t{\n#if !defined(BOOST_SPIRIT_X3_NO_RTTI)\n\t\t\treturn typeid(Parser).name();\n#else\n\t\t\treturn \"undefined\";\n#endif\n\t\t}\n\t};\n\n\ttemplate <typename Parser>\n\tstd::string what(Parser const& p)\n\t{\n\t\treturn get_info<Parser>()(p);\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Subject, typename Derived, typename Context>\n\tstruct has_attribute<x3::unary_parser<Subject, Derived>, Context>\n\t\t: has_attribute<Subject, Context> {};\n\n\ttemplate <typename Left, typename Right, typename Derived, typename Context>\n\tstruct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>\n\t\t: mpl::bool_<has_attribute<Left, Context>::value ||\n\t\t\t\thas_attribute<Right, Context>::value> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/proxy.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM)\n#define BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM\n\n#include \"parser.hpp\"\n#include \"detail/parse_into_container.hpp\"\n#include \"../support/traits/attribute_category.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject, typename Derived>\n\tstruct proxy : unary_parser<Subject, Derived>\n\t{\n\t\tstatic bool const is_pass_through_unary = true;\n\n\t\tconstexpr proxy(Subject const& subject)\n\t\t  : unary_parser<Subject, Derived>(subject) {}\n\n\t\t// Overload this when appropriate. The proxy parser will pick up\n\t\t// the most derived overload.\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute, typename Category>\n\t\tbool parse_subject(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr, Category) const\n\t\t{\n\t\t\tthis->subject.parse(first, last, context, rcontext, attr);\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\n\t\t// Main entry point.\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RuleContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RuleContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->derived().parse_subject(first, last, context, rcontext, attr\n\t\t\t\t, typename traits::attribute_category<Attribute>::type());\n\t\t}\n\t};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core/skip_over.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM)\n#define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM\n\n#include \"../support/unused.hpp\"\n#include \"../support/context.hpp\"\n#include \"../support/traits/attribute_category.hpp\"\n#include <boost/mpl/bool.hpp>\n#include <boost/mpl/not.hpp>\n#include <boost/type_traits/remove_cv.hpp>\n#include <boost/type_traits/remove_reference.hpp>\n#include <boost/utility/declval.hpp>\n#include <optional>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct expectation_failure_tag;\n\n\ttemplate <typename Iterator>\n\tstruct BOOST_SYMBOL_VISIBLE expectation_failure : std::runtime_error\n\t{\n\tpublic:\n\n\t\texpectation_failure(Iterator where, std::string const& which)\n\t\t  : std::runtime_error(\"boost::spirit::x3::expectation_failure\")\n\t\t  , where_(where), which_(which)\n\t\t{}\n\t\t~expectation_failure() {}\n\n\t\tstd::string which() const { return which_; }\n\t\tIterator const& where() const { return where_; }\n\n\tprivate:\n\n\t\tIterator where_;\n\t\tstd::string which_;\n\t};\n\t///////////////////////////////////////////////////////////////////////////\n\t// Move the /first/ iterator to the first non-matching position\n\t// given a skip-parser. The function is a no-op if unused_type or\n\t// unused_skipper is passed as the skip-parser.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Skipper>\n\tstruct unused_skipper : unused_type\n\t{\n\t\tunused_skipper(Skipper const& skipper)\n\t\t  : skipper(skipper) {}\n\t\tSkipper const& skipper;\n\t};\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename Skipper>\n\t\tstruct is_unused_skipper\n\t\t  : mpl::false_ {};\n\n\t\ttemplate <typename Skipper>\n\t\tstruct is_unused_skipper<unused_skipper<Skipper>>\n\t\t  : mpl::true_ {};\n\n\t\ttemplate <> \n\t\tstruct is_unused_skipper<unused_type>\n\t\t  : mpl::true_ {};\n\n\t\ttemplate <typename Skipper>\n\t\tinline Skipper const&\n\t\tget_unused_skipper(Skipper const& skipper)\n\t\t{\n\t\t\treturn skipper;\n\t\t}\n\t\ttemplate <typename Skipper>\n\t\tinline Skipper const&\n\t\tget_unused_skipper(unused_skipper<Skipper> const& unused_skipper)\n\t\t{\n\t\t\treturn unused_skipper.skipper;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Skipper>\n\t\tinline void skip_over(\n\t\t\tIterator& first, Iterator const& last, Skipper const& skipper)\n\t\t{\n\t\t\tstd::optional<expectation_failure<Iterator>> failure;\n\t\t\twhile (skipper.parse(first, last, make_context<expectation_failure_tag>(failure), unused, unused))\n\t\t\t\t/***/;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tinline void skip_over(Iterator&, Iterator const&, unused_type)\n\t\t{\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Skipper>\n\t\tinline void skip_over(\n\t\t\tIterator&, Iterator const&, unused_skipper<Skipper> const&)\n\t\t{\n\t\t}\n\t}\n\n\t// this tag is used to find the skipper from the context\n\tstruct skipper_tag;\n\n\ttemplate <typename Context>\n\tstruct has_skipper\n\t  : mpl::not_<detail::is_unused_skipper<\n\t\t\ttypename remove_cv<typename remove_reference<\n\t\t\t\tdecltype(x3::get<skipper_tag>(boost::declval<Context>()))\n\t\t\t>::type>::type\n\t\t>> {};\n\n\ttemplate <typename Iterator, typename Context>\n\tinline void skip_over(\n\t\tIterator& first, Iterator const& last, Context const& context)\n\t{\n\t\tdetail::skip_over(first, last, x3::get<skipper_tag>(context));\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/core.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM)\n#define BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM\n\n#include \"core/parse.hpp\"\n//~ #include \"core/parse_attr.hpp\"\n#include \"core/parser.hpp\"\n#include \"core/skip_over.hpp\"\n#include \"core/action.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/confix.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2009 Chris Hoeppler\n\tCopyright (c) 2014 Lee Clagett\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n\n#if !defined(BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM)\n#define BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM\n\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate<typename Prefix, typename Subject, typename Postfix>\n\tstruct confix_directive :\n\t\tunary_parser<Subject, confix_directive<Prefix, Subject, Postfix>>\n\t{\n\t\ttypedef unary_parser<\n\t\t\tSubject, confix_directive<Prefix, Subject, Postfix>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr confix_directive(Prefix const& prefix\n\t\t\t\t\t\t , Subject const& subject\n\t\t\t\t\t\t , Postfix const& postfix) :\n\t\t\tbase_type(subject),\n\t\t\tprefix(prefix),\n\t\t\tpostfix(postfix)\n\t\t{\n\t\t}\n\n\t\ttemplate<typename Iterator, typename Context\n\t\t\t\t , typename RContext, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t\t, Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tIterator save = first;\n\n\t\t\tif (!(prefix.parse(first, last, context, rcontext, unused) &&\n\t\t\t\t  this->subject.parse(first, last, context, rcontext, attr) &&\n\t\t\t\t  postfix.parse(first, last, context, rcontext, unused)))\n\t\t\t{\n\t\t\t\tfirst = save;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tPrefix prefix;\n\t\tPostfix postfix;\n\t};\n\n\ttemplate<spirit_parser Prefix, spirit_parser Postfix>\n\tstruct confix_gen\n\t{\n\t\ttemplate<spirit_parser Subject>\n\t\tconstexpr confix_directive<\n\t\t\tPrefix, Subject, Postfix>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { prefix, subject, postfix };\n\t\t}\n\n\t\tPrefix prefix;\n\t\tPostfix postfix;\n\t};\n\n\n\ttemplate<spirit_parser Prefix, spirit_parser Postfix>\n\tconstexpr confix_gen<Prefix, Postfix>\n\tconfix(Prefix const& prefix, Postfix const& postfix)\n\t{\n\t\treturn { prefix, postfix };\n\t}\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/expect.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EXPECT_MARCH_16_2012_1024PM)\n#define BOOST_SPIRIT_X3_EXPECT_MARCH_16_2012_1024PM\n\n#include \"../support/context.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../core/detail/parse_into_container.hpp\"\n\n#include <boost/config.hpp> // for BOOST_SYMBOL_VISIBLE\n#include <boost/throw_exception.hpp>\n#include <stdexcept>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tnamespace detail {\n\t\tinline bool has_expectation_failure_impl(bool& failure) {\n\t\t\treturn failure;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tbool has_expectation_failure_impl(\n\t\t\tstd::optional<expectation_failure<Iterator>>& failure\n\t\t) {\n\t\t\treturn static_cast<bool>(failure);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Subject>\n\t\tvoid set_expectation_failure_impl(\n\t\t\tIterator const& where,\n\t\t\tSubject const& subject,\n\t\t\tbool& failure\n\t\t) {\n\t\t\tfailure = true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Subject>\n\t\tvoid set_expectation_failure_impl(\n\t\t\tIterator const& where,\n\t\t\tSubject const& subject,\n\t\t\tstd::optional<expectation_failure<Iterator>>& failure\n\t\t) {\n\t\t\tfailure = expectation_failure<Iterator>{\n\t\t\t\twhere,\n\t\t\t\twhat(subject)\n\t\t\t};\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\texpectation_failure<Iterator> get_expectation_failure_impl(\n\t\t\tIterator const& where, bool& failure\n\t\t) {\n\t\t\treturn {where, {}};\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tauto const& get_expectation_failure_impl(\n\t\t\tIterator const&,\n\t\t\tstd::optional<expectation_failure<Iterator>>& failure\n\t\t) {\n\t\t\treturn *failure;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvoid reset_expectation_failure_impl(bool& failure) {\n\t\t\tfailure = false;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvoid reset_expectation_failure_impl(std::optional<expectation_failure<Iterator>>& failure) {\n\t\t\tfailure = std::nullopt;\n\t\t}\n\t}\n\n\ttemplate <typename Context> \n\tbool has_expectation_failure(Context const& context) {\n\t\treturn detail::has_expectation_failure_impl(\n\t\t\tx3::get<expectation_failure_tag>(context));\n\t}\n\n\ttemplate <typename Iterator, typename Subject, typename Context>\n\tvoid set_expectation_failure(\n\t\tIterator const& where,\n\t\tSubject const& subject,\n\t\tContext const& context\n\t) {\n\t\tdetail::set_expectation_failure_impl(\n\t\t\twhere,\n\t\t\tsubject,\n\t\t\tx3::get<expectation_failure_tag>(context)\n\t\t);\n\t}\n\n\ttemplate <typename Iterator, typename Context>\n\tdecltype(auto) get_expectation_failure(\n\t\tIterator const& where,\n\t\tContext const& context\n\t) {\n\t\treturn detail::get_expectation_failure_impl(\n\t\t\twhere, x3::get<expectation_failure_tag>(context));\n\t}\n\n\ttemplate <typename Context>\n\tvoid reset_expectation_failure(Context const& context) {\n\t\tdetail::reset_expectation_failure_impl(\n\t\t\tx3::get<expectation_failure_tag>(context));\n\t}\n\n\ttemplate <typename Subject>\n\tstruct expect_directive : unary_parser<Subject, expect_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, expect_directive<Subject> > base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\n\t\tconstexpr expect_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tbool r = this->subject.parse(first, last, context, rcontext, attr);\n\n\t\t\tif (!r)\n\t\t\t{\n\t\t\t\tif(!has_expectation_failure(context))\n\t\t\t\t{\n\t\t\t\t\tset_expectation_failure(first, this->subject, context);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t};\n\n\tstruct expect_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr expect_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto expect = expect_gen{};\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\t// Special case handling for expect expressions.\n\ttemplate <typename Subject, typename Context, typename RContext>\n\tstruct parse_into_container_impl<expect_directive<Subject>, Context, RContext>\n\t{\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\texpect_directive<Subject> const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr)\n\t\t{\n\t\t\tbool r = parse_into_container(\n\t\t\t\tparser.subject, first, last, context, rcontext, attr);\n\n\t\t\tif (!r)\n\t\t\t{\n\t\t\t\tif(!has_expectation_failure(context))\n\t\t\t\t{\n\t\t\t\t\tset_expectation_failure(first, parser.subject, context);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/lexeme.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_LEXEME_MARCH_24_2007_0802AM)\n#define BOOST_SPIRIT_X3_LEXEME_MARCH_24_2007_0802AM\n\n#include \"../support/context.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include <boost/type_traits/remove_reference.hpp>\n#include <boost/utility/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct lexeme_directive : unary_parser<Subject, lexeme_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, lexeme_directive<Subject> > base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr lexeme_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename enable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\tauto const& skipper = x3::get<skipper_tag>(context);\n\n\t\t\ttypedef unused_skipper<\n\t\t\t\ttypename remove_reference<decltype(skipper)>::type>\n\t\t\tunused_skipper_type;\n\t\t\tunused_skipper_type unused_skipper(skipper);\n\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<skipper_tag>(unused_skipper, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename disable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\t//  no need to pre-skip if skipper is unused\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , context\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n\n\tstruct lexeme_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr lexeme_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto lexeme = lexeme_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/matches.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2015 Mario Lang\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_HOME_X3_EXTENSIONS_MATCHES_HPP)\n#define BOOST_SPIRIT_HOME_X3_EXTENSIONS_MATCHES_HPP\n\n#include \"expect.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include \"../support/unused.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct matches_directive : unary_parser<Subject, matches_directive<Subject>>\n\t{\n\t\tusing base_type = unary_parser<Subject, matches_directive<Subject>>;\n\t\tstatic bool const has_attribute = true;\n\t\tusing attribute_type = bool;\n\n\t\tconstexpr matches_directive(Subject const& subject) : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tbool const result = this->subject.parse(\n\t\t\t\t\tfirst, last, context, rcontext, unused);\n\t\t\tif (has_expectation_failure(context)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ttraits::move_to(result, attr);\n\t\t\treturn true;\n\t\t}\n\t};\n\n\tstruct matches_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr matches_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto matches = matches_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/no_case.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Thomas Bernard\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NO_CASE_SEPT_16_2014_0912PM)\n#define BOOST_SPIRIT_X3_NO_CASE_SEPT_16_2014_0912PM\n\n#include \"../support/context.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../support/no_case.hpp\"\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t// propagate no_case information through the context\n\ttemplate <typename Subject>\n\tstruct no_case_directive : unary_parser<Subject, no_case_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, no_case_directive<Subject> > base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr no_case_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<no_case_tag>(no_case_compare_, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n\n\tstruct no_case_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr no_case_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto no_case = no_case_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/no_skip.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NO_SKIP_JAN_16_2010_0802PM)\n#define BOOST_SPIRIT_X3_NO_SKIP_JAN_16_2010_0802PM\n\n#include \"../support/context.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include <boost/type_traits/remove_reference.hpp>\n#include <boost/utility/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t// same as lexeme[], but does not pre-skip\n\ttemplate <typename Subject>\n\tstruct no_skip_directive : unary_parser<Subject, no_skip_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, no_skip_directive<Subject> > base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr no_skip_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename enable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tauto const& skipper = x3::get<skipper_tag>(context);\n\n\t\t\ttypedef unused_skipper<\n\t\t\t\ttypename remove_reference<decltype(skipper)>::type>\n\t\t\tunused_skipper_type;\n\t\t\tunused_skipper_type unused_skipper(skipper);\n\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<skipper_tag>(unused_skipper, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename disable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , context\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n\n\tstruct no_skip_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr no_skip_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto no_skip = no_skip_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/omit.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_OMIT_MARCH_24_2007_0802AM)\n#define BOOST_SPIRIT_X3_OMIT_MARCH_24_2007_0802AM\n\n#include \"../support/unused.hpp\"\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// omit_directive forces the attribute of subject parser\n\t// to be unused_type\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Subject>\n\tstruct omit_directive : unary_parser<Subject, omit_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, omit_directive<Subject> > base_type;\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\ttypedef Subject subject_type;\n\t\tconstexpr omit_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, unused_type) const\n\t\t{\n\t\t\treturn this->subject.parse(first, last, context, rcontext, unused);\n\t\t}\n\t};\n\n\tstruct omit_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr omit_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto omit = omit_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/raw.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#ifndef BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP\n#define BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP\n\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include \"../support/traits/pseudo_attribute.hpp\"\n#include <boost/range/iterator_range_core.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t// this is a pseudo attribute type indicating that the parser wants the\n\t// iterator range pointing to the [first, last) matching characters from\n\t// the input iterators.\n\tstruct raw_attribute_type {};\n\n\ttemplate <typename Subject>\n\tstruct raw_directive : unary_parser<Subject, raw_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, raw_directive<Subject> > base_type;\n\t\ttypedef raw_attribute_type attribute_type;\n\t\tstatic bool const handles_container = true;\n\t\ttypedef Subject subject_type;\n\n\t\tconstexpr raw_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t\t, typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\tIterator i = first;\n\t\t\tif (this->subject.parse(i, last, context, rcontext, unused))\n\t\t\t{\n\t\t\t\ttraits::move_to(first, i, attr);\n\t\t\t\tfirst = i;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, unused_type) const\n\t\t{\n\t\t\treturn this->subject.parse(first, last, context, rcontext, unused);\n\t\t}\n\t};\n\n\tstruct raw_gen\n\t{\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr raw_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto raw = raw_gen{};\n\n\tnamespace traits\n\t{\n\t\ttemplate <typename Context, typename Iterator>\n\t\tstruct pseudo_attribute<Context, raw_attribute_type, Iterator>\n\t\t{\n\t\t\tusing attribute_type = raw_attribute_type;\n\t\t\tusing type = boost::iterator_range<Iterator>;\n\n\t\t\tstatic type call(Iterator& first, Iterator const& last, attribute_type)\n\t\t\t{\n\t\t\t\treturn { first, last };\n\t\t\t}\n\t\t};\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/repeat.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2014 Thomas Bernard\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP\n#define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP\n\n#include \"expect.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../operator/kleene.hpp\"\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename T>\n\tstruct exact_count // handles repeat(exact)[p]\n\t{\n\t\ttypedef T type;\n\t\tbool got_max(T i) const { return i >= exact_value; }\n\t\tbool got_min(T i) const { return i >= exact_value; }\n\n\t\tT const exact_value;\n\t};\n\n\ttemplate <typename T>\n\tstruct finite_count // handles repeat(min, max)[p]\n\t{\n\t\ttypedef T type;\n\t\tbool got_max(T i) const { return i >= max_value; }\n\t\tbool got_min(T i) const { return i >= min_value; }\n\n\t\tT const min_value;\n\t\tT const max_value;\n\t};\n\n\ttemplate <typename T>\n\tstruct infinite_count // handles repeat(min, inf)[p]\n\t{\n\t\ttypedef T type;\n\t\tbool got_max(T /*i*/) const { return false; }\n\t\tbool got_min(T i) const { return i >= min_value; }\n\n\t\tT const min_value;\n\t};\n}}}}\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate<typename Subject, typename RepeatCountLimit>\n\tstruct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>\n\t{\n\t\ttypedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = true;\n\n\t\tconstexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)\n\t\t  : base_type(subject)\n\t\t  , repeat_limit(repeat_limit_)\n\t\t{}\n\n\t\ttemplate<typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tIterator local_iterator = first;\n\t\t\ttypename RepeatCountLimit::type i{};\n\t\t\tfor (/**/; !repeat_limit.got_min(i); ++i)\n\t\t\t{\n\t\t\t\tif (!detail::parse_into_container(\n\t\t\t\t\t  this->subject, local_iterator, last, context, rcontext, attr))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfirst = local_iterator;\n\t\t\t// parse some more up to the maximum specified\n\t\t\tfor (/**/; !repeat_limit.got_max(i); ++i)\n\t\t\t{\n\t\t\t\tif (!detail::parse_into_container(\n\t\t\t\t\t  this->subject, first, last, context, rcontext, attr))\n\t\t\t\t\treturn !has_expectation_failure(context);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tRepeatCountLimit repeat_limit;\n\t};\n\n\t// Infinite loop tag type\n\tstruct inf_type {};\n\tconstexpr inf_type inf = inf_type();\n\n\tstruct repeat_gen\n\t{\n\t\ttemplate<spirit_parser Subject>\n\t\tconstexpr auto operator[](Subject const& subject) const\n\t\t{\n\t\t\treturn *subject;\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tstruct repeat_gen_lvl1\n\t\t{\n\t\t\tconstexpr repeat_gen_lvl1(T&& repeat_limit_)\n\t\t\t  : repeat_limit(repeat_limit_)\n\t\t\t{}\n\n\t\t\ttemplate<spirit_parser Subject>\n\t\t\tconstexpr repeat_directive< Subject, T>\n\t\t\toperator[](Subject const& subject) const\n\t\t\t{\n\t\t\t\treturn { subject,repeat_limit };\n\t\t\t}\n\n\t\t\tT repeat_limit;\n\t\t};\n\n\t\ttemplate <typename T>\n\t\tconstexpr repeat_gen_lvl1<detail::exact_count<T>>\n\t\toperator()(T const exact) const\n\t\t{\n\t\t\treturn { detail::exact_count<T>{exact} };\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tconstexpr repeat_gen_lvl1<detail::finite_count<T>>\n\t\toperator()(T const min_val, T const max_val) const\n\t\t{\n\t\t\treturn { detail::finite_count<T>{min_val,max_val} };\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tconstexpr repeat_gen_lvl1<detail::infinite_count<T>>\n\t\toperator()(T const min_val, inf_type const &) const\n\t\t{\n\t\t\treturn { detail::infinite_count<T>{min_val} };\n\t\t}\n\t};\n\n\tconstexpr auto repeat = repeat_gen{};\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Subject, typename RepeatCountLimit, typename Context>\n\tstruct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>\n\t  : build_container<typename attribute_of<Subject, Context>::type> {};\n}}}}\n\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/seek.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2011 Jamboree\n\tCopyright (c) 2014 Lee Clagett\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM)\n#define BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM\n\n#include \"expect.hpp\"\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate<typename Subject>\n\tstruct seek_directive : unary_parser<Subject, seek_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, seek_directive<Subject>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr seek_directive(Subject const& subject) :\n\t\t\tbase_type(subject) {}\n\n\t\ttemplate<typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tfor (Iterator current(first);; ++current)\n\t\t\t{\n\t\t\t\tif (this->subject.parse(current, last, context, rcontext, attr))\n\t\t\t\t{\n\t\t\t\t\tfirst = current;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (has_expectation_failure(context))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// fail only after subject fails & no input\n\t\t\t\tif (current == last)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t};\n\n\tstruct seek_gen\n\t{\n\t\ttemplate<spirit_parser Subject>\n\t\tconstexpr seek_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto seek = seek_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/skip.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SKIP_JANUARY_26_2008_0422PM)\n#define BOOST_SPIRIT_X3_SKIP_JANUARY_26_2008_0422PM\n\n#include \"../support/context.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include <boost/utility/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct reskip_directive : unary_parser<Subject, reskip_directive<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, reskip_directive<Subject>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr reskip_directive(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename disable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tauto const& skipper =\n\t\t\t\tdetail::get_unused_skipper(x3::get<skipper_tag>(context));\n\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<skipper_tag>(skipper, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\ttypename enable_if<has_skipper<Context>, bool>::type\n\t\tparse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , context\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n\n\ttemplate <typename Subject, typename Skipper>\n\tstruct skip_directive : unary_parser<Subject, skip_directive<Subject, Skipper>>\n\t{\n\t\ttypedef unary_parser<Subject, skip_directive<Subject, Skipper>> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\tconstexpr skip_directive(Subject const& subject, Skipper const& skipper)\n\t\t  : base_type(subject)\n\t\t  , skipper(skipper)\n\t\t{}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<skipper_tag>(skipper, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\n\t\tSkipper const skipper;\n\t};\n\n\tstruct reskip_gen\n\t{\n\t\ttemplate <typename Skipper>\n\t\tstruct skip_gen\n\t\t{\n\t\t\tconstexpr skip_gen(Skipper const& skipper)\n\t\t\t  : skipper_(skipper) {}\n\n\t\t\ttemplate <spirit_parser Subject>\n\t\t\tconstexpr skip_directive<Subject, Skipper>\n\t\t\toperator[](Subject const& subject) const\n\t\t\t{\n\t\t\t\treturn { subject, skipper_ };\n\t\t\t}\n\n\t\t\tSkipper skipper_;\n\t\t};\n\n\t\ttemplate <typename Skipper>\n\t\tconstexpr skip_gen<Skipper> const operator()(Skipper const& skipper) const\n\t\t{\n\t\t\treturn { skipper };\n\t\t}\n\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr reskip_directive<Subject>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\tconstexpr auto skip = reskip_gen{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive/with.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#ifndef BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP\n#define BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP\n\n#include \"../support/unused.hpp\"\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// with directive injects a value into the context prior to parsing.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Subject, typename Derived, typename T>\n\tstruct with_value_holder\n\t  : unary_parser<Subject, Derived>\n\t{\n\t\ttypedef unary_parser<Subject, Derived> base_type;\n\t\tmutable T val;\n\t\tconstexpr with_value_holder(Subject const& subject, T&& val)\n\t\t  : base_type(subject)\n\t\t  , val(std::forward<T>(val)) {}\n\t};\n\n\ttemplate <typename Subject, typename Derived, typename T>\n\tstruct with_value_holder<Subject, Derived, T&>\n\t  : unary_parser<Subject, Derived>\n\t{\n\t\ttypedef unary_parser<Subject, Derived> base_type;\n\t\tT& val;\n\t\tconstexpr with_value_holder(Subject const& subject, T& val)\n\t\t  : base_type(subject)\n\t\t  , val(val) {}\n\t};\n\n\ttemplate <typename Subject, typename ID, typename T>\n\tstruct with_directive\n\t  : with_value_holder<Subject, with_directive<Subject, ID, T>, T>\n\t{\n\t\ttypedef with_value_holder<Subject, with_directive<Subject, ID, T>, T> base_type;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\n\t\ttypedef Subject subject_type;\n\n\t\tconstexpr with_directive(Subject const& subject, T&& val)\n\t\t  : base_type(subject, std::forward<T>(val)) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<ID>(this->val, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n   \n\ttemplate <typename ID, typename T>\n\tstruct with_gen\n\t{\n\t\tT&& val;\n\n\t\ttemplate <spirit_parser Subject>\n\t\tconstexpr with_directive<Subject, ID, T>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject, std::forward<T>(val) };\n\t\t}\n\t};\n\n\ttemplate <typename ID, typename T>\n\tconstexpr with_gen<ID, T> with(T&& val)\n\t{\n\t\treturn { std::forward<T>(val) };\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/directive.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM)\n#define BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM\n\n//~ #include \"directive/as.hpp\"\n#include \"directive/confix.hpp\"\n//~ #include \"directive/encoding.hpp\"\n//~ #include \"directive/hold.hpp\"\n#include \"directive/expect.hpp\"\n#include \"directive/lexeme.hpp\"\n#include \"directive/matches.hpp\"\n#include \"directive/no_case.hpp\"\n#include \"directive/no_skip.hpp\"\n#include \"directive/omit.hpp\"\n#include \"directive/raw.hpp\"\n#include \"directive/repeat.hpp\"\n#include \"directive/seek.hpp\"\n#include \"directive/skip.hpp\"\n#include \"directive/with.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal/debug_handler_state.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)\n#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tenum debug_handler_state\n\t{\n\t\tpre_parse\n\t  , successful_parse\n\t  , failed_parse\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal/detail/rule.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)\n#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM\n\n#include \"../../auxiliary/guard.hpp\"\n#include \"../../core/parser.hpp\"\n#include \"../../core/skip_over.hpp\"\n#include \"../../directive/expect.hpp\"\n#include \"transform_attribute.hpp\"\n#include <boost/utility/addressof.hpp>\n#include <boost/core/ignore_unused.hpp>\n#if defined(BOOST_SPIRIT_X3_DEBUG)\n#include \"../simple_trace.hpp\"\n#endif\n\n#include <type_traits>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename ID>\n\tstruct identity;\n\n\ttemplate <typename ID, typename Attribute = unused_type, bool force_attribute = false>\n\tstruct rule;\n\n\tstruct parse_pass_context_tag;\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename ID>\n\t\tstruct rule_id {};\n\n\t\t// we use this so we can detect if the default parse_rule\n\t\t// is the being called.\n\t\tstruct default_parse_rule_result\n\t\t{\n\t\t\tdefault_parse_rule_result(bool r)\n\t\t\t  : r(r) {}\n\t\t\toperator bool() const { return r; }\n\t\t\tbool r;\n\t\t};\n\t}\n\n\t// default parse_rule implementation\n\ttemplate <typename ID, typename Iterator\n\t  , typename Context, typename ActualAttribute>\n\tinline detail::default_parse_rule_result\n\tparse_rule(\n\t\tdetail::rule_id<ID>\n\t  , Iterator& first, Iterator const& last\n\t  , Context const& context, ActualAttribute& attr);\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n#if defined(BOOST_SPIRIT_X3_DEBUG)\n\ttemplate <typename Iterator, typename Attribute>\n\tstruct context_debug\n\t{\n\t\tcontext_debug(\n\t\t\tchar const* rule_name\n\t\t  , Iterator const& first, Iterator const& last\n\t\t  , Attribute const& attr\n\t\t  , bool const& ok_parse //was parse successful?\n\t\t  )\n\t\t  : ok_parse(ok_parse), rule_name(rule_name)\n\t\t  , first(first), last(last)\n\t\t  , attr(attr)\n\t\t  , f(detail::get_simple_trace())\n\t\t{\n\t\t\tf(first, last, attr, pre_parse, rule_name);\n\t\t}\n\n\t\t~context_debug()\n\t\t{\n\t\t\tauto status = ok_parse ? successful_parse : failed_parse ;\n\t\t\tf(first, last, attr, status, rule_name);\n\t\t}\n\n\t\tbool const& ok_parse;\n\t\tchar const* rule_name;\n\t\tIterator const& first;\n\t\tIterator const& last;\n\t\tAttribute const& attr;\n\t\tdetail::simple_trace_type& f;\n\t};\n#endif\n\n\ttemplate <typename ID, typename Iterator, typename Context, typename Enable = void>\n\tstruct has_on_error : mpl::false_ {};\n\n\ttemplate <typename ID, typename Iterator, typename Context>\n\tstruct has_on_error<ID, Iterator, Context,\n\t\t\tdecltype(void(\n\t\t\t\tstd::declval<ID>().on_error(\n\t\t\t\t\tstd::declval<Iterator&>()\n\t\t\t\t  , std::declval<Iterator>()\n\t\t\t\t  , std::declval<expectation_failure<Iterator>>()\n\t\t\t\t  , std::declval<Context>()\n\t\t\t\t)\n\t\t\t))\n\t\t>\n\t  : mpl::true_\n\t{};\n\n\ttemplate <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>\n\tstruct has_on_success : mpl::false_ {};\n\n\ttemplate <typename ID, typename Iterator, typename Attribute, typename Context>\n\tstruct has_on_success<ID, Iterator, Context, Attribute,\n\t\t\tdecltype(void(\n\t\t\t\tstd::declval<ID>().on_success(\n\t\t\t\t\tstd::declval<Iterator&>()\n\t\t\t\t  , std::declval<Iterator&>()\n\t\t\t\t  , std::declval<Attribute&>()\n\t\t\t\t  , std::declval<Context>()\n\t\t\t\t)\n\t\t\t))\n\t\t>\n\t  : mpl::true_\n\t{};\n\n\ttemplate <typename ID>\n\tstruct make_id\n\t{\n\t\ttypedef identity<ID> type;\n\t};\n\n\ttemplate <typename ID>\n\tstruct make_id<identity<ID>>\n\t{\n\t\ttypedef identity<ID> type;\n\t};\n\n\ttemplate <typename ID, typename RHS, typename Context>\n\tContext const&\n\tmake_rule_context(RHS const& /* rhs */, Context const& context\n\t  , mpl::false_ /* is_default_parse_rule */)\n\t{\n\t\treturn context;\n\t}\n\n\ttemplate <typename ID, typename RHS, typename Context>\n\tauto make_rule_context(RHS const& rhs, Context const& context\n\t  , mpl::true_ /* is_default_parse_rule */ )\n\t{\n\t\treturn make_unique_context<ID>(rhs, context);\n\t}\n\n\ttemplate <typename Attribute, typename ID, bool skip_definition_injection = false>\n\tstruct rule_parser\n\t{\n\t\ttemplate <typename Iterator, typename Context, typename ActualAttribute>\n\t\tstatic bool call_on_success(\n\t\t\tIterator& /* before */, Iterator& /* after */\n\t\t  , Context const& /* context */, ActualAttribute& /* attr */\n\t\t  , mpl::false_ /* No on_success handler */ )\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename ActualAttribute>\n\t\tstatic bool call_on_success(\n\t\t\tIterator& before, Iterator& after\n\t\t  , Context const& context, ActualAttribute& attr\n\t\t  , mpl::true_ /* Has on_success handler */)\n\t\t{\n\t\t\tx3::skip_over(before, after, context);\n\t\t\tbool pass = true;\n\t\t\tID().on_success(\n\t\t\t\tbefore\n\t\t\t  , after\n\t\t\t  , attr\n\t\t\t  , make_context<parse_pass_context_tag>(pass, context)\n\t\t\t);\n\t\t\treturn pass;\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator, typename Context\n\t\t  , typename RContext, typename ActualAttribute>\n\t\tstatic bool parse_rhs_main(\n\t\t\tRHS const& rhs\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, ActualAttribute& attr\n\t\t  , mpl::false_)\n\t\t{\n\t\t\t// see if the user has a BOOST_SPIRIT_DEFINE for this rule\n\t\t\ttypedef\n\t\t\t\tdecltype(parse_rule(\n\t\t\t\t\tdetail::rule_id<ID>{}, first, last\n\t\t\t\t  , make_unique_context<ID>(rhs, context), std::declval<Attribute&>()))\n\t\t\tparse_rule_result;\n\n\t\t\t// If there is no BOOST_SPIRIT_DEFINE for this rule,\n\t\t\t// we'll make a context for this rule tagged by its ID\n\t\t\t// so we can extract the rule later on in the default\n\t\t\t// (generic) parse_rule function.\n\t\t\ttypedef\n\t\t\t\tis_same<parse_rule_result, default_parse_rule_result>\n\t\t\tis_default_parse_rule;\n\n\t\t\tIterator start = first;\n\t\t\tbool r = rhs.parse(\n\t\t\t\tfirst\n\t\t\t  , last\n\t\t\t  , make_rule_context<ID>(rhs, context, std::conditional_t<skip_definition_injection, mpl::false_, is_default_parse_rule>())\n\t\t\t  , rcontext\n\t\t\t  , attr\n\t\t\t);\n\n\t\t\tif (r)\n\t\t\t{\n\t\t\t\tr = call_on_success(start, first, context, attr\n\t\t\t\t  , has_on_success<ID, Iterator, Context, ActualAttribute>());\n\t\t\t}\n\n\t\t\treturn r;\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator, typename Context\n\t\t  , typename RContext, typename ActualAttribute>\n\t\tstatic bool parse_rhs_main(\n\t\t\tRHS const& rhs\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, ActualAttribute& attr\n\t\t  , mpl::true_ /* on_error is found */)\n\t\t{\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tif(parse_rhs_main(rhs, first, last, context, rcontext, attr, mpl::false_())) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else if(has_expectation_failure(context)) {\n\t\t\t\t\tswitch (ID().on_error(first, last, get_expectation_failure(first, context), context))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase error_handler_result::fail:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tcase error_handler_result::retry:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcase error_handler_result::accept:\n\t\t\t\t\t\t\treset_expectation_failure(context);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase error_handler_result::rethrow:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator\n\t\t  , typename Context, typename RContext, typename ActualAttribute>\n\t\tstatic bool parse_rhs_main(\n\t\t\tRHS const& rhs\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, ActualAttribute& attr)\n\t\t{\n\t\t\treturn parse_rhs_main(\n\t\t\t\trhs, first, last, context, rcontext, attr\n\t\t\t  , has_on_error<ID, Iterator, Context>()\n\t\t\t);\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator\n\t\t  , typename Context, typename RContext, typename ActualAttribute>\n\t\tstatic bool parse_rhs(\n\t\t\tRHS const& rhs\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, ActualAttribute& attr\n\t\t  , mpl::false_)\n\t\t{\n\t\t\treturn parse_rhs_main(rhs, first, last, context, rcontext, attr);\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator\n\t\t  , typename Context, typename RContext, typename ActualAttribute>\n\t\tstatic bool parse_rhs(\n\t\t\tRHS const& rhs\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, ActualAttribute& /* attr */\n\t\t  , mpl::true_)\n\t\t{\n\t\t\treturn parse_rhs_main(rhs, first, last, context, rcontext, unused);\n\t\t}\n\n\t\ttemplate <typename RHS, typename Iterator, typename Context\n\t\t  , typename ActualAttribute, typename ExplicitAttrPropagation>\n\t\tstatic bool call_rule_definition(\n\t\t\tRHS const& rhs\n\t\t  , char const* rule_name\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, ActualAttribute& attr\n\t\t  , ExplicitAttrPropagation)\n\t\t{\n\t\t\tboost::ignore_unused(rule_name);\n\n\t\t\t// do down-stream transformation, provides attribute for\n\t\t\t// rhs parser\n\t\t\ttypedef traits::transform_attribute<\n\t\t\t\tActualAttribute, Attribute, parser_id>\n\t\t\ttransform;\n\n\t\t\ttypedef typename transform::type transform_attr;\n\t\t\ttransform_attr attr_ = transform::pre(attr);\n\n\t\t\tbool ok_parse\n\t\t\t  //Creates a place to hold the result of parse_rhs\n\t\t\t  //called inside the following scope.\n\t\t\t  ;\n\t\t\t{\n\t\t\t // Create a scope to cause the dbg variable below (within\n\t\t\t // the #if...#endif) to call it's DTOR before any\n\t\t\t // modifications are made to the attribute, attr_ passed\n\t\t\t // to parse_rhs (such as might be done in\n\t\t\t // transform::post when, for example,\n\t\t\t // ActualAttribute is a recursive variant).\n#if defined(BOOST_SPIRIT_X3_DEBUG)\n\t\t\t\tcontext_debug<Iterator, transform_attr>\n\t\t\t\tdbg(rule_name, first, last, attr_, ok_parse);\n#endif\n\t\t\t\tok_parse = parse_rhs(rhs, first, last, context, attr_, attr_\n\t\t\t\t   , mpl::bool_\n\t\t\t\t\t < (  RHS::has_action\n\t\t\t\t\t   && !ExplicitAttrPropagation::value\n\t\t\t\t\t   )\n\t\t\t\t\t >()\n\t\t\t\t  );\n\t\t\t}\n\t\t\tif (ok_parse)\n\t\t\t{\n\t\t\t\t// do up-stream transformation, this integrates the results\n\t\t\t\t// back into the original attribute value, if appropriate\n\t\t\t\ttransform::post(attr, std::forward<transform_attr>(attr_));\n\t\t\t}\n\t\t\treturn ok_parse;\n\t\t}\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal/detail/transform_attribute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#ifndef BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP\n#define BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP\n\n#include \"../../support/traits/transform_attribute.hpp\"\n#include \"../../support/traits/move_to.hpp\"\n#include <type_traits>\n#include <utility>\n\n///////////////////////////////////////////////////////////////////////////////\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct parser_id;\n\n\ttemplate <typename Exposed, typename Transformed>\n\tstruct default_transform_attribute\n\t{\n\t\ttypedef Transformed type;\n\n\t\tstatic Transformed pre(Exposed&) { return Transformed(); }\n\n\t\tstatic void post(Exposed& val, Transformed&& attribute)\n\t\t{\n\t\t\ttraits::move_to(std::forward<Transformed>(attribute), val);\n\t\t}\n\t};\n\n\t// handle case where no transformation is required as the types are the same\n\ttemplate <typename Attribute>\n\tstruct default_transform_attribute<Attribute, Attribute>\n\t{\n\t\ttypedef Attribute& type;\n\t\tstatic Attribute& pre(Attribute& val) { return val; }\n\t\tstatic void post(Attribute&, Attribute const&) {}\n\t};\n\n\t// main specialization for x3\n\ttemplate <typename Exposed, typename Transformed, typename Enable = void>\n\tstruct transform_attribute\n\t  : default_transform_attribute<Exposed, Transformed> {};\n\n\t// unused_type needs some special handling as well\n\ttemplate <>\n\tstruct transform_attribute<unused_type, unused_type>\n\t{\n\t\ttypedef unused_type type;\n\t\tstatic unused_type pre(unused_type) { return unused; }\n\t\tstatic void post(unused_type, unused_type) {}\n\t};\n\n\ttemplate <>\n\tstruct transform_attribute<unused_type const, unused_type>\n\t  : transform_attribute<unused_type, unused_type> {};\n\n\ttemplate <typename Attribute>\n\tstruct transform_attribute<unused_type, Attribute>\n\t  : transform_attribute<unused_type, unused_type> {};\n\n\ttemplate <typename Attribute>\n\tstruct transform_attribute<unused_type const, Attribute>\n\t  : transform_attribute<unused_type, unused_type> {};\n\n\ttemplate <typename Attribute>\n\tstruct transform_attribute<Attribute, unused_type>\n\t  : transform_attribute<unused_type, unused_type> {};\n\n\ttemplate <typename Attribute>\n\tstruct transform_attribute<Attribute const, unused_type>\n\t  : transform_attribute<unused_type, unused_type> {};\n}}}\n\n///////////////////////////////////////////////////////////////////////////////\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Exposed, typename Transformed>\n\tstruct transform_attribute<Exposed, Transformed, x3::parser_id>\n\t  : x3::transform_attribute<Exposed, Transformed>\n\t{\n\t\tstatic_assert(!std::is_reference<Exposed>::value,\n\t\t\t\"Exposed cannot be a reference type\");\n\t\tstatic_assert(!std::is_reference<Transformed>::value,\n\t\t\t\"Transformed cannot be a reference type\");\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal/rule.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)\n#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM\n\n#include \"detail/rule.hpp\"\n#include <boost/type_traits/is_same.hpp>\n#include \"../support/context.hpp\"\n#include <boost/preprocessor/variadic/to_seq.hpp>\n#include <boost/preprocessor/variadic/elem.hpp>\n#include <boost/preprocessor/seq/for_each.hpp>\n#include <type_traits>\n\n#if !defined(BOOST_SPIRIT_X3_NO_RTTI)\n#include <typeinfo>\n#endif\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t// default parse_rule implementation\n\ttemplate <typename ID, typename Iterator\n\t  , typename Context, typename ActualAttribute>\n\tinline detail::default_parse_rule_result\n\tparse_rule(\n\t\tdetail::rule_id<ID>\n\t  , Iterator& first, Iterator const& last\n\t  , Context const& context, ActualAttribute& attr)\n\t{\n\t\tstatic_assert(!is_same<decltype(x3::get<ID>(context)), unused_type>::value,\n\t\t\t\"BOOST_SPIRIT_DEFINE undefined for this rule.\");\n\t\treturn x3::get<ID>(context).parse(first, last, context, unused, attr);\n\t}\n\n\ttemplate <typename ID, typename RHS, typename Attribute, bool force_attribute_, bool skip_definition_injection = false>\n\tstruct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection>>\n\t{\n\t\ttypedef rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection> this_type;\n\t\ttypedef ID id;\n\t\ttypedef RHS rhs_type;\n\t\ttypedef rule<ID, Attribute, force_attribute_> lhs_type;\n\t\ttypedef Attribute attribute_type;\n\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<Attribute, unused_type>::value;\n\t\tstatic bool const handles_container =\n\t\t\ttraits::is_container<Attribute>::value;\n\t\tstatic bool const force_attribute =\n\t\t\tforce_attribute_;\n\n\t\tconstexpr rule_definition(RHS const& rhs, char const* name)\n\t\t  : rhs(rhs), name(name) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute_>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute_& attr) const\n\t\t{\n\t\t\treturn detail::rule_parser<attribute_type, ID, skip_definition_injection>\n\t\t\t\t::call_rule_definition(\n\t\t\t\t\trhs, name, first, last\n\t\t\t\t  , context\n\t\t\t\t  , attr\n\t\t\t\t  , mpl::bool_<force_attribute>());\n\t\t}\n\n\t\tRHS rhs;\n\t\tchar const* name;\n\t};\n\n\ttemplate <typename ID, typename Attribute, bool force_attribute_>\n\tstruct rule : parser<rule<ID, Attribute, force_attribute_>>\n\t{\n\t\tstatic_assert(!std::is_reference<Attribute>::value,\n\t\t\t\t\t  \"Reference qualifier on rule attribute type is meaningless\");\n\n\t\ttypedef ID id;\n\t\ttypedef Attribute attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!std::is_same<std::remove_const_t<Attribute>, unused_type>::value;\n\t\tstatic bool const handles_container =\n\t\t\ttraits::is_container<Attribute>::value;\n\t\tstatic bool const force_attribute = force_attribute_;\n\n#if !defined(BOOST_SPIRIT_X3_NO_RTTI)\n\t\trule() : name(typeid(rule).name()) {}\n#else\n\t\tconstexpr rule() : name(\"unnamed\") {}\n#endif\n\n\t\tconstexpr rule(char const* name)\n\t\t  : name(name) {}\n\n\t\tconstexpr rule(rule const& r)\n\t\t  : name(r.name)\n\t\t{\n\t\t\t// Assert that we are not copying an unitialized static rule. If\n\t\t\t// the static is in another TU, it may be initialized after we copy\n\t\t\t// it. If so, its name member will be nullptr.\n\t\t\tBOOST_ASSERT_MSG(r.name, \"uninitialized rule\"); // static initialization order fiasco\n\t\t}\n\n\t\ttemplate <spirit_parser RHS>\n\t\tconstexpr rule_definition<\n\t\t\tID, RHS, Attribute, force_attribute_>\n\t\toperator=(RHS const& rhs) const&\n\t\t{\n\t\t\treturn { rhs, name };\n\t\t}\n\n\t\ttemplate <spirit_parser RHS>\n\t\tconstexpr rule_definition<\n\t\t\tID, RHS, Attribute, true>\n\t\toperator%=(RHS const& rhs) const&\n\t\t{\n\t\t\treturn { rhs, name };\n\t\t}\n\n\t\t// When a rule placeholder constructed and immediately consumed it cannot be used recursively,\n\t\t// that's why the rule definition injection into a parser context can be skipped.\n\t\t// This optimization has a huge impact on compile times because immediate rules are commonly\n\t\t// used to cast an attribute like `as`/`attr_cast` does in Qi.\n\t\ttemplate <spirit_parser RHS>\n\t\tconstexpr rule_definition<\n\t\t\tID, RHS, Attribute, force_attribute_, true>\n\t\toperator=(RHS const& rhs) const&&\n\t\t{\n\t\t\treturn { rhs, name };\n\t\t}\n\n\t\ttemplate <spirit_parser RHS>\n\t\tconstexpr rule_definition<\n\t\t\tID, RHS, Attribute, true, true>\n\t\toperator%=(RHS const& rhs) const&&\n\t\t{\n\t\t\treturn { rhs, name };\n\t\t}\n\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute_>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute_& attr) const\n\t\t{\n\t\t\tstatic_assert(has_attribute,\n\t\t\t\t\"The rule does not have an attribute. Check your parser.\");\n\n\t\t\tusing transform = traits::transform_attribute<\n\t\t\t\tAttribute_, attribute_type, parser_id>;\n\n\t\t\tusing transform_attr = typename transform::type;\n\t\t\ttransform_attr attr_ = transform::pre(attr);\n\n\t\t\tif (parse_rule(detail::rule_id<ID>{}, first, last, context, attr_)) {\n\t\t\t\ttransform::post(attr, std::forward<transform_attr>(attr_));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t\t, Context const& context, unused_type, unused_type) const\n\t\t{\n\t\t\t// make sure we pass exactly the rule attribute type\n\t\t\tattribute_type no_attr{};\n\t\t\treturn parse_rule(detail::rule_id<ID>{}, first, last, context, no_attr);\n\t\t}\n\n\t\tchar const* name;\n\t};\n\n\tnamespace traits\n\t{\n\t\ttemplate <typename T, typename Enable = void>\n\t\tstruct is_rule : mpl::false_ {};\n\n\t\ttemplate <typename ID, typename Attribute, bool force_attribute>\n\t\tstruct is_rule<rule<ID, Attribute, force_attribute>> : mpl::true_ {};\n\n\t\ttemplate <typename ID, typename Attribute, typename RHS, bool force_attribute, bool skip_definition_injection>\n\t\tstruct is_rule<rule_definition<ID, RHS, Attribute, force_attribute, skip_definition_injection>> : mpl::true_ {};\n\t}\n\n\ttemplate <typename T>\n\tstruct get_info<T, typename enable_if<traits::is_rule<T>>::type>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(T const& r) const\n\t\t{\n\t\t\tBOOST_ASSERT_MSG(r.name, \"uninitialized rule\"); // static initialization order fiasco\n\t\t\treturn r.name? r.name : \"uninitialized\";\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_DECLARE_(r, data, rule_type)                               \\\n\ttemplate <typename Iterator, typename Context>                              \\\n\tbool parse_rule(                                                            \\\n\t\t::boost::spirit::x3::detail::rule_id<rule_type::id>                     \\\n\t  , Iterator& first, Iterator const& last                                   \\\n\t  , Context const& context, rule_type::attribute_type& attr);               \\\n\t/***/\n\n#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH(                        \\\n\tBOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))            \\\n\t/***/\n\n#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)\n#define BOOST_SPIRIT_DEFINE_(r, data, rule_name)                                \\\n\tusing BOOST_PP_CAT(rule_name, _synonym) = decltype(rule_name);              \\\n\ttemplate <typename Iterator, typename Context>                              \\\n\tinline bool parse_rule(                                                     \\\n\t\t::boost::spirit::x3::detail::rule_id<BOOST_PP_CAT(rule_name, _synonym)::id> \\\n\t  , Iterator& first, Iterator const& last                                   \\\n\t  , Context const& context, BOOST_PP_CAT(rule_name, _synonym)::attribute_type& attr) \\\n\t{                                                                           \\\n\t\tusing rule_t = BOOST_JOIN(rule_name, _synonym);                         \\\n\t\treturn ::boost::spirit::x3::detail                                      \\\n\t\t\t::rule_parser<typename rule_t::attribute_type, rule_t::id, true>    \\\n\t\t\t::call_rule_definition(                                             \\\n\t\t\t\tBOOST_JOIN(rule_name, _def), rule_name.name                     \\\n\t\t\t  , first, last, context, attr                                      \\\n\t\t\t  , ::boost::mpl::bool_<rule_t::force_attribute>());                \\\n\t}                                                                           \\\n\t/***/\n#else\n#define BOOST_SPIRIT_DEFINE_(r, data, rule_name)                                \\\n\ttemplate <typename Iterator, typename Context>                              \\\n\tinline bool parse_rule(                                                     \\\n\t\t::boost::spirit::x3::detail::rule_id<decltype(rule_name)::id>           \\\n\t  , Iterator& first, Iterator const& last                                   \\\n\t  , Context const& context, decltype(rule_name)::attribute_type& attr)      \\\n\t{                                                                           \\\n\t\tusing rule_t = decltype(rule_name);                                     \\\n\t\treturn ::boost::spirit::x3::detail                                      \\\n\t\t\t::rule_parser<typename rule_t::attribute_type, rule_t::id, true>    \\\n\t\t\t::call_rule_definition(                                             \\\n\t\t\t\tBOOST_JOIN(rule_name, _def), rule_name.name                     \\\n\t\t\t  , first, last, context, attr                                      \\\n\t\t\t  , ::boost::mpl::bool_<rule_t::force_attribute>());                \\\n\t}                                                                           \\\n\t/***/\n#endif\n\n#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH(                         \\\n\tBOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))             \\\n\t/***/\n\n#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context)                  \\\n\ttemplate bool parse_rule<Iterator, Context>(                                \\\n\t\t::boost::spirit::x3::detail::rule_id<rule_type::id>                     \\\n\t  , Iterator& first, Iterator const& last                                   \\\n\t  , Context const& context, rule_type::attribute_type&);                    \\\n\t/***/\n\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal/simple_trace.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)\n#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM\n\n#include \"../support/unused.hpp\"\n#include \"../support/traits/print_token.hpp\"\n#include \"../support/traits/print_attribute.hpp\"\n#include \"debug_handler_state.hpp\"\n#include <boost/type_traits/is_same.hpp>\n#include <iostream>\n\n//  The stream to use for debug output\n#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)\n#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr\n#endif\n\n//  number of tokens to print while debugging\n#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)\n#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20\n#endif\n\n//  number of spaces to indent\n#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)\n#define BOOST_SPIRIT_X3_DEBUG_INDENT 2\n#endif\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tnamespace detail\n\t{\n\t\ttemplate <typename Char>\n\t\tinline void token_printer(std::ostream& o, Char c)\n\t\t{\n\t\t\t// allow customization of the token printer routine\n\t\t\tx3::traits::print_token(o, c);\n\t\t}\n\t}\n\n\ttemplate <int IndentSpaces = 2, int CharsToPrint = 20>\n\tstruct simple_trace\n\t{\n\t\tsimple_trace(std::ostream& out)\n\t\t  : out(out), indent(0) {}\n\n\t\tvoid print_indent(int n) const\n\t\t{\n\t\t\tn *= IndentSpaces;\n\t\t\tfor (int i = 0; i != n; ++i)\n\t\t\t\tout << ' ';\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvoid print_some(\n\t\t\tchar const* tag\n\t\t  , Iterator first, Iterator const& last) const\n\t\t{\n\t\t\tprint_indent(indent);\n\t\t\tout << '<' << tag << '>';\n\t\t\tint const n = CharsToPrint;\n\t\t\tfor (int i = 0; first != last && i != n && *first; ++i, ++first)\n\t\t\t\tdetail::token_printer(out, *first);\n\t\t\tout << \"</\" << tag << '>' << std::endl;\n\n\t\t\t// $$$ FIXME convert invalid xml characters (e.g. '<') to valid\n\t\t\t// character entities. $$$\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute, typename State>\n\t\tvoid operator()(\n\t\t\tIterator const& first\n\t\t  , Iterator const& last\n\t\t  , Attribute const& attr\n\t\t  , State state\n\t\t  , std::string const& rule_name) const\n\t\t{\n\t\t\tswitch (state)\n\t\t\t{\n\t\t\t\tcase pre_parse:\n\t\t\t\t\tprint_indent(indent++);\n\t\t\t\t\tout\n\t\t\t\t\t\t<< '<' << rule_name << '>'\n\t\t\t\t\t\t<< std::endl;\n\t\t\t\t\tprint_some(\"try\", first, last);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase successful_parse:\n\t\t\t\t\tprint_some(\"success\", first, last);\n\t\t\t\t\tif (!is_same<Attribute, unused_type>::value)\n\t\t\t\t\t{\n\t\t\t\t\t\tprint_indent(indent);\n\t\t\t\t\t\tout\n\t\t\t\t\t\t\t<< \"<attributes>\";\n\t\t\t\t\t\ttraits::print_attribute(out, attr);\n\t\t\t\t\t\tout\n\t\t\t\t\t\t\t<< \"</attributes>\";\n\t\t\t\t\t\tout << std::endl;\n\t\t\t\t\t}\n\t\t\t\t\tprint_indent(--indent);\n\t\t\t\t\tout\n\t\t\t\t\t\t<< \"</\" << rule_name << '>'\n\t\t\t\t\t\t<< std::endl;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase failed_parse:\n\t\t\t\t\tprint_indent(indent);\n\t\t\t\t\tout << \"<fail/>\" << std::endl;\n\t\t\t\t\tprint_indent(--indent);\n\t\t\t\t\tout\n\t\t\t\t\t\t<< \"</\" << rule_name << '>'\n\t\t\t\t\t\t<< std::endl;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tstd::ostream& out;\n\t\tmutable int indent;\n\t};\n\n\tnamespace detail\n\t{\n\t\ttypedef simple_trace<\n\t\t\tBOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>\n\t\tsimple_trace_type;\n\n\t\tinline simple_trace_type&\n\t\tget_simple_trace()\n\t\t{\n\t\t\tstatic simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);\n\t\t\treturn tracer;\n\t\t}\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/nonterminal.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM)\n#define BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM\n\n#include \"nonterminal/rule.hpp\"\n//~ #include \"nonterminal/error_handler.hpp\"\n//~ #include \"nonterminal/debug_handler.hpp\"\n//~ #include \"nonterminal/success_handler.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/bool.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2009  Hartmut Kaiser\n\tCopyright (c) 2014  Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#ifndef BOOST_SPIRIT_X3_NUMERIC_BOOL_HPP\n#define BOOST_SPIRIT_X3_NUMERIC_BOOL_HPP\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"bool_policies.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>\n\tstruct bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>\n\t{\n\t\ttypedef Encoding encoding;\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\tconstexpr bool_parser()\n\t\t\t: policies() {}\n\n\t\tconstexpr bool_parser(BoolPolicies const& policies)\n\t\t\t: policies(policies) {}\n\n\t\ttemplate <typename Iterator, typename Context>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, T& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn policies.parse_true(first, last, attr, get_case_compare<encoding>(context))\n\t\t\t\t|| policies.parse_false(first, last, attr, get_case_compare<encoding>(context));\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr_param) const\n\t\t{\n\t\t\t// this case is called when Attribute is not T\n\t\t\tT attr_;\n\t\t\tif (parse(first, last, context, unused, attr_))\n\t\t\t{\n\t\t\t\ttraits::move_to(attr_, attr_param);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tBoolPolicies policies;\n\t};\n\n\ttemplate <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>\n\tstruct literal_bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>\n\t{\n\t\ttypedef Encoding encoding;\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Value>\n\t\tconstexpr literal_bool_parser(Value const& n)\n\t\t\t: policies(), n_(n) {}\n\n\t\ttemplate <typename Value>\n\t\tconstexpr literal_bool_parser(Value const& n, BoolPolicies const& policies)\n\t\t\t: policies(policies), n_(n) {}\n\n\t\ttemplate <typename Iterator, typename Context>\n\t\tbool parse_main(Iterator& first, Iterator const& last\n\t\t  , Context const& context, T& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn (n_ && policies.parse_true(first, last, attr, get_case_compare<encoding>(context)))\n\t\t\t\t|| (!n_ && policies.parse_false(first, last, attr, get_case_compare<encoding>(context)));\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, T& attr) const\n\t\t{\n\t\t\treturn parse_main(first, last, context, attr);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr_param) const\n\t\t{\n\t\t\t// this case is called when Attribute is not T\n\t\t\tT attr_;\n\t\t\tif (parse_main(first, last, context, attr_))\n\t\t\t{\n\t\t\t\ttraits::move_to(attr_, attr_param);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tBoolPolicies policies;\n\t\tT n_;\n\t};\n\n\tnamespace standard\n\t{\n\t\ttypedef bool_parser<bool, char_encoding::standard> bool_type;\n\t\tconstexpr bool_type bool_ = {};\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::standard> true_type;\n\t\tconstexpr true_type true_ = { true };\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::standard> false_type;\n\t\tconstexpr false_type false_ = { false };\n\t}\n\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tnamespace standard_wide\n\t{\n\t\ttypedef bool_parser<bool, char_encoding::standard_wide> bool_type;\n\t\tconstexpr bool_type bool_ = {};\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::standard_wide> true_type;\n\t\tconstexpr true_type true_ = { true };\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::standard_wide> false_type;\n\t\tconstexpr false_type false_ = { false };\n\t}\n#endif\n\n\tnamespace ascii\n\t{\n\t\ttypedef bool_parser<bool, char_encoding::ascii> bool_type;\n\t\tconstexpr bool_type bool_ = {};\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::ascii> true_type;\n\t\tconstexpr true_type true_ = { true };\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::ascii> false_type;\n\t\tconstexpr false_type false_ = { false };\n\t}\n\n\tnamespace iso8859_1\n\t{\n\t\ttypedef bool_parser<bool, char_encoding::iso8859_1> bool_type;\n\t\tconstexpr bool_type bool_ = {};\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::iso8859_1> true_type;\n\t\tconstexpr true_type true_ = { true };\n\n\t\ttypedef literal_bool_parser<bool, char_encoding::iso8859_1> false_type;\n\t\tconstexpr false_type false_ = { false };\n\t}\n\n\tusing standard::bool_;\n\tusing standard::true_;\n\tusing standard::false_;\n\n\t}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/bool_policies.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2009  Hartmut Kaiser\n\tCopyright (c) 2014  Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_BOOL_POLICIES_SEP_29_2009_0710AM)\n#define BOOST_SPIRIT_X3_BOOL_POLICIES_SEP_29_2009_0710AM\n\n#include \"../string/detail/string_parse.hpp\"\n#include \"../support/traits/move_to.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Default boolean policies\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T = bool>\n\tstruct bool_policies\n\t{\n\t\ttemplate <typename Iterator, typename Attribute, typename CaseCompare>\n\t\tstatic bool\n\t\tparse_true(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)\n\t\t{\n\t\t\tif (detail::string_parse(\"true\", first, last, unused, case_compare))\n\t\t\t{\n\t\t\t\ttraits::move_to(T(true), attr_);    // result is true\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute, typename CaseCompare>\n\t\tstatic bool\n\t\tparse_false(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)\n\t\t{\n\t\t\tif (detail::string_parse(\"false\", first, last, unused, case_compare))\n\t\t\t{\n\t\t\t\ttraits::move_to(T(false), attr_);   // result is false\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/int.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM)\n#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../support/numeric_utils/extract_int.hpp\"\n#include <cstdint>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <\n\t\ttypename T\n\t  , unsigned Radix = 10\n\t  , unsigned MinDigits = 1\n\t  , int MaxDigits = -1>\n\tstruct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits>>\n\t{\n\t\t// check template parameter 'Radix' for validity\n\t\tstatic_assert(\n\t\t\t(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),\n\t\t\t\"Error Unsupported Radix\");\n\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr) const\n\t\t{\n\t\t\ttypedef extract_int<T, Radix, MinDigits, MaxDigits> extract;\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn extract::call(first, last, attr);\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name)                              \\\n\ttypedef int_parser<int_type> name##type;                                    \\\n\tconstexpr name##type name = {};                                             \\\n\t/***/\n\n\tBOOST_SPIRIT_X3_INT_PARSER(long, long_)\n\tBOOST_SPIRIT_X3_INT_PARSER(short, short_)\n\tBOOST_SPIRIT_X3_INT_PARSER(int, int_)\n\tBOOST_SPIRIT_X3_INT_PARSER(long long, long_long)\n\n\tBOOST_SPIRIT_X3_INT_PARSER(int8_t, int8)\n\tBOOST_SPIRIT_X3_INT_PARSER(int16_t, int16)\n\tBOOST_SPIRIT_X3_INT_PARSER(int32_t, int32)\n\tBOOST_SPIRIT_X3_INT_PARSER(int64_t, int64)\n\n#undef BOOST_SPIRIT_X3_INT_PARSER\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/real.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM)\n#define BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"real_policies.hpp\"\n#include \"../support/numeric_utils/extract_real.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename T, typename RealPolicies = real_policies<T> >\n\tstruct real_parser : parser<real_parser<T, RealPolicies> >\n\t{\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\tconstexpr real_parser()\n\t\t\t: policies() {}\n\n\t\tconstexpr real_parser(RealPolicies const& policies)\n\t\t\t: policies(policies) {}\n\n\t\ttemplate <typename Iterator, typename Context>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, T& attr_) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn extract_real<T, RealPolicies>::parse(first, last, attr_, policies);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr_param) const\n\t\t{\n\t\t\t// this case is called when Attribute is not T\n\t\t\tT attr_;\n\t\t\tif (parse(first, last, context, unused, attr_))\n\t\t\t{\n\t\t\t\ttraits::move_to(attr_, attr_param);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tRealPolicies policies;\n\t};\n\n\ttypedef real_parser<float> float_type;\n\tconstexpr float_type float_ = {};\n\n\ttypedef real_parser<double> double_type;\n\tconstexpr double_type double_ = {};\n\n\ttypedef real_parser<long double> long_double_type;\n\tconstexpr long_double_type long_double = {};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/real_policies.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_REAL_POLICIES_APRIL_17_2006_1158PM)\n#define BOOST_SPIRIT_X3_REAL_POLICIES_APRIL_17_2006_1158PM\n\n#include \"../string/detail/string_parse.hpp\"\n#include \"../support/numeric_utils/extract_int.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Default (unsigned) real number policies\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct ureal_policies\n\t{\n\t\t// trailing dot policy suggested by Gustavo Guerra\n\t\tstatic bool const allow_leading_dot = true;\n\t\tstatic bool const allow_trailing_dot = true;\n\t\tstatic bool const expect_dot = false;\n\n\t\ttemplate <typename Iterator>\n\t\tstatic bool\n\t\tparse_sign(Iterator& /*first*/, Iterator const& /*last*/)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool\n\t\tparse_n(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\treturn extract_uint<T, 10, 1, -1>::call(first, last, attr_);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tstatic bool\n\t\tparse_dot(Iterator& first, Iterator const& last)\n\t\t{\n\t\t\tif (first == last || *first != '.')\n\t\t\t\treturn false;\n\t\t\t++first;\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool\n\t\tparse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\treturn extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tstatic bool\n\t\tparse_exp(Iterator& first, Iterator const& last)\n\t\t{\n\t\t\tif (first == last || (*first != 'e' && *first != 'E'))\n\t\t\t\treturn false;\n\t\t\t++first;\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tstatic bool\n\t\tparse_exp_n(Iterator& first, Iterator const& last, int& attr_)\n\t\t{\n\t\t\treturn extract_int<int, 10, 1, -1>::call(first, last, attr_);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t//  The parse_nan() and parse_inf() functions get called whenever\n\t\t//  a number to parse does not start with a digit (after having\n\t\t//  successfully parsed an optional sign).\n\t\t//\n\t\t//  The functions should return true if a Nan or Inf has been found. In\n\t\t//  this case the attr should be set to the matched value (NaN or\n\t\t//  Inf). The optional sign will be automatically applied afterwards.\n\t\t//\n\t\t//  The default implementation below recognizes representations of NaN\n\t\t//  and Inf as mandated by the C99 Standard and as proposed for\n\t\t//  inclusion into the C++0x Standard: nan, nan(...), inf and infinity\n\t\t//  (the matching is performed case-insensitively).\n\t\t///////////////////////////////////////////////////////////////////////\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool\n\t\tparse_nan(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn false;   // end of input reached\n\n\t\t\tif (*first != 'n' && *first != 'N')\n\t\t\t\treturn false;   // not \"nan\"\n\n\t\t\t// nan[(...)] ?\n\t\t\tif (detail::string_parse(\"nan\", \"NAN\", first, last, unused))\n\t\t\t{\n\t\t\t\tif (first != last && *first == '(')\n\t\t\t\t{\n\t\t\t\t\t// skip trailing (...) part\n\t\t\t\t\tIterator i = first;\n\n\t\t\t\t\twhile (++i != last && *i != ')')\n\t\t\t\t\t\t;\n\t\t\t\t\tif (i == last)\n\t\t\t\t\t\treturn false;     // no trailing ')' found, give up\n\n\t\t\t\t\tfirst = ++i;\n\t\t\t\t}\n\t\t\t\tattr_ = std::numeric_limits<T>::quiet_NaN();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool\n\t\tparse_inf(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn false;   // end of input reached\n\n\t\t\tif (*first != 'i' && *first != 'I')\n\t\t\t\treturn false;   // not \"inf\"\n\n\t\t\t// inf or infinity ?\n\t\t\tif (detail::string_parse(\"inf\", \"INF\", first, last, unused))\n\t\t\t{\n\t\t\t\t// skip allowed 'inity' part of infinity\n\t\t\t\tdetail::string_parse(\"inity\", \"INITY\", first, last, unused);\n\t\t\t\tattr_ = std::numeric_limits<T>::infinity();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Default (signed) real number policies\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct real_policies : ureal_policies<T>\n\t{\n\t\ttemplate <typename Iterator>\n\t\tstatic bool\n\t\tparse_sign(Iterator& first, Iterator const& last)\n\t\t{\n\t\t\treturn extract_sign(first, last);\n\t\t}\n\t};\n\n\ttemplate <typename T>\n\tstruct strict_ureal_policies : ureal_policies<T>\n\t{\n\t\tstatic bool const expect_dot = true;\n\t};\n\n\ttemplate <typename T>\n\tstruct strict_real_policies : real_policies<T>\n\t{\n\t\tstatic bool const expect_dot = true;\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric/uint.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2011 Jan Frederick Eick\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM)\n#define BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"../support/numeric_utils/extract_int.hpp\"\n#include <cstdint>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <\n\t\ttypename T\n\t  , unsigned Radix = 10\n\t  , unsigned MinDigits = 1\n\t  , int MaxDigits = -1>\n\tstruct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits>>\n\t{\n\t\t// check template parameter 'Radix' for validity\n\t\tstatic_assert(\n\t\t\t(Radix >= 2 && Radix <= 36),\n\t\t\t\"Error Unsupported Radix\");\n\n\t\ttypedef T attribute_type;\n\t\tstatic bool const has_attribute = true;\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr) const\n\t\t{\n\t\t\ttypedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn extract::call(first, last, attr);\n\t\t}\n\t};\n\n#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, name)                            \\\n\ttypedef uint_parser<uint_type> name##type;                                  \\\n\tconstexpr name##type name = {};                                             \\\n\t/***/\n\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned long, ulong_)\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned short, ushort_)\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned int, uint_)\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned long long, ulong_long)\n\n\tBOOST_SPIRIT_X3_UINT_PARSER(uint8_t, uint8)\n\tBOOST_SPIRIT_X3_UINT_PARSER(uint16_t, uint16)\n\tBOOST_SPIRIT_X3_UINT_PARSER(uint32_t, uint32)\n\tBOOST_SPIRIT_X3_UINT_PARSER(uint64_t, uint64)\n\n#undef BOOST_SPIRIT_X3_UINT_PARSER\n\n#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, radix, name)                     \\\n\ttypedef uint_parser<uint_type, radix> name##type;                           \\\n\tconstexpr name##type name = name##type();                                   \\\n\t/***/\n\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned, 2, bin)\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned, 8, oct)\n\tBOOST_SPIRIT_X3_UINT_PARSER(unsigned, 16, hex)\n\n#undef BOOST_SPIRIT_X3_UINT_PARSER\n\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/numeric.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM)\n#define BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM\n\n#include \"numeric/bool.hpp\"\n#include \"numeric/int.hpp\"\n#include \"numeric/uint.hpp\"\n#ifndef BOOST_SPIRIT_NO_REAL_NUMBERS\n#include \"numeric/real.hpp\"\n#endif\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/alternative.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ALTERNATIVE_JAN_07_2013_1131AM)\n#define BOOST_SPIRIT_X3_ALTERNATIVE_JAN_07_2013_1131AM\n\n#include \"../support/traits/attribute_of_binary.hpp\"\n#include \"../core/parser.hpp\"\n#include \"detail/alternative.hpp\"\n#include \"../directive/expect.hpp\"\n\n#include <boost/variant/variant_fwd.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct alternative : binary_parser<Left, Right, alternative<Left, Right>>\n\t{\n\t\ttypedef binary_parser<Left, Right, alternative<Left, Right>> base_type;\n\n\t\tconstexpr alternative(Left const& left, Right const& right)\n\t\t\t: base_type(left, right) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, unused_type) const\n\t\t{\n\t\t\treturn this->left.parse(first, last, context, rcontext, unused) ||\n\t\t\t\t(\n\t\t\t\t\t!has_expectation_failure(context) &&\n\t\t\t\t\tthis->right.parse(first, last, context, rcontext, unused)\n\t\t\t\t);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn detail::parse_alternative(this->left, first, last, context, rcontext, attr) ||\n\t\t\t\t(\n\t\t\t\t\t!has_expectation_failure(context) &&\n\t\t\t\t\tdetail::parse_alternative(this->right, first, last, context, rcontext, attr)\n\t\t\t\t);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Left, spirit_parser Right>\n\tconstexpr alternative<\n\t\tLeft\n\t  , Right>\n\toperator|(Left const& left, Right const& right)\n\t{\n\t\treturn { left, right };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct attribute_of<x3::alternative<Left, Right>, Context>\n\t\t: x3::detail::attribute_of_binary<boost::variant, x3::alternative, Left, Right, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/and_predicate.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_AND_PREDICATE_MARCH_23_2007_0617PM)\n#define BOOST_SPIRIT_X3_AND_PREDICATE_MARCH_23_2007_0617PM\n\n#include \"../core/parser.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct and_predicate : unary_parser<Subject, and_predicate<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, and_predicate<Subject>> base_type;\n\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\tconstexpr and_predicate(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& /*attr*/) const\n\t\t{\n\t\t\tIterator i = first;\n\t\t\treturn this->subject.parse(i, last, context, rcontext, unused);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Subject>\n\tconstexpr and_predicate<Subject>\n\toperator&(Subject const& subject)\n\t{\n\t\treturn { subject };\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/detail/alternative.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM)\n#define BOOST_SPIRIT_X3_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM\n\n#include \"../../support/traits/attribute_of.hpp\"\n#include \"../../support/traits/pseudo_attribute.hpp\"\n#include \"../../support/traits/is_variant.hpp\"\n#include \"../../support/traits/tuple_traits.hpp\"\n#include \"../../support/traits/move_to.hpp\"\n#include \"../../support/traits/variant_has_substitute.hpp\"\n#include \"../../support/traits/variant_find_substitute.hpp\"\n#include \"../../core/detail/parse_into_container.hpp\"\n\n#include <boost/mpl/if.hpp>\n\n#include <boost/fusion/include/front.hpp>\n\n#include <boost/type_traits/is_same.hpp>\n#include <type_traits>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct alternative;\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\tstruct pass_variant_unused\n\t{\n\t\ttypedef unused_type type;\n\n\t\ttemplate <typename T>\n\t\tstatic unused_type\n\t\tcall(T&)\n\t\t{\n\t\t\treturn unused_type();\n\t\t}\n\t};\n\n\ttemplate <typename Attribute>\n\tstruct pass_variant_used\n\t{\n\t\ttypedef Attribute& type;\n\n\t\tstatic Attribute&\n\t\tcall(Attribute& v)\n\t\t{\n\t\t\treturn v;\n\t\t}\n\t};\n\n\ttemplate <>\n\tstruct pass_variant_used<unused_type> : pass_variant_unused {};\n\n\ttemplate <typename Parser, typename Attribute, typename Context\n\t  , typename Enable = void>\n\tstruct pass_parser_attribute\n\t{\n\t\ttypedef typename\n\t\t\ttraits::attribute_of<Parser, Context>::type\n\t\tattribute_type;\n\t\ttypedef typename\n\t\t\ttraits::variant_find_substitute<Attribute, attribute_type>::type\n\t\tsubstitute_type;\n\n\t\ttypedef typename\n\t\t\tmpl::if_<\n\t\t\t\tis_same<Attribute, substitute_type>\n\t\t\t  , Attribute&\n\t\t\t  , substitute_type\n\t\t\t>::type\n\t\ttype;\n\n\t\ttemplate <typename Attribute_>\n\t\tstatic Attribute_&\n\t\tcall(Attribute_& attribute, mpl::true_)\n\t\t{\n\t\t\treturn attribute;\n\t\t}\n\n\t\ttemplate <typename Attribute_>\n\t\tstatic type\n\t\tcall(Attribute_&, mpl::false_)\n\t\t{\n\t\t\treturn type();\n\t\t}\n\n\t\ttemplate <typename Attribute_>\n\t\tstatic type\n\t\tcall(Attribute_& attribute)\n\t\t{\n\t\t\treturn call(attribute, is_same<Attribute_, typename remove_reference<type>::type>());\n\t\t}\n\t};\n\n\t// Pass non-variant attributes as-is\n\ttemplate <typename Parser, typename Attribute, typename Context\n\t  , typename Enable = void>\n\tstruct pass_non_variant_attribute\n\t{\n\t\ttypedef Attribute& type;\n\n\t\tstatic Attribute&\n\t\tcall(Attribute& attribute)\n\t\t{\n\t\t\treturn attribute;\n\t\t}\n\t};\n\n\t// Unwrap single element sequences\n\ttemplate <typename Parser, typename Attribute, typename Context>\n\tstruct pass_non_variant_attribute<Parser, Attribute, Context,\n\t\ttypename enable_if<traits::is_size_one_sequence<Attribute>>::type>\n\t{\n\t\ttypedef typename remove_reference<\n\t\t\ttypename fusion::result_of::front<Attribute>::type>::type\n\t\tattr_type;\n\n\t\ttypedef pass_parser_attribute<Parser, attr_type, Context> pass;\n\t\ttypedef typename pass::type type;\n\n\t\ttemplate <typename Attribute_>\n\t\tstatic type\n\t\tcall(Attribute_& attr)\n\t\t{\n\t\t\treturn pass::call(fusion::front(attr));\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Attribute, typename Context>\n\tstruct pass_parser_attribute<Parser, Attribute, Context,\n\t\ttypename enable_if_c<(!traits::is_variant<Attribute>::value)>::type>\n\t\t: pass_non_variant_attribute<Parser, Attribute, Context>\n\t{};\n\n\ttemplate <typename Parser, typename Context>\n\tstruct pass_parser_attribute<Parser, unused_type, Context>\n\t\t: pass_variant_unused {};\n\n\ttemplate <typename Parser, typename Attribute, typename Context>\n\tstruct pass_variant_attribute :\n\t\tmpl::if_c<traits::has_attribute<Parser, Context>::value\n\t\t  , pass_parser_attribute<Parser, Attribute, Context>\n\t\t  , pass_variant_unused>::type\n\t{\n\t};\n\n\ttemplate <typename L, typename R, typename Attribute, typename Context>\n\tstruct pass_variant_attribute<alternative<L, R>, Attribute, Context> :\n\t\tmpl::if_c<traits::has_attribute<alternative<L, R>, Context>::value\n\t\t  , pass_variant_used<Attribute>\n\t\t  , pass_variant_unused>::type\n\t{\n\t};\n\n\ttemplate <bool Condition>\n\tstruct move_if\n\t{\n\t\ttemplate<typename T1, typename T2>\n\t\tstatic void call(T1& /* attr_ */, T2& /* attr */) {}\n\t};\n\n\ttemplate <>\n\tstruct move_if<true>\n\t{\n\t\ttemplate<typename T1, typename T2>\n\t\tstatic void call(T1& attr_, T2& attribute)\n\t\t{\n\t\t\ttraits::move_to(attr_, attribute);\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_alternative(Parser const& p, Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attribute)\n\t{\n\t\tusing pass = detail::pass_variant_attribute<Parser, Attribute, Context>;\n\t\tusing pseudo = traits::pseudo_attribute<Context, typename pass::type, Iterator>;\n\n\t\ttypename pseudo::type attr_ = pseudo::call(first, last, pass::call(attribute));\n\n\t\tif (p.parse(first, last, context, rcontext, attr_))\n\t\t{\n\t\t\tmove_if<!std::is_reference<decltype(attr_)>::value>::call(attr_, attribute);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\ttemplate <typename Subject>\n\tstruct alternative_helper : unary_parser<Subject, alternative_helper<Subject>>\n\t{\n\t\tstatic bool const is_pass_through_unary = true;\n\n\t\tusing unary_parser<Subject, alternative_helper<Subject>>::unary_parser;\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn detail::parse_alternative(this->subject, first, last, context, rcontext, attr);\n\t\t}\n\t};\n\n\ttemplate <typename Left, typename Right, typename Context, typename RContext>\n\tstruct parse_into_container_impl<alternative<Left, Right>, Context, RContext>\n\t{\n\t\ttypedef alternative<Left, Right> parser_type;\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attribute, mpl::false_)\n\t\t{\n\t\t\treturn detail::parse_into_container(parser.left, first, last, context, rcontext, attribute)\n\t\t\t\t|| detail::parse_into_container(parser.right, first, last, context, rcontext, attribute);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attribute, mpl::true_)\n\t\t{\n\t\t\treturn detail::parse_into_container(alternative_helper<Left>{parser.left}, first, last, context, rcontext, attribute)\n\t\t\t\t|| detail::parse_into_container(alternative_helper<Right>{parser.right}, first, last, context, rcontext, attribute);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attribute)\n\t\t{\n\t\t\treturn call(parser, first, last, context, rcontext, attribute,\n\t\t\t\ttypename traits::is_variant<typename traits::container_value<Attribute>::type>::type{});\n\t\t}\n\t};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/detail/sequence.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SEQUENCE_DETAIL_JAN_06_2013_1015AM)\n#define BOOST_SPIRIT_X3_SEQUENCE_DETAIL_JAN_06_2013_1015AM\n\n#include \"../../support/traits/attribute_of.hpp\"\n#include \"../../support/traits/attribute_category.hpp\"\n#include \"../../support/traits/has_attribute.hpp\"\n#include \"../../support/traits/is_substitute.hpp\"\n#include \"../../support/traits/container_traits.hpp\"\n#include \"../../support/traits/tuple_traits.hpp\"\n#include \"../../core/detail/parse_into_container.hpp\"\n\n#include <boost/fusion/include/begin.hpp>\n#include <boost/fusion/include/end.hpp>\n#include <boost/fusion/include/advance.hpp>\n#include <boost/fusion/include/deref.hpp>\n#include <boost/fusion/include/empty.hpp>\n#include <boost/fusion/include/front.hpp>\n#include <boost/fusion/include/iterator_range.hpp>\n\n#include <boost/mpl/if.hpp>\n\n#include <boost/type_traits/add_reference.hpp>\n#include <boost/type_traits/is_same.hpp>\n\n#include <iterator> // for std::make_move_iterator\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct sequence;\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename Parser, typename Context, typename Enable = void>\n\tstruct sequence_size\n\t{\n\t\tstatic int const value = traits::has_attribute<Parser, Context>::value;\n\t};\n\n\ttemplate <typename Parser, typename Context>\n\tstruct sequence_size_subject\n\t  : sequence_size<typename Parser::subject_type, Context> {};\n\n\ttemplate <typename Parser, typename Context>\n\tstruct sequence_size<Parser, Context\n\t  , typename enable_if_c<(Parser::is_pass_through_unary)>::type>\n\t  : sequence_size_subject<Parser, Context> {};\n\n\ttemplate <typename L, typename R, typename Context>\n\tstruct sequence_size<sequence<L, R>, Context>\n\t{\n\t\tstatic int const value =\n\t\t\tsequence_size<L, Context>::value +\n\t\t\tsequence_size<R, Context>::value;\n\t};\n\n\tstruct pass_sequence_attribute_unused\n\t{\n\t\ttypedef unused_type type;\n\n\t\ttemplate <typename T>\n\t\tstatic unused_type\n\t\tcall(T&)\n\t\t{\n\t\t\treturn unused_type();\n\t\t}\n\t};\n\n\ttemplate <typename Attribute>\n\tstruct pass_sequence_attribute_size_one_view\n\t{\n\t\ttypedef typename fusion::result_of::deref<\n\t\t\ttypename fusion::result_of::begin<Attribute>::type\n\t\t>::type type;\n\n\t\tstatic type call(Attribute& attribute)\n\t\t{\n\t\t\treturn fusion::deref(fusion::begin(attribute));\n\t\t}\n\t};\n\n\ttemplate <typename Attribute>\n\tstruct pass_through_sequence_attribute\n\t{\n\t\ttypedef Attribute& type;\n\n\t\ttemplate <typename Attribute_>\n\t\tstatic Attribute_&\n\t\tcall(Attribute_& attribute)\n\t\t{\n\t\t\treturn attribute;\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Attribute, typename Enable = void>\n\tstruct pass_sequence_attribute :\n\t\tmpl::if_<\n\t\t\ttraits::is_size_one_view<Attribute>\n\t\t  , pass_sequence_attribute_size_one_view<Attribute>\n\t\t  , pass_through_sequence_attribute<Attribute>>::type {};\n\n\ttemplate <typename L, typename R, typename Attribute>\n\tstruct pass_sequence_attribute<sequence<L, R>, Attribute>\n\t  : pass_through_sequence_attribute<Attribute> {};\n\n\ttemplate <typename Parser, typename Attribute>\n\tstruct pass_sequence_attribute_subject :\n\t\tpass_sequence_attribute<typename Parser::subject_type, Attribute> {};\n\n\ttemplate <typename Parser, typename Attribute>\n\tstruct pass_sequence_attribute<Parser, Attribute\n\t  , typename enable_if_c<(Parser::is_pass_through_unary)>::type>\n\t  : pass_sequence_attribute_subject<Parser, Attribute> {};\n\n\ttemplate <typename L, typename R, typename Attribute, typename Context\n\t  , typename Enable = void>\n\tstruct partition_attribute\n\t{\n\t\tusing attr_category = typename traits::attribute_category<Attribute>::type;\n\t\tstatic_assert(is_same<traits::tuple_attribute, attr_category>::value,\n\t\t\t\"The parser expects tuple-like attribute type\");\n\n\t\tstatic int const l_size = sequence_size<L, Context>::value;\n\t\tstatic int const r_size = sequence_size<R, Context>::value;\n\n\t\tstatic int constexpr actual_size = fusion::result_of::size<Attribute>::value;\n\t\tstatic int constexpr expected_size = l_size + r_size;\n\n\t\t// If you got an error here, then you are trying to pass\n\t\t// a fusion sequence with the wrong number of elements\n\t\t// as that expected by the (sequence) parser.\n\t\tstatic_assert(\n\t\t\tactual_size >= expected_size\n\t\t  , \"Size of the passed attribute is less than expected.\"\n\t\t);\n\t\tstatic_assert(\n\t\t\tactual_size <= expected_size\n\t\t  , \"Size of the passed attribute is bigger than expected.\"\n\t\t);\n\n\t\ttypedef typename fusion::result_of::begin<Attribute>::type l_begin;\n\t\ttypedef typename fusion::result_of::advance_c<l_begin, l_size>::type l_end;\n\t\ttypedef typename fusion::result_of::end<Attribute>::type r_end;\n\t\ttypedef fusion::iterator_range<l_begin, l_end> l_part;\n\t\ttypedef fusion::iterator_range<l_end, r_end> r_part;\n\t\ttypedef pass_sequence_attribute<L, l_part> l_pass;\n\t\ttypedef pass_sequence_attribute<R, r_part> r_pass;\n\n\t\tstatic l_part left(Attribute& s)\n\t\t{\n\t\t\tauto i = fusion::begin(s);\n\t\t\treturn l_part(i, fusion::advance_c<l_size>(i));\n\t\t}\n\n\t\tstatic r_part right(Attribute& s)\n\t\t{\n\t\t\treturn r_part(\n\t\t\t\tfusion::advance_c<l_size>(fusion::begin(s))\n\t\t\t  , fusion::end(s));\n\t\t}\n\t};\n\n\ttemplate <typename L, typename R, typename Attribute, typename Context>\n\tstruct partition_attribute<L, R, Attribute, Context,\n\t\ttypename enable_if_c<(!traits::has_attribute<L, Context>::value &&\n\t\t\ttraits::has_attribute<R, Context>::value)>::type>\n\t{\n\t\ttypedef unused_type l_part;\n\t\ttypedef Attribute& r_part;\n\t\ttypedef pass_sequence_attribute_unused l_pass;\n\t\ttypedef pass_sequence_attribute<R, Attribute> r_pass;\n\n\t\tstatic unused_type left(Attribute&)\n\t\t{\n\t\t\treturn unused;\n\t\t}\n\n\t\tstatic Attribute& right(Attribute& s)\n\t\t{\n\t\t\treturn s;\n\t\t}\n\t};\n\n\ttemplate <typename L, typename R, typename Attribute, typename Context>\n\tstruct partition_attribute<L, R, Attribute, Context,\n\t\ttypename enable_if_c<(traits::has_attribute<L, Context>::value &&\n\t\t\t!traits::has_attribute<R, Context>::value)>::type>\n\t{\n\t\ttypedef Attribute& l_part;\n\t\ttypedef unused_type r_part;\n\t\ttypedef pass_sequence_attribute<L, Attribute> l_pass;\n\t\ttypedef pass_sequence_attribute_unused r_pass;\n\n\t\tstatic Attribute& left(Attribute& s)\n\t\t{\n\t\t\treturn s;\n\t\t}\n\n\t\tstatic unused_type right(Attribute&)\n\t\t{\n\t\t\treturn unused;\n\t\t}\n\t};\n\n\ttemplate <typename L, typename R, typename Attribute, typename Context>\n\tstruct partition_attribute<L, R, Attribute, Context,\n\t\ttypename enable_if_c<(!traits::has_attribute<L, Context>::value &&\n\t\t\t!traits::has_attribute<R, Context>::value)>::type>\n\t{\n\t\ttypedef unused_type l_part;\n\t\ttypedef unused_type r_part;\n\t\ttypedef pass_sequence_attribute_unused l_pass;\n\t\ttypedef pass_sequence_attribute_unused r_pass;\n\n\t\tstatic unused_type left(Attribute&)\n\t\t{\n\t\t\treturn unused;\n\t\t}\n\n\t\tstatic unused_type right(Attribute&)\n\t\t{\n\t\t\treturn unused;\n\t\t}\n\t};\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute, typename AttributeCategory>\n\tbool parse_sequence(\n\t\tParser const& parser, Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attr\n\t  , AttributeCategory)\n\t{\n\t\tusing Left = typename Parser::left_type;\n\t\tusing Right = typename Parser::right_type;\n\t\tusing partition = partition_attribute<Left, Right, Attribute, Context>;\n\t\tusing l_pass = typename partition::l_pass;\n\t\tusing r_pass = typename partition::r_pass;\n\n\t\ttypename partition::l_part l_part = partition::left(attr);\n\t\ttypename partition::r_part r_part = partition::right(attr);\n\t\ttypename l_pass::type l_attr = l_pass::call(l_part);\n\t\ttypename r_pass::type r_attr = r_pass::call(r_part);\n\n\t\tIterator save = first;\n\t\tif (parser.left.parse(first, last, context, rcontext, l_attr)\n\t\t\t&& parser.right.parse(first, last, context, rcontext, r_attr))\n\t\t\treturn true;\n\t\tfirst = save;\n\t\treturn false;\n\t}\n\n\ttemplate <typename Parser, typename Context>\n\tconstexpr bool pass_sequence_container_attribute\n\t\t= sequence_size<Parser, Context>::value > 1;\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\ttypename enable_if_c<pass_sequence_container_attribute<Parser, Context>, bool>::type\n\tparse_sequence_container(\n\t\tParser const& parser\n\t  , Iterator& first, Iterator const& last, Context const& context\n\t  , RContext& rcontext, Attribute& attr)\n\t{\n\t\treturn parser.parse(first, last, context, rcontext, attr);\n\t}\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\ttypename disable_if_c<pass_sequence_container_attribute<Parser, Context>, bool>::type\n\tparse_sequence_container(\n\t\tParser const& parser\n\t  , Iterator& first, Iterator const& last, Context const& context\n\t  , RContext& rcontext, Attribute& attr)\n\t{\n\t\treturn parse_into_container(parser, first, last, context, rcontext, attr);\n\t}\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_sequence(\n\t\tParser const& parser , Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attr\n\t  , traits::container_attribute)\n\t{\n\t\tIterator save = first;\n\t\tif (parse_sequence_container(parser.left, first, last, context, rcontext, attr)\n\t\t\t&& parse_sequence_container(parser.right, first, last, context, rcontext, attr))\n\t\t\treturn true;\n\t\tfirst = save;\n\t\treturn false;\n\t}\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_sequence_assoc(\n\t\tParser const& parser , Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_ /*should_split*/)\n\t{\n\t    return parse_into_container(parser, first, last, context, rcontext, attr);\n\t}\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_sequence_assoc(\n\t\tParser const& parser , Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_ /*should_split*/)\n\t{\n\t\tIterator save = first;\n\t\tif (parser.left.parse( first, last, context, rcontext, attr)\n\t\t\t&& parser.right.parse(first, last, context, rcontext, attr))\n\t\t\treturn true;\n\t\tfirst = save;\n\t\treturn false;\n\t}\n\n\ttemplate <typename Parser, typename Iterator, typename Context\n\t  , typename RContext, typename Attribute>\n\tbool parse_sequence(\n\t\tParser const& parser, Iterator& first, Iterator const& last\n\t  , Context const& context, RContext& rcontext, Attribute& attr\n\t  , traits::associative_attribute)\n\t{\n\t\t// we can come here in 2 cases:\n\t\t// - when sequence is key >> value and therefore must\n\t\t// be parsed with tuple synthesized attribute and then\n\t\t// that tuple is used to save into associative attribute provided here.\n\t\t// Example:  key >> value;\n\t\t//\n\t\t// - when either this->left or this->right provides full key-value\n\t\t// pair (like in case 1) and another one provides nothing.\n\t\t// Example:  eps >> rule<class x; fusion::map<...> >\n\t\t//\n\t\t// first case must be parsed as whole, and second one should\n\t\t// be parsed separately for left and right.\n\n\t\ttypedef typename traits::attribute_of<\n\t\t\tdecltype(parser.left), Context>::type l_attr_type;\n\t\ttypedef typename traits::attribute_of<\n\t\t\tdecltype(parser.right), Context>::type r_attr_type;\n\n\t\ttypedef typename\n\t\t\tmpl::or_<\n\t\t\t\tis_same<l_attr_type, unused_type>\n\t\t\t  , is_same<r_attr_type, unused_type> >\n\t\tshould_split;\n\n\t\treturn parse_sequence_assoc(parser, first, last, context, rcontext, attr\n\t\t  , should_split());\n\t}\n\n\ttemplate <typename Left, typename Right, typename Context, typename RContext>\n\tstruct parse_into_container_impl<sequence<Left, Right>, Context, RContext>\n\t{\n\t\ttypedef sequence<Left, Right> parser_type;\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)\n\t\t{\n\t\t\t// inform user what went wrong if we jumped here in attempt to\n\t\t\t// parse incompatible sequence into fusion::map\n\t\t\tstatic_assert(!is_same< typename traits::attribute_category<Attribute>::type,\n\t\t\t\t  traits::associative_attribute>::value,\n\t\t\t\t  \"To parse directly into fusion::map sequence must produce tuple attribute \"\n\t\t\t\t  \"where type of first element is existing key in fusion::map and second element \"\n\t\t\t\t  \"is value to be stored under that key\");\n\n\t\t\tAttribute attr_{};\n\t\t\tif (!parse_sequence(parser\n\t\t\t       , first, last, context, rcontext, attr_, traits::container_attribute()))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ttraits::append(attr, std::make_move_iterator(traits::begin(attr_)),\n\t\t\t\t\t\t\t\t std::make_move_iterator(traits::end(attr_)));\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)\n\t\t{\n\t\t\treturn parse_into_container_base_impl<parser_type>::call(\n\t\t\t\tparser, first, last, context, rcontext, attr);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool call(\n\t\t\tparser_type const& parser\n\t\t  , Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr)\n\t\t{\n\t\t\ttypedef typename\n\t\t\t\ttraits::attribute_of<parser_type, Context>::type\n\t\t\tattribute_type;\n\n\t\t\ttypedef typename\n\t\t\t\ttraits::container_value<Attribute>::type\n\t\t\tvalue_type;\n\n\t\t\treturn call(parser, first, last, context, rcontext, attr\n\t        , typename traits::is_substitute<attribute_type, value_type>::type());\n\t\t}\n\t};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/difference.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_DIFFERENCE_FEBRUARY_11_2007_1250PM)\n#define BOOST_SPIRIT_X3_DIFFERENCE_FEBRUARY_11_2007_1250PM\n\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../support/traits/has_attribute.hpp\"\n#include \"../core/parser.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct difference : binary_parser<Left, Right, difference<Left, Right>>\n\t{\n\t\ttypedef binary_parser<Left, Right, difference<Left, Right>> base_type;\n\t\tstatic bool const handles_container = Left::handles_container;\n\n\t\tconstexpr difference(Left const& left, Right const& right)\n\t\t  : base_type(left, right) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\t// Try Right first\n\t\t\tIterator start = first;\n\t\t\tif (this->right.parse(first, last, context, rcontext, unused))\n\t\t\t{\n\t\t\t\t// Right succeeds, we fail.\n\t\t\t\tfirst = start;\n\t\t\t\treturn false;\n\t\t\t} else if(has_expectation_failure(context)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Right fails, now try Left\n\t\t\treturn this->left.parse(first, last, context, rcontext, attr);\n\t\t}\n\n\t\ttemplate <typename Left_, typename Right_>\n\t\tconstexpr difference<Left_, Right_>\n\t\tmake(Left_ const& left, Right_ const& right) const\n\t\t{\n\t\t\treturn { left, right };\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Left, spirit_parser Right>\n\tconstexpr difference<\n\t\tLeft\n\t  , Right>\n\toperator-(Left const& left, Right const& right)\n\t{\n\t\treturn { left, right };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct attribute_of<x3::difference<Left, Right>, Context>\n\t\t: attribute_of<Left, Context> {};\n\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct has_attribute<x3::difference<Left, Right>, Context>\n\t\t: has_attribute<Left, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/kleene.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_KLEENE_JANUARY_07_2007_0818AM)\n#define BOOST_SPIRIT_X3_KLEENE_JANUARY_07_2007_0818AM\n\n#include \"../core/parser.hpp\"\n#include \"../support/traits/container_traits.hpp\"\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../core/detail/parse_into_container.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct kleene : unary_parser<Subject, kleene<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, kleene<Subject>> base_type;\n\t\tstatic bool const handles_container = true;\n\n\t\tconstexpr kleene(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\twhile (detail::parse_into_container(\n\t\t\t\tthis->subject, first, last, context, rcontext, attr))\n\t\t\t\t;\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Subject>\n\tconstexpr kleene<Subject>\n\toperator*(Subject const& subject)\n\t{\n\t\treturn { subject };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Subject, typename Context>\n\tstruct attribute_of<x3::kleene<Subject>, Context>\n\t\t: build_container<\n\t\t\ttypename attribute_of<Subject, Context>::type> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/list.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_LIST_MARCH_24_2007_1031AM)\n#define BOOST_SPIRIT_X3_LIST_MARCH_24_2007_1031AM\n\n#include \"../core/parser.hpp\"\n#include \"../support/traits/container_traits.hpp\"\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../core/detail/parse_into_container.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct list : binary_parser<Left, Right, list<Left, Right>>\n\t{\n\t\ttypedef binary_parser<Left, Right, list<Left, Right>> base_type;\n\t\tstatic bool const handles_container = true;\n\n\t\tconstexpr list(Left const& left, Right const& right)\n\t\t  : base_type(left, right) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\t// in order to succeed we need to match at least one element\n\t\t\tif (!detail::parse_into_container(\n\t\t\t\tthis->left, first, last, context, rcontext, attr))\n\t\t\t\treturn false;\n\n\t\t\tIterator iter = first;\n\t\t\twhile (this->right.parse(iter, last, context, rcontext, unused)\n\t\t\t\t&& detail::parse_into_container(\n\t\t\t\t\tthis->left, iter, last, context, rcontext, attr))\n\t\t\t{\n\t\t\t\tfirst = iter;\n\t\t\t}\n\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Left, spirit_parser Right>\n\tconstexpr list<\n\t\tLeft\n\t  , Right>\n\toperator%(Left const& left, Right const& right)\n\t{\n\t\treturn { left, right };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct attribute_of<x3::list<Left, Right>, Context>\n\t\t: traits::build_container<\n\t\t\ttypename attribute_of<Left, Context>::type> {};\n\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct has_attribute<x3::list<Left, Right>, Context>\n\t\t: has_attribute<Left, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/not_predicate.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NOT_PREDICATE_MARCH_23_2007_0618PM)\n#define BOOST_SPIRIT_X3_NOT_PREDICATE_MARCH_23_2007_0618PM\n\n#include \"../core/parser.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct not_predicate : unary_parser<Subject, not_predicate<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, not_predicate<Subject>> base_type;\n\n\t\ttypedef unused_type attribute_type;\n\t\tstatic bool const has_attribute = false;\n\n\t\tconstexpr not_predicate(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& /*attr*/) const\n\t\t{\n\t\t\tIterator i = first;\n\t\t\treturn !this->subject.parse(i, last, context, rcontext, unused) && !has_expectation_failure(context);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Subject>\n\tconstexpr not_predicate<Subject>\n\toperator!(Subject const& subject)\n\t{\n\t\treturn { subject };\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/optional.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_OPTIONAL_MARCH_23_2007_1117PM)\n#define BOOST_SPIRIT_X3_OPTIONAL_MARCH_23_2007_1117PM\n\n#include \"../core/proxy.hpp\"\n#include \"../core/detail/parse_into_container.hpp\"\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include \"../support/traits/optional_traits.hpp\"\n#include \"../support/traits/attribute_category.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct optional : proxy<Subject, optional<Subject>>\n\t{\n\t\ttypedef proxy<Subject, optional<Subject>> base_type;\n\t\tstatic bool const is_pass_through_unary = false;\n\t\tstatic bool const handles_container = true;\n\n\t\tconstexpr optional(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\tusing base_type::parse_subject;\n\n\t\t// Attribute is a container\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse_subject(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr\n\t\t  , traits::container_attribute) const\n\t\t{\n\t\t\tdetail::parse_into_container(\n\t\t\t\tthis->subject, first, last, context, rcontext, attr);\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\n\t\t// Attribute is an optional\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse_subject(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr\n\t\t  , traits::optional_attribute) const\n\t\t{\n\t\t\ttypedef typename\n\t\t\t\tx3::traits::optional_value<Attribute>::type\n\t\t\tvalue_type;\n\n\t\t\t// create a local value\n\t\t\tvalue_type val{};\n\n\t\t\tif (this->subject.parse(first, last, context, rcontext, val))\n\t\t\t{\n\t\t\t\t// assign the parsed value into our attribute\n\t\t\t\tx3::traits::move_to(val, attr);\n\t\t\t}\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Subject>\n\tconstexpr optional<Subject>\n\toperator-(Subject const& subject)\n\t{\n\t\treturn { subject };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Subject, typename Context>\n\tstruct attribute_of<x3::optional<Subject>, Context>\n\t\t: build_optional<\n\t\t\ttypename attribute_of<Subject, Context>::type> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/plus.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PLUS_MARCH_13_2007_0127PM)\n#define BOOST_SPIRIT_X3_PLUS_MARCH_13_2007_0127PM\n\n#include \"../core/parser.hpp\"\n#include \"../support/traits/container_traits.hpp\"\n#include \"../support/traits/attribute_of.hpp\"\n#include \"../core/detail/parse_into_container.hpp\"\n#include \"../directive/expect.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Subject>\n\tstruct plus : unary_parser<Subject, plus<Subject>>\n\t{\n\t\ttypedef unary_parser<Subject, plus<Subject>> base_type;\n\t\tstatic bool const handles_container = true;\n\n\t\tconstexpr plus(Subject const& subject)\n\t\t  : base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\tif (!detail::parse_into_container(\n\t\t\t\tthis->subject, first, last, context, rcontext, attr))\n\t\t\t\treturn false;\n\n\t\t\twhile (detail::parse_into_container(\n\t\t\t\tthis->subject, first, last, context, rcontext, attr))\n\t\t\t\t;\n\t\t\treturn !has_expectation_failure(context);\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Subject>\n\tconstexpr plus<Subject>\n\toperator+(Subject const& subject)\n\t{\n\t\treturn { subject };\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Subject, typename Context>\n\tstruct attribute_of<x3::plus<Subject>, Context>\n\t\t: build_container<\n\t\t\ttypename attribute_of<Subject, Context>::type> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator/sequence.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SEQUENCE_JAN_06_2013_1015AM)\n#define BOOST_SPIRIT_X3_SEQUENCE_JAN_06_2013_1015AM\n\n#include \"../support/traits/attribute_of_binary.hpp\"\n#include \"../core/parser.hpp\"\n#include \"detail/sequence.hpp\"\n#include \"../directive/expect.hpp\"\n\n#include <boost/fusion/include/deque_fwd.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Left, typename Right>\n\tstruct sequence : binary_parser<Left, Right, sequence<Left, Right>>\n\t{\n\t\ttypedef binary_parser<Left, Right, sequence<Left, Right>> base_type;\n\n\t\tconstexpr sequence(Left const& left, Right const& right)\n\t\t\t: base_type(left, right) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, unused_type) const\n\t\t{\n\t\t\tIterator save = first;\n\t\t\tif (this->left.parse(first, last, context, rcontext, unused)\n\t\t\t\t&& this->right.parse(first, last, context, rcontext, unused))\n\t\t\t\treturn true;\n\t\t\tfirst = save;\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Context\n\t\t  , typename RContext, typename Attribute>\n\t\tbool parse(\n\t\t\tIterator& first, Iterator const& last\n\t\t  , Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn detail::parse_sequence(*this, first, last, context, rcontext, attr\n\t\t\t  , typename traits::attribute_category<Attribute>::type());\n\t\t}\n\t};\n\n\ttemplate <spirit_parser Left, spirit_parser Right>\n\tconstexpr sequence<\n\t\tLeft\n\t  , Right>\n\toperator>>(Left const& left, Right const& right)\n\t{\n\t\treturn { left, right };\n\t}\n\n\ttemplate <typename Left, typename Right>\n\tconstexpr auto operator>(Left const& left, Right const& right)\n\t{\n\t\treturn left >> expect[right];\n\t}\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Left, typename Right, typename Context>\n\tstruct attribute_of<x3::sequence<Left, Right>, Context>\n\t\t: x3::detail::attribute_of_binary<fusion::deque, x3::sequence, Left, Right, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/operator.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM)\n#define BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM\n\n#include \"operator/sequence.hpp\"\n#include \"operator/alternative.hpp\"\n//~ #include \"operator/sequential_or.hpp\"\n//~ #include \"operator/permutation.hpp\"\n#include \"operator/difference.hpp\"\n#include \"operator/list.hpp\"\n#include \"operator/optional.hpp\"\n#include \"operator/kleene.hpp\"\n#include \"operator/plus.hpp\"\n#include \"operator/and_predicate.hpp\"\n#include \"operator/not_predicate.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/detail/string_parse.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM)\n#define BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM\n\n#include \"../../support/traits/move_to.hpp\"\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename Char, typename Iterator, typename Attribute, typename CaseCompareFunc>\n\tinline bool string_parse(\n\t\tChar const* str\n\t  , Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare) \n\t{\n\t\tIterator i = first;\n\t\tChar ch = *str;\n\n\t\tfor (; !!ch; ++i)\n\t\t{\n\t\t\tif (i == last || (compare(ch, *i) != 0))\n\t\t\t\treturn false;\n\t\t\tch = *++str;\n\t\t}\n\n\t\tx3::traits::move_to(first, i, attr);\n\t\tfirst = i;\n\t\treturn true;\n\t}\n\n\ttemplate <typename String, typename Iterator, typename Attribute, typename CaseCompareFunc>\n\tinline bool string_parse(\n\t\tString const& str\n\t  , Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)\n\t{\n\t\tIterator i = first;\n\t\tauto stri = str.begin();\n\t\tauto const str_last = str.end();\n\n\t\tfor (; stri != str_last; ++stri, ++i)\n\t\t\tif (i == last || (compare(*stri, *i) != 0))\n\t\t\t\treturn false;\n\t\tx3::traits::move_to(first, i, attr);\n\t\tfirst = i;\n\t\treturn true;\n\t}\n\n\ttemplate <typename Char, typename Iterator, typename Attribute>\n\tinline bool string_parse(\n\t\tChar const* uc_i, Char const* lc_i\n\t  , Iterator& first, Iterator const& last, Attribute& attr)\n\t{\n\t\tIterator i = first;\n\n\t\tfor (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)\n\t\t\tif (i == last || ((*uc_i != *i) && (*lc_i != *i)))\n\t\t\t\treturn false;\n\t\tx3::traits::move_to(first, i, attr);\n\t\tfirst = i;\n\t\treturn true;\n\t}\n\n\ttemplate <typename String, typename Iterator, typename Attribute>\n\tinline bool string_parse(\n\t\tString const& ucstr, String const& lcstr\n\t  , Iterator& first, Iterator const& last, Attribute& attr)\n\t{\n\t\tauto uc_i = ucstr.begin();\n\t\tauto const uc_last = ucstr.end();\n\t\tauto lc_i = lcstr.begin();\n\t\tIterator i = first;\n\n\t\tfor (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)\n\t\t\tif (i == last || ((*uc_i != *i) && (*lc_i != *i)))\n\t\t\t\treturn false;\n\t\tx3::traits::move_to(first, i, attr);\n\t\tfirst = i;\n\t\treturn true;\n\t}\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/detail/tst.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)\n#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM\n\n#include <boost/call_traits.hpp>\n#include <boost/assert.hpp>\n\n#include <string>\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\t// This file contains low level TST routines, not for\n\t// public consumption.\n\n\ttemplate <typename Char, typename T>\n\tstruct tst_node\n\t{\n\t\ttst_node(Char id)\n\t\t  : id(id), data(0), lt(0), eq(0), gt(0)\n\t\t{\n\t\t}\n\n\t\ttemplate <typename Alloc>\n\t\tstatic void\n\t\tdestruct_node(tst_node* p, Alloc* alloc)\n\t\t{\n\t\t\tif (p)\n\t\t\t{\n\t\t\t\tif (p->data)\n\t\t\t\t\talloc->delete_data(p->data);\n\t\t\t\tdestruct_node(p->lt, alloc);\n\t\t\t\tdestruct_node(p->eq, alloc);\n\t\t\t\tdestruct_node(p->gt, alloc);\n\t\t\t\talloc->delete_node(p);\n\t\t\t}\n\t\t}\n\n\t\ttemplate <typename Alloc>\n\t\tstatic tst_node*\n\t\tclone_node(tst_node* p, Alloc* alloc)\n\t\t{\n\t\t\tif (p)\n\t\t\t{\n\t\t\t\ttst_node* clone = alloc->new_node(p->id);\n\t\t\t\tif (p->data)\n\t\t\t\t\tclone->data = alloc->new_data(*p->data);\n\t\t\t\tclone->lt = clone_node(p->lt, alloc);\n\t\t\t\tclone->eq = clone_node(p->eq, alloc);\n\t\t\t\tclone->gt = clone_node(p->gt, alloc);\n\t\t\t\treturn clone;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename CaseCompare>\n\t\tstatic T*\n\t\tfind(tst_node* start, Iterator& first, Iterator last, CaseCompare comp)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn 0;\n\n\t\t\tIterator i = first;\n\t\t\tIterator latest = first;\n\t\t\ttst_node* p = start;\n\t\t\tT* found = 0;\n\n\t\t\twhile (p && i != last)\n\t\t\t{\n\t\t\t\tint32_t c = comp(*i,p->id);\n\t\t\t\tif (c == 0)\n\t\t\t\t{\n\t\t\t\t\tif (p->data)\n\t\t\t\t\t{\n\t\t\t\t\t\tfound = p->data;\n\t\t\t\t\t\tlatest = i;\n\t\t\t\t\t}\n\t\t\t\t\tp = p->eq;\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\telse if (c < 0)\n\t\t\t\t{\n\t\t\t\t\tp = p->lt;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tp = p->gt;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (found)\n\t\t\t\tfirst = ++latest; // one past the last matching char\n\t\t\treturn found;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Alloc>\n\t\tstatic T*\n\t\tadd(\n\t\t\ttst_node*& start\n\t\t  , Iterator first\n\t\t  , Iterator last\n\t\t  , typename boost::call_traits<T>::param_type val\n\t\t  , Alloc* alloc)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn 0;\n\n\t\t\ttst_node** pp = &start;\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tauto c = *first;\n\n\t\t\t\tif (*pp == 0)\n\t\t\t\t\t*pp = alloc->new_node(c);\n\t\t\t\ttst_node* p = *pp;\n\n\t\t\t\tif (c == p->id)\n\t\t\t\t{\n\t\t\t\t\tif (++first == last)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (p->data == 0)\n\t\t\t\t\t\t\tp->data = alloc->new_data(val);\n\t\t\t\t\t\treturn p->data;\n\t\t\t\t\t}\n\t\t\t\t\tpp = &p->eq;\n\t\t\t\t}\n\t\t\t\telse if (c < p->id)\n\t\t\t\t{\n\t\t\t\t\tpp = &p->lt;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpp = &p->gt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Alloc>\n\t\tstatic void\n\t\tremove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)\n\t\t{\n\t\t\tif (p == 0 || first == last)\n\t\t\t\treturn;\n\n\t\t\tauto c = *first;\n\n\t\t\tif (c == p->id)\n\t\t\t{\n\t\t\t\tif (++first == last)\n\t\t\t\t{\n\t\t\t\t\tif (p->data)\n\t\t\t\t\t{\n\t\t\t\t\t\talloc->delete_data(p->data);\n\t\t\t\t\t\tp->data = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tremove(p->eq, first, last, alloc);\n\t\t\t}\n\t\t\telse if (c < p->id)\n\t\t\t{\n\t\t\t\tremove(p->lt, first, last, alloc);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tremove(p->gt, first, last, alloc);\n\t\t\t}\n\n\t\t\tif (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)\n\t\t\t{\n\t\t\t\talloc->delete_node(p);\n\t\t\t\tp = 0;\n\t\t\t}\n\t\t}\n\n\t\ttemplate <typename F>\n\t\tstatic void\n\t\tfor_each(tst_node* p, std::basic_string<Char> prefix, F f)\n\t\t{\n\t\t\tif (p)\n\t\t\t{\n\t\t\t\tfor_each(p->lt, prefix, f);\n\t\t\t\tstd::basic_string<Char> s = prefix + p->id;\n\t\t\t\tfor_each(p->eq, s, f);\n\t\t\t\tif (p->data)\n\t\t\t\t\tf(s, *p->data);\n\t\t\t\tfor_each(p->gt, prefix, f);\n\t\t\t}\n\t\t}\n\n\t\tChar id;        // the node's identity character\n\t\tT* data;        // optional data\n\t\ttst_node* lt;   // left pointer\n\t\ttst_node* eq;   // middle pointer\n\t\ttst_node* gt;   // right pointer\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/literal_string.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)\n#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM\n\n#include \"../core/parser.hpp\"\n#include \"../core/skip_over.hpp\"\n#include \"detail/string_parse.hpp\"\n#include \"../support/no_case.hpp\"\n#include \"../support/utility/utf8.hpp\"\n#include \"../../support/char_encoding/ascii.hpp\"\n#include \"../../support/char_encoding/standard.hpp\"\n#include \"../../support/char_encoding/standard_wide.hpp\"\n\n#include <boost/type_traits/is_same.hpp>\n#include <boost/type_traits/add_reference.hpp>\n#include <string>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename String, typename Encoding,\n\t\ttypename Attribute = std::basic_string<typename Encoding::char_type>>\n\tstruct literal_string : parser<literal_string<String, Encoding, Attribute>>\n\t{\n\t\ttypedef typename Encoding::char_type char_type;\n\t\ttypedef Encoding encoding;\n\t\ttypedef Attribute attribute_type;\n\t\tstatic bool const has_attribute =\n\t\t\t!is_same<unused_type, attribute_type>::value;\n\t\tstatic bool const handles_container = has_attribute;\n\n\t\tconstexpr literal_string(typename add_reference< typename add_const<String>::type >::type str)\n\t\t  : str(str)\n\t\t{}\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute_>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute_& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\t\t\treturn detail::string_parse(str, first, last, attr, get_case_compare<encoding>(context));\n\t\t}\n\n\t\tString str;\n\t};\n\n\tnamespace standard\n\t{\n\t\tconstexpr literal_string<char const*, char_encoding::standard>\n\t\tstring(char const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<char>, char_encoding::standard>\n\t\tstring(std::basic_string<char> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline constexpr literal_string<char const*, char_encoding::standard, unused_type>\n\t\tlit(char const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tliteral_string<std::basic_string<Char>, char_encoding::standard, unused_type>\n\t\tlit(std::basic_string<Char> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t}\n\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tnamespace standard_wide\n\t{\n\t\tconstexpr literal_string<wchar_t const*, char_encoding::standard_wide>\n\t\tstring(wchar_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide>\n\t\tstring(std::basic_string<wchar_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tconstexpr literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>\n\t\tlit(wchar_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide, unused_type>\n\t\tlit(std::basic_string<wchar_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t}\n#endif\n\n#if defined(BOOST_SPIRIT_X3_UNICODE)\n\tnamespace unicode\n\t{\n\t\tconstexpr literal_string<char32_t const*, char_encoding::unicode>\n\t\tstring(char32_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<char32_t>, char_encoding::unicode>\n\t\tstring(std::basic_string<char32_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tconstexpr literal_string<char32_t const*, char_encoding::unicode, unused_type>\n\t\tlit(char32_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<char32_t>, char_encoding::unicode, unused_type>\n\t\tlit(std::basic_string<char32_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t}\n#endif\n\n\tnamespace ascii\n\t{\n\t\tconstexpr literal_string<wchar_t const*, char_encoding::ascii>\n\t\tstring(wchar_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<wchar_t>, char_encoding::ascii>\n\t\tstring(std::basic_string<wchar_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tconstexpr literal_string<char const*, char_encoding::ascii, unused_type>\n\t\tlit(char const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tliteral_string<std::basic_string<Char>, char_encoding::ascii, unused_type>\n\t\tlit(std::basic_string<Char> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t}\n\n\tnamespace iso8859_1\n\t{\n\t\tconstexpr literal_string<wchar_t const*, char_encoding::iso8859_1>\n\t\tstring(wchar_t const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tinline literal_string<std::basic_string<wchar_t>, char_encoding::iso8859_1>\n\t\tstring(std::basic_string<wchar_t> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\tconstexpr literal_string<char const*, char_encoding::iso8859_1, unused_type>\n\t\tlit(char const* s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tliteral_string<std::basic_string<Char>, char_encoding::iso8859_1, unused_type>\n\t\tlit(std::basic_string<Char> const& s)\n\t\t{\n\t\t\treturn { s };\n\t\t}\n\t}\n\n\tusing standard::string;\n\tusing standard::lit;\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tusing standard_wide::string;\n\tusing standard_wide::lit;\n#endif\n\n\ttemplate <typename String, typename Encoding, typename Attribute>\n\tstruct get_info<literal_string<String, Encoding, Attribute>>\n\t{\n\t\ttypedef std::string result_type;\n\t\tstd::string operator()(literal_string<String, Encoding, Attribute> const& p) const\n\t\t{\n\t\t\treturn '\"' + to_utf8(p.str) + '\"';\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/symbols.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Carl Barron\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)\n#define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM\n\n#include \"../core/skip_over.hpp\"\n#include \"../core/parser.hpp\"\n#include \"tst.hpp\"\n#include \"../support/unused.hpp\"\n#include \"../support/traits/string_traits.hpp\"\n#include \"../support/traits/move_to.hpp\"\n#include \"../support/no_case.hpp\"\n\n#include \"../../support/char_encoding/ascii.hpp\"\n#include \"../../support/char_encoding/iso8859_1.hpp\"\n#include \"../../support/char_encoding/standard.hpp\"\n#include \"../../support/char_encoding/standard_wide.hpp\"\n\n#include <initializer_list>\n#include <iterator> // std::begin\n#include <memory> // std::shared_ptr\n#include <type_traits>\n\n#if defined(BOOST_MSVC)\n# pragma warning(push)\n# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning\n#endif\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <\n\t\ttypename Encoding\n\t  , typename T = unused_type\n\t  , typename Lookup = tst<typename Encoding::char_type, T> >\n\tstruct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>\n\t{\n\t\ttypedef typename Encoding::char_type char_type; // the character type\n\t\ttypedef Encoding encoding;\n\t\ttypedef T value_type; // the value associated with each entry\n\t\ttypedef value_type attribute_type;\n\n\t\tstatic bool const has_attribute =\n\t\t\t!std::is_same<unused_type, attribute_type>::value;\n\t\tstatic bool const handles_container =\n\t\t\ttraits::is_container<attribute_type>::value;\n\n\t\tsymbols_parser(std::string const& name = \"symbols\")\n\t\t  : add{*this}\n\t\t  , remove{*this}\n\t\t  , lookup(std::make_shared<Lookup>())\n\t\t  , name_(name)\n\t\t{\n\t\t}\n\n\t\tsymbols_parser(symbols_parser const& syms)\n\t\t  : add{*this}\n\t\t  , remove{*this}\n\t\t  , lookup(syms.lookup)\n\t\t  , name_(syms.name_)\n\t\t{\n\t\t}\n\n\t\ttemplate <typename Symbols>\n\t\tsymbols_parser(Symbols const& syms, std::string const& name = \"symbols\")\n\t\t  : symbols_parser(name)\n\t\t{\n\t\t\tfor (auto& sym : syms)\n\t\t\t\tadd(sym);\n\t\t}\n\n\t\ttemplate <typename Symbols, typename Data>\n\t\tsymbols_parser(Symbols const& syms, Data const& data\n\t\t\t  , std::string const& name = \"symbols\")\n\t\t  : symbols_parser(name)\n\t\t{\n\t\t\tusing std::begin;\n\t\t\tauto di = begin(data);\n\t\t\tfor (auto& sym : syms)\n\t\t\t\tadd(sym, *di++);\n\t\t}\n\n\t\tsymbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms\n\t\t\t  , std::string const & name=\"symbols\")\n\t\t  : symbols_parser(name)\n\t\t{\n\t\t\tfor (auto& sym : syms)\n\t\t\t\tadd(sym.first, sym.second);\n\t\t}\n\n\t\tsymbols_parser(std::initializer_list<char_type const*> syms\n\t\t\t  , std::string const &name=\"symbols\")\n\t\t  : symbols_parser(name)\n\t\t{\n\t\t\tfor (auto str : syms)\n\t\t\t\tadd(str);\n\t\t}\n\n\t\tsymbols_parser&\n\t\toperator=(symbols_parser const& rhs)\n\t\t{\n\t\t\tname_ = rhs.name_;\n\t\t\tlookup = rhs.lookup;\n\t\t\treturn *this;\n\t\t}\n\n\t\tvoid clear()\n\t\t{\n\t\t\tlookup->clear();\n\t\t}\n\n\t\tstruct adder;\n\t\tstruct remover;\n\n\t\ttemplate <typename Str>\n\t\tadder const&\n\t\toperator=(Str const& str)\n\t\t{\n\t\t\tlookup->clear();\n\t\t\treturn add(str);\n\t\t}\n\n\t\ttemplate <typename Str>\n\t\tfriend adder const&\n\t\toperator+=(symbols_parser& sym, Str const& str)\n\t\t{\n\t\t\treturn sym.add(str);\n\t\t}\n\n\t\ttemplate <typename Str>\n\t\tfriend remover const&\n\t\toperator-=(symbols_parser& sym, Str const& str)\n\t\t{\n\t\t\treturn sym.remove(str);\n\t\t}\n\n\t\ttemplate <typename F>\n\t\tvoid for_each(F f) const\n\t\t{\n\t\t\tlookup->for_each(f);\n\t\t}\n\n\t\ttemplate <typename Str>\n\t\tvalue_type& at(Str const& str)\n\t\t{\n\t\t\treturn *lookup->add(traits::get_string_begin<char_type>(str)\n\t\t\t\t, traits::get_string_end<char_type>(str), T());\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvalue_type* prefix_find(Iterator& first, Iterator const& last)\n\t\t{\n\t\t\treturn lookup->find(first, last, case_compare<Encoding>());\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvalue_type const* prefix_find(Iterator& first, Iterator const& last) const\n\t\t{\n\t\t\treturn lookup->find(first, last, case_compare<Encoding>());\n\t\t}\n\n\t\ttemplate <typename Str>\n\t\tvalue_type* find(Str const& str)\n\t\t{\n\t\t\treturn find_impl(traits::get_string_begin<char_type>(str)\n\t\t\t\t, traits::get_string_end<char_type>(str));\n\t\t}\n\n\t\ttemplate <typename Str>\n\t\tvalue_type const* find(Str const& str) const\n\t\t{\n\t\t\treturn find_impl(traits::get_string_begin<char_type>(str)\n\t\t\t\t, traits::get_string_end<char_type>(str));\n\t\t}\n\n\tprivate:\n\n\t\ttemplate <typename Iterator>\n\t\tvalue_type* find_impl(Iterator begin, Iterator end)\n\t\t{\n\t\t\tvalue_type* r = lookup->find(begin, end, case_compare<Encoding>());\n\t\t\treturn begin == end ? r : 0;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvalue_type const* find_impl(Iterator begin, Iterator end) const\n\t\t{\n\t\t\tvalue_type const* r = lookup->find(begin, end, case_compare<Encoding>());\n\t\t\treturn begin == end ? r : 0;\n\t\t}\n\n\tpublic:\n\n\t\ttemplate <typename Iterator, typename Context, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last\n\t\t  , Context const& context, unused_type, Attribute& attr) const\n\t\t{\n\t\t\tx3::skip_over(first, last, context);\n\n\t\t\tif (value_type const* val_ptr\n\t\t\t\t= lookup->find(first, last, get_case_compare<Encoding>(context)))\n\t\t\t{\n\t\t\t\tx3::traits::move_to(*val_ptr, attr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid name(std::string const &str)\n\t\t{\n\t\t\tname_ = str;\n\t\t}\n\t\tstd::string const &name() const\n\t\t{\n\t\t\treturn name_;\n\t\t}\n\n\t\tstruct adder\n\t\t{\n\t\t\ttemplate <typename Iterator>\n\t\t\tadder const&\n\t\t\toperator()(Iterator first, Iterator last, T const& val) const\n\t\t\t{\n\t\t\t\tsym.lookup->add(first, last, val);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <typename Str>\n\t\t\tadder const&\n\t\t\toperator()(Str const& s, T const& val = T()) const\n\t\t\t{\n\t\t\t\tsym.lookup->add(traits::get_string_begin<char_type>(s)\n\t\t\t\t  , traits::get_string_end<char_type>(s), val);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <typename Str>\n\t\t\tadder const&\n\t\t\toperator,(Str const& s) const\n\t\t\t{\n\t\t\t\tsym.lookup->add(traits::get_string_begin<char_type>(s)\n\t\t\t\t  , traits::get_string_end<char_type>(s), T());\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tsymbols_parser& sym;\n\t\t};\n\n\t\tstruct remover\n\t\t{\n\t\t\ttemplate <typename Iterator>\n\t\t\tremover const&\n\t\t\toperator()(Iterator const& first, Iterator const& last) const\n\t\t\t{\n\t\t\t\tsym.lookup->remove(first, last);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <typename Str>\n\t\t\tremover const&\n\t\t\toperator()(Str const& s) const\n\t\t\t{\n\t\t\t\tsym.lookup->remove(traits::get_string_begin<char_type>(s)\n\t\t\t\t  , traits::get_string_end<char_type>(s));\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate <typename Str>\n\t\t\tremover const&\n\t\t\toperator,(Str const& s) const\n\t\t\t{\n\t\t\t\tsym.lookup->remove(traits::get_string_begin<char_type>(s)\n\t\t\t\t  , traits::get_string_end<char_type>(s));\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tsymbols_parser& sym;\n\t\t};\n\n\t\tadder add;\n\t\tremover remove;\n\t\tstd::shared_ptr<Lookup> lookup;\n\t\tstd::string name_;\n\t};\n\n\ttemplate <typename Encoding, typename T, typename Lookup>\n\tstruct get_info<symbols_parser<Encoding, T, Lookup>>\n\t{\n\t  typedef std::string result_type;\n\t  result_type operator()(symbols_parser< Encoding, T\n\t\t\t\t\t\t\t\t\t, Lookup\n\t\t\t\t\t\t\t\t\t> const& symbols) const\n\t  {\n\t\t return symbols.name();\n\t  }\n\t};\n\n\tnamespace standard\n\t{\n\t\ttemplate <typename T = unused_type>\n\t\tusing symbols = symbols_parser<char_encoding::standard, T>;\n\t}\n\n\tusing standard::symbols;\n\n#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE\n\tnamespace standard_wide\n\t{\n\t\ttemplate <typename T = unused_type>\n\t\tusing symbols = symbols_parser<char_encoding::standard_wide, T>;\n\t}\n#endif\n\n\tnamespace ascii\n\t{\n\t\ttemplate <typename T = unused_type>\n\t\tusing symbols = symbols_parser<char_encoding::ascii, T>;\n\t}\n\n\tnamespace iso8859_1\n\t{\n\t\ttemplate <typename T = unused_type>\n\t\tusing symbols = symbols_parser<char_encoding::iso8859_1, T>;\n\t}\n\n}}}\n\n#if defined(BOOST_MSVC)\n# pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/tst.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)\n#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM\n\n#include \"detail/tst.hpp\"\n\n#include <string>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct tst_pass_through\n\t{\n\t\ttemplate <typename Char>\n\t\tChar operator()(Char ch) const\n\t\t{\n\t\t\treturn ch;\n\t\t}\n\t};\n\n\ttemplate <typename Char, typename T>\n\tstruct tst\n\t{\n\t\ttypedef Char char_type; // the character type\n\t\ttypedef T value_type; // the value associated with each entry\n\t\ttypedef detail::tst_node<Char, T> node;\n\n\t\ttst()\n\t\t  : root(0)\n\t\t{\n\t\t}\n\n\t\t~tst()\n\t\t{\n\t\t\tclear();\n\t\t}\n\n\t\ttst(tst const& rhs)\n\t\t  : root(0)\n\t\t{\n\t\t\tcopy(rhs);\n\t\t}\n\n\t\ttst& operator=(tst const& rhs)\n\t\t{\n\t\t\treturn assign(rhs);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename CaseCompare>\n\t\tT* find(Iterator& first, Iterator last, CaseCompare caseCompare) const\n\t\t{\n\t\t\treturn node::find(root, first, last, caseCompare);\n\t\t}\n\n\t\t/*template <typename Iterator>\n\t\tT* find(Iterator& first, Iterator last) const\n\t\t{\n\t\t\treturn find(first, last, case_compare<tst_pass_through());\n\t\t}*/\n\n\t\ttemplate <typename Iterator>\n\t\tT* add(\n\t\t\tIterator first\n\t\t  , Iterator last\n\t\t  , typename boost::call_traits<T>::param_type val)\n\t\t{\n\t\t\treturn node::add(root, first, last, val, this);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvoid remove(Iterator first, Iterator last)\n\t\t{\n\t\t\tnode::remove(root, first, last, this);\n\t\t}\n\n\t\tvoid clear()\n\t\t{\n\t\t\tnode::destruct_node(root, this);\n\t\t\troot = 0;\n\t\t}\n\n\t\ttemplate <typename F>\n\t\tvoid for_each(F f) const\n\t\t{\n\t\t\tnode::for_each(root, std::basic_string<Char>(), f);\n\t\t}\n\n\tprivate:\n\n\t\tfriend struct detail::tst_node<Char, T>;\n\n\t\tvoid copy(tst const& rhs)\n\t\t{\n\t\t\troot = node::clone_node(rhs.root, this);\n\t\t}\n\n\t\ttst& assign(tst const& rhs)\n\t\t{\n\t\t\tif (this != &rhs)\n\t\t\t{\n\t\t\t\tclear();\n\t\t\t\tcopy(rhs);\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\tnode* root;\n\n\t\tnode* new_node(Char id)\n\t\t{\n\t\t\treturn new node(id);\n\t\t}\n\n\t\tT* new_data(typename boost::call_traits<T>::param_type val)\n\t\t{\n\t\t\treturn new T(val);\n\t\t}\n\n\t\tvoid delete_node(node* p)\n\t\t{\n\t\t\tdelete p;\n\t\t}\n\n\t\tvoid delete_data(T* p)\n\t\t{\n\t\t\tdelete p;\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string/tst_map.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)\n#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM\n\n#include \"detail/tst.hpp\"\n#include <unordered_map>\n#include <boost/pool/object_pool.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct tst_pass_through; // declared in tst.hpp\n\n\ttemplate <typename Char, typename T>\n\tstruct tst_map\n\t{\n\t\ttypedef Char char_type; // the character type\n\t\ttypedef T value_type; // the value associated with each entry\n\t\ttypedef detail::tst_node<Char, T> node;\n\n\t\ttst_map()\n\t\t{\n\t\t}\n\n\t\t~tst_map()\n\t\t{\n\t\t\t// Nothing to do here.\n\t\t\t// The pools do the right thing for us\n\t\t}\n\n\t\ttst_map(tst_map const& rhs)\n\t\t{\n\t\t\tcopy(rhs);\n\t\t}\n\n\t\ttst_map& operator=(tst_map const& rhs)\n\t\t{\n\t\t\treturn assign(rhs);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Filter>\n\t\tT* find(Iterator& first, Iterator last, Filter filter) const\n\t\t{\n\t\t\tif (first != last)\n\t\t\t{\n\t\t\t\tIterator save = first;\n\t\t\t\ttypename map_type::const_iterator\n\t\t\t\t\ti = map.find(filter(*first++));\n\t\t\t\tif (i == map.end())\n\t\t\t\t{\n\t\t\t\t\tfirst = save;\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif (T* p = node::find(i->second.root, first, last, filter))\n\t\t\t\t{\n\t\t\t\t\treturn p;\n\t\t\t\t}\n\t\t\t\treturn i->second.data;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tT* find(Iterator& first, Iterator last) const\n\t\t{\n\t\t\treturn find(first, last, tst_pass_through());\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tbool add(\n\t\t\tIterator first\n\t\t  , Iterator last\n\t\t  , typename boost::call_traits<T>::param_type val)\n\t\t{\n\t\t\tif (first != last)\n\t\t\t{\n\t\t\t\tmap_data x = {0, 0};\n\t\t\t\tstd::pair<typename map_type::iterator, bool>\n\t\t\t\t\tr = map.insert(std::pair<Char, map_data>(*first++, x));\n\n\t\t\t\tif (first != last)\n\t\t\t\t{\n\t\t\t\t\treturn node::add(r.first->second.root\n\t\t\t\t\t  , first, last, val, this) ? true : false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (r.first->second.data)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tr.first->second.data = this->new_data(val);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tvoid remove(Iterator first, Iterator last)\n\t\t{\n\t\t\tif (first != last)\n\t\t\t{\n\t\t\t\ttypename map_type::iterator i = map.find(*first++);\n\t\t\t\tif (i != map.end())\n\t\t\t\t{\n\t\t\t\t\tif (first != last)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode::remove(i->second.root, first, last, this);\n\t\t\t\t\t}\n\t\t\t\t\telse if (i->second.data)\n\t\t\t\t\t{\n\t\t\t\t\t\tthis->delete_data(i->second.data);\n\t\t\t\t\t\ti->second.data = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (i->second.data == 0 && i->second.root == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tmap.erase(i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid clear()\n\t\t{\n\t\t\tfor (typename map_type::value_type& x : map)\n\t\t\t{\n\t\t\t\tnode::destruct_node(x.second.root, this);\n\t\t\t\tif (x.second.data)\n\t\t\t\t\tthis->delete_data(x.second.data);\n\t\t\t}\n\t\t\tmap.clear();\n\t\t}\n\n\t\ttemplate <typename F>\n\t\tvoid for_each(F f) const\n\t\t{\n\t\t\tfor (typename map_type::value_type const& x : map)\n\t\t\t{\n\t\t\t\tstd::basic_string<Char> s(1, x.first);\n\t\t\t\tnode::for_each(x.second.root, s, f);\n\t\t\t\tif (x.second.data)\n\t\t\t\t\tf(s, *x.second.data);\n\t\t\t}\n\t\t}\n\n\tprivate:\n\n\t\tfriend struct detail::tst_node<Char, T>;\n\n\t\tstruct map_data\n\t\t{\n\t\t\tnode* root;\n\t\t\tT* data;\n\t\t};\n\n\t\ttypedef std::unordered_map<Char, map_data> map_type;\n\n\t\tvoid copy(tst_map const& rhs)\n\t\t{\n\t\t\tfor (typename map_type::value_type const& x : rhs.map)\n\t\t\t{\n\t\t\t\tmap_data xx = {node::clone_node(x.second.root, this), 0};\n\t\t\t\tif (x.second.data)\n\t\t\t\t\txx.data = data_pool.construct(*x.second.data);\n\t\t\t\tmap[x.first] = xx;\n\t\t\t}\n\t\t}\n\n\t\ttst_map& assign(tst_map const& rhs)\n\t\t{\n\t\t\tif (this != &rhs)\n\t\t\t{\n\t\t\t\tfor (typename map_type::value_type& x : map)\n\t\t\t\t{\n\t\t\t\t\tnode::destruct_node(x.second.root, this);\n\t\t\t\t}\n\t\t\t\tmap.clear();\n\t\t\t\tcopy(rhs);\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\tnode* new_node(Char id)\n\t\t{\n\t\t\treturn node_pool.construct(id);\n\t\t}\n\n\t\tT* new_data(typename boost::call_traits<T>::param_type val)\n\t\t{\n\t\t\treturn data_pool.construct(val);\n\t\t}\n\n\t\tvoid delete_node(node* p)\n\t\t{\n\t\t\tnode_pool.destroy(p);\n\t\t}\n\n\t\tvoid delete_data(T* p)\n\t\t{\n\t\t\tdata_pool.destroy(p);\n\t\t}\n\n\t\tmap_type map;\n\t\tobject_pool<node> node_pool;\n\t\tobject_pool<T> data_pool;\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/string.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM)\n#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM\n\n#include \"string/literal_string.hpp\"\n#include \"string/symbols.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/ast/position_tagged.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM)\n#define BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM\n\n#include <boost/range/iterator_range_core.hpp>\n#include <boost/type_traits/is_base_of.hpp>\n#include <boost/core/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct position_tagged\n\t{\n\t\t// Use this to annotate an AST with the iterator position.\n\t\t// These ids are used as a key to the position_cache (below)\n\t\t// and marks the start and end of an AST node.\n\t\tint id_first = -1;\n\t\tint id_last = -1;\n\t};\n\n\ttemplate <typename Container>\n\tclass position_cache\n\t{\n\tpublic:\n\n\t\ttypedef typename Container::value_type iterator_type;\n\n\t\tposition_cache(\n\t\t\titerator_type first\n\t\t  , iterator_type last)\n\t\t  : first_(first), last_(last) {}\n\n\t\t// This will catch all nodes inheriting from position_tagged\n\t\tboost::iterator_range<iterator_type>\n\t\tposition_of(position_tagged const& ast) const\n\t\t{\n\t\t\treturn\n\t\t\t\tboost::iterator_range<iterator_type>(\n\t\t\t\t\tpositions.at(ast.id_first) // throws if out of range\n\t\t\t\t  , positions.at(ast.id_last)  // throws if out of range\n\t\t\t\t);\n\t\t}\n\n\t\t// This will catch all nodes except those inheriting from position_tagged\n\t\ttemplate <typename AST>\n\t\ttypename boost::enable_if_c<\n\t\t\t(!is_base_of<position_tagged, AST>::value)\n\t\t  , boost::iterator_range<iterator_type>\n\t\t>::type\n\t\tposition_of(AST const& /* ast */) const\n\t\t{\n\t\t\t// returns an empty position\n\t\t\treturn boost::iterator_range<iterator_type>();\n\t\t}\n\n\t\t// This will catch all nodes except those inheriting from position_tagged\n\t\ttemplate <typename AST>\n\t\tvoid annotate(AST& /* ast */, iterator_type /* first */, iterator_type /* last */, mpl::false_)\n\t\t{\n\t\t\t// (no-op) no need for tags\n\t\t}\n\n\t\t// This will catch all nodes inheriting from position_tagged\n\t\tvoid annotate(position_tagged& ast, iterator_type first, iterator_type last, mpl::true_)\n\t\t{\n\t\t\tast.id_first = int(positions.size());\n\t\t\tpositions.push_back(first);\n\t\t\tast.id_last = int(positions.size());\n\t\t\tpositions.push_back(last);\n\t\t}\n\n\t\ttemplate <typename AST>\n\t\tvoid annotate(AST& ast, iterator_type first, iterator_type last)\n\t\t{\n\t\t\tannotate(ast, first, last, is_base_of<position_tagged, AST>());\n\t\t}\n\n\t\tContainer const&\n\t\tget_positions() const\n\t\t{\n\t\t\treturn positions;\n\t\t}\n\n\t\titerator_type first() const { return first_; }\n\t\titerator_type last() const { return last_; }\n\n\tprivate:\n\n\t\tContainer positions;\n\t\titerator_type first_;\n\t\titerator_type last_;\n\t};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/ast/variant.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM)\n#define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM\n\n#include <boost/config.hpp>\n#include <boost/variant.hpp>\n#include <boost/mpl/list.hpp>\n#include <utility>\n#include <type_traits>\n\n///////////////////////////////////////////////////////////////////////////////\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename T>\n\tclass forward_ast\n\t{\n\tpublic:\n\n\t\ttypedef T type;\n\n\tpublic:\n\n\t\tforward_ast() : p_(new T) {}\n\n\t\tforward_ast(forward_ast const& operand)\n\t\t\t: p_(new T(operand.get())) {}\n\n\t\tforward_ast(forward_ast&& operand) BOOST_NOEXCEPT\n\t\t\t: p_(operand.p_)\n\t\t{\n\t\t\toperand.p_ = 0;\n\t\t}\n\n\t\tforward_ast(T const& operand)\n\t\t\t: p_(new T(operand)) {}\n\n\t\tforward_ast(T&& operand)\n\t\t\t: p_(new T(std::move(operand))) {}\n\n\t\t~forward_ast()\n\t\t{\n\t\t\tboost::checked_delete(p_);\n\t\t}\n\n\t\tforward_ast& operator=(forward_ast const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)\n\t\t{\n\t\t\tassign(rhs.get());\n\t\t\treturn *this;\n\t\t}\n\n\t\tvoid swap(forward_ast& operand) BOOST_NOEXCEPT\n\t\t{\n\t\t\tT* temp = operand.p_;\n\t\t\toperand.p_ = p_;\n\t\t\tp_ = temp;\n\t\t}\n\n\t\tforward_ast& operator=(T const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)\n\t\t{\n\t\t\tassign(rhs);\n\t\t\treturn *this;\n\t\t}\n\n\t\tforward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT\n\t\t{\n\t\t\tswap(rhs);\n\t\t\treturn *this;\n\t\t}\n\n\t\tforward_ast& operator=(T&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<T>::value)\n\t\t{\n\t\t\tget() = std::move(rhs);\n\t\t\treturn *this;\n\t\t}\n\n\t\tT& get() BOOST_NOEXCEPT { return *get_pointer(); }\n\t\tconst T& get() const BOOST_NOEXCEPT { return *get_pointer(); }\n\n\t\tT* get_pointer() BOOST_NOEXCEPT { return p_; }\n\t\tconst T* get_pointer() const BOOST_NOEXCEPT { return p_; }\n\n\t\toperator T const&() const BOOST_NOEXCEPT { return this->get(); }\n\t\toperator T&() BOOST_NOEXCEPT { return this->get(); }\n\n\tprivate:\n\n\t\tvoid assign(const T& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<T>::value)\n\t\t{\n\t\t\tthis->get() = rhs;\n\t\t}\n\n\t\tT* p_;\n\t};\n\n\t// function template swap\n\t//\n\t// Swaps two forward_ast<T> objects of the same type T.\n\t//\n\ttemplate <typename T>\n\tinline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT\n\t{\n\t\tlhs.swap(rhs);\n\t}\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename T>\n\t\tstruct remove_forward : mpl::identity<T>\n\t\t{};\n\n\t\ttemplate <typename T>\n\t\tstruct remove_forward<forward_ast<T>> : mpl::identity<T>\n\t\t{};\n\t}\n\n#if defined(BOOST_MSVC)\n# pragma warning(push)\n# pragma warning(disable: 4521) // multiple copy constructors specified\n#endif\n\ttemplate <typename ...Types>\n\tstruct variant\n\t{\n\t\t// tell spirit that this is an adapted variant\n\t\tstruct adapted_variant_tag;\n\n\t\tusing variant_type = boost::variant<Types...>;\n\t\tusing types        = mpl::list<typename detail::remove_forward<Types>::type...>;\n\t\tusing base_type    = variant; // The current instantiation\n\n\t\ttemplate<typename T>\n\t\tusing non_self_t // used only for SFINAE checks below\n\t\t\t= std::enable_if_t<!(std::is_base_of<base_type\n\t\t\t\t\t\t\t\t\t\t\t\t,std::remove_reference_t<T>\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t::value)\n\t\t\t\t\t\t\t  >;\n\n\t\tvariant() BOOST_NOEXCEPT_IF(std::is_nothrow_default_constructible<variant_type>::value) : var() {}\n\n\t\ttemplate <typename T, class = non_self_t<T>>\n\t\texplicit variant(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T const&>::value))\n\t\t\t: var(rhs) {}\n\n\t\ttemplate <typename T, class = non_self_t<T>>\n\t\texplicit variant(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, T&&>::value))\n\t\t\t: var(std::forward<T>(rhs)) {}\n\n\t\tvariant(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_constructible<variant_type>::value)\n\t\t\t: var(rhs.var) {}\n\n\t\tvariant(variant& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_constructible<variant_type, variant_type&>::value))\n\t\t\t: var(rhs.var) {}\n\n\t\tvariant(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_constructible<variant_type>::value)\n\t\t\t: var(std::move(rhs.var)) {}\n\n\t\tvariant& operator=(variant const& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_copy_assignable<variant_type>::value)\n\t\t{\n\t\t\tvar = rhs.get();\n\t\t\treturn *this;\n\t\t}\n\n\t\tvariant& operator=(variant&& rhs) BOOST_NOEXCEPT_IF(std::is_nothrow_move_assignable<variant_type>::value)\n\t\t{\n\t\t\tvar = std::move(rhs.get());\n\t\t\treturn *this;\n\t\t}\n\n\t\ttemplate <typename T, class = non_self_t<T>>\n\t\tvariant& operator=(T const& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T const&>::value))\n\t\t{\n\t\t\tvar = rhs;\n\t\t\treturn *this;\n\t\t}\n\n\t\ttemplate <typename T, class = non_self_t<T>>\n\t\tvariant& operator=(T&& rhs) BOOST_NOEXCEPT_IF((std::is_nothrow_assignable<variant_type, T&&>::value))\n\t\t{\n\t\t\tvar = std::forward<T>(rhs);\n\t\t\treturn *this;\n\t\t}\n\n\t\ttemplate <typename F>\n\t\ttypename F::result_type apply_visitor(F const& v)\n\t\t{\n\t\t\treturn var.apply_visitor(v);\n\t\t}\n\n\t\ttemplate <typename F>\n\t\ttypename F::result_type apply_visitor(F const& v) const\n\t\t{\n\t\t\treturn var.apply_visitor(v);\n\t\t}\n\n\t\ttemplate <typename F>\n\t\ttypename F::result_type apply_visitor(F& v)\n\t\t{\n\t\t\treturn var.apply_visitor(v);\n\t\t}\n\n\t\ttemplate <typename F>\n\t\ttypename F::result_type apply_visitor(F& v) const\n\t\t{\n\t\t\treturn var.apply_visitor(v);\n\t\t}\n\n\t\tvariant_type const& get() const BOOST_NOEXCEPT\n\t\t{\n\t\t\treturn var;\n\t\t}\n\n\t\tvariant_type& get() BOOST_NOEXCEPT\n\t\t{\n\t\t\treturn var;\n\t\t}\n\n\t\tvoid swap(variant& rhs) BOOST_NOEXCEPT\n\t\t{\n\t\t\tvar.swap(rhs.var);\n\t\t}\n\n\t\tvariant_type var;\n\t};\n#if defined(BOOST_MSVC)\n# pragma warning(pop)\n#endif\n}}}\n\nnamespace boost\n{\n\ttemplate <typename T, typename ...Types>\n\tinline T const&\n\tget(boost::spirit::x3::variant<Types...> const& x) BOOST_NOEXCEPT\n\t{\n\t\treturn boost::get<T>(x.get());\n\t}\n\n\ttemplate <typename T, typename ...Types>\n\tinline T&\n\tget(boost::spirit::x3::variant<Types...>& x) BOOST_NOEXCEPT\n\t{\n\t\treturn boost::get<T>(x.get());\n\t}\n\n\ttemplate <typename T, typename ...Types>\n\tinline T const*\n\tget(boost::spirit::x3::variant<Types...> const* x) BOOST_NOEXCEPT\n\t{\n\t\treturn boost::get<T>(&x->get());\n\t}\n\n\ttemplate <typename T, typename ...Types>\n\tinline T*\n\tget(boost::spirit::x3::variant<Types...>* x) BOOST_NOEXCEPT\n\t{\n\t\treturn boost::get<T>(&x->get());\n\t}\n}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/context.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)\n#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM\n\n#include \"unused.hpp\"\n#include <boost/mpl/identity.hpp>\n#include <type_traits>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename ID, typename T, typename Next = unused_type>\n\tstruct context\n\t{\n\t\tT& val;\n\t\tNext next;\n\t};\n\n\ttemplate <typename ID, typename T, typename Next>\n\tstruct context<ID, T, Next const&>\n\t{\n\t\tT& val;\n\t\tNext const& next;\n\t};\n\n\tnamespace detail {\n\t\ttemplate <typename ID, typename T, typename Next>\n\t\tT& get(context<ID, T, Next> const& ctx, mpl::identity<ID>)\n\t\t{\n\t\t\treturn ctx.val;\n\t\t}\n\n\t\ttemplate <typename ID>\n\t\tunused_type get(unused_type, mpl::identity<ID>)\n\t\t{\n\t\t\treturn {};\n\t\t}\n\n\t\ttemplate <typename ID, typename T, typename Next, typename DifferentID>\n\t\tdecltype(auto) get(context<ID, T, Next> const& ctx, mpl::identity<DifferentID> id)\n\t\t{\n\t\t\treturn get(ctx.next, id);\n\t\t}\n\t}\n\n\ttemplate <typename Tag, typename Context>\n\tinline decltype(auto) get(Context const& ctx)\n\t{\n\t\treturn detail::get(ctx, mpl::identity<Tag>());\n\t}\n\n\tnamespace detail {\n\t\ttemplate <typename ID, typename T, typename Next>\n\t\tauto const& remove(context<ID, T, Next> const& ctx, mpl::identity<ID>)\n\t\t{\n\t\t\treturn ctx.next;\n\t\t}\n\n\t\ttemplate <typename ID, typename T, typename Next, typename DifferentID>\n\t\tauto remove(context<ID, T, Next> const& ctx, mpl::identity<DifferentID> id)\n\t\t{\n\t\t\treturn context<ID, T, decltype(remove(ctx.next, id))>{ ctx.val, remove(ctx.next, id) };\n\t\t}\n\n\t\ttemplate <typename ID, typename FoundVal, typename T, typename Next, std::enable_if_t<!std::is_same<FoundVal, unused_type>::value>* =nullptr>\n\t\tinline auto make_context(T& val, Next const& next) -> context<ID, T, decltype(remove(next, mpl::identity<ID>()))>\n\t\t{\n\t\t\treturn { val, remove(next, mpl::identity<ID>()) };\n\t\t}\n\n\t\t// optimization: don't rebuild the context when ID could not be found\n\t\ttemplate <typename ID, typename FoundVal, typename T, typename Next, std::enable_if_t<std::is_same<FoundVal, unused_type>::value>* =nullptr>\n\t\tinline context<ID, T, Next const&> make_context(T& val, Next const& next)\n\t\t{\n\t\t\treturn { val, next };\n\t\t}\n\t}\n\n\ttemplate <typename ID, typename T, typename Next>\n\tinline decltype(auto) make_context(T& val, Next const& next)\n\t{\n\t\treturn detail::make_context<ID, decltype(x3::get<ID>(next))>(val, next);\n\t}\n\n\ttemplate <typename ID, typename T>\n\tinline context<ID, T> make_context(T& val)\n\t{\n\t\treturn { val };\n\t}\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename ID, typename T, typename Next, typename FoundVal>\n\t\tinline Next const&\n\t\tmake_unique_context(T& /* val */, Next const& next, FoundVal&)\n\t\t{\n\t\t\treturn next;\n\t\t}\n\n\t\ttemplate <typename ID, typename T, typename Next>\n\t\tinline context<ID, T, Next const&>\n\t\tmake_unique_context(T& val, Next const& next, unused_type)\n\t\t{\n\t\t\treturn { val, next };\n\t\t}\n\t}\n\n\ttemplate <typename ID, typename T, typename Next>\n\tinline auto\n\tmake_unique_context(T& val, Next const& next)\n\t{\n\t\treturn detail::make_unique_context<ID>(val, next, x3::get<ID>(next));\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/no_case.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM)\n#define BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM\n\n#include \"unused.hpp\"\n#include \"context.hpp\"\n#include \"../char/char_class_tags.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct no_case_tag {};\n\n\ttemplate <typename Encoding>\n\tstruct case_compare\n\t{\n\t\ttemplate <typename Char, typename CharSet>\n\t\tbool in_set(Char ch, CharSet const& set)\n\t\t{\n\t\t\treturn set.test(ch);\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tint32_t operator()(Char lc, Char rc) const\n\t\t{\n\t\t\treturn lc - rc;\n\t\t}\n\n\t\ttemplate <typename CharClassTag>\n\t\tCharClassTag get_char_class_tag(CharClassTag tag) const\n\t\t{\n\t\t\treturn tag;\n\t\t}\n\t};\n\n\ttemplate <typename Encoding>\n\tstruct no_case_compare\n\t{\n\t\ttemplate <typename Char, typename CharSet>\n\t\tbool in_set(Char ch_, CharSet const& set)\n\t\t{\n\t\t\tusing char_type = typename Encoding::classify_type;\n\t\t\tauto ch = char_type(ch_);\n\t\t\treturn set.test(ch_)\n\t\t\t\t|| set.test(static_cast<Char>(Encoding::islower(ch)\n\t\t\t\t\t? Encoding::toupper(ch) : Encoding::tolower(ch)));\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tint32_t operator()(Char lc_, Char const rc_) const\n\t\t{\n\t\t\tusing char_type = typename Encoding::classify_type;\n\t\t\tauto lc = char_type(lc_);\n\t\t\tauto rc = char_type(rc_);\n\t\t\treturn Encoding::islower(rc)\n\t\t\t\t? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;\n\t\t}\n\n\t\ttemplate <typename CharClassTag>\n\t\tCharClassTag get_char_class_tag(CharClassTag tag) const\n\t\t{\n\t\t\treturn tag;\n\t\t}\n\n\t\talpha_tag get_char_class_tag(lower_tag ) const\n\t\t{\n\t\t\treturn {};\n\t\t}\n\n\t\talpha_tag get_char_class_tag(upper_tag ) const\n\t\t{\n\t\t\treturn {};\n\t\t}\n\n\t};\n\n\ttemplate <typename Encoding>\n\tcase_compare<Encoding> get_case_compare_impl(unused_type const&)\n\t{\n\t\treturn {};\n\t}\n\n\ttemplate <typename Encoding>\n\tno_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)\n\t{\n\t\treturn {};\n\t}\n\n\ttemplate <typename Encoding, typename Context>\n\tinline decltype(auto) get_case_compare(Context const& context)\n\t{\n\t\treturn get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));\n\t}\n\n\tauto const no_case_compare_ = no_case_tag{};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/numeric_utils/detail/extract_int.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2011 Jan Frederick Eick\n\tCopyright (c) 2011 Christopher Jefferson\n\tCopyright (c) 2006 Stephen Nutt\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)\n#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM\n\n#include \"../../unused.hpp\"\n#include \"../../traits/attribute_type.hpp\"\n#include \"../../traits/move_to.hpp\"\n#include \"../../traits/numeric_traits.hpp\"\n#include \"../../../../support/char_encoding/ascii.hpp\"\n\n#include <boost/preprocessor/repetition/repeat.hpp>\n#include <boost/preprocessor/iteration/local.hpp>\n#include <boost/preprocessor/comparison/less.hpp>\n#include <boost/preprocessor/control/if.hpp>\n#include <boost/preprocessor/seq/elem.hpp>\n\n#include <boost/utility/enable_if.hpp>\n\n#include <boost/type_traits/is_integral.hpp>\n#include <boost/type_traits/is_signed.hpp>\n#include <boost/type_traits/make_unsigned.hpp>\n\n#include <boost/mpl/bool.hpp>\n#include <boost/mpl/and.hpp>\n#include <boost/limits.hpp>\n\n#include <iterator> // for std::iterator_traits\n\n#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)\n# define SPIRIT_NUMERICS_LOOP_UNROLL 3\n#endif\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//\n\t//  The maximum radix digits that can be represented without\n\t//  overflow:\n\t//\n\t//          template<typename T, unsigned Radix>\n\t//          struct digits_traits::value;\n\t//\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, unsigned Radix>\n\tstruct digits_traits;\n\n\ttemplate <int Digits, unsigned Radix>\n\tstruct digits2_to_n;\n\n// lookup table for log2(x) : 2 <= x <= 36\n#define BOOST_SPIRIT_X3_LOG2 (#error)(#error)                                   \\\n\t\t(1000000)(1584960)(2000000)(2321920)(2584960)(2807350)                  \\\n\t\t(3000000)(3169920)(3321920)(3459430)(3584960)(3700430)                  \\\n\t\t(3807350)(3906890)(4000000)(4087460)(4169920)(4247920)                  \\\n\t\t(4321920)(4392310)(4459430)(4523560)(4584960)(4643850)                  \\\n\t\t(4700430)(4754880)(4807350)(4857980)(4906890)(4954190)                  \\\n\t\t(5000000)(5044390)(5087460)(5129280)(5169925)                           \\\n\t/***/\n\n#define BOOST_PP_LOCAL_MACRO(Radix)                                             \\\n\ttemplate <int Digits> struct digits2_to_n<Digits, Radix>                    \\\n\t{                                                                           \\\n\t\tBOOST_STATIC_CONSTANT(int, value = static_cast<int>(                    \\\n\t\t\t(Digits * 1000000) /                                                \\\n\t\t\t\tBOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2)));               \\\n\t};                                                                          \\\n\t/***/\n\n#define BOOST_PP_LOCAL_LIMITS (2, 36)\n#include BOOST_PP_LOCAL_ITERATE()\n\n#undef BOOST_SPIRIT_X3_LOG2\n\n\ttemplate <typename T, unsigned Radix>\n\tstruct digits_traits : digits2_to_n<std::numeric_limits<T>::digits, Radix>\n\t{\n\t\tstatic_assert(std::numeric_limits<T>::radix == 2, \"\");\n\t};\n\n\ttemplate <typename T>\n\tstruct digits_traits<T, 10>\n\t{\n\t\tstatic int constexpr value = std::numeric_limits<T>::digits10;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\n\t//  Traits class for radix specific number conversion\n\t//\n\t//      Test the validity of a single character:\n\t//\n\t//          template<typename Char> static bool is_valid(Char ch);\n\t//\n\t//      Convert a digit from character representation to binary\n\t//      representation:\n\t//\n\t//          template<typename Char> static int digit(Char ch);\n\t//\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <unsigned Radix>\n\tstruct radix_traits\n\t{\n\t\ttemplate <typename Char>\n\t\tinline static bool is_valid(Char ch)\n\t\t{\n\t\t\treturn (ch >= '0' && ch <= (Radix > 10 ? '9' : static_cast<char>('0' + Radix -1)))\n\t\t\t\t|| (Radix > 10 && ch >= 'a' && ch <= static_cast<char>('a' + Radix -10 -1))\n\t\t\t\t|| (Radix > 10 && ch >= 'A' && ch <= static_cast<char>('A' + Radix -10 -1));\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tinline static unsigned digit(Char ch)\n\t\t{\n\t\t\treturn ch < 'A'\n\t\t\t\t? ch - '0'\n\t\t\t\t: ch < 'a'\n\t\t\t\t\t? ch - 'A' + 10\n\t\t\t\t\t: ch - 'a' + 10;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  positive_accumulator/negative_accumulator: Accumulator policies for\n\t//  extracting integers. Use positive_accumulator if number is positive.\n\t//  Use negative_accumulator if number is negative.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <unsigned Radix>\n\tstruct positive_accumulator\n\t{\n\t\ttemplate <typename T, typename Char>\n\t\tinline static void add(T& n, Char ch, mpl::false_) // unchecked add\n\t\t{\n\t\t\tconst int digit = radix_traits<Radix>::digit(ch);\n\t\t\tn = n * T(Radix) + T(digit);\n\t\t}\n\n\t\ttemplate <typename T, typename Char>\n\t\tinline static bool add(T& n, Char ch, mpl::true_) // checked add\n\t\t{\n\t\t\t// Ensure n *= Radix will not overflow\n\t\t\tT const max = (std::numeric_limits<T>::max)();\n\t\t\tT const val = max / Radix;\n\t\t\tif (n > val)\n\t\t\t\treturn false;\n\n\t\t\tT tmp = n * Radix;\n\n\t\t\t// Ensure n += digit will not overflow\n\t\t\tconst int digit = radix_traits<Radix>::digit(ch);\n\t\t\tif (tmp > max - digit)\n\t\t\t\treturn false;\n\n\t\t\tn = tmp + static_cast<T>(digit);\n\t\t\treturn true;\n\t\t}\n\t};\n\n\ttemplate <unsigned Radix>\n\tstruct negative_accumulator\n\t{\n\t\ttemplate <typename T, typename Char>\n\t\tinline static void add(T& n, Char ch, mpl::false_) // unchecked subtract\n\t\t{\n\t\t\tconst int digit = radix_traits<Radix>::digit(ch);\n\t\t\tn = n * T(Radix) - T(digit);\n\t\t}\n\n\t\ttemplate <typename T, typename Char>\n\t\tinline static bool add(T& n, Char ch, mpl::true_) // checked subtract\n\t\t{\n\t\t\t// Ensure n *= Radix will not underflow\n\t\t\tT const min = (std::numeric_limits<T>::min)();\n\t\t\tT const val = min / T(Radix);\n\t\t\tif (n < val)\n\t\t\t\treturn false;\n\n\t\t\tT tmp = n * Radix;\n\n\t\t\t// Ensure n -= digit will not underflow\n\t\t\tint const digit = radix_traits<Radix>::digit(ch);\n\t\t\tif (tmp < min + digit)\n\t\t\t\treturn false;\n\n\t\t\tn = tmp - static_cast<T>(digit);\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Common code for extract_int::parse specializations\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <unsigned Radix, typename Accumulator, int MaxDigits>\n\tstruct int_extractor\n\t{\n\t\ttemplate <typename Char, typename T>\n\t\tinline static bool\n\t\tcall(Char ch, std::size_t count, T& n, mpl::true_)\n\t\t{\n\t\t\tstd::size_t constexpr\n\t\t\t\toverflow_free = digits_traits<T, Radix>::value - 1;\n\n\t\t\tif (count < overflow_free)\n\t\t\t{\n\t\t\t\tAccumulator::add(n, ch, mpl::false_());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!Accumulator::add(n, ch, mpl::true_()))\n\t\t\t\t\treturn false; //  over/underflow!\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Char, typename T>\n\t\tinline static bool\n\t\tcall(Char ch, std::size_t /*count*/, T& n, mpl::false_)\n\t\t{\n\t\t\t// no need to check for overflow\n\t\t\tAccumulator::add(n, ch, mpl::false_());\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Char>\n\t\tinline static bool\n\t\tcall(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Char, typename T>\n\t\tinline static bool\n\t\tcall(Char ch, std::size_t count, T& n)\n\t\t{\n\t\t\treturn call(ch, count, n\n\t\t\t  , mpl::bool_<\n\t\t\t\t\t(   (MaxDigits < 0)\n\t\t\t\t\t||  (MaxDigits > digits_traits<T, Radix>::value)\n\t\t\t\t\t)\n\t\t\t\t  && traits::check_overflow<T>::value\n\t\t\t\t>()\n\t\t\t);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  End of loop checking: check if the number of digits\n\t//  being parsed exceeds MaxDigits. Note: if MaxDigits == -1\n\t//  we don't do any checking.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <int MaxDigits>\n\tstruct check_max_digits\n\t{\n\t\tinline static bool\n\t\tcall(std::size_t count)\n\t\t{\n\t\t\treturn count < MaxDigits; // bounded\n\t\t}\n\t};\n\n\ttemplate <>\n\tstruct check_max_digits<-1>\n\t{\n\t\tinline static bool\n\t\tcall(std::size_t /*count*/)\n\t\t{\n\t\t\treturn true; // unbounded\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  extract_int: main code for extracting integers\n\t///////////////////////////////////////////////////////////////////////////\n#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data)                                   \\\n\t\tif (!check_max_digits<MaxDigits>::call(count + leading_zeros)           \\\n\t\t\t|| it == last)                                                      \\\n\t\t\tbreak;                                                              \\\n\t\tch = *it;                                                               \\\n\t\tif (!radix_check::is_valid(ch) || !extractor::call(ch, count, val))     \\\n\t\t\tbreak;                                                              \\\n\t\t++it;                                                                   \\\n\t\t++count;                                                                \\\n\t/**/\n\n\ttemplate <\n\t\ttypename T, unsigned Radix, unsigned MinDigits, int MaxDigits\n\t  , typename Accumulator = positive_accumulator<Radix>\n\t  , bool Accumulate = false\n\t>\n\tstruct extract_int\n\t{\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(push)\n# pragma warning(disable: 4127)   // conditional expression is constant\n# pragma warning(disable: 4459)   // declaration hides global declaration\n#endif\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool\n\t\tparse_main(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , Attribute& attr)\n\t\t{\n\t\t\ttypedef radix_traits<Radix> radix_check;\n\t\t\ttypedef int_extractor<Radix, Accumulator, MaxDigits> extractor;\n\t\t\ttypedef typename\n\t\t\t\tstd::iterator_traits<Iterator>::value_type\n\t\t\tchar_type;\n\n\t\t\tIterator it = first;\n\t\t\tstd::size_t leading_zeros = 0;\n\t\t\tif (!Accumulate)\n\t\t\t{\n\t\t\t\t// skip leading zeros\n\t\t\t\twhile (it != last && *it == '0' && leading_zeros < MaxDigits)\n\t\t\t\t{\n\t\t\t\t\t++it;\n\t\t\t\t\t++leading_zeros;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttypedef typename\n\t\t\t\ttraits::attribute_type<Attribute>::type\n\t\t\tattribute_type;\n\n\t\t\tattribute_type val = Accumulate ? attr : attribute_type(0);\n\t\t\tstd::size_t count = 0;\n\t\t\tchar_type ch;\n\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tBOOST_PP_REPEAT(\n\t\t\t\t\tSPIRIT_NUMERICS_LOOP_UNROLL\n\t\t\t\t  , SPIRIT_NUMERIC_INNER_LOOP, _)\n\t\t\t}\n\n\t\t\tif (count + leading_zeros >= MinDigits)\n\t\t\t{\n\t\t\t\ttraits::move_to(val, attr);\n\t\t\t\tfirst = it;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(pop)\n#endif\n\n\t\ttemplate <typename Iterator>\n\t\tinline static bool\n\t\tparse(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , unused_type)\n\t\t{\n\t\t\tT n = 0; // must calculate value to detect over/underflow\n\t\t\treturn parse_main(first, last, n);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool\n\t\tparse(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , Attribute& attr)\n\t\t{\n\t\t\treturn parse_main(first, last, attr);\n\t\t}\n\t};\n#undef SPIRIT_NUMERIC_INNER_LOOP\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//  extract_int: main code for extracting integers\n\t//  common case where MinDigits == 1 and MaxDigits = -1\n\t///////////////////////////////////////////////////////////////////////////\n#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data)                                   \\\n\t\tif (it == last)                                                         \\\n\t\t\tbreak;                                                              \\\n\t\tch = *it;                                                               \\\n\t\tif (!radix_check::is_valid(ch))                                         \\\n\t\t\tbreak;                                                              \\\n\t\tif (!extractor::call(ch, count, val))                                   \\\n\t\t\treturn false;                                                       \\\n\t\t++it;                                                                   \\\n\t\t++count;                                                                \\\n\t/**/\n\n\ttemplate <typename T, unsigned Radix, typename Accumulator, bool Accumulate>\n\tstruct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>\n\t{\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(push)\n# pragma warning(disable: 4127)   // conditional expression is constant\n# pragma warning(disable: 4459)   // declaration hides global declaration\n#endif\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool\n\t\tparse_main(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , Attribute& attr)\n\t\t{\n\t\t\ttypedef radix_traits<Radix> radix_check;\n\t\t\ttypedef int_extractor<Radix, Accumulator, -1> extractor;\n\t\t\ttypedef typename\n\t\t\t\tstd::iterator_traits<Iterator>::value_type\n\t\t\tchar_type;\n\n\t\t\tIterator it = first;\n\t\t\tstd::size_t count = 0;\n\t\t\tif (!Accumulate)\n\t\t\t{\n\t\t\t\t// skip leading zeros\n\t\t\t\twhile (it != last && *it == '0')\n\t\t\t\t{\n\t\t\t\t\t++it;\n\t\t\t\t\t++count;\n\t\t\t\t}\n\n\t\t\t\tif (it == last)\n\t\t\t\t{\n\t\t\t\t\tif (count == 0) // must have at least one digit\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tattr = 0;\n\t\t\t\t\tfirst = it;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttypedef typename\n\t\t\t\ttraits::attribute_type<Attribute>::type\n\t\t\tattribute_type;\n\n\t\t\tattribute_type val = Accumulate ? attr : attribute_type(0);\n\t\t\tchar_type ch = *it;\n\n\t\t\tif (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))\n\t\t\t{\n\t\t\t\tif (count == 0) // must have at least one digit\n\t\t\t\t\treturn false;\n\t\t\t\ttraits::move_to(val, attr);\n\t\t\t\tfirst = it;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tcount = 0;\n\t\t\t++it;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tBOOST_PP_REPEAT(\n\t\t\t\t\tSPIRIT_NUMERICS_LOOP_UNROLL\n\t\t\t\t  , SPIRIT_NUMERIC_INNER_LOOP, _)\n\t\t\t}\n\n\t\t\ttraits::move_to(val, attr);\n\t\t\tfirst = it;\n\t\t\treturn true;\n\t\t}\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(pop)\n#endif\n\n\t\ttemplate <typename Iterator>\n\t\tinline static bool\n\t\tparse(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , unused_type)\n\t\t{\n\t\t\tT n = 0; // must calculate value to detect over/underflow\n\t\t\treturn parse_main(first, last, n);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool\n\t\tparse(\n\t\t\tIterator& first\n\t\t  , Iterator const& last\n\t\t  , Attribute& attr)\n\t\t{\n\t\t\treturn parse_main(first, last, attr);\n\t\t}\n\t};\n\n#undef SPIRIT_NUMERIC_INNER_LOOP\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/numeric_utils/extract_int.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2011 Jan Frederick Eick\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM)\n#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM\n\n#include \"../traits/move_to.hpp\"\n#include \"detail/extract_int.hpp\"\n#include <boost/assert.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  Extract the prefix sign (- or +), return true if a '-' was found\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator>\n\tinline bool\n\textract_sign(Iterator& first, Iterator const& last)\n\t{\n\t\t(void)last;                  // silence unused warnings\n\t\tBOOST_ASSERT(first != last); // precondition\n\n\t\t// Extract the sign\n\t\tbool neg = *first == '-';\n\t\tif (neg || (*first == '+'))\n\t\t{\n\t\t\t++first;\n\t\t\treturn neg;\n\t\t}\n\t\treturn false;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Low level unsigned integer parser\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits\n\t  , bool Accumulate = false>\n\tstruct extract_uint\n\t{\n\t\t// check template parameter 'Radix' for validity\n\t\tstatic_assert(\n\t\t\t(Radix >= 2 && Radix <= 36),\n\t\t\t\"Error Unsupported Radix\");\n\n\t\ttemplate <typename Iterator>\n\t\tinline static bool call(Iterator& first, Iterator const& last, T& attr)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn false;\n\n\t\t\ttypedef detail::extract_int<\n\t\t\t\tT\n\t\t\t  , Radix\n\t\t\t  , MinDigits\n\t\t\t  , MaxDigits\n\t\t\t  , detail::positive_accumulator<Radix>\n\t\t\t  , Accumulate>\n\t\t\textract_type;\n\n\t\t\tIterator save = first;\n\t\t\tif (!extract_type::parse(first, last, attr))\n\t\t\t{\n\t\t\t\tfirst = save;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\t// this case is called when Attribute is not T\n\t\t\tT attr;\n\t\t\tif (call(first, last, attr))\n\t\t\t{\n\t\t\t\ttraits::move_to(attr, attr_);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Low level signed integer parser\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>\n\tstruct extract_int\n\t{\n\t\t// check template parameter 'Radix' for validity\n\t\tstatic_assert(\n\t\t\t(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),\n\t\t\t\"Error Unsupported Radix\");\n\n\t\ttemplate <typename Iterator>\n\t\tinline static bool call(Iterator& first, Iterator const& last, T& attr)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn false;\n\n\t\t\ttypedef detail::extract_int<\n\t\t\t\tT, Radix, MinDigits, MaxDigits>\n\t\t\textract_pos_type;\n\n\t\t\ttypedef detail::extract_int<\n\t\t\t\tT, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >\n\t\t\textract_neg_type;\n\n\t\t\tIterator save = first;\n\t\t\tbool hit = extract_sign(first, last);\n\t\t\tif (hit)\n\t\t\t\thit = extract_neg_type::parse(first, last, attr);\n\t\t\telse\n\t\t\t\thit = extract_pos_type::parse(first, last, attr);\n\n\t\t\tif (!hit)\n\t\t\t{\n\t\t\t\tfirst = save;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tinline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)\n\t\t{\n\t\t\t// this case is called when Attribute is not T\n\t\t\tT attr;\n\t\t\tif (call(first, last, attr))\n\t\t\t{\n\t\t\t\ttraits::move_to(attr, attr_);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/numeric_utils/extract_real.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_EXTRACT_REAL_APRIL_18_2006_0901AM)\n#define BOOST_SPIRIT_X3_EXTRACT_REAL_APRIL_18_2006_0901AM\n\n#include <cmath>\n#include <boost/limits.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include \"../unused.hpp\"\n#include \"pow10.hpp\"\n#include \"../traits/move_to.hpp\"\n#include <boost/assert.hpp>\n\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(push)\n# pragma warning(disable: 4100)   // 'p': unreferenced formal parameter\n# pragma warning(disable: 4127)   // conditional expression is constant\n#endif\n\nnamespace boost { namespace spirit { namespace x3 { namespace extension\n{\n\tusing x3::traits::pow10;\n\n\ttemplate <typename T>\n\tinline bool\n\tscale(int exp, T& n)\n\t{\n\t\tconstexpr auto max_exp = std::numeric_limits<T>::max_exponent10;\n\t\tconstexpr auto min_exp = std::numeric_limits<T>::min_exponent10;\n\n\t\tif (exp >= 0)\n\t\t{\n\t\t\t// return false if exp exceeds the max_exp\n\t\t\t// do this check only for primitive types!\n\t\t\tif (is_floating_point<T>() && exp > max_exp)\n\t\t\t\treturn false;\n\t\t\tn *= pow10<T>(exp);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (exp < min_exp)\n\t\t\t{\n\t\t\t\tn /= pow10<T>(-min_exp);\n\n\t\t\t\t// return false if exp still exceeds the min_exp\n\t\t\t\t// do this check only for primitive types!\n\t\t\t\texp += -min_exp;\n\t\t\t\tif (is_floating_point<T>() && exp < min_exp)\n\t\t\t\t\treturn false;\n\n\t\t\t\tn /= pow10<T>(-exp);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tn /= pow10<T>(-exp);\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tinline bool\n\tscale(int /*exp*/, unused_type /*n*/)\n\t{\n\t\t// no-op for unused_type\n\t\treturn true;\n\t}\n\n\ttemplate <typename T>\n\tinline bool\n\tscale(int exp, int frac, T& n)\n\t{\n\t\treturn scale(exp - frac, n);\n\t}\n\n\tinline bool\n\tscale(int /*exp*/, int /*frac*/, unused_type /*n*/)\n\t{\n\t\t// no-op for unused_type\n\t\treturn true;\n\t}\n\n\tinline float\n\tnegate(bool neg, float n)\n\t{\n\t\treturn neg ? (std::copysignf)(n, -1.f) : n;\n\t}\n\n\tinline double\n\tnegate(bool neg, double n)\n\t{\n\t\treturn neg ? (std::copysign)(n, -1.) : n;\n\t}\n\n\tinline long double\n\tnegate(bool neg, long double n)\n\t{\n\t\treturn neg ? (std::copysignl)(n, -1.) : n;\n\t}\n\n\ttemplate <typename T>\n\tinline T\n\tnegate(bool neg, T const& n)\n\t{\n\t\treturn neg ? -n : n;\n\t}\n\n\tinline unused_type\n\tnegate(bool /*neg*/, unused_type n)\n\t{\n\t\t// no-op for unused_type\n\t\treturn n;\n\t}\n}}}}\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename T, typename RealPolicies>\n\tstruct extract_real\n\t{\n\t\ttemplate <typename Iterator, typename Attribute>\n\t\tstatic bool\n\t\tparse(Iterator& first, Iterator const& last, Attribute& attr,\n\t\t\tRealPolicies const& p)\n\t\t{\n\t\t\tif (first == last)\n\t\t\t\treturn false;\n\t\t\tIterator save = first;\n\n\t\t\t// Start by parsing the sign. neg will be true if\n\t\t\t// we got a \"-\" sign, false otherwise.\n\t\t\tbool neg = p.parse_sign(first, last);\n\n\t\t\t// Now attempt to parse an integer\n\t\t\tT n = 0;\n\t\t\tbool got_a_number = p.parse_n(first, last, n);\n\n\t\t\t// If we did not get a number it might be a NaN, Inf or a leading\n\t\t\t// dot.\n\t\t\tif (!got_a_number)\n\t\t\t{\n\t\t\t\t// Check whether the number to parse is a NaN or Inf\n\t\t\t\tif (p.parse_nan(first, last, n) ||\n\t\t\t\t\tp.parse_inf(first, last, n))\n\t\t\t\t{\n\t\t\t\t\t// If we got a negative sign, negate the number\n\t\t\t\t\ttraits::move_to(extension::negate(neg, n), attr);\n\t\t\t\t\treturn true;    // got a NaN or Inf, return early\n\t\t\t\t}\n\n\t\t\t\t// If we did not get a number and our policies do not\n\t\t\t\t// allow a leading dot, fail and return early (no-match)\n\t\t\t\tif (!p.allow_leading_dot)\n\t\t\t\t{\n\t\t\t\t\tfirst = save;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool e_hit = false;\n\t\t\tIterator e_pos;\n\t\t\tint frac_digits = 0;\n\n\t\t\t// Try to parse the dot ('.' decimal point)\n\t\t\tif (p.parse_dot(first, last))\n\t\t\t{\n\t\t\t\t// We got the decimal point. Now we will try to parse\n\t\t\t\t// the fraction if it is there. If not, it defaults\n\t\t\t\t// to zero (0) only if we already got a number.\n\t\t\t\tIterator savef = first;\n\t\t\t\tif (p.parse_frac_n(first, last, n))\n\t\t\t\t{\n\t\t\t\t\t// Optimization note: don't compute frac_digits if T is\n\t\t\t\t\t// an unused_type. This should be optimized away by the compiler.\n\t\t\t\t\tif (!is_same<T, unused_type>::value)\n\t\t\t\t\t\tfrac_digits =\n\t\t\t\t\t\t\tstatic_cast<int>(std::distance(savef, first));\n\t\t\t\t\tBOOST_ASSERT(frac_digits >= 0);\n\t\t\t\t}\n\t\t\t\telse if (!got_a_number || !p.allow_trailing_dot)\n\t\t\t\t{\n\t\t\t\t\t// We did not get a fraction. If we still haven't got a\n\t\t\t\t\t// number and our policies do not allow a trailing dot,\n\t\t\t\t\t// return no-match.\n\t\t\t\t\tfirst = save;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Now, let's see if we can parse the exponent prefix\n\t\t\t\te_pos = first;\n\t\t\t\te_hit = p.parse_exp(first, last);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// No dot and no number! Return no-match.\n\t\t\t\tif (!got_a_number)\n\t\t\t\t{\n\t\t\t\t\tfirst = save;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// If we must expect a dot and we didn't see an exponent\n\t\t\t\t// prefix, return no-match.\n\t\t\t\te_pos = first;\n\t\t\t\te_hit = p.parse_exp(first, last);\n\t\t\t\tif (p.expect_dot && !e_hit)\n\t\t\t\t{\n\t\t\t\t\tfirst = save;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (e_hit)\n\t\t\t{\n\t\t\t\t// We got the exponent prefix. Now we will try to parse the\n\t\t\t\t// actual exponent. It is an error if it is not there.\n\t\t\t\tint exp = 0;\n\t\t\t\tif (p.parse_exp_n(first, last, exp))\n\t\t\t\t{\n\t\t\t\t\t// Got the exponent value. Scale the number by\n\t\t\t\t\t// exp-frac_digits.\n\t\t\t\t\tif (!extension::scale(exp, frac_digits, n))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If there is no number, disregard the exponent altogether.\n\t\t\t\t\t// by resetting 'first' prior to the exponent prefix (e|E)\n\t\t\t\t\tfirst = e_pos;\n\n\t\t\t\t\t// Scale the number by -frac_digits.\n\t\t\t\t\tif (!extension::scale(-frac_digits, n))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (frac_digits)\n\t\t\t{\n\t\t\t\t// No exponent found. Scale the number by -frac_digits.\n\t\t\t\tif (!extension::scale(-frac_digits, n))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// If we got a negative sign, negate the number\n\t\t\ttraits::move_to(extension::negate(neg, n), attr);\n\n\t\t\t// Success!!!\n\t\t\treturn true;\n\t\t}\n\t};\n\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(pop)\n#endif\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/numeric_utils/pow10.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM)\n#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM\n\n#include <boost/config/no_tr1/cmath.hpp>\n#include <boost/limits.hpp>\n#include \"../unused.hpp\"\n#include \"../traits/numeric_traits.hpp\"\n#include <cfloat>\n\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(push)\n# pragma warning(disable: 4244)   // conversion from 'double' to 'float', possible loss of data\n#endif\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\tnamespace detail\n\t{\n\t\ttemplate <typename T, typename Enable = void>\n\t\tstruct pow10_helper\n\t\t{\n\t\t\tstatic T call(unsigned dim)\n\t\t\t{\n\t\t\t\tusing namespace std;    // allow for ADL to find the correct overload\n\t\t\t\treturn pow(T(10), T(dim));\n\t\t\t}\n\t\t};\n\n\t\ttemplate <>\n\t\tstruct pow10_helper<unused_type>\n\t\t{\n\t\t\tstatic unused_type call(unused_type)\n\t\t\t{\n\t\t\t\treturn unused;\n\t\t\t}\n\t\t};\n\n#if (DBL_MAX_10_EXP == 308) // for IEEE-754\n\t\ttemplate <>\n\t\tstruct pow10_helper<double>\n\t\t{\n\t\t\tstatic double call(unsigned dim)\n\t\t\t{\n\t\t\t\tstatic double const exponents[] =\n\t\t\t\t{\n\t\t\t\t\t1e0,   1e1,   1e2,   1e3,   1e4,   1e5,   1e6,   1e7,   1e8,    1e9,\n\t\t\t\t\t1e10,  1e11,  1e12,  1e13,  1e14,  1e15,  1e16,  1e17,  1e18,  1e19,\n\t\t\t\t\t1e20,  1e21,  1e22,  1e23,  1e24,  1e25,  1e26,  1e27,  1e28,  1e29,\n\t\t\t\t\t1e30,  1e31,  1e32,  1e33,  1e34,  1e35,  1e36,  1e37,  1e38,  1e39,\n\t\t\t\t\t1e40,  1e41,  1e42,  1e43,  1e44,  1e45,  1e46,  1e47,  1e48,  1e49,\n\t\t\t\t\t1e50,  1e51,  1e52,  1e53,  1e54,  1e55,  1e56,  1e57,  1e58,  1e59,\n\t\t\t\t\t1e60,  1e61,  1e62,  1e63,  1e64,  1e65,  1e66,  1e67,  1e68,  1e69,\n\t\t\t\t\t1e70,  1e71,  1e72,  1e73,  1e74,  1e75,  1e76,  1e77,  1e78,  1e79,\n\t\t\t\t\t1e80,  1e81,  1e82,  1e83,  1e84,  1e85,  1e86,  1e87,  1e88,  1e89,\n\t\t\t\t\t1e90,  1e91,  1e92,  1e93,  1e94,  1e95,  1e96,  1e97,  1e98,  1e99,\n\t\t\t\t\t1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,\n\t\t\t\t\t1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,\n\t\t\t\t\t1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,\n\t\t\t\t\t1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,\n\t\t\t\t\t1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,\n\t\t\t\t\t1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,\n\t\t\t\t\t1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,\n\t\t\t\t\t1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,\n\t\t\t\t\t1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,\n\t\t\t\t\t1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,\n\t\t\t\t\t1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,\n\t\t\t\t\t1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,\n\t\t\t\t\t1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,\n\t\t\t\t\t1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,\n\t\t\t\t\t1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,\n\t\t\t\t\t1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,\n\t\t\t\t\t1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,\n\t\t\t\t\t1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,\n\t\t\t\t\t1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,\n\t\t\t\t\t1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,\n\t\t\t\t\t1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,\n\t\t\t\t};\n\t\t\t\tBOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));\n\t\t\t\treturn exponents[dim];\n\t\t\t}\n\t\t};\n\n\t\ttemplate <>\n\t\tstruct pow10_helper<float>\n\t\t{\n\t\t\tstatic float call(unsigned dim)\n\t\t\t{\n\t\t\t\treturn pow10_helper<double>::call(dim);\n\t\t\t}\n\t\t};\n#endif // for IEEE-754\n\t}\n\n\ttemplate <typename T>\n\tinline T pow10(unsigned dim)\n\t{\n\t\treturn detail::pow10_helper<T>::call(dim);\n\t}\n}}}}\n\n#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)\n# pragma warning(pop)\n#endif\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/subcontext.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM)\n#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM\n\n#include \"context.hpp\"\n#include \"unused.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename... T>\n\tstruct subcontext;\n\n\ttemplate <>\n\tstruct subcontext<>\n\t{\n\t\ttemplate <typename Context>\n\t\tsubcontext(Context const& /*context*/)\n\t\t{}\n\t};\n\n\ttemplate <typename T>\n\tstruct subcontext<T>\n\t  : context<typename T::first_type, typename T::second_type>\n\t{\n\t\ttypedef context<\n\t\t\ttypename T::first_type, typename T::second_type\n\t\t> context_type;\n\n\t\ttemplate <typename Context>\n\t\tsubcontext(Context const& context)\n\t\t  : context_type{x3::get<typename T::first_type>(context), unused}\n\t\t{}\n\t};\n\n\ttemplate <typename T, typename... Tail>\n\tstruct subcontext<T, Tail...>\n\t  : subcontext<Tail...>\n\t  , context<\n\t\t\ttypename T::first_type, typename T::second_type\n\t\t  , subcontext<Tail...> const&\n\t\t>\n\t{\n\t\ttypedef subcontext<Tail...> base_type;\n\t\ttypedef context<\n\t\t\ttypename T::first_type, typename T::second_type\n\t\t  , base_type const&\n\t\t> context_type;\n\n\t\ttemplate <typename Context>\n\t\tsubcontext(Context const& context)\n\t\t  : base_type(context)\n\t\t  , context_type{\n\t\t\t\tx3::get<typename T::first_type>(context)\n\t\t\t  , *static_cast<base_type*>(this)}\n\t\t{}\n\t};\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/attribute_category.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)\n#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM\n\n#include <boost/mpl/identity.hpp>\n#include <boost/mpl/logical.hpp>\n#include <boost/mpl/eval_if.hpp>\n#include <boost/fusion/include/is_sequence.hpp>\n#include <boost/fusion/support/category_of.hpp>\n#include \"is_variant.hpp\"\n#include \"is_range.hpp\"\n#include \"container_traits.hpp\"\n#include \"optional_traits.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n   struct unused_type;\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\tstruct unused_attribute {};\n\tstruct plain_attribute {};\n\tstruct container_attribute {};\n\tstruct tuple_attribute {};\n\tstruct associative_attribute {};\n\tstruct variant_attribute {};\n\tstruct optional_attribute {};\n\tstruct range_attribute {};\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct attribute_category\n\t\t: mpl::identity<plain_attribute> {};\n\n\ttemplate <>\n\tstruct attribute_category<unused_type>\n\t\t: mpl::identity<unused_attribute> {};\n\n\ttemplate <>\n\tstruct attribute_category<unused_type const>\n\t\t: mpl::identity<unused_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category< T\n\t, typename enable_if<\n\t\t  typename mpl::eval_if<\n\t\t  fusion::traits::is_sequence<T>\n\t\t  , fusion::traits::is_associative<T>\n\t\t  , mpl::false_\n\t\t  >::type >::type >\n\t\t: mpl::identity<associative_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category< T\n\t, typename enable_if<\n\t\t  mpl::and_<\n\t\t  fusion::traits::is_sequence<T>\n\t\t  , mpl::not_<fusion::traits::is_associative<T> >\n\t\t  > >::type >\n\t\t: mpl::identity<tuple_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category<T,\n\t\ttypename enable_if<traits::is_variant<T>>::type>\n\t\t: mpl::identity<variant_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category<T,\n\t\ttypename enable_if<traits::is_optional<T>>::type>\n\t\t: mpl::identity<optional_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category<T,\n\t\ttypename enable_if<traits::is_range<T>>::type>\n\t\t: mpl::identity<range_attribute> {};\n\n\ttemplate <typename T>\n\tstruct attribute_category< T\n\t, typename enable_if<\n\t\t  mpl::and_<\n\t\t  traits::is_container<T>\n\t\t  , mpl::not_<fusion::traits::is_sequence<T> >\n\t\t  , mpl::not_<traits::is_range<T> >\n\t\t  > >::type >\n\t\t: mpl::identity<container_attribute> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/attribute_of.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM)\n#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM\n\n#include \"../utility/sfinae.hpp\"\n#include <boost/mpl/identity.hpp>\n#include <boost/utility/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Get the attribute type of a component. By default, this gets the\n\t// Component's attribute_type typedef or instantiates a nested attribute\n\t// metafunction. Components may specialize this if such an attribute_type\n\t// is not readily available (e.g. expensive to compute at compile time).\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Component, typename Context, typename Enable = void>\n\tstruct attribute_of;\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename Component, typename Context, typename Enable = void>\n\t\tstruct default_attribute_of;\n\n\t\ttemplate <typename Component, typename Context>\n\t\tstruct default_attribute_of<Component, Context,\n\t\t\ttypename disable_if_substitution_failure<\n\t\t\t\ttypename Component::attribute_type>::type>\n\t\t  : mpl::identity<typename Component::attribute_type> {};\n\n\t\ttemplate <typename Component, typename Context>\n\t\tstruct default_attribute_of<Component, Context,\n\t\t\ttypename disable_if_substitution_failure<\n\t\t\t\ttypename Component::template attribute<Context>::type>::type>\n\t\t  : Component::template attribute<Context> {};\n\n\t\ttemplate <typename Component, typename Context>\n\t\tstruct default_attribute_of<Component, Context,\n\t\t\ttypename enable_if_c<Component::is_pass_through_unary>::type>\n\t\t  : attribute_of<typename Component::subject_type, Context>{};\n\t}\n\n\ttemplate <typename Component, typename Context, typename Enable>\n\tstruct attribute_of : detail::default_attribute_of<Component, Context> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/attribute_of_binary.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2020 Nikita Kniazev\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#ifndef BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY\n#define BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY\n\n#include \"attribute_of.hpp\"\n#include \"../unused.hpp\"\n#include <boost/type_traits/type_identity.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename... T>\n\tstruct type_sequence\n\t{\n\t\tusing type = type_sequence;\n\n\t\tstatic const int size = sizeof...(T);\n\n\t\ttemplate <typename... U>\n\t\tusing append = type_sequence<T..., U...>;\n\n\t\ttemplate <typename... U>\n\t\tusing prepend = type_sequence<U..., T...>;\n\n\t\ttemplate <typename U>\n\t\tusing extend = typename U::template prepend<T...>;\n\n\t\ttemplate <template <typename...> class U>\n\t\tusing transfer_to = U<T...>;\n\t};\n\n\ttemplate <typename Attribute>\n\tstruct types_of_binary_init : type_sequence<Attribute> {};\n\ttemplate <>\n\tstruct types_of_binary_init<unused_type> : type_sequence<> {};\n\ttemplate <>\n\tstruct types_of_binary_init<unused_type const> : type_sequence<> {};\n\n\ttemplate <template <typename, typename> class B, typename P, typename C>\n\tstruct get_types_of_binary\n\t  : types_of_binary_init<typename traits::attribute_of<P, C>::type> {};\n\ttemplate <template <typename, typename> class B, typename L, typename R, typename C>\n\tstruct get_types_of_binary<B, B<L, R>, C>\n\t  : get_types_of_binary<B, L, C>::template extend<get_types_of_binary<B, R, C>> {};\n\n\ttemplate <template <typename...> class A, typename T, int = T::size>\n\tstruct type_sequence_to_attribute { using type = typename T::template transfer_to<A>; };\n\ttemplate <template <typename...> class A, typename T>\n\tstruct type_sequence_to_attribute<A, T, 1> : T::template transfer_to<type_identity> {};\n\ttemplate <template <typename...> class A, typename T>\n\tstruct type_sequence_to_attribute<A, T, 0> { using type = unused_type; };\n\n\ttemplate <template <typename...> class A, template <typename, typename> class B,\n\t\ttypename L, typename R, typename C>\n\tusing attribute_of_binary = type_sequence_to_attribute<A,\n\t\t\t\t\t\t\t\t\ttypename get_types_of_binary<B, B<L, R>, C>::type>;\n}}}}\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/attribute_type.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)\n#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM\n\n#include <boost/mpl/identity.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Retrieve the attribute type to use from the given type\n\t//\n\t// This is needed to extract the correct attribute type from proxy classes\n\t// as utilized in FUSION_ADAPT_ADT et. al.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Attribute, typename Enable = void>\n\tstruct attribute_type : mpl::identity<Attribute> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/container_traits.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)\n#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM\n\n#include <boost/fusion/support/category_of.hpp>\n#include \"../unused.hpp\"\n#include <boost/fusion/include/deque.hpp>\n#include <boost/mpl/identity.hpp>\n#include <boost/type_traits/make_void.hpp>\n#include <boost/range/iterator.hpp>\n\n#include <vector>\n#include <string>\n#include <iterator>\n#include <algorithm>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  This file contains some container utils for stl containers.\n\t///////////////////////////////////////////////////////////////////////////\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename T, typename Enabler = void>\n\t\tstruct is_container_impl : mpl::false_ {};\n\n\t\ttemplate <typename T>\n\t\tstruct is_container_impl<T, void_t<\n\t\t\ttypename T::value_type, typename boost::range_iterator<T>::type,\n\t\t\ttypename T::size_type, typename T::reference> > : mpl::true_ {};\n\n\t\ttemplate <typename T, typename Enabler = void>\n\t\tstruct is_associative_impl : mpl::false_ {};\n\n\t\ttemplate <typename T>\n\t\tstruct is_associative_impl<T, void_t<typename T::key_type>>\n\t\t\t: mpl::true_ {};\n\t}\n\n\ttemplate <typename T>\n\tusing is_container = typename detail::is_container_impl<T>::type;\n\n\ttemplate <typename T>\n\tusing is_associative = typename detail::is_associative_impl<T>::type;\n\n\t///////////////////////////////////////////////////////////////////////////\n\tnamespace detail\n\t{\n\t\ttemplate <typename T>\n\t\tstruct remove_value_const : mpl::identity<T> {};\n\n\t\ttemplate <typename T>\n\t\tstruct remove_value_const<T const> : remove_value_const<T> {};\n\n\t\ttemplate <typename F, typename S>\n\t\tstruct remove_value_const<std::pair<F, S>>\n\t\t{\n\t\t\ttypedef typename remove_value_const<F>::type first_type;\n\t\t\ttypedef typename remove_value_const<S>::type second_type;\n\t\t\ttypedef std::pair<first_type, second_type> type;\n\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Enable = void>\n\tstruct container_value\n\t  : detail::remove_value_const<typename Container::value_type>\n\t{};\n\n\ttemplate <typename Container>\n\tstruct container_value<Container const> : container_value<Container> {};\n\n\t// There is no single container value for fusion maps, but because output\n\t// of this metafunc is used to check wheter parser's attribute can be\n\t// saved to container, we simply return whole fusion::map as is\n\t// so that check can be done in traits::is_substitute specialisation\n\ttemplate <typename T>\n\tstruct container_value<T\n\t\t\t   , typename enable_if<typename mpl::eval_if <\n\t\t\t\t\t\t    fusion::traits::is_sequence<T>\n\t\t\t\t\t\t    , fusion::traits::is_associative<T>\n\t\t\t\t\t\t    , mpl::false_ >::type >::type>\n\t: mpl::identity<T> {};\n\n\ttemplate <>\n\tstruct container_value<unused_type> : mpl::identity<unused_type> {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Enable = void>\n\tstruct container_iterator\n\t\t: mpl::identity<typename boost::range_iterator<Container>::type> {};\n\n\ttemplate <>\n\tstruct container_iterator<unused_type>\n\t\t: mpl::identity<unused_type const*> {};\n\n\ttemplate <>\n\tstruct container_iterator<unused_type const>\n\t\t: mpl::identity<unused_type const*> {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename T>\n\tbool push_back(Container& c, T&& val);\n\n\ttemplate <typename Container, typename Enable = void>\n\tstruct push_back_container\n\t{\n\t\ttemplate <typename T>\n\t\tstatic bool call(Container& c, T&& val)\n\t\t{\n\t\t\tc.insert(c.end(), static_cast<T&&>(val));\n\t\t\treturn true;\n\t\t}\n\t};\n\n\ttemplate <typename Container, typename T>\n\tinline bool push_back(Container& c, T&& val)\n\t{\n\t\treturn push_back_container<Container>::call(c, static_cast<T&&>(val));\n\t}\n\n\ttemplate <typename Container>\n\tinline bool push_back(Container&, unused_type)\n\t{\n\t\treturn true;\n\t}\n\n\ttemplate <typename T>\n\tinline bool push_back(unused_type, T&&)\n\t{\n\t\treturn true;\n\t}\n\n\tinline bool push_back(unused_type, unused_type)\n\t{\n\t\treturn true;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Iterator>\n\tbool append(Container& c, Iterator first, Iterator last);\n\n\ttemplate <typename Container, typename Enable = void>\n\tstruct append_container\n\t{\n\tprivate:\n\t\ttemplate <typename Iterator>\n\t\tstatic void insert(Container& c, Iterator first, Iterator last, mpl::false_)\n\t\t{\n\t\t\tc.insert(c.end(), first, last);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tstatic void insert(Container& c, Iterator first, Iterator last, mpl::true_)\n\t\t{\n\t\t\tc.insert(first, last);\n\t\t}\n\n\tpublic:\n\t\ttemplate <typename Iterator>\n\t\tstatic bool call(Container& c, Iterator first, Iterator last)\n\t\t{\n\t\t\tinsert(c, first, last, is_associative<Container>{});\n\t\t\treturn true;\n\t\t}\n\t};\n\n\ttemplate <typename Container, typename Iterator>\n\tinline bool append(Container& c, Iterator first, Iterator last)\n\t{\n\t\treturn append_container<Container>::call(c, first, last);\n\t}\n\n\ttemplate <typename Iterator>\n\tinline bool append(unused_type, Iterator /* first */, Iterator /* last */)\n\t{\n\t\treturn true;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Enable = void>\n\tstruct is_empty_container\n\t{\n\t\tstatic bool call(Container const& c)\n\t\t{\n\t\t\treturn c.empty();\n\t\t}\n\t};\n\n\ttemplate <typename Container>\n\tinline bool is_empty(Container const& c)\n\t{\n\t\treturn is_empty_container<Container>::call(c);\n\t}\n\n\tinline bool is_empty(unused_type)\n\t{\n\t\treturn true;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Enable = void>\n\tstruct begin_container\n\t{\n\t\tstatic typename container_iterator<Container>::type call(Container& c)\n\t\t{\n\t\t\treturn c.begin();\n\t\t}\n\t};\n\n\ttemplate <typename Container>\n\tinline typename container_iterator<Container>::type\n\tbegin(Container& c)\n\t{\n\t\treturn begin_container<Container>::call(c);\n\t}\n\n\tinline unused_type const*\n\tbegin(unused_type)\n\t{\n\t\treturn &unused;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Container, typename Enable = void>\n\tstruct end_container\n\t{\n\t\tstatic typename container_iterator<Container>::type call(Container& c)\n\t\t{\n\t\t\treturn c.end();\n\t\t}\n\t};\n\n\ttemplate <typename Container>\n\tinline typename container_iterator<Container>::type\n\tend(Container& c)\n\t{\n\t\treturn end_container<Container>::call(c);\n\t}\n\n\tinline unused_type const*\n\tend(unused_type)\n\t{\n\t\treturn &unused;\n\t}\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Enable = void>\n\tstruct deref_iterator\n\t{\n\t\ttypedef typename std::iterator_traits<Iterator>::reference type;\n\t\tstatic type call(Iterator& it)\n\t\t{\n\t\t\treturn *it;\n\t\t}\n\t};\n\n\ttemplate <typename Iterator>\n\ttypename deref_iterator<Iterator>::type\n\tderef(Iterator& it)\n\t{\n\t\treturn deref_iterator<Iterator>::call(it);\n\t}\n\n\tinline unused_type\n\tderef(unused_type const*)\n\t{\n\t\treturn unused;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Enable = void>\n\tstruct next_iterator\n\t{\n\t\tstatic void call(Iterator& it)\n\t\t{\n\t\t\t++it;\n\t\t}\n\t};\n\n\ttemplate <typename Iterator>\n\tvoid next(Iterator& it)\n\t{\n\t\tnext_iterator<Iterator>::call(it);\n\t}\n\n\tinline void next(unused_type const*)\n\t{\n\t\t// do nothing\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Iterator, typename Enable = void>\n\tstruct compare_iterators\n\t{\n\t\tstatic bool call(Iterator const& it1, Iterator const& it2)\n\t\t{\n\t\t\treturn it1 == it2;\n\t\t}\n\t};\n\n\ttemplate <typename Iterator>\n\tbool compare(Iterator& it1, Iterator& it2)\n\t{\n\t\treturn compare_iterators<Iterator>::call(it1, it2);\n\t}\n\n\tinline bool compare(unused_type const*, unused_type const*)\n\t{\n\t\treturn false;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct build_container : mpl::identity<std::vector<T>> {};\n\n\ttemplate <typename T>\n\tstruct build_container<boost::fusion::deque<T> > : build_container<T> {};\n\n\ttemplate <>\n\tstruct build_container<unused_type> : mpl::identity<unused_type> {};\n\n\ttemplate <>\n\tstruct build_container<char> : mpl::identity<std::string> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/handles_container.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM)\n#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM\n\n#include <boost/mpl/bool.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Whether a component handles container attributes intrinsically\n\t// (or whether container attributes need to be split up separately).\n\t// By default, this gets the Component's handles_container nested value.\n\t// Components may specialize this if such a handles_container is not \n\t// readily available (e.g. expensive to compute at compile time).\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Component, typename Context, typename Enable = void>\n\tstruct handles_container : mpl::bool_<Component::handles_container> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/has_attribute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM)\n#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM\n\n#include \"attribute_of.hpp\"\n#include \"../utility/sfinae.hpp\"\n#include <boost/mpl/bool.hpp>\n#include <boost/mpl/not.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include <boost/utility/enable_if.hpp>\n\nnamespace boost { namespace spirit { namespace x3\n{\n   struct unused_type;\n}}}\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Whether a component has an attribute. By default, this compares the \n\t// component attribute against unused_type. If the component provides a\n\t// nested constant expression has_attribute as a hint, that value is used\n\t// instead. Components may specialize this.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Component, typename Context, typename Enable = void>\n\tstruct has_attribute;\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename Component, typename Context, typename Enable = void>\n\t\tstruct default_has_attribute\n\t\t  : mpl::not_<is_same<unused_type,\n\t\t\t\ttypename attribute_of<Component, Context>::type>> {};\n\n\t\ttemplate <typename Component, typename Context>\n\t\tstruct default_has_attribute<Component, Context,\n\t\t\ttypename disable_if_substitution_failure<\n\t\t\t\tmpl::bool_<Component::has_attribute>>::type>\n\t\t  : mpl::bool_<Component::has_attribute> {};\n\n\t\ttemplate <typename Component, typename Context>\n\t\tstruct default_has_attribute<Component, Context,\n\t\t\ttypename enable_if_c<Component::is_pass_through_unary>::type>\n\t\t  : has_attribute<typename Component::subject_type, Context> {};\n\t}\n\n\ttemplate <typename Component, typename Context, typename Enable>\n\tstruct has_attribute : detail::default_has_attribute<Component, Context> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/is_range.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_IS_RANGE_DEC_06_2017_1900PM)\n#define BOOST_SPIRIT_X3_IS_RANGE_DEC_06_2017_1900PM\n\n#include <boost/range/range_fwd.hpp>\n#include <boost/mpl/bool.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_range\n\t  : mpl::false_\n\t{};\n\n\ttemplate <typename T>\n\tstruct is_range<boost::iterator_range<T>>\n\t  : mpl::true_\n\t{};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/is_substitute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)\n#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM\n\n#include \"container_traits.hpp\"\n#include \"tuple_traits.hpp\"\n#include <boost/fusion/include/is_sequence.hpp>\n#include <boost/fusion/include/map.hpp>\n#include <boost/fusion/include/value_at_key.hpp>\n#include <boost/fusion/adapted/mpl.hpp>\n#include <boost/mpl/placeholders.hpp>\n#include <boost/mpl/equal.hpp>\n#include <boost/mpl/apply.hpp>\n#include <boost/mpl/filter_view.hpp>\n#include <boost/mpl/size.hpp>\n#include <boost/mpl/logical.hpp>\n#include <boost/mpl/at.hpp>\n#include <boost/mpl/count_if.hpp>\n#include <boost/utility/enable_if.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include <optional>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Find out if T can be a (strong) substitute for Attribute\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, typename Attribute, typename Enable = void>\n\tstruct is_substitute;\n\n\ttemplate <typename Variant, typename Attribute>\n\tstruct variant_has_substitute;\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename T, typename Attribute>\n\t\tstruct value_type_is_substitute\n\t\t  : is_substitute<\n\t\t\t\ttypename container_value<T>::type\n\t\t\t  , typename container_value<Attribute>::type>\n\t\t{};\n\n\t\ttemplate <typename T, typename Attribute, typename Enable = void>\n\t\tstruct is_substitute_impl : mpl::false_ {};\n\n\t\ttemplate <typename T, typename Attribute>\n\t\tstruct is_substitute_impl<T, Attribute,\n\t\t\ttypename enable_if<\n\t\t\t\tmpl::and_<\n\t\t\t\t\tfusion::traits::is_sequence<T>,\n\t\t\t\t\tfusion::traits::is_sequence<Attribute>,\n\t\t\t\t\tmpl::equal<T, Attribute, is_substitute<mpl::_1, mpl::_2>>\n\t\t\t\t>\n\t\t\t>::type>\n\t\t  : mpl::true_ {};\n\n\t\ttemplate <typename T, typename Attribute>\n\t\tstruct is_substitute_impl<T, Attribute,\n\t\t\ttypename enable_if<\n\t\t\t\tmpl::and_<\n\t\t\t\t\tis_container<T>,\n\t\t\t\t\tis_container<Attribute>,\n\t\t\t\t\tvalue_type_is_substitute<T, Attribute>\n\t\t\t\t>\n\t\t\t>::type>\n\t\t  : mpl::true_ {};\n\n\t\ttemplate <typename T, typename Attribute>\n\t\tstruct is_substitute_impl<T, Attribute,\n\t\t\ttypename enable_if<\n\t\t\t\tis_variant<Attribute>\n\t\t\t>::type>\n\t\t  : variant_has_substitute<Attribute, T>\n\t\t{};\n\t}\n\n\ttemplate <typename T, typename Attribute, typename Enable /*= void*/>\n\tstruct is_substitute\n\t\t: mpl::or_<\n\t\t\t  is_same<T, Attribute>,\n\t\t\t  detail::is_substitute_impl<T, Attribute>> {};\n\n\t// for reference T\n\ttemplate <typename T, typename Attribute, typename Enable>\n\tstruct is_substitute<T&, Attribute, Enable>\n\t\t: is_substitute<T, Attribute, Enable> {};\n\n\t// for reference Attribute\n\ttemplate <typename T, typename Attribute, typename Enable>\n\tstruct is_substitute<T, Attribute&, Enable>\n\t\t: is_substitute<T, Attribute, Enable> {};\n\n\t// 2 element mpl tuple is compatible with fusion::map if:\n\t// - it's first element type is existing key in map\n\t// - it second element type is compatible to type stored at the key in map\n\ttemplate <typename T, typename Attribute>\n\tstruct is_substitute<T, Attribute\n\t, typename enable_if<\n\t      typename mpl::eval_if<\n\t\t  mpl::and_<fusion::traits::is_sequence<T>\n\t\t\t    , fusion::traits::is_sequence<Attribute>>\n\t\t  , mpl::and_<traits::has_size<T, 2>\n\t\t\t   , fusion::traits::is_associative<Attribute>>\n\t\t  , mpl::false_>::type>::type>\n\n\t{\n\t\t// checking that \"p_key >> p_value\" parser can\n\t\t// store it's result in fusion::map attribute\n\t\ttypedef typename mpl::at_c<T, 0>::type p_key;\n\t\ttypedef typename mpl::at_c<T, 1>::type p_value;\n\n\t\t// for simple p_key type we just check that\n\t\t// such key can be found in attr and that value under that key\n\t\t// matches p_value\n\t\ttemplate <typename Key, typename Value, typename Map>\n\t\tstruct has_kv_in_map\n\t\t\t: mpl::eval_if<\n\t\t\t\tfusion::result_of::has_key<Map, Key>\n\t\t\t  , mpl::apply<\n\t\t\t\t\tis_substitute<\n\t\t\t\t\t\tfusion::result_of::value_at_key<mpl::_1, Key>\n\t\t\t\t\t  , Value>\n\t\t\t\t\t  , Map>\n\t\t\t  , mpl::false_>\n\t\t{};\n\n\t\t// if p_key is variant over multiple types (as a result of\n\t\t// \"(key1|key2|key3) >> p_value\" parser) check that all\n\t\t// keys are found in fusion::map attribute and that values\n\t\t// under these keys match p_value\n\t\ttemplate <typename Variant>\n\t\tstruct variant_kv\n\t\t\t: mpl::equal_to<\n\t\t\t\tmpl::size< typename Variant::types>\n\t\t\t  , mpl::size< mpl::filter_view<typename Variant::types\n\t\t\t  , has_kv_in_map<mpl::_1, p_value, Attribute>>>\n\t\t\t>\n\t\t{};\n\n\t\ttypedef typename\n\t\t\tmpl::eval_if<\n\t\t\t\tis_variant<p_key>\n\t\t\t  , variant_kv<p_key>\n\t\t\t  , has_kv_in_map<p_key, p_value, Attribute>\n\t\t\t>::type\n\t\ttype;\n\t};\n\n\ttemplate <typename T, typename Attribute>\n\tstruct is_substitute<std::optional<T>, std::optional<Attribute>>\n\t  : is_substitute<T, Attribute> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/is_variant.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM)\n#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM\n\n#include <boost/variant.hpp>\n#include <boost/mpl/has_xxx.hpp>\n#include <boost/mpl/bool.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\tnamespace detail\n\t{\n\t\t// By declaring a nested struct in your class/struct, you tell\n\t\t// spirit that it is regarded as a variant type. The minimum\n\t\t// required interface for such a variant is that it has constructors\n\t\t// for various types supported by your variant and a typedef 'types'\n\t\t// which is an mpl sequence of the contained types.\n\t\t//\n\t\t// This is an intrusive interface. For a non-intrusive interface,\n\t\t// use the is_variant trait.\n\t\tBOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)\n\t}\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_variant\n\t  : detail::has_adapted_variant_tag<T>\n\t{};\n\n\ttemplate <BOOST_VARIANT_ENUM_PARAMS(typename T)>\n\tstruct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>\n\t  : mpl::true_\n\t{};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/move_to.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)\n#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM\n\n#include \"attribute_category.hpp\"\n#include \"tuple_traits.hpp\"\n#include \"variant_has_substitute.hpp\"\n\n#include <boost/assert.hpp>\n#include <boost/fusion/include/is_sequence.hpp>\n#include <boost/fusion/include/front.hpp>\n#include <boost/fusion/include/move.hpp>\n#include <boost/fusion/include/is_sequence.hpp>\n#include <utility>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Source, typename Dest>\n\tinline void move_to(Source&& src, Dest& dest);\n\n\ttemplate <typename T>\n\tinline void move_to(T& src, T& dest);\n\n\ttemplate <typename T>\n\tinline void move_to(T const& src, T& dest);\n\n\ttemplate <typename T>\n\tinline void move_to(T&& src, T& dest);\n\n\ttemplate <typename Iterator, typename Dest>\n\tinline void move_to(Iterator first, Iterator last, Dest& dest);\n\n\ttemplate <typename Dest>\n\tinline void move_to(unused_type, Dest&) {}\n\n\ttemplate <typename Source>\n\tinline void move_to(Source&, unused_type) {}\n\n\tinline void move_to(unused_type, unused_type) {}\n\n\ttemplate <typename Iterator>\n\tinline void\n\tmove_to(Iterator, Iterator, unused_type) {}\n\n\tnamespace detail\n\t{\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source&, Dest&, unused_attribute) {}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to_plain(Source& src, Dest& dest, mpl::false_) // src is not a single-element tuple\n\t\t{\n\t\t\tdest = std::move(src);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to_plain(Source& src, Dest& dest, mpl::true_) // src is a single-element tuple\n\t\t{\n\t\t\tdest = std::move(fusion::front(src));\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source& src, Dest& dest, plain_attribute)\n\t\t{\n\t\t\ttypename mpl::and_<\n\t\t\t\tfusion::traits::is_sequence<Source>,\n\t\t\t\tis_size_one_sequence<Source> >\n\t\t\tis_single_element_sequence;\n\n\t\t\tmove_to_plain(src, dest, is_single_element_sequence);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline typename enable_if<is_container<Source>>::type\n\t\tmove_to(Source& src, Dest& dest, container_attribute)\n\t\t{\n\t\t\ttraits::move_to(src.begin(), src.end(), dest);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline typename enable_if<\n\t\t\tmpl::and_<\n\t\t\t\tis_same_size_sequence<Dest, Source>,\n\t\t\t\tmpl::not_<is_size_one_sequence<Dest> > >\n\t\t>::type\n\t\tmove_to(Source& src, Dest& dest, tuple_attribute)\n\t\t{\n\t\t\tfusion::move(std::move(src), dest);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline typename enable_if<\n\t\t\tis_size_one_sequence<Dest>\n\t\t>::type\n\t\tmove_to(Source& src, Dest& dest, tuple_attribute)\n\t\t{\n\t\t\ttraits::move_to(src, fusion::front(dest));\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source& src, Dest& dest, variant_attribute, mpl::false_)\n\t\t{\n\t\t\tdest = std::move(src);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::false_)\n\t\t{\n\t\t\t// dest is a variant, src is a single element fusion sequence that the variant\n\t\t\t// cannot directly hold. We'll try to unwrap the single element fusion sequence.\n\n\t\t\t// Make sure that the Dest variant can really hold Source\n\t\t\tstatic_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,\n\t\t\t\t\"Error! The destination variant (Dest) cannot hold the source type (Source)\");\n\n\t\t\tdest = std::move(fusion::front(src));\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::true_)\n\t\t{\n\t\t\t// dest is a variant, src is a single element fusion sequence that the variant\n\t\t\t// *can* directly hold.\n\t\t\tdest = std::move(src);\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source& src, Dest& dest, variant_attribute, mpl::true_)\n\t\t{\n\t\t\tmove_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source& src, Dest& dest, variant_attribute tag)\n\t\t{\n\t\t\tmove_to(src, dest, tag, is_size_one_sequence<Source>());\n\t\t}\n\n\t\ttemplate <typename Source, typename Dest>\n\t\tinline void\n\t\tmove_to(Source& src, Dest& dest, optional_attribute)\n\t\t{\n\t\t\tdest = std::move(src);\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tinline void\n\t\tmove_to(Iterator, Iterator, unused_type, unused_attribute) {}\n\n\t\ttemplate <typename Iterator, typename Dest>\n\t\tinline void\n\t\tmove_to(Iterator first, Iterator last, Dest& dest, container_attribute)\n\t\t{\n\t\t\tif (is_empty(dest))\n\t\t\t\tdest = Dest(first, last);\n\t\t\telse\n\t\t\t\tappend(dest, first, last);\n\t\t}\n\n\t\ttemplate <typename Iterator, typename Dest>\n\t\tinline typename enable_if<\n\t\t\tis_size_one_sequence<Dest>\n\t\t>::type\n\t\tmove_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)\n\t\t{\n\t\t\ttraits::move_to(first, last, fusion::front(dest));\n\t\t}\n\n\t\ttemplate <typename Iterator>\n\t\tinline void\n\t\tmove_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_attribute)\n\t\t{\n\t\t\trng = {first, last};\n\t\t}\n\t}\n\n\ttemplate <typename Source, typename Dest>\n\tinline void move_to(Source&& src, Dest& dest)\n\t{\n\t\tdetail::move_to(src, dest, typename attribute_category<Dest>::type());\n\t}\n\n\ttemplate <typename T>\n\tinline void move_to(T& src, T& dest)\n\t{\n\t\tBOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));\n\t\tdest = std::move(src);\n\t}\n\n\ttemplate <typename T>\n\tinline void move_to(T const& src, T& dest)\n\t{\n\t\tBOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));\n\t\tdest = src;\n\t}\n\n\ttemplate <typename T>\n\tinline void move_to(T&& src, T& dest)\n\t{\n\t\tBOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));\n\t\tdest = std::move(src);\n\t}\n\n\ttemplate <typename Iterator, typename Dest>\n\tinline void move_to(Iterator first, Iterator last, Dest& dest)\n\t{\n\t\t// $$$ Use std::move_iterator when iterator is not a const-iterator $$$\n\t\tdetail::move_to(first, last, dest, typename attribute_category<Dest>::type());\n\t}\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/numeric_traits.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM)\n#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM\n\n#include <boost/config.hpp>\n#include <boost/mpl/bool.hpp>\n#include <limits>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Determine if T is a boolean type\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct is_bool : mpl::false_ {};\n\n\ttemplate <typename T>\n\tstruct is_bool<T const> : is_bool<T> {};\n\n\ttemplate <>\n\tstruct is_bool<bool> : mpl::true_ {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Determine if T is a signed integer type\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct is_int : mpl::false_ {};\n\n\ttemplate <typename T>\n\tstruct is_int<T const> : is_int<T> {};\n\n\ttemplate <>\n\tstruct is_int<short> : mpl::true_ {};\n\n\ttemplate <>\n\tstruct is_int<int> : mpl::true_ {};\n\n\ttemplate <>\n\tstruct is_int<long> : mpl::true_ {};\n\n#ifdef BOOST_HAS_LONG_LONG\n\ttemplate <>\n\tstruct is_int<boost::long_long_type> : mpl::true_ {};\n#endif\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Determine if T is an unsigned integer type\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct is_uint : mpl::false_ {};\n\n\ttemplate <typename T>\n\tstruct is_uint<T const> : is_uint<T> {};\n\n#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)\n\ttemplate <>\n\tstruct is_uint<unsigned short> : mpl::true_ {};\n#endif\n\n\ttemplate <>\n\tstruct is_uint<unsigned int> : mpl::true_ {};\n\n\ttemplate <>\n\tstruct is_uint<unsigned long> : mpl::true_ {};\n\n#ifdef BOOST_HAS_LONG_LONG\n\ttemplate <>\n\tstruct is_uint<boost::ulong_long_type> : mpl::true_ {};\n#endif\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Determine if T is a floating point type\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct is_real : mpl::false_ {};\n\n\ttemplate <typename T>\n\tstruct is_real<T const> : is_uint<T> {};\n\n\ttemplate <>\n\tstruct is_real<float> : mpl::true_ {};\n\n\ttemplate <>\n\tstruct is_real<double> : mpl::true_ {};\n\n\ttemplate <>\n\tstruct is_real<long double> : mpl::true_ {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// customization points for numeric operations\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, typename Enable = void>\n\tstruct absolute_value;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_negative;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_zero;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct pow10_helper;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_nan;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_infinite;\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct check_overflow : mpl::bool_<std::numeric_limits<T>::is_bounded> {};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/optional_traits.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)\n#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM\n\n#include \"../unused.hpp\"\n#include <boost/mpl/identity.hpp>\n#include <optional>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T, typename Enable = void>\n\tstruct is_optional\n\t  : mpl::false_\n\t{};\n\n\ttemplate <typename T>\n\tstruct is_optional<std::optional<T>>\n\t  : mpl::true_\n\t{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// build_optional\n\t//\n\t// Build a std::optional from T. Return unused_type if T is unused_type.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct build_optional\n\t{\n\t\ttypedef std::optional<T> type;\n\t};\n\n\ttemplate <typename T>\n\tstruct build_optional<std::optional<T> >\n\t{\n\t\ttypedef std::optional<T> type;\n\t};\n\n\ttemplate <>\n\tstruct build_optional<unused_type>\n\t{\n\t\ttypedef unused_type type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// optional_value\n\t//\n\t// Get the optional's value_type. Handles unused_type as well.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename T>\n\tstruct optional_value : mpl::identity<T> {};\n\n\ttemplate <typename T>\n\tstruct optional_value<std::optional<T> >\n\t  : mpl::identity<T> {};\n\n\ttemplate <>\n\tstruct optional_value<unused_type>\n\t  : mpl::identity<unused_type> {};\n\n\ttemplate <>\n\tstruct optional_value<unused_type const>\n\t  : mpl::identity<unused_type> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/print_attribute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n================================================_==============================*/\n#if !defined(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)\n#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM\n\n#include <boost/variant.hpp>\n#include <boost/fusion/include/is_sequence.hpp>\n#include <boost/fusion/include/for_each.hpp>\n#include \"attribute_category.hpp\"\n#include \"is_variant.hpp\"\n#ifdef BOOST_SPIRIT_X3_UNICODE\n#include \"../../../support/char_encoding/unicode.hpp\"\n#endif\n#include <optional>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Out, typename T>\n\tvoid print_attribute(Out& out, T const& val);\n\n\ttemplate <typename Out>\n\tinline void print_attribute(Out&, unused_type) {}\n\n\t///////////////////////////////////////////////////////////////////////////\n\tnamespace detail\n\t{\n\t\ttemplate <typename Out>\n\t\tstruct print_fusion_sequence\n\t\t{\n\t\t\tprint_fusion_sequence(Out& out)\n\t\t\t  : out(out), is_first(true) {}\n\n\t\t\ttypedef void result_type;\n\n\t\t\ttemplate <typename T>\n\t\t\tvoid operator()(T const& val) const\n\t\t\t{\n\t\t\t\tif (is_first)\n\t\t\t\t\tis_first = false;\n\t\t\t\telse\n\t\t\t\t\tout << \", \";\n\t\t\t\tx3::traits::print_attribute(out, val);\n\t\t\t}\n\n\t\t\tOut& out;\n\t\t\tmutable bool is_first;\n\t\t};\n\n\t\t// print elements in a variant\n\t\ttemplate <typename Out>\n\t\tstruct print_visitor : static_visitor<>\n\t\t{\n\t\t\tprint_visitor(Out& out) : out(out) {}\n\n\t\t\ttemplate <typename T>\n\t\t\tvoid operator()(T const& val) const\n\t\t\t{\n\t\t\t\tx3::traits::print_attribute(out, val);\n\t\t\t}\n\n\t\t\tOut& out;\n\t\t};\n\t}\n\n\ttemplate <typename Out, typename T, typename Enable = void>\n\tstruct print_attribute_debug\n\t{\n\t\t// for unused_type\n\t\tstatic void call(Out& out, unused_type, unused_attribute)\n\t\t{\n\t\t\tout << \"unused\";\n\t\t}\n\n\t\t// for plain data types\n\t\ttemplate <typename T_>\n\t\tstatic void call(Out& out, T_ const& val, plain_attribute)\n\t\t{\n\t\t\tout << val;\n\t\t}\n\n#ifdef BOOST_SPIRIT_X3_UNICODE\n\t\tstatic void call(Out& out, char_encoding::unicode::char_type val, plain_attribute)\n\t\t{\n\t\t\tif (val >= 0 && val < 127)\n\t\t\t{\n\t\t\t  if (iscntrl(val))\n\t\t\t\tout << \"\\\\\" << std::oct << int(val) << std::dec;\n\t\t\t  else if (isprint(val))\n\t\t\t\tout << char(val);\n\t\t\t  else\n\t\t\t\tout << \"\\\\x\" << std::hex << int(val) << std::dec;\n\t\t\t}\n\t\t\telse\n\t\t\t  out << \"\\\\x\" << std::hex << int(val) << std::dec;\n\t\t}\n\n\t\tstatic void call(Out& out, char val, plain_attribute tag)\n\t\t{\n\t\t\tcall(out, static_cast<char_encoding::unicode::char_type>(val), tag);\n\t\t}\n#endif\n\n\t\t// for fusion data types\n\t\ttemplate <typename T_>\n\t\tstatic void call(Out& out, T_ const& val, tuple_attribute)\n\t\t{\n\t\t\tout << '[';\n\t\t\tfusion::for_each(val, detail::print_fusion_sequence<Out>(out));\n\t\t\tout << ']';\n\t\t}\n\n\t\t// stl container\n\t\ttemplate <typename T_>\n\t\tstatic void call(Out& out, T_ const& val, container_attribute)\n\t\t{\n\t\t\tout << '[';\n\t\t\tif (!traits::is_empty(val))\n\t\t\t{\n\t\t\t\tbool first = true;\n\t\t\t\ttypename container_iterator<T_ const>::type iend = traits::end(val);\n\t\t\t\tfor (typename container_iterator<T_ const>::type i = traits::begin(val);\n\t\t\t\t\t !traits::compare(i, iend); traits::next(i))\n\t\t\t\t{\n\t\t\t\t\tif (!first)\n\t\t\t\t\t\tout << \", \";\n\t\t\t\t\tfirst = false;\n\t\t\t\t\tx3::traits::print_attribute(out, traits::deref(i));\n\t\t\t\t}\n\t\t\t}\n\t\t\tout << ']';\n\t\t}\n\n\t\t// for variant types\n\t\ttemplate <typename T_>\n\t\tstatic void call(Out& out, T_ const& val, variant_attribute)\n\t\t{\n\t\t\tapply_visitor(detail::print_visitor<Out>(out), val);\n\t\t}\n\n\t\t// for optional types\n\t\ttemplate <typename T_>\n\t\tstatic void call(Out& out, T_ const& val, optional_attribute)\n\t\t{\n\t\t\tif (val)\n\t\t\t\tx3::traits::print_attribute(out, *val);\n\t\t\telse\n\t\t\t\tout << \"[empty]\";\n\t\t}\n\n\t\t// main entry point\n\t\tstatic void call(Out& out, T const& val)\n\t\t{\n\t\t\tcall(out, val, typename attribute_category<T>::type());\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Out, typename T>\n\tinline void print_attribute(Out& out, T const& val)\n\t{\n\t\tprint_attribute_debug<Out, T>::call(out, val);\n\t}\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/print_token.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n================================================_==============================*/\n#if !defined(BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)\n#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM\n\n#include <boost/mpl/if.hpp>\n#include <boost/mpl/and.hpp>\n#include <boost/type_traits/is_convertible.hpp>\n#include <cctype>\n#include <ios>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// generate debug output for lookahead token (character) stream\n\tnamespace detail\n\t{\n\t\tstruct token_printer_debug_for_chars\n\t\t{\n\t\t\ttemplate<typename Out, typename Char>\n\t\t\tstatic void print(Out& o, Char c)\n\t\t\t{\n\t\t\t\tusing namespace std;    // allow for ADL to find the proper iscntrl\n\n\t\t\t\tswitch (c)\n\t\t\t\t{\n\t\t\t\t\tcase '\\a': o << \"\\\\a\"; break;\n\t\t\t\t\tcase '\\b': o << \"\\\\b\"; break;\n\t\t\t\t\tcase '\\f': o << \"\\\\f\"; break;\n\t\t\t\t\tcase '\\n': o << \"\\\\n\"; break;\n\t\t\t\t\tcase '\\r': o << \"\\\\r\"; break;\n\t\t\t\t\tcase '\\t': o << \"\\\\t\"; break;\n\t\t\t\t\tcase '\\v': o << \"\\\\v\"; break;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (c >= 0 && c < 127)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t  if (iscntrl(c))\n\t\t\t\t\t\t\to << \"\\\\\" << std::oct << int(c);\n\t\t\t\t\t\t  else if (isprint(c))\n\t\t\t\t\t\t\to << char(c);\n\t\t\t\t\t\t  else\n\t\t\t\t\t\t\to << \"\\\\x\" << std::hex << int(c);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t  o << \"\\\\x\" << std::hex << int(c);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// for token types where the comparison with char constants wouldn't work\n\t\tstruct token_printer_debug\n\t\t{\n\t\t\ttemplate<typename Out, typename T>\n\t\t\tstatic void print(Out& o, T const& val)\n\t\t\t{\n\t\t\t\to << val;\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate <typename T, typename Enable = void>\n\tstruct token_printer_debug\n\t  : mpl::if_<\n\t\t\tmpl::and_<\n\t\t\t\tis_convertible<T, char>, is_convertible<char, T> >\n\t\t  , detail::token_printer_debug_for_chars\n\t\t  , detail::token_printer_debug>::type\n\t{};\n\n\ttemplate <typename Out, typename T>\n\tinline void print_token(Out& out, T const& val)\n\t{\n\t\t// allow to customize the token printer routine\n\t\ttoken_printer_debug<T>::print(out, val);\n\t}\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/pseudo_attribute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2019 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM)\n#define BOOST_SPIRIT_X3_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM\n\n#include <utility>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Pseudo attributes are placeholders for parsers that can only know\n\t// its actual attribute at parse time. This trait customization point\n\t// provides a mechanism to convert the trait to the actual trait at\n\t// parse time.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Context, typename Attribute, typename Iterator\n\t  , typename Enable = void>\n\tstruct pseudo_attribute\n\t{\n\t\tusing attribute_type = Attribute;\n\t\tusing type = Attribute;\n\n\t\tstatic type&& call(Iterator&, Iterator const&, attribute_type&& attribute)\n\t\t{\n\t\t\treturn std::forward<type>(attribute);\n\t\t}\n\t};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/string_traits.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\tCopyright (c)      2010 Bryce Lelbach\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n================================================_==============================*/\n#if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)\n#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM\n\n#include <string>\n#include <boost/mpl/bool.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t// Get the C string from a string\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename String>\n\tstruct extract_c_string;\n\n\ttemplate <typename String>\n\tstruct extract_c_string\n\t{\n\t\ttemplate <typename T>\n\t\tstatic T const* call (T* str)\n\t\t{\n\t\t\treturn (T const*)str;\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tstatic T const* call (T const* str)\n\t\t{\n\t\t\treturn str;\n\t\t}\n\t};\n\n\t// Forwarder that strips const\n\ttemplate <typename T>\n\tstruct extract_c_string<T const>\n\t{\n\t\tstatic decltype(auto) call(T const str)\n\t\t{\n\t\t\treturn extract_c_string<T>::call(str);\n\t\t}\n\t};\n\n\t// Forwarder that strips references\n\ttemplate <typename T>\n\tstruct extract_c_string<T&>\n\t{\n\t\tstatic decltype(auto) call(T& str)\n\t\t{\n\t\t\treturn extract_c_string<T>::call(str);\n\t\t}\n\t};\n\n\t// Forwarder that strips const references\n\ttemplate <typename T>\n\tstruct extract_c_string<T const&>\n\t{\n\t\tstatic decltype(auto) call(T const& str)\n\t\t{\n\t\t\treturn extract_c_string<T>::call(str);\n\t\t}\n\t};\n\n\ttemplate <typename T, typename Traits, typename Allocator>\n\tstruct extract_c_string<std::basic_string<T, Traits, Allocator> >\n\t{\n\t\ttypedef std::basic_string<T, Traits, Allocator> string;\n\n\t\tstatic T const* call (string const& str)\n\t\t{\n\t\t\treturn str.c_str();\n\t\t}\n\t};\n\n\ttemplate <typename T>\n\tdecltype(auto) get_c_string(T* str)\n\t{\n\t\treturn extract_c_string<T*>::call(str);\n\t}\n\n\ttemplate <typename T>\n\tdecltype(auto) get_c_string(T const* str)\n\t{\n\t\treturn extract_c_string<T const*>::call(str);\n\t}\n\n\ttemplate <typename String>\n\tdecltype(auto) get_c_string(String& str)\n\t{\n\t\treturn extract_c_string<String>::call(str);\n\t}\n\n\ttemplate <typename String>\n\tdecltype(auto) get_c_string(String const& str)\n\t{\n\t\treturn extract_c_string<String>::call(str);\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Get the begin/end iterators from a string\n\t///////////////////////////////////////////////////////////////////////////\n\n\t// Implementation for C-style strings.\n\n\ttemplate <typename T>\n\tinline T const* get_string_begin(T const* str) { return str; }\n\n\ttemplate <typename T>\n\tinline T* get_string_begin(T* str) { return str; }\n\n\ttemplate <typename T>\n\tinline T const* get_string_end(T const* str)\n\t{\n\t\tT const* last = str;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn last;\n\t}\n\n\ttemplate <typename T>\n\tinline T* get_string_end(T* str)\n\t{\n\t\tT* last = str;\n\t\twhile (*last)\n\t\t\tlast++;\n\t\treturn last;\n\t}\n\n\t// Implementation for containers (includes basic_string).\n\ttemplate <typename T, typename Str>\n\tinline auto get_string_begin(Str const& str) -> decltype(str.begin())\n\t{ return str.begin(); }\n\n\ttemplate <typename T, typename Str>\n\tinline auto get_string_begin(Str& str) -> decltype(str.begin())\n\t{ return str.begin(); }\n\n\ttemplate <typename T, typename Str>\n\tinline auto get_string_end(Str const& str) -> decltype(str.end())\n\t{ return str.end(); }\n\n\ttemplate <typename T, typename Str>\n\tinline auto get_string_end(Str& str) -> decltype(str.end())\n\t{ return str.end(); }\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/transform_attribute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2012 Hartmut Kaiser\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM)\n#define BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM\n\n#include <boost/mpl/identity.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  transform_attribute\n\t//\n\t//  Sometimes the user needs to transform the attribute types for certain\n\t//  attributes. This template can be used as a customization point, where\n\t//  the user is able specify specific transformation rules for any attribute\n\t//  type.\n\t///////////////////////////////////////////////////////////////////////////\n\ttemplate <typename Exposed, typename Transformed, typename Tag\n\t  , typename Enable = void>\n\tstruct transform_attribute;\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/tuple_traits.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n================================================_==============================*/\n#if !defined(BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM)\n#define BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM\n\n#include <boost/fusion/include/is_sequence.hpp>\n#include <boost/fusion/include/is_view.hpp>\n#include <boost/fusion/include/size.hpp>\n#include <boost/mpl/bool.hpp>\n#include <boost/mpl/and.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename A, typename B>\n\tstruct has_same_size\n\t  : mpl::bool_<(\n\t\t\tfusion::result_of::size<A>::value ==\n\t\t\tfusion::result_of::size<B>::value\n\t\t)>\n\t{};\n\n\ttemplate <typename T, std::size_t N>\n\tstruct has_size\n\t  : mpl::bool_<(fusion::result_of::size<T>::value == N)>\n\t{};\n\n\ttemplate <typename A, typename B>\n\tstruct is_same_size_sequence\n\t  : mpl::and_<\n\t\t\tfusion::traits::is_sequence<A>\n\t\t  , fusion::traits::is_sequence<B>\n\t\t  , has_same_size<A, B>\n\t\t>\n\t{};\n\n\ttemplate <typename Seq>\n\tstruct is_size_one_sequence\n\t  : mpl::and_<\n\t\t\tfusion::traits::is_sequence<Seq>\n\t\t  , has_size<Seq, 1>\n\t\t>\n\t{};\n\n\ttemplate <typename View>\n\tstruct is_size_one_view\n\t  : mpl::and_<\n\t\t\tfusion::traits::is_view<View>\n\t\t  , has_size<View, 1>\n\t\t>\n\t{};\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/variant_find_substitute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM)\n#define BOOST_SPIRIT_X3_VARIANT_FIND_SUBSTITUTE_APR_18_2014_930AM\n\n#include \"is_substitute.hpp\"\n#include <boost/mpl/find.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Variant, typename T>\n\tstruct variant_find_substitute\n\t{\n\t\t// Get the type from the Variant that can be a substitute for T.\n\t\t// If none is found, just return T\n\n\t\ttypedef Variant variant_type;\n\t\ttypedef typename variant_type::types types;\n\t\ttypedef typename mpl::end<types>::type end;\n\n\t\ttypedef typename mpl::find<types, T>::type iter_1;\n\n\t\ttypedef typename\n\t\t\tmpl::eval_if<\n\t\t\t\tis_same<iter_1, end>,\n\t\t\t\tmpl::find_if<types, traits::is_substitute<T, mpl::_1> >,\n\t\t\t\tmpl::identity<iter_1>\n\t\t\t>::type\n\t\titer;\n\n\t\ttypedef typename\n\t\t\tmpl::eval_if<\n\t\t\t\tis_same<iter, end>,\n\t\t\t\tmpl::identity<T>,\n\t\t\t\tmpl::deref<iter>\n\t\t\t>::type\n\t\ttype;\n\t};\n\n\ttemplate <typename Variant>\n\tstruct variant_find_substitute<Variant, Variant>\n\t\t: mpl::identity<Variant> {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/traits/variant_has_substitute.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\thttp://spirit.sourceforge.net/\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM)\n#define BOOST_SPIRIT_X3_VARIANT_HAS_SUBSTITUTE_APR_18_2014_925AM\n\n#include \"is_substitute.hpp\"\n#include <boost/mpl/find.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace traits\n{\n\ttemplate <typename Variant, typename T>\n\tstruct variant_has_substitute_impl\n\t{\n\t\t// Find a type from the Variant that can be a substitute for T.\n\t\t// return true_ if one is found, else false_\n\n\t\ttypedef Variant variant_type;\n\t\ttypedef typename variant_type::types types;\n\t\ttypedef typename mpl::end<types>::type end;\n\n\t\ttypedef typename mpl::find<types, T>::type iter_1;\n\n\t\ttypedef typename\n\t\t\tmpl::eval_if<\n\t\t\t\tis_same<iter_1, end>,\n\t\t\t\tmpl::find_if<types, traits::is_substitute<T, mpl::_1>>,\n\t\t\t\tmpl::identity<iter_1>\n\t\t\t>::type\n\t\titer;\n\n\t\ttypedef mpl::not_<is_same<iter, end>> type;\n\t};\n\n\ttemplate <typename Variant, typename T>\n\tstruct variant_has_substitute\n\t\t: variant_has_substitute_impl<Variant, T>::type {};\n\n\ttemplate <typename T>\n\tstruct variant_has_substitute<unused_type, T> : mpl::true_ {};\n\n\ttemplate <typename T>\n\tstruct variant_has_substitute<unused_type const, T> : mpl::true_ {};\n\n}}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/unused.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2001-2011 Hartmut Kaiser\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM)\n#define BOOST_SPIRIT_X3_UNUSED_APRIL_16_2006_0616PM\n\n#include <iosfwd>\n\n///////////////////////////////////////////////////////////////////////////////\nnamespace boost { namespace spirit { namespace x3\n{\n\tstruct unused_type\n\t{\n\t\tunused_type() = default;\n\n\t\ttemplate <typename T>\n\t\tunused_type(T const&)\n\t\t{\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tunused_type const&\n\t\toperator=(T const&) const\n\t\t{\n\t\t\treturn *this;\n\t\t}\n\n\t\ttemplate <typename T>\n\t\tunused_type&\n\t\toperator=(T const&)\n\t\t{\n\t\t\treturn *this;\n\t\t}\n\n\t\tfriend std::ostream& operator<<(std::ostream& out, unused_type const&)\n\t\t{\n\t\t\treturn out;\n\t\t}\n\n\t\tfriend std::istream& operator>>(std::istream& in, unused_type&)\n\t\t{\n\t\t\treturn in;\n\t\t}\n\t};\n\n\tconstexpr auto unused = unused_type{};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/annotate_on_success.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2015 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n=============================================================================*/\n#if !defined(BOOST_SPIRIT_X3__ANNOTATE_ON_SUCCESS_HPP)\n#define BOOST_SPIRIT_X3__ANNOTATE_ON_SUCCESS_HPP\n\n#include \"../ast/variant.hpp\"\n#include \"../context.hpp\"\n#include \"error_reporting.hpp\"\n#include \"lambda_visitor.hpp\"\n#include \"../traits/is_variant.hpp\"\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t///////////////////////////////////////////////////////////////////////////\n\t//  The on_success handler tags the AST with the iterator position\n\t//  for error handling.\n\t//\n\t//  The on_success handler also ties the AST to a vector of iterator\n\t//  positions for the purpose of subsequent semantic error handling\n\t//  when the program is being compiled. See x3::position_cache in\n\t//  x3/support/ast.\n\t//\n\t//  We'll ask the X3's error_handler utility to do these.\n\t///////////////////////////////////////////////////////////////////////////\n\n\tstruct annotate_on_success\n\t{\n\t\ttemplate <typename Iterator, typename Context, typename... Types>\n\t\tinline void on_success(Iterator const& first, Iterator const& last\n\t\t  , variant<Types...>& ast, Context const& context)\n\t\t{\n\t\t\tast.apply_visitor(x3::make_lambda_visitor<void>([&](auto& node)\n\t\t\t{\n\t\t\t\tthis->on_success(first, last, node, context);\n\t\t\t}));\n\t\t}\n\n\t\ttemplate <typename T, typename Iterator, typename Context>\n\t\tinline void on_success(Iterator const& first, Iterator const& last\n\t\t  , forward_ast<T>& ast, Context const& context)\n\t\t{\n\t\t\tthis->on_success(first, last, ast.get(), context);\n\t\t}\n\n\t\ttemplate <typename T, typename Iterator, typename Context>\n\t\tinline typename disable_if<traits::is_variant<T>>::type on_success(Iterator const& first, Iterator const& last\n\t\t  , T& ast, Context const& context)\n\t\t{\n\t\t\tauto& error_handler = x3::get<error_handler_tag>(context).get();\n\t\t\terror_handler.tag(ast, first, last);\n\t\t}\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/error_reporting.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM)\n#define BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM\n\n#include \"../ast/position_tagged.hpp\"\n#include \"utf8.hpp\"\n#include <ostream>\n\n// Clang-style error handling utilities\n\nnamespace boost { namespace spirit { namespace x3\n{\n\t// tag used to get our error handler from the context\n\tstruct error_handler_tag;\n\n\ttemplate <typename Iterator>\n\tclass error_handler\n\t{\n\tpublic:\n\n\t\ttypedef Iterator iterator_type;\n\n\t\terror_handler(\n\t\t\tIterator first, Iterator last, std::ostream& err_out\n\t\t  , std::string file = \"\", int tabs = 4)\n\t\t  : err_out(err_out)\n\t\t  , file(file)\n\t\t  , tabs(tabs)\n\t\t  , pos_cache(first, last) {}\n\n\t\ttypedef void result_type;\n\n\t\tvoid operator()(Iterator err_pos, std::string const& error_message) const;\n\t\tvoid operator()(Iterator err_first, Iterator err_last, std::string const& error_message) const;\n\t\tvoid operator()(position_tagged pos, std::string const& message) const\n\t\t{\n\t\t\tauto where = pos_cache.position_of(pos);\n\t\t\t(*this)(where.begin(), where.end(), message);\n\t\t}\n\n\t\ttemplate <typename AST>\n\t\tvoid tag(AST& ast, Iterator first, Iterator last)\n\t\t{\n\t\t\treturn pos_cache.annotate(ast, first, last);\n\t\t}\n\n\t\tboost::iterator_range<Iterator> position_of(position_tagged pos) const\n\t\t{\n\t\t\treturn pos_cache.position_of(pos);\n\t\t}\n\n\t\tposition_cache<std::vector<Iterator>> const& get_position_cache() const\n\t\t{\n\t\t\treturn pos_cache;\n\t\t}\n\n\tprivate:\n\n\t\tvoid print_file_line(std::size_t line) const;\n\t\tvoid print_line(Iterator line_start, Iterator last) const;\n\t\tvoid print_indicator(Iterator& line_start, Iterator last, char ind) const;\n\t\tIterator get_line_start(Iterator first, Iterator pos) const;\n\t\tstd::size_t position(Iterator i) const;\n\n\t\tstd::ostream& err_out;\n\t\tstd::string file;\n\t\tint tabs;\n\t\tposition_cache<std::vector<Iterator>> pos_cache;\n\t};\n\n\ttemplate <typename Iterator>\n\tvoid error_handler<Iterator>::print_file_line(std::size_t line) const\n\t{\n\t\tif (file != \"\")\n\t\t{\n\t\t\terr_out << \"In file \" << file << \", \";\n\t\t}\n\t\telse\n\t\t{\n\t\t\terr_out << \"In \";\n\t\t}\n\n\t\terr_out << \"line \" << line << ':' << std::endl;\n\t}\n\n\ttemplate <typename Iterator>\n\tvoid error_handler<Iterator>::print_line(Iterator start, Iterator last) const\n\t{\n\t\tauto end = start;\n\t\twhile (end != last)\n\t\t{\n\t\t\tauto c = *end;\n\t\t\tif (c == '\\r' || c == '\\n')\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\t++end;\n\t\t}\n\t\ttypedef typename std::iterator_traits<Iterator>::value_type char_type;\n\t\tstd::basic_string<char_type> line{start, end};\n\t\terr_out << x3::to_utf8(line) << std::endl;\n\t}\n\n\ttemplate <typename Iterator>\n\tvoid error_handler<Iterator>::print_indicator(Iterator& start, Iterator last, char ind) const\n\t{\n\t\tfor (; start != last; ++start)\n\t\t{\n\t\t\tauto c = *start;\n\t\t\tif (c == '\\r' || c == '\\n')\n\t\t\t\tbreak;\n\t\t\telse if (c == '\\t')\n\t\t\t\tfor (int i = 0; i < tabs; ++i)\n\t\t\t\t\terr_out << ind;\n\t\t\telse\n\t\t\t\terr_out << ind;\n\t\t}\n\t}\n\n\ttemplate <class Iterator>\n\tinline Iterator error_handler<Iterator>::get_line_start(Iterator first, Iterator pos) const\n\t{\n\t\tIterator latest = first;\n\t\tfor (Iterator i = first; i != pos;)\n\t\t\tif (*i == '\\r' || *i == '\\n')\n\t\t\t\tlatest = ++i;\n\t\t\telse\n\t\t\t\t++i;\n\t\treturn latest;\n\t}\n\n\ttemplate <typename Iterator>\n\tstd::size_t error_handler<Iterator>::position(Iterator i) const\n\t{\n\t\tstd::size_t line { 1 };\n\t\ttypename std::iterator_traits<Iterator>::value_type prev { 0 };\n\n\t\tfor (Iterator pos = pos_cache.first(); pos != i; ++pos) {\n\t\t\tauto c = *pos;\n\t\t\tswitch (c) {\n\t\t\tcase '\\n':\n\t\t\t\tif (prev != '\\r') ++line;\n\t\t\t\tbreak;\n\t\t\tcase '\\r':\n\t\t\t\t++line;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tprev = c;\n\t\t}\n\n\t\treturn line;\n\t}\n\n\ttemplate <typename Iterator>\n\tvoid error_handler<Iterator>::operator()(\n\t\tIterator err_pos, std::string const& error_message) const\n\t{\n\t\tIterator first = pos_cache.first();\n\t\tIterator last = pos_cache.last();\n\n\t\tprint_file_line(position(err_pos));\n\t\terr_out << error_message << std::endl;\n\n\t\tIterator start = get_line_start(first, err_pos);\n\t\tprint_line(start, last);\n\t\tprint_indicator(start, err_pos, '_');\n\t\terr_out << \"^_\" << std::endl;\n\t}\n\n\ttemplate <typename Iterator>\n\tvoid error_handler<Iterator>::operator()(\n\t\tIterator err_first, Iterator err_last, std::string const& error_message) const\n\t{\n\t\tIterator first = pos_cache.first();\n\t\tIterator last = pos_cache.last();\n\n\t\tprint_file_line(position(err_first));\n\t\terr_out << error_message << std::endl;\n\n\t\tIterator start = get_line_start(first, err_first);\n\t\tprint_line(start, last);\n\t\tprint_indicator(start, err_first, ' ');\n\t\tprint_indicator(start, err_last, '~');\n\t\terr_out << \" <<-- Here\" << std::endl;\n\t}\n\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/is_callable.hpp",
    "content": "/*//////////////////////////////////////////////////////////////////////////////\n\tCopyright (c) 2014 Jamboree\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//////////////////////////////////////////////////////////////////////////////*/\n#ifndef BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED\n#define BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED\n\n#include <boost/mpl/bool.hpp>\n\nnamespace boost { namespace spirit { namespace x3 { namespace detail\n{\n\ttemplate <typename Sig, typename Enable = void>\n\tstruct is_callable_impl : mpl::false_ {};\n\n\ttemplate <typename F, typename... A>\n\tstruct is_callable_impl<F(A...),\n\t\tdecltype(void(std::declval<F>()(std::declval<A>()...)))>\n\t  : mpl::true_\n\t{};\n}}}}\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Sig>\n\tstruct is_callable;\n\n\ttemplate <typename F, typename... A>\n\tstruct is_callable<F(A...)> : detail::is_callable_impl<F(A...)> {};\n}}}\n\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/lambda_visitor.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2014 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM)\n#define BOOST_SPIRIT_X3_LAMBDA_VISITOR_MAY_19_2014_1116AM\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename RT, typename... Lambdas>\n\tstruct lambda_visitor;\n\n\ttemplate <typename RT, typename F, typename... Lambdas>\n\tstruct lambda_visitor<RT, F, Lambdas...> : F, lambda_visitor<RT, Lambdas...>\n\t{\n\t\ttypedef lambda_visitor<RT , Lambdas...> base_type;\n\t\tusing F::operator();\n\t\tusing base_type::operator();\n\t\tlambda_visitor(F f, Lambdas... lambdas)\n\t\t  : F(f), base_type(lambdas...)\n\t\t{}\n\t};\n\n\ttemplate <typename RT, typename F>\n\tstruct lambda_visitor<RT, F> : F\n\t{\n\t\ttypedef RT result_type;\n\t\tusing F::operator();\n\t\tlambda_visitor(F f)\n\t\t  : F(f)\n\t\t{}\n\t};\n\n\ttemplate <typename RT>\n\tstruct lambda_visitor<RT>\n\t{\n\t\ttypedef RT result_type;\n\t};\n\n\ttemplate <typename RT, typename... Lambdas>\n\tlambda_visitor<RT, Lambdas...> make_lambda_visitor(Lambdas... lambdas)\n\t{\n\t\treturn { lambdas... };\n\t}\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/sfinae.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2013 Agustin Berge\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM)\n#define BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttemplate <typename Expr, typename T = void>\n\tstruct disable_if_substitution_failure\n\t{\n\t\ttypedef T type;\n\t};\n\n\ttemplate <typename Expr, typename T>\n\tstruct lazy_disable_if_substitution_failure\n\t{\n\t\ttypedef typename T::type type;\n\t};\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/support/utility/utf8.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2014 Joel de Guzman\n\tCopyright (c) 2023 Nikita Kniazev\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)\n#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM\n\n#include <boost/config.hpp>\n#include <type_traits>\n#include <string>\n\nnamespace boost { namespace spirit { namespace x3\n{\n\ttypedef char32_t ucs4_char;\n\ttypedef char utf8_char;\n\ttypedef std::basic_string<ucs4_char> ucs4_string;\n\ttypedef std::basic_string<utf8_char> utf8_string;\n\nnamespace detail {\n\tinline void utf8_put_encode(utf8_string& out, ucs4_char x)\n\t{\n\t\t// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf D90\n\t\tif (BOOST_UNLIKELY(x > 0x10FFFFul || (0xD7FFul < x && x < 0xE000ul)))\n\t\t\tx = 0xFFFDul;\n\n\t\t// Table 3-6. UTF-8 Bit Distribution\n\t\tif (x < 0x80ul) {\n\t\t\tout.push_back(static_cast<unsigned char>(x));\n\t\t}\n\t\telse if (x < 0x800ul) {\n\t\t\tout.push_back(static_cast<unsigned char>(0xC0ul + (x >> 6)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));\n\t\t}\n\t\telse if (x < 0x10000ul) {\n\t\t\tout.push_back(static_cast<unsigned char>(0xE0ul + (x >> 12)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));\n\t\t}\n\t\telse {\n\t\t\tout.push_back(static_cast<unsigned char>(0xF0ul + (x >> 18)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + ((x >> 12) & 0x3Ful)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));\n\t\t\tout.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));\n\t\t}\n\t}\n}\n\n\ttemplate <typename Char>\n\tinline utf8_string to_utf8(Char value)\n\t{\n\t\tutf8_string result;\n\t\ttypedef typename std::make_unsigned<Char>::type UChar;\n\t\tdetail::utf8_put_encode(result, static_cast<UChar>(value));\n\t\treturn result;\n\t}\n\n\ttemplate <typename Char>\n\tinline utf8_string to_utf8(Char const* str)\n\t{\n\t\tutf8_string result;\n\t\ttypedef typename std::make_unsigned<Char>::type UChar;\n\t\twhile (*str)\n\t\t\tdetail::utf8_put_encode(result, static_cast<UChar>(*str++));\n\t\treturn result;\n\t}\n\n\ttemplate <typename Char, typename Traits, typename Allocator>\n\tinline utf8_string\n\tto_utf8(std::basic_string<Char, Traits, Allocator> const& str)\n\t{\n\t\tutf8_string result;\n\t\ttypedef typename std::make_unsigned<Char>::type UChar;\n\t\tfor (Char ch : str)\n\t\t\tdetail::utf8_put_encode(result, static_cast<UChar>(ch));\n\t\treturn result;\n\t}\n\n\t// Assume wchar_t content is UTF-16 on MSVC, or mingw/wineg++ with -fshort-wchar\n#if defined(_MSC_VER) || defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2\n\tinline utf8_string to_utf8(wchar_t value)\n\t{\n\t\tutf8_string result;\n\t\tdetail::utf8_put_encode(result, static_cast<std::make_unsigned<wchar_t>::type>(value));\n\t\treturn result;\n\t}\n\nnamespace detail {\n\tinline ucs4_char decode_utf16(wchar_t const*& s)\n\t{\n\t\ttypedef std::make_unsigned<wchar_t>::type uwchar_t;\n\n\t\tuwchar_t x(*s);\n\t\tif (x < 0xD800ul || x > 0xDFFFul)\n\t\t\treturn x;\n\n\t\t// expected high-surrogate\n\t\tif (BOOST_UNLIKELY((x >> 10) != 0b110110ul))\n\t\t\treturn 0xFFFDul;\n\n\t\tuwchar_t y(*++s);\n\t\t// expected low-surrogate\n\t\tif (BOOST_UNLIKELY((y >> 10) != 0b110111ul))\n\t\t\treturn 0xFFFDul;\n\n\t\treturn ((x & 0x3FFul) << 10) + (y & 0x3FFul) + 0x10000ul;\n\t}\n}\n\n\tinline utf8_string to_utf8(wchar_t const* str)\n\t{\n\t\tutf8_string result;\n\t\tfor (ucs4_char c; (c = detail::decode_utf16(str)) != ucs4_char(); ++str)\n\t\t\tdetail::utf8_put_encode(result, c);\n\t\treturn result;\n\t}\n\n\ttemplate <typename Traits, typename Allocator>\n\tinline utf8_string\n\tto_utf8(std::basic_string<wchar_t, Traits, Allocator> const& str)\n\t{\n\t\treturn to_utf8(str.c_str());\n\t}\n#endif\n}}}\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3/version.hpp",
    "content": "/*=============================================================================\n  Copyright (c) 2001-2011 Joel de Guzman\n  Copyright (c) 2001-2011 Hartmut Kaiser\n  http://spirit.sourceforge.net/\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 BOOST_SPIRIT_X3_VERSION_HPP\n#define BOOST_SPIRIT_X3_VERSION_HPP\n\n///////////////////////////////////////////////////////////////////////////////\n//\n//  This is the version of the current Spirit X3 distribution\n//\n///////////////////////////////////////////////////////////////////////////////\n#define SPIRIT_X3_VERSION 0x3010\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit/x3.hpp",
    "content": "/*=============================================================================\n\tCopyright (c) 2001-2013 Joel de Guzman\n\n\tDistributed under the Boost Software License, Version 1.0. (See accompanying\n\tfile LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n==============================================================================*/\n#if !defined(BOOST_SPIRIT_X3_MARCH_04_2007_0852PM)\n#define BOOST_SPIRIT_X3_MARCH_04_2007_0852PM\n\n#if defined(_MSC_VER)\n#pragma once\n#endif\n\n#if !defined BOOST_SPIRIT_X3_HIDE_CXX17_WARNING && !( true \\\n  && defined __cpp_if_constexpr && __cpp_if_constexpr >= 201606 \\\n  && defined __cpp_inline_variables && __cpp_inline_variables >= 201606 \\\n  && defined __cpp_fold_expressions && __cpp_fold_expressions >= 201603 \\\n  && defined __cpp_variadic_using && __cpp_variadic_using >= 201611 \\\n  && (defined __cpp_template_auto && __cpp_template_auto >= 201606 \\\n\t  || defined __cpp_nontype_template_parameter_auto && __cpp_nontype_template_parameter_auto >= 201606) \\\n  && defined __cpp_nontype_template_args && __cpp_nontype_template_args >= 201411 \\\n)\n# define BOOST_SPIRIT_X3_STRINGIZE_IMPL(x) #x\n# define BOOST_SPIRIT_X3_STRINGIZE(x) BOOST_SPIRIT_X3_STRINGIZE_IMPL(x)\n# if defined __GNUC__ || defined __clang__\n#  warning \"Spirit X3 will soon use C++17 features which your compiler does not support\"\n#  if (defined __clang__ && __clang_major__ >= 4 || __GNUC__ >= 7) &&  __cplusplus < 201703L\n#   warning \"Use -std=c++17 or -std=gnu++17 compiler flag to enable C++17 mode\"\n#  endif\n#  warning \"Minimal supported compiler versions: Clang 4 / GCC 7 / MSC 1915 (VS 2017 v15.8)\"\n#  if defined __clang__\n#   pragma message \"This compiler seems to be Clang \" BOOST_SPIRIT_X3_STRINGIZE(__clang_major__) \" (__cplusplus=\" BOOST_SPIRIT_X3_STRINGIZE(__cplusplus) \")\"\n#  else\n#   pragma message \"This compiler seems to be GCC \" BOOST_SPIRIT_X3_STRINGIZE(__GNUC__) \" (__cplusplus=\" BOOST_SPIRIT_X3_STRINGIZE(__cplusplus) \")\"\n#  endif\n#  warning \"Define BOOST_SPIRIT_X3_HIDE_CXX17_WARNING to hide the warning\"\n# elif defined _MSC_VER\n#  pragma message (__FILE__ \"(\" BOOST_SPIRIT_X3_STRINGIZE(__LINE__) \"): warning: Spirit X3 will soon use C++17 features which your compiler does not support\" )\n#  ifdef _MSVC_LANG\n#   if _MSC_VER >= 1915 && _MSVC_LANG < 201703L\n#    pragma message (__FILE__ \"(\" BOOST_SPIRIT_X3_STRINGIZE(__LINE__) \"): warning: Use /std:c++17 compiler flag to enable C++17 mode\" )\n#   endif\n#   define BOOST_SPIRIT_X3_TMP \"_MSVC_LANG=\" BOOST_SPIRIT_X3_STRINGIZE(_MSVC_LANG)\n#  elif defined _HAS_CXX17\n#   define BOOST_SPIRIT_X3_TMP \"_HAS_CXX17 defined\"\n#  else\n#   define BOOST_SPIRIT_X3_TMP \"__cplusplus=\" BOOST_SPIRIT_X3_STRINGIZE(__cplusplus)\n#  endif\n#  pragma message (__FILE__ \"(\" BOOST_SPIRIT_X3_STRINGIZE(__LINE__) \"): warning: Minimal supported compiler versions: Clang 4 / GCC 7 / MSC 1915 (VS 2017 v15.8)\" )\n#  pragma message (__FILE__ \"(\" BOOST_SPIRIT_X3_STRINGIZE(__LINE__) \"): warning: This compiler seems to be MSC \" BOOST_SPIRIT_X3_STRINGIZE(_MSC_VER) \" (\" BOOST_SPIRIT_X3_TMP \")\" )\n#  undef BOOST_SPIRIT_X3_TMP\n#  pragma message (__FILE__ \"(\" BOOST_SPIRIT_X3_STRINGIZE(__LINE__) \"): warning: Define BOOST_SPIRIT_X3_HIDE_CXX17_WARNING to hide the warning\" )\n# else\n#  pragma message \"warning: Spirit X3 will soon use C++17 features which your compiler does not support\"\n#  pragma message \"warning: Minimal supported compiler versions: Clang 4 / GCC 7 / MSC 1915 (VS 2017 v15.8)\"\n#  pragma message \"warning: Define BOOST_SPIRIT_X3_HIDE_CXX17_WARNING to hide the warning\"\n# endif\n# undef BOOST_SPIRIT_X3_STRINGIZE\n# undef BOOST_SPIRIT_X3_STRINGIZE_IMPL\n#endif\n\n#include \"x3/auxiliary.hpp\"\n#include \"x3/char.hpp\"\n#include \"x3/directive.hpp\"\n#include \"x3/nonterminal.hpp\"\n#include \"x3/numeric.hpp\"\n#include \"x3/operator.hpp\"\n#include \"x3/core.hpp\"\n#include \"x3/string.hpp\"\n\n#endif\n"
  },
  {
    "path": "tc/string/spirit.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/as_lvalue.h\"\n#include \"../base/tag_type.h\"\n#include \"../range/subrange.h\"\n#include \"../range/subrange.h\"\n#include \"../algorithm/find.h\"\n#include \"../algorithm/append.h\"\n#include \"../algorithm/quantifier.h\"\n#include \"../algorithm/equal.h\"\n#include \"../static_vector.h\"\n\n#include \"ascii.h\"\n#include \"char.h\"\n\n#include <boost/version.hpp>\n#include <boost/fusion/support/config.hpp>\n#include <boost/fusion/support/tag_of_fwd.hpp>\n#include <boost/fusion/iterator/iterator_facade.hpp>\n\n#ifndef __clang__\nMODIFY_WARNINGS_BEGIN(\n\t((disable)(4127)) // conditional expression is constant\n\t((disable)(4459)) // declaration hides global declaration\n)\n#else\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wsign-conversion\"\n#pragma clang diagnostic ignored \"-Wconversion\"\n#pragma clang diagnostic ignored \"-Wsign-compare\"\n#pragma clang diagnostic ignored \"-Wunknown-warning-option\"\n#pragma clang diagnostic ignored \"-Wdeprecated-copy\"\n#endif\n#include \"spirit/x3.hpp\"\n#ifndef __clang__\nMODIFY_WARNINGS_END\n#else\n#pragma clang diagnostic pop\n#endif\n\n\n// Adapt tc::tuple for boost::fusion\n\nnamespace boost::fusion {\n\tstruct tc_tuple_tag;\n\tstruct random_access_traversal_tag;\n\n\ttemplate <typename Tuple, int Index>\n\tstruct tc_tuple_iterator : iterator_facade<tc_tuple_iterator<Tuple, Index>, random_access_traversal_tag> {\n\t\tusing tuple_type = Tuple;\n\t\tstatic auto constexpr index = Index;\n\n\t\tconstexpr explicit tc_tuple_iterator(Tuple& tuple) noexcept : m_tuple(tuple) {}\n\n\t\tTuple& m_tuple;\n\n\t\ttemplate <typename Iterator>\n\t\tstruct value_of : std::tuple_element<Iterator::index, typename remove_const<typename Iterator::tuple_type>::type> {};\n\n\t\ttemplate <typename Iterator>\n\t\tstruct deref {\n\t\t\tusing type = decltype(tc::get<Index>(std::declval<Iterator const&>().m_tuple));\n\t\t\tstatic constexpr type call(Iterator const& iter) noexcept {\n\t\t\t\treturn tc::get<Index>(iter.m_tuple);\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename Iterator, typename N>\n\t\tstruct advance {\n\t\t\tusing type = tc_tuple_iterator<typename Iterator::tuple_type, Iterator::index+N::value>;\n\t\t\tstatic constexpr auto call(Iterator const& i) noexcept {\n\t\t\t\treturn type(i.m_tuple);\n\t\t\t}\n\t\t};\n\n\t\ttemplate <typename Iterator>\n\t\tstruct next : advance<Iterator, tc::constant<1>> {};\n\n\t\ttemplate <typename Iterator>\n\t\tstruct prior : advance<Iterator, tc::constant<-1>> {};\n\n\t\ttemplate <typename First, typename Last>\n\t\tstruct distance {\n\t\t\tusing type = tc::constant<Last::index-First::index>;\n\t\t\tstatic constexpr type call(First const&, Last const&) noexcept { return {}; }\n\t\t};\n\t};\n\n\tnamespace traits {\n\t\ttemplate <typename... Elements>\n\t\tstruct tag_of<tc::tuple<Elements...>> {\n\t\t\tusing type = tc_tuple_tag;\n\t\t};\n\t}\n\n\tnamespace extension {\n\t\ttemplate<> struct is_sequence_impl<tc_tuple_tag> {\n\t\t\ttemplate<typename T> using apply = tc::constant<true>;\n\t\t};\n\n\t\ttemplate<> struct is_view_impl<tc_tuple_tag> {\n\t\t\ttemplate<typename T> using apply = tc::constant<false>;\n\t\t};\n\n\t\ttemplate<> struct category_of_impl<tc_tuple_tag> {\n\t\t\ttemplate<typename T> using apply = std::type_identity<random_access_traversal_tag>;\n\t\t};\n\n\t\ttemplate <> struct size_impl<tc_tuple_tag> {\n\t\t\ttemplate <typename Sequence> using apply = tc::constant<std::tuple_size<Sequence>::value>;\n\t\t};\n\n\t\ttemplate <> struct at_impl<tc_tuple_tag> {\n\t\t\ttemplate <typename Sequence, typename N>\n\t\t\tstruct apply {\n\t\t\t\tstatic constexpr decltype(auto) call(Sequence& seq) noexcept {\n\t\t\t\t\treturn tc::get<N::value>(seq);\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\n\t\ttemplate <> struct begin_impl<tc_tuple_tag> {\n\t\t\ttemplate <typename Sequence>\n\t\t\tstruct apply {\n\t\t\t\tusing type = tc_tuple_iterator<Sequence, 0>;\n\t\t\t\tstatic constexpr auto call(Sequence& v) noexcept {\n\t\t\t\t\treturn type(v);\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\n\t\ttemplate <> struct end_impl<tc_tuple_tag> {\n\t\t\ttemplate <typename Sequence>\n\t\t\tstruct apply {\n\t\t\t\tusing type = tc_tuple_iterator<Sequence, std::tuple_size<typename remove_const<Sequence>::type>::value>;\n\t\t\t\tstatic constexpr auto call(Sequence& v) noexcept {\n\t\t\t\t\treturn type(v);\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\t}\n}\n\n// We prefer x3::rule to simple parser. Because:\n//   1. parsers are copied around in spirit.\n//   2. x3::rule is a special parser reference which does not store the actual parser inside.\n// The standard way to define a namespace scope x3::rule is like below:\n//   x3::rule<struct SIdXXX(, Attribute)> const ruleXXX;\n//   auto const ruleXXX_def = actual_parser;\n//   BOOST_SPIRIT_DEFINE(ruleXXX)\n// Notes:\n//   1. We don't have to wrap actual_parser with tc::attr_is or x3::omit.\n//   2. The attribute can be propagated exactly as in tc::attr_is.\n\nnamespace x3 = boost::spirit::x3;\nnamespace tc {\n\ttemplate< typename Rng, typename Expr, typename... Attr>\n\tbool parse( Rng const& rng, Expr const& expr, Attr&... attr ) MAYTHROW {\n\t\tif constexpr( 2 <= sizeof...(Attr) ) {\n\t\t\treturn tc::parse(rng, expr, tc::as_lvalue(tc::tie(attr...)));\n\t\t} else {\n\t\t\treturn x3::parse( tc::begin(rng), tc::end(rng), x3::with<x3::expectation_failure_tag>(false)[expr], attr... ); // MAYTHROW\n\t\t}\n\t}\n\ttemplate< typename Iterator, typename Expr, typename... Attr>\n\tbool parse_iterator( Iterator& itBegin, Iterator const& itEnd, Expr const& expr, Attr&... attr ) MAYTHROW {\n\t\tif constexpr( 2 <= sizeof...(Attr) ) {\n\t\t\treturn tc::parse_iterator(itBegin, itEnd, expr, tc::as_lvalue(tc::tie(attr...))); // MAYTHROW\n\t\t} else {\n\t\t\treturn x3::parse( itBegin, itEnd, x3::with<x3::expectation_failure_tag>(false)[expr], attr... ); // MAYTHROW\n\t\t}\n\t}\n\ttemplate< typename Rng, typename Expr, typename... Attr>\n\tbool parse_consume( Rng & rng, Expr const& expr, Attr&... attr ) MAYTHROW {\n\t\tif constexpr( 2 <= sizeof...(Attr) ) {\n\t\t\treturn tc::parse_consume(rng, expr, tc::as_lvalue(tc::tie(attr...))); // MAYTHROW\n\t\t} else {\n\t\t\tauto itBegin = tc::begin(rng);\n\t\t\tif(x3::parse( itBegin, tc::end(rng), x3::with<x3::expectation_failure_tag>(false)[expr], attr... )) { // MAYTHROW\n\t\t\t\ttc::drop_inplace( rng, itBegin );\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\ttemplate< typename Rng, typename Expr, typename Skipper, typename... Attr>\n\tbool phrase_parse( Rng const& rng, Expr const& expr, Skipper const& skipper, Attr&... attr ) MAYTHROW {\n\t\tif constexpr( 2 <= sizeof...(Attr) ) {\n\t\t\treturn tc::phrase_parse(rng, expr, skipper, tc::as_lvalue(tc::tie(attr...)));\n\t\t} else {\n\t\t\treturn x3::phrase_parse( tc::begin(rng), tc::end(rng), x3::with<x3::expectation_failure_tag>(false)[expr], skipper, attr... ); // MAYTHROW\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate <typename Expr>\n\t\tstruct x3parser : Expr {\n\t\t\tconstexpr x3parser(Expr expr) : Expr(tc_move(expr)) {}\n\n\t\t\ttemplate <typename Rng>\n\t\t\t[[nodiscard]] constexpr auto operator()(Rng const& rng) const MAYTHROW {\n\t\t\t\tstd::optional<typename Expr::attribute_type> oresult(std::in_place);\n\t\t\t\tif (!tc::parse(rng, *this > x3::eoi, *oresult)) {\n\t\t\t\t\toresult=std::nullopt;\n\t\t\t\t}\n\t\t\t\treturn oresult;\n\t\t\t}\n\t\t};\n\t}\n\ttemplate <typename Expr>\n\tconstexpr auto x3parser(Expr&& expr) return_ctor_MAYTHROW(no_adl::x3parser<std::remove_cvref_t<Expr>>, (tc_move_if_owned(expr)))\n\n\tnamespace no_adl {\n\t\tstruct any_one_impl final : x3::char_parser<any_one_impl> {\n\t\t\tstatic bool const has_attribute = false;\n\t\t\tusing attribute_type = x3::unused_type;\n\n\t\t\ttemplate<typename Context>\n\t\t\tconstexpr bool test(tc::unused /*char*/, Context const&) const& noexcept {\n\t\t\t\tstatic_assert(!x3::has_skipper<Context>::value);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t};\n\t}\n\tinline constexpr auto any_one = no_adl::any_one_impl();\n\n\tnamespace no_adl {\n\t\ttemplate<typename T>\n\t\tstruct one_impl final : x3::char_parser<one_impl<T>> {\n\t\t\tstatic bool const has_attribute = true;\n\t\t\tusing attribute_type = T;\n\n\t\t\ttemplate<typename U, typename Context>\n\t\t\tbool test(U const u, Context const&) const& noexcept {\n\t\t\t\t// A skipper with a parser that takes anything is strange. We do use skippers with restricted_enums.\n\t\t\t\tstatic_assert(requires { T::constructible_from(std::declval<U const&>()); } || !x3::has_skipper<Context>::value);\n\t\t\t\treturn parse_match(u);\n\t\t\t}\n\n\t\t\ttemplate<typename U>\n\t\t\tbool parse_match(U const u) const& noexcept {\n\t\t\t\tif constexpr (requires { T::constructible_from(std::declval<U const&>()); }) {\n\t\t\t\t\treturn T::constructible_from(u);\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert(tc::safely_constructible_from<T, U const&>);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\ttemplate<typename T>\n\tconstexpr auto one = no_adl::one_impl<T>();\n\n\tnamespace no_adl {\n\t\ttemplate<typename Rng>\n\t\tstruct char_set final: x3::char_parser<char_set<Rng>> {\n\t\t\tstatic bool const has_attribute = true;\n\t\t\tusing attribute_type = tc::range_value_t<Rng>;\n\n\t\t\tconstexpr char_set(Rng&& rng) noexcept\n\t\t\t\t: m_rng(tc::aggregate_tag, tc_move_if_owned(rng)) {}\n\n\t\t\ttemplate <typename CharType, typename Context>\n\t\t\tbool test(CharType const& ch, Context& context) const& noexcept {\n\t\t\t\treturn tc::any_of(*m_rng, [&](auto const& chAllowed) noexcept {\n\t\t\t\t\treturn tc::equal_to_or_parse_match(ch, chAllowed);\n\t\t\t\t});\n\t\t\t}\n\t\tprivate:\n\t\t\ttc::reference_or_value<Rng> m_rng;\n\t\t};\n\t}\n\ttemplate<typename Rng>\n\tconstexpr no_adl::char_set<Rng> static_char_class(Rng&& rng) noexcept {\n\t\treturn tc_move_if_owned(rng);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename String>\n\t\tstruct lit_impl final: x3::parser<lit_impl<String>> {\n\t\t\tstatic bool const has_attribute = false;\n\t\t\tusing attribute_type = x3::unused_type;\n\n\t\t\texplicit constexpr lit_impl(String&& str) noexcept: m_str(tc::aggregate_tag, tc_move_if_owned(str)) {}\n\n\t\t\ttemplate<typename Iterator, typename Context, typename Attribute>\n\t\t\tbool parse(Iterator& first, Iterator const& last, Context const& context, x3::unused_type, Attribute& attr) const& {\n\t\t\t\tx3::skip_over(first, last, context);\n\t\t\t\tif(auto const first_=tc::starts_with<tc::return_border_or_null>(tc::make_iterator_range(first, last), *m_str)) {\n\t\t\t\t\tfirst=first_;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\tprivate:\n\t\t\ttc::reference_or_value<String> m_str;\n\t\t};\n\t}\n\ttemplate<typename String>\n\tconstexpr auto lit(String&& str) noexcept {\n\t\treturn no_adl::lit_impl<String>(tc_move_if_owned(str));\n\t}\n\n\tnamespace no_adl {\n\t\t// tc::attr_is<T>[parser] directive creates an x3::rule_definition (an x3::parser with a customized attribute type).\n\t\t// When specifying an attribute, in some cases the attribute can be filled by the parser without any additional code:\n\t\t//   auto const parser = tc::attr_is<tc::string<char>>[+x3::alpha];\n\t\t// In other cases, you may have to write a semantic action and access the attribute via x3::_val(ctx) to fill it:\n\t\t//   auto const parser = tc::attr_is<tc::string<char>>[+x3::alpha[([](auto const& ctx) noexcept {\n\t\t//     tc::append(\n\t\t//       x3::_val(ctx)/*attribute of innermost x3::rule_definition, which is what is specified in tc::attr_is<>*/,\n\t\t//       tc::single(x3::_attr(ctx))/*automatic attribute of the parser attached; in this case x3::alpha is producing char*/\n\t\t//     );\n\t\t//   })]];\n\t\ttemplate<typename T>\n\t\tstruct attr_is_type {\n\t\t\ttemplate<x3::spirit_parser Expr>\n\t\t\tconstexpr auto operator[](Expr&& expr) const& noexcept {\n\t\t\t\t// returns a x3::rule_definition with attr_is_id, Attribute type of T and rhs parser of expr\n\t\t\t\treturn x3::rule<struct attr_is_id, T>{\"attr_is\"} = tc_move_if_owned(expr);\n\t\t\t}\n\t\t};\n\t}\n\ttemplate<typename T>\n\tinline constexpr no_adl::attr_is_type<T> attr_is = {};\n\n\tnamespace no_adl {\n\t\tstruct asciiblank final: x3::char_parser<asciiblank> {\n\t\t\tstatic bool const has_attribute = false;\n\t\t\tusing attribute_type = x3::unused_type;\n\n\t\t\ttemplate <typename CharType>\n\t\t\tstatic bool test(CharType const& ch, tc::unused /*context*/) noexcept {\n\t\t\t\treturn tc::isasciiblank(ch);\n\t\t\t}\n\t\t};\n\n\t\tstruct asciispace final: x3::char_parser<asciispace> {\n\t\t\tstatic bool const has_attribute = false;\n\t\t\tusing attribute_type = x3::unused_type;\n\n\t\t\ttemplate <typename CharType>\n\t\t\tstatic bool test(CharType const& ch, tc::unused /*context*/) noexcept {\n\t\t\t\treturn tc::isasciispace(ch);\n\t\t\t}\n\t\t};\n\t}\n\tinline constexpr auto asciiblank = no_adl::asciiblank{};\n\tinline constexpr auto asciispace = no_adl::asciispace{};\n\n\ttemplate <bool bSigned>\n\tstruct xml_percentage_policies final : std::conditional_t<bSigned, x3::real_policies<double>, x3::ureal_policies<double>> {\n\t\tstatic constexpr bool allow_leading_dot = false;\n\t\tstatic constexpr bool allow_trailing_dot = false;\n\t\t// do not parse exponents\n\t\ttemplate<typename Iterator> static bool parse_exp(Iterator& first, Iterator const& last) noexcept { return false; }\n\t\t// do not parse NANs\n\t\ttemplate<typename Iterator, typename Attribute> static bool parse_nan(Iterator& first, Iterator const& last, Attribute& attr) noexcept { return false; }\n\t\t// do not parse INFs\n\t\ttemplate<typename Iterator, typename Attribute> static bool parse_inf(Iterator& first, Iterator const& last, Attribute& attr) noexcept { return false; }\n\t};\n\n\tinline constexpr auto asciixdigit = tc::one<tc::char_asciidigit> | tc::one<tc::restricted_enum<char, 'A', 'F'>> | tc::one<tc::restricted_enum<char, 'a', 'f'>>;\n\n\tnamespace no_adl {\n\t\ttemplate<tc::char_type T>\n\t\tstruct char_encoding final {\n\t\t\tusing char_type = T;\n\n\t\t\ttemplate<typename Char> requires std::same_as<Char, T>\n\t\t\tstatic constexpr bool ischar(Char ch) noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tstatic ::boost::uint32_t toucs4(int const ch) noexcept { // for debug only\n\t\t\t\treturn ch;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<tc::char_type T, T tFirst, T tLast>\n\t\tstruct char_encoding<tc::restricted_enum<T, tFirst, tLast>> final {\n\t\t\tusing char_type = tc::restricted_enum<T, tFirst, tLast>;\n\n\t\t\ttemplate<tc::char_like Char>\n\t\t\tstatic constexpr bool ischar(Char ch) noexcept {\n\t\t\t\treturn char_type(tFirst) <= ch && ch <= char_type(tLast); // We reuse the SFINAE from the comparison operators of restricted_enum.\n\t\t\t}\n\t\t\tstatic ::boost::uint32_t toucs4(int const ch) noexcept { // for debug only\n\t\t\t\treturn ch;\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::char_encoding;\n\n\ttemplate<typename Char, typename T>\n\tusing symbols = x3::symbols_parser<tc::char_encoding<Char>, T>;\n\n\tnamespace no_adl {\n\t\tstruct move_attr_to_val_impl final {\n\t\t\ttemplate<typename Context>\n\t\t\tvoid operator()(Context& ctx) noexcept {\n\t\t\t\tx3::_val(ctx)=tc_move_always(x3::_attr(ctx));\n\t\t\t}\n\t\t};\n\t\ttemplate<typename T>\n\t\tstruct move_attr_to_ext_val_impl final {\n\t\t\tconstexpr move_attr_to_ext_val_impl(T& t) noexcept: m_t(t) {}\n\t\t\ttemplate<typename Context>\n\t\t\tvoid operator()(Context& ctx) noexcept {\n\t\t\t\tm_t=tc_move_always(x3::_attr(ctx));\n\t\t\t}\n\t\tprivate:\n\t\t\tT& m_t;\n\t\t};\n\t}\n\n\ttemplate<typename T>\n\tconstexpr auto move_attr_to_val(T& t) noexcept {\n\t\treturn no_adl::move_attr_to_ext_val_impl<T>(t);\n\t}\n\n\tconstexpr auto move_attr_to_val() noexcept {\n\t\treturn no_adl::move_attr_to_val_impl();\n\t}\n}\n\n///////////////////////////////\n// x3::with_val\n\nnamespace boost::spirit::x3 {\n\ttemplate<typename Subject, typename ID>\n\tstruct with_val_directive : unary_parser<Subject, with_val_directive<Subject, ID>>\n\t{\n\t\tusing base_type = typename with_val_directive::unary_parser;\n\t\tstatic bool const is_pass_through_unary = true;\n\t\tstatic bool const handles_container = Subject::handles_container;\n\t\tusing subject_type = Subject;\n\n\t\tconstexpr with_val_directive(Subject const& subject): base_type(subject) {}\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last, Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn this->subject.parse(\n\t\t\t\tfirst, last\n\t\t\t  , make_context<ID>(rcontext, context)\n\t\t\t  , rcontext\n\t\t\t  , attr);\n\t\t}\n\t};\n\n\ttemplate <typename ID>\n\tstruct with_val_gen\n\t{\t\n\t\ttemplate <x3::spirit_parser Subject>\n\t\tconstexpr with_val_directive<Subject, ID>\n\t\toperator[](Subject const& subject) const\n\t\t{\n\t\t\treturn { subject };\n\t\t}\n\t};\n\n\ttemplate<typename ID>\n\tinline constexpr auto with_val = with_val_gen<ID>{};\n}\n\n///////////////////////////////\n// x3::lazy\n\nnamespace boost::spirit::x3\n{\n\ttemplate <typename context_tag>\n\tstruct lazy_parser : parser<lazy_parser<context_tag>>\n\t{\n\t\tusing base_type = typename lazy_parser::parser;\n\n\t\ttemplate <typename Iterator, typename Context, typename RContext, typename Attribute>\n\t\tbool parse(Iterator& first, Iterator const& last, Context const& context, RContext& rcontext, Attribute& attr) const\n\t\t{\n\t\t\treturn x3::get<context_tag>(context).parse(first, last, context, rcontext, attr);\n\t\t}\n\t};\n\n\ttemplate <typename context_tag>\n\tinline constexpr auto lazy = lazy_parser<context_tag>{};\n}\n\nnamespace boost::spirit::x3::traits\n{\n\ttemplate <typename context_tag, typename Context>\n\tstruct attribute_of<x3::lazy_parser<context_tag>, Context>\n\t\t: attribute_of<\n\t\t\ttypename remove_cv<typename remove_reference<\n\t\t\t\tdecltype(x3::get<context_tag>(std::declval<Context>()))\n\t\t\t>::type>::type,\n\t\t\tContext\n\t\t> {};\n\n\ttemplate <typename context_tag, typename Context>\n\tstruct has_attribute<x3::lazy_parser<context_tag>, Context>\n\t\t: has_attribute<\n\t\t\ttypename remove_cv<typename remove_reference<\n\t\t\t\tdecltype(x3::get<context_tag>(std::declval<Context>()))\n\t\t\t>::type>::type,\n\t\t\tContext\n\t\t> {};\n}\n\n///////////////////////////////\n// static_vector support\n\nnamespace boost::spirit::x3::traits\n{\n\ttemplate <typename T, tc::static_vector_size_t N>\n\tstruct push_back_container<tc::static_vector<T, N>, void>\n\t{\n\t\ttemplate <typename Value>\n\t\tstatic bool call(tc::static_vector<T, N>& c, Value&& val)\n\t\t{\n\t\t\ttc::cont_emplace_back(c, tc_move_if_owned(val));\n\t\t\treturn true;\n\t\t}\n\t};\n\ttemplate <typename T, tc::static_vector_size_t N>\n\tstruct append_container<tc::static_vector<T, N>, void>\n\t{\n\t\ttemplate <typename Iterator>\n\t\tstatic bool call(tc::static_vector<T, N>& c, Iterator first, Iterator last)\n\t\t{\n\t\t\ttc::append(c, tc::make_iterator_range(first, last));\n\t\t\treturn true;\n\t\t}\n\t};\n\ttemplate <typename T, tc::static_vector_size_t N>\n\tstruct is_empty_container<tc::static_vector<T, N>, void>\n\t{\n\t\tstatic bool call(tc::static_vector<T, N> const& c) noexcept\n\t\t{\n\t\t\treturn tc::empty(c);\n\t\t}\n\t};\n}\n"
  },
  {
    "path": "tc/string/spirit_algorithm.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"../base/assert_defs.h\"\n#include \"../range/meta.h\"\n#include \"../algorithm/algorithm.h\"\n#include \"spirit.h\"\n\nnamespace tc {\n\ttemplate<typename RangeReturn, typename Rng, tc::derived_from<x3::parser_base> Expr>\n\t[[nodiscard]] decltype(auto) starts_with_expr(Rng&& rng, Expr const& expr) noexcept {\n\t\tauto itEndParse = tc::begin(rng);\n\t\tif (tc::parse_iterator(itEndParse, tc::end(rng), expr)) {\n\t\t\treturn RangeReturn::pack_border(tc_move(itEndParse), tc_move_if_owned(rng));\n\t\t}\n\t\treturn RangeReturn::pack_no_border(tc_move_if_owned(rng));\n\t}\n\n\t// 1 or more elements from rngWhat are required to match each element from rngWhere\n\ttemplate<typename RangeReturn, typename RngWhere, typename RngWhat, typename Pred>\n\t[[nodiscard]] decltype(auto) search_first_impl(RngWhere&& rngWhere, RngWhat const& rngWhat, Pred predConsume) noexcept {\n\t\tauto const itWhereEnd = tc::end(rngWhere);\n\t\tauto const itWhatBegin = tc::begin(rngWhat);\n\t\tauto const itWhatEnd = tc::end(rngWhat);\n\t\tfor (auto itWhere = tc::begin(rngWhere);; ++itWhere) {\n\t\t\tauto itWhere2 = itWhere;\n\t\t\tauto itWhat = itWhatBegin;\n\t\t\tfor (;;) {\n\t\t\t\tif (itWhatEnd == itWhat) {\n\t\t\t\t\treturn RangeReturn::pack_view(tc_move_if_owned(rngWhere), tc_move(itWhere), tc_move(itWhere2));\n\t\t\t\t}\n\t\t\t\tif (itWhereEnd == itWhere2) {\n\t\t\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rngWhere));\n\t\t\t\t}\n\t\t\t\tif (!predConsume(tc::as_const(*itWhere2), itWhat, itWhatEnd)) break;\n\t\t\t\t++itWhere2;\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename RangeReturn, typename RngWhere, typename RngWhat, typename Pred> requires (!tc::derived_from<RngWhat, x3::parser_base>)\n\t[[nodiscard]] decltype(auto) search_first(RngWhere&& rngWhere, RngWhat const& rngWhat, Pred pred) noexcept {\n\t\treturn search_first_impl<RangeReturn>(tc_move_if_owned(rngWhere), rngWhat, [&](auto const& valWhere, auto& itWhat, auto const& /*itWhatEnd*/) noexcept {\n\t\t\treturn pred(valWhere, tc::as_const(*itWhat)) && (++itWhat, true);\n\t\t});\n\t}\n\n\ttemplate<typename RangeReturn, typename RngWhere, typename RngWhat>\n\t[[nodiscard]] decltype(auto) search_first(RngWhere&& rngWhere, RngWhat const& rngWhat) noexcept {\n\t\treturn tc::search_first<RangeReturn>(tc_move_if_owned(rngWhere), rngWhat, tc::fn_equal_to_or_parse_match());\n\t}\n\n\ttemplate<typename RangeReturn, typename Rng, tc::derived_from<x3::parser_base> Expr>\n\tdecltype(auto) search_first(Rng&& rng, Expr const& expr) noexcept {\n\t\tauto const itEnd = tc::end(rng);\n\t\tfor (auto it = tc::begin(rng); it != itEnd; ++it) {\n\t\t\tauto itEndParse = it;\n\t\t\tif (tc::parse_iterator(itEndParse, itEnd, expr)) {\n\t\t\t\treturn RangeReturn::pack_view(tc_move_if_owned(rng), tc_move(it), tc_move(itEndParse));\n\t\t\t}\n\t\t}\n\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rng));\n\t}\n\n\ttemplate<typename RangeReturn, typename RngWhere, typename What>\n\tdecltype(auto) search_unique(RngWhere&& rngWhere, What const& what) noexcept {\n\t\tif(auto const orng=tc::search_first<tc::return_view_or_none>(rngWhere, what)) {\n\t\t\tauto itEnd=VERIFYPRED(tc::end(*orng), !tc::search_first<tc::return_bool>(tc::drop(rngWhere, _), what)); // do not inline, rngWhere is forwarded\n\t\t\treturn RangeReturn::pack_view(tc_move_if_owned(rngWhere), tc::begin(*orng), tc_move(itEnd));\n\t\t} else {\n\t\t\treturn RangeReturn::pack_no_element(tc_move_if_owned(rngWhere));\n\t\t}\n\t}\n\n\t// cannot use list::remove because T may not be list::value_type\n\t// cannot use key-based lookup for set/map because T may not be Cont::value_type and !Cont::predicate()(a,b) && !Cont::predicate()(b,a) may not be the same as ==\n\ttemplate<typename Cont, typename T> requires (!tc::derived_from<T, x3::parser_base>)\n\tvoid remove_inplace(Cont& cont, T const& t) noexcept {\n\t\ttc::filter_inplace( cont, [&](auto const& _) noexcept { return !tc::equal_to(_, t); } );\n\t}\n\n\ttemplate<typename Cont, tc::derived_from<x3::parser_base> Expr>\n\tvoid remove_inplace(Cont& cont, tc::iterator_t<Cont> it, Expr const& expr) noexcept {\n\t\tfor(auto const itEnd = tc::end(cont); it != itEnd; ++it) {\n\t\t\tauto itBegin=it;\n\t\t\tif(tc::parse_iterator(it, itEnd, expr)) {\n\t\t\t\ttc::range_filter< tc::decay_t<Cont> > rngfilter(cont, itBegin);\n\t\t\t\twhile(it != itEnd) {\n\t\t\t\t\tif(!tc::parse_iterator(it, itEnd, expr)) {\n\t\t\t\t\t\trngfilter.keep(it++);  // may invalidate it, so move away first\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\ttemplate<typename Cont, tc::derived_from<x3::parser_base> Expr>\n\tvoid remove_inplace(Cont& cont, Expr const& expr) noexcept {\n\t\ttc::remove_inplace(cont, tc::begin(cont), expr);\n\t}\n\n\t// removes all original occurrences of rng within cont, but not occurrences that have been created during the process\n\t// so remove_all_inplace(\"aabb\", \"ab\") -> \"ab\"\n\ttemplate<typename Cont, typename Rng>\n\tvoid remove_all_inplace(Cont& cont, Rng const& rng) noexcept {\n\t\t_ASSERT(!tc::empty(rng)); // What does it mean to remove all empty subranges? Causes an infinite loop down below.\n\t\tauto const itEnd = tc::end(cont);\n\t\tauto it = tc::begin(cont);\n\t\ttc::range_filter< tc::decay_t<Cont> > rngfilter(cont, it);\n\t\twhile (itEnd != it) {\n\t\t\tif (auto const itBorder = tc::starts_with<tc::return_border_or_null>(tc::slice(cont, it, itEnd), rng)) {\n\t\t\t\tit = itBorder;\n\t\t\t} else {\n\t\t\t\trngfilter.keep(it++); // may invalidate it, so move away first\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tc/string/xmlparser.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"parserbase.h\"\n#include \"spirit.h\"\n#include \"../container/container.h\"\n#include \"../container/cont_assign.h\"\n#include \"../range/join_framed_adaptor.h\"\n\nnamespace tc::xml {\n\tnamespace no_adl {\n\t\tstruct parse_error final {};\n\t}\n\tusing no_adl::parse_error;\n\t\n\tnamespace no_adl {\n\t\ttemplate<tc::decayed Func>\n\t\tstruct [[nodiscard]] simple_error_handler {\n\t\t\tsimple_error_handler()=default;\n\t\t\tconstexpr explicit simple_error_handler(Func func) noexcept\n\t\t\t\t: m_func(tc_move(func))\n\t\t\t{}\n\t\t\tvoid semantic_error(auto const& strInput, tc::unused /*itch*/, auto&&...) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid parse_warning(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid parse_warning(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/, tc::unused /*strAttributeName*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid parse_error(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid parse_error(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/, tc::unused /*strAttributeName*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid end_unexpected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid end_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid root_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid name_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid invalid_namespace_prefix(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid attribute_name_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid child_expected(auto const& strInput, tc::unused /*itch*/, tc::unused /*strName*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid char_expected(auto const& strInput, tc::unused /*itch*/, tc::unused /*ch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid characters_expected(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid characters_unexpected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid attribute_expected(auto const& strInput, tc::unused /*itch*/, tc::unused /*strTag*/, tc::unused /*strAttributeName*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid element_end_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid quotation_marks_expected(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\t\t\tvoid unsupported_declaration_found(auto const& strInput, tc::unused /*itch*/) const& MAYTHROW {\n\t\t\t\tm_func(strInput);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tFunc m_func;\n\t\t};\n\n\t\ttemplate< typename Rng >\n\t\tstruct [[nodiscard]] decode_adaptor\n\t\t\t: tc::index_range_adaptor<\n\t\t\t\tdecode_adaptor<Rng>,\n\t\t\t\tRng, tc::index_range_adaptor_flags::inherit_begin_end\n\t\t\t>\n\t\t{\n\t\tprivate:\n\t\t\tusing this_type = decode_adaptor;\n\t\t\tusing base_ = typename decode_adaptor::index_range_adaptor;\n\t\t\tusing char_type=tc::range_value_t<Rng>;\n\n\t\tpublic:\n\t\t\tusing typename base_::tc_index;\n\n\t\t\tvoid SkipOverSemicolon(tc_index& idx) const& MAYTHROW {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tfor(;;) {\n\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\tif(tc::at_end_index(base, idx)) break;\n\t\t\t\t\tif(tc::char_ascii(';')==tc::dereference_index(base, idx)) {\n\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tSTATIC_FINAL(increment_index)(tc_index& idx) const& MAYTHROW -> void {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tauto t=tc::dereference_index(base, idx); // we return characters, which we can always return by value\n\t\t\t\tif(tc::char_ascii('&')==t) {\n\t\t\t\t\tSkipOverSemicolon(idx);\n\t\t\t\t} else {\n\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<bool bIncrement>\n\t\t\tchar_type ProcessEscaped(tc_index& idx) const& MAYTHROW {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\tif(!tc::at_end_index(base, idx)) {\n\t\t\t\t\tswitch(tc::dereference_index(base, idx)) {\n\t\t\t\t\tcase tc::explicit_cast<char_type>('a'):\n\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\tif(!tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\tswitch(tc::dereference_index(base, idx)) {\n\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('m'): // amp\n\t\t\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\t\t\treturn tc::char_ascii('&');\n\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('p'): // apos\n\t\t\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\t\t\treturn tc::char_ascii('\\'');\n\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>(';'):\n\t\t\t\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, idx);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase tc::explicit_cast<char_type>('l'): // lt\n\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\treturn tc::char_ascii('<');\n\t\t\t\t\tcase tc::explicit_cast<char_type>('g'): // gt\n\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\treturn tc::char_ascii('>');\n\t\t\t\t\tcase tc::explicit_cast<char_type>('q'): // quot\n\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\treturn tc::char_ascii('\"');\n\t\t\t\t\tcase tc::explicit_cast<char_type>('#'): // numeric character reference\n\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\tif(!tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\tauto const NumericCharacterReference=[&](auto N) MAYTHROW -> char_type {\n\t\t\t\t\t\t\t\tint n;\n\t\t\t\t\t\t\t\tauto str=tc::drop(base, idx);\n\t\t\t\t\t\t\t\tif(tc::parse_consume( str, x3::uint_parser<decltype(n), decltype(N)::value>(), n )) { // MAYTHROW\n\t\t\t\t\t\t\t\t\tidx=tc::begin_index(str);\n\t\t\t\t\t\t\t\t\tif(!tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\t\t\t\tif(tc::char_ascii(';')==tc::dereference_index(base, idx)) {\n\t\t\t\t\t\t\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, idx);\n\t\t\t\t\t\t\t\t\t\t\treturn static_cast<char_type>(VERIFYPRED(n, tc::char_in_range<char_type>(_)));\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if constexpr(bIncrement) {\n\t\t\t\t\t\t\t\t\tif(tc::char_ascii(';')==tc::dereference_index(base, idx)) {\n\t\t\t\t\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tSkipOverSemicolon(idx);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn tc::char_ascii('&'); // replacement character would be nicer, but has multiple code units, which we do not yet support\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif(tc::char_ascii('x')==tc::dereference_index(base, idx)) {\n\t\t\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\t\t\tif(!tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\t\t\treturn NumericCharacterReference(tc::constant<16>());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn NumericCharacterReference(tc::constant<10>());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase tc::explicit_cast<char_type>(';'):\n\t\t\t\t\t\tif constexpr(bIncrement) tc::increment_index(base, idx);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif constexpr(bIncrement) SkipOverSemicolon(idx);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tc::char_ascii('&'); // replacement character would be nicer, but has multiple code units, which we do not yet support\n\t\t\t};\n\n\t\t\tSTATIC_FINAL(dereference_index)(tc_index const& idx) const& MAYTHROW {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tauto t=tc::dereference_index(base, idx); // we return characters, which we can always return by value\n\t\t\t\tif(tc::char_ascii('&')==t) {\n\t\t\t\t\treturn ProcessEscaped<false>(tc::as_lvalue(tc::decay_copy(idx)));\n\t\t\t\t} else {\n\t\t\t\t\treturn t;\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\tusing base_::base_;\n\n\t\t\tconstexpr decode_adaptor() = default;\n\n\t\t\tstatic decltype(auto) element_base_index(tc_index const& idx) noexcept {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t\tstatic decltype(auto) element_base_index(tc_index&& idx) noexcept {\n\t\t\t\treturn tc_move(idx);\n\t\t\t}\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink sink) const& MAYTHROW -> tc::common_type_t<\n\t\t\t\tdecltype(tc::continue_if_not_break(sink, tc::dereference_index(this->base_range(), std::declval<tc_index const&>()))),\n\t\t\t\ttc::constant<tc::continue_>\n\t\t\t> {\n\t\t\t\tauto& base=this->base_range();\n\t\t\t\tauto idx=tc::begin_index(base);\n\t\t\t\tfor(;;) {\n\t\t\t\t\tif(tc::at_end_index(base, idx)) return tc::constant<tc::continue_>();\n\t\t\t\t\tif(tc::char_ascii('&')!=tc::dereference_index(base, idx)) {\n\t\t\t\t\t\tauto idxBegin=idx;\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\ttc::increment_index(base, idx);\n\t\t\t\t\t\t\tif(tc::at_end_index(base, idx)) {\n\t\t\t\t\t\t\t\ttc_return_if_break( tc::for_each(tc::slice(base, idxBegin, idx), sink) );\n\t\t\t\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while(tc::char_ascii('&')!=tc::dereference_index(base, idx));\n\t\t\t\t\t\ttc_return_if_break( tc::for_each(tc::slice(base, idxBegin, idx), sink) );\n\t\t\t\t\t}\n\t\t\t\t\ttc_return_if_break(tc::continue_if_not_break(sink, ProcessEscaped<true>(idx)))\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename WithString>\n\t\tstruct with_iterator_range /* not final */ {\n\t\t\tWithString m_withstring;\n\n\t\t\ttemplate<tc::range_with_iterators String>\n\t\t\tauto chunk(String&& str) const& MAYTHROW {\n\t\t\t\tm_withstring(tc_move_if_owned(str)); // MAYTHROW\n\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t}\n\t\t};\n\t\ttemplate<typename WithString>\n\t\twith_iterator_range(WithString) -> with_iterator_range<WithString>; // CTAD not working for aggregates (clang)\n\t}\n\tusing no_adl::simple_error_handler;\n\n\t// The inline here is necessary to ensure that the type of the lambda is the same in all compilation units.\n\ttemplate <typename T>\n\tinline auto constexpr assert_and_throw = tc::xml::simple_error_handler([](tc::unused) THROW(T) {\n\t\t_ASSERTNOTIFYFALSE; throw T();\n\t});\n\tinline auto constexpr assert_no_error = tc::xml::simple_error_handler([](tc::unused) noexcept {\n\t\t_ASSERTNORETURNFALSE;\n\t});\n\n\ttemplate<typename Rng>\n\tconstexpr auto decode(Rng&& rng)\n\t\treturn_ctor_noexcept( no_adl::decode_adaptor<Rng>, (aggregate_tag, tc_move_if_owned(rng)) )\n\n\ttemplate<typename String>\n\tauto split_qualified_name(String const& str) noexcept {\n\t\ttc_auto_cref(itch, tc::find_unique<tc::return_border_after_or_begin>(str, tc::char_ascii(':')));\n\t\treturn std::make_pair(\n\t\t\ttc::begin(str)==itch ? tc::take(str, itch) : tc::take(str, tc_modified(itch, --_)),\n\t\t\ttc::drop(str, itch)\n\t\t);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate< typename T, typename = void >\n\t\tstruct has_discard_until : std::false_type { };\n\n\t\ttemplate< typename T > requires requires(T t) { &t.discard_until; }\n\t\tstruct has_discard_until<T> : std::true_type {};\n#pragma push_macro(\"case_whitespace\")\n#define case_whitespace case tc::explicit_cast<char_type>('\\t'): case tc::explicit_cast<char_type>('\\n'): case tc::explicit_cast<char_type>('\\r'): case tc::explicit_cast<char_type>(' ')\n\n\t\tTC_DEFINE_ENUM(EXmlEntity, exmlentity, (START)(EMPTYELEMENT)(EMPTYELEMENTCLOSING)(OPENINGTAG)(CLOSINGTAG)(CHARACTERS)(CDATA));\n\n\t\ttemplate<typename Char>\n\t\tstruct namespace_info : tc::noncopyable {\n\t\tprotected:\n\t\t\tusing SetNamespace = tc::unordered_set_range<tc::string<Char>>;\n\t\t\tSetNamespace m_setstrns;\n\t\t\t\n\t\tpublic:\n\t\t\t// Namespace is a nullable type\n\t\t\t// Passing a nullptr as a namespace to any parser method implies\n\t\t\t// that the matched element has no namespace, i.e., it belongs to the default namespace\n\t\t\t// and the default namespace has no value because either\n\t\t\t// - there is no xmlns=\"...\" declaration in scope\n\t\t\t// - or there is a xmlns=\"\" declaration in scope\n\t\t\t//\n\t\t\t// Using a namespace prefix t in the scope of a declaration xmlns:t=\"\" is explicitly forbidden\n\t\t\t// and causes an invalid_namespace_prefix parser error.\n\t\t\t// https://www.w3.org/TR/2006/REC-xml-names11-20060816/#nsc-NSDeclared\n\t\t\tusing Namespace = tc::string<Char> const*; // pointer is stable, iterator is not\n\t\t\t\n\t\t\ttemplate<typename Rng>\n\t\t\tNamespace register_namespace(Rng const& strURI) & noexcept {\n\t\t\t\t// An empty string is a valid URI but has special semantics in the XML namespace 1.1 spec.\n\t\t\t\t// It undefines a previously defined namespace prefix for its scope.\n\t\t\t\t// https://www.w3.org/TR/2006/REC-xml-names11-20060816/#scoping\n\t\t\t\t_ASSERT(!tc::empty(strURI));\n\t\t\t\treturn std::addressof(*tc::cont_try_emplace(m_setstrns, decode(strURI)).first);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<typename String, typename ErrorHandler>\n\t\tstruct [[nodiscard]] parser : parser_base<String, ErrorHandler>, namespace_info<tc::range_value_t<String>> {\n\t\tprivate:\n\t\t\tusing base_ = parser_base<String, ErrorHandler>;\n\t\tpublic:\n\t\t\tusing typename base_::char_type;\n\n\t\t\tusing SetNamespace=typename namespace_info<char_type>::SetNamespace;\n\t\t\tusing Namespace=typename namespace_info<char_type>::Namespace;\n\t\t\t\n\t\t\texplicit parser(String&& strInput, ErrorHandler errorhandler) MAYTHROW\n\t\t\t\t: base_(tc_move_if_owned(strInput), tc_move(errorhandler))\n\t\t\t\t, m_strMain(tc::slice(this->input(), this->m_itchInput, this->m_itchInput))\n\t\t\t\t, m_bConsumed(false)\n\t\t\t{\n\t\t\t\tNext(); // MAYTHROW\n\t\t\t\tSkipWhitespaceCharacters(); // MAYTHROW\n\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.root_expected)>(m_itchEntityBegin); // MAYTHROW\n\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\t; // root element\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tusing base_::expect_end;\n\n\t\t\t[[nodiscard]] auto characters() & MAYTHROW {\n\t\t\t\tEnsureFresh(); // MAYTHROW\n\t\t\t\tswitch(m_exmlentity) {\n\t\t\t\tcase exmlentityCDATA:\n\t\t\t\tcase exmlentityCHARACTERS:\n\t\t\t\t\tm_bConsumed=true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tm_bConsumed=false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn tc::generator_range_output<char_type>([this](auto sink) MAYTHROW -> tc::common_type_t<\n\t\t\t\t\tdecltype(tc::for_each(m_strMain, tc_move(sink))),\n\t\t\t\t\tdecltype(tc::for_each(xml::decode(m_strMain), tc_move(sink))),\n\t\t\t\t\ttc::constant<tc::continue_>\n\t\t\t\t> {\n\t\t\t\t\tswitch(m_exmlentity) {\n\t\t\t\t\tcase exmlentityCDATA:\n\t\t\t\t\t\treturn tc::for_each(m_strMain, tc_move(sink)); // MAYTHROW\n\t\t\t\t\tcase exmlentityCHARACTERS:\n\t\t\t\t\t\treturn tc::for_each(xml::decode(m_strMain), tc_move(sink)); // MAYTHROW\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn tc::constant<tc::continue_>();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto parse_characters(auto const& parser) & MAYTHROW {\n\t\t\t\tdecltype(parser(tc::make_empty_range<char_type>())) ot;\n\t\t\t\tWithCharacters([&](auto const& strCharacters) MAYTHROW {\n\t\t\t\t\tif (!tc::empty(strCharacters)) {\n\t\t\t\t\t\tif (ot = parser(strCharacters); !ot) {\n\t\t\t\t\t\t\tthis->template warning_at<tc_mem_fn(.parse_warning)>(m_itchEntityBegin, m_strMain); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}); // MAYTHROW\n\t\t\t\treturn ot;\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto expect_parse_characters(auto const& parser) & MAYTHROW {\n\t\t\t\ttc::decay_t<decltype(*parser(tc::make_empty_range<char_type>()))> t;\n\t\t\t\tWithCharacters([&](auto const& strCharacters) MAYTHROW {\n\t\t\t\t\tif (tc::empty(strCharacters)) {\n\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.characters_expected)>(m_itchEntityBegin, m_strMain); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t\tif (auto ot = parser(strCharacters); !ot) {\n\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.parse_error)>(m_itchEntityBegin, m_strMain); // MAYTHROW\n\t\t\t\t\t} else {\n\t\t\t\t\t\tt = *ot;\n\t\t\t\t\t}\n\t\t\t\t}); // MAYTHROW\n\t\t\t\treturn t;\n\t\t\t}\n\n\t\t\ttemplate<typename T>\n\t\t\tvoid assign_expect_parse_characters(T& t, auto const& parser) & MAYTHROW {\n\t\t\t\tt = expect_parse_characters(parser); // MAYTHROW\n\t\t\t}\n\n\t\t\ttemplate<typename T, template<typename> typename Parser>\n\t\t\tvoid assign_expect_parse_characters(T& t, Parser<tc::deduce_tag> const&) & MAYTHROW {\n\t\t\t\tt = expect_parse_characters(Parser<T>()); // MAYTHROW\n\t\t\t}\n\n\t\t\tbool child(Namespace ons, auto const& strName) & MAYTHROW {\n\t\t\t\tEnsureFreshSkipWhitespaceCharacters(); // MAYTHROW\n\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\t{\n\t\t\t\t\t\tauto const paironsstr = expanded_name(); // MAYTHROW\n\t\t\t\t\t\tif(ons==paironsstr.first && tc::equal(strName, paironsstr.second)) {\n\t\t\t\t\t\t\tm_bConsumed=true;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t[[fallthrough]];\n\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\tm_bConsumed=false;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool child(auto const& strName) & MAYTHROW {\n\t\t\t\treturn child(/*ons*/ nullptr, strName); // MAYTHROW\n\t\t\t}\n\n\t\t\t// For <mso:control id=\"...\"> return a std::pair<Namespace, String>\n\t\t\t// with the namespace for prefix 'mso' and local name 'control'.\n\t\t\t// Namespace may be nullptr if the current tag has no namespace.\n\t\t\t// https://www.w3.org/TR/2006/REC-xml-names11-20060816/#concepts\n\t\t\tauto expanded_name() & MAYTHROW {\n\t\t\t\tauto const pairstrstr = split_qualified_name(qualified_tag_name());\n\t\t\t\tauto const ons = namespace_for_prefix(pairstrstr.first);\n\t\t\t\t\n\t\t\t\t// Namespace prefixes must be declared\n\t\t\t\t// https://www.w3.org/TR/2006/REC-xml-names11-20060816/#nsc-NSDeclared\n\t\t\t\tif(!ons && !tc::empty(pairstrstr.first)) {\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.invalid_namespace_prefix)>(m_itchEntityBegin); // MAYTHROW\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn std::make_pair(ons, pairstrstr.second);\n\t\t\t}\n\n\t\t\t// Do not use in typical parsing code. Instead use more specific child(ns, \"...\").\n\t\t\tbool child() & MAYTHROW {\n\t\t\t\tEnsureFreshSkipWhitespaceCharacters(); // MAYTHROW\n\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\tm_bConsumed=true;\n\t\t\t\t\treturn true;\n\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\tm_bConsumed=false;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid expect_child(Namespace ons, auto const& strName) & MAYTHROW {\n\t\t\t\tif (!child(ons, strName)) {\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.child_expected)>(m_itchEntityBegin, strName); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid expect_child(auto const& strName) & MAYTHROW {\n\t\t\t\texpect_child(/*ons*/ nullptr, strName); // MAYTHROW\n\t\t\t}\n\n\t\t\tbool skip_child(Namespace ons, auto const& strName) & MAYTHROW {\n\t\t\t\tif (child(ons, strName)) { // MAYTHROW\n\t\t\t\t\tskip_rest_of_element(); // MAYTHROW\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool skip_child(auto const& strName) & MAYTHROW {\n\t\t\t\treturn skip_child(/*ons*/ nullptr, strName); // MAYTHROW\n\t\t\t}\n\n\n\t\t\tvoid skip_rest_of_element() & MAYTHROW {\n\t\t\t\tEnsureFresh(); // MAYTHROW\n\t\t\t\tm_bConsumed=true;\n\t\t\t\tSkipRestOfElementInternal(); // MAYTHROW\n\t\t\t}\n\n\t\t\tbool skip() & MAYTHROW {\n\t\t\t\tEnsureFresh(); // MAYTHROW\n\t\t\t\tm_bConsumed=true;\n\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\tcase exmlentityCDATA:\n\t\t\t\tcase exmlentityCHARACTERS:\n\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t\treturn true;\n\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t\tSkipRestOfElementInternal(); // MAYTHROW\n\t\t\t\t\treturn true;\n\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We deliberately do not offer bool element_end() because we want our code to be like the XML schema syntax.\n\t\t\t// Match whatever comes before the end, and if it does not match, expect_element_end().\n\t\t\tvoid expect_element_end() & MAYTHROW {\n\t\t\t\tEnsureFreshSkipWhitespaceCharacters(); // MAYTHROW\n\t\t\t\tm_bConsumed=true;\n\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.element_end_expected)>(m_itchEntityBegin); // MAYTHROW\n\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\tcase exmlentityCLOSINGTAG: ;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool find_child(Namespace ons, auto const& strName) & MAYTHROW {\n\t\t\t\tEnsureFresh(); // MAYTHROW\n\t\t\t\tm_bConsumed=true;\n\t\t\t\tfor(;;) {\n\t\t\t\t\tswitch_no_default(m_exmlentity) {\n\t\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto const paironsstr = expanded_name(); // MAYTHROW\n\t\t\t\t\t\t\tif(ons==paironsstr.first && tc::equal(strName, paironsstr.second)) return true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(exmlentityOPENINGTAG==m_exmlentity) {\n\t\t\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t\t\t\tSkipRestOfElementInternal(); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase exmlentityCDATA:\n\t\t\t\t\tcase exmlentityCHARACTERS:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool find_child(auto const& strName) & MAYTHROW {\n\t\t\t\treturn find_child(/*ons*/ nullptr, strName); // MAYTHROW\n\t\t\t}\n\n\t\t\tvoid expect_find_child(Namespace ons, auto const& strName) & MAYTHROW {\n\t\t\t\tif (!find_child(ons, strName)) {\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.child_expected)>(m_itchEntityBegin, strName); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid expect_find_child(auto const& strName) & MAYTHROW {\n\t\t\t\texpect_find_child(/*ons*/ nullptr, strName); // MAYTHROW\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto attribute(auto const& strName) & noexcept {\n\t\t\t\t// TODO: Attributes can have qualified names **but** the default namespace never applies to unqualified attributes:\n\t\t\t\t// An attribute with unqualified name always has no namespace value, not the default namespace.\n\t\t\t\t// See https://www.w3.org/TR/2006/REC-xml-names11-20060816/#scoping-defaulting\n\t\t\t\t_ASSERTANYOF(m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityOPENINGTAG));\n\t\t\t\treturn tc::and_then(\n\t\t\t\t\ttc::find_first_if<tc::return_element_or_null>(m_vecpairstrAttributes, [&](auto const& pairstrstr) noexcept {\n\t\t\t\t\t\treturn tc::equal(pairstrstr.first, strName);\n\t\t\t\t\t}),\n\t\t\t\t\t[&](auto const& pairstrstr) noexcept {\n\t\t\t\t\t\treturn std::optional(xml::decode(pairstrstr.second));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto attributes() const& noexcept {\n\t\t\t\treturn tc::transform(\n\t\t\t\t\tm_vecpairstrAttributes,\n\t\t\t\t\t[&](auto const& pairstrstr) noexcept {\n\t\t\t\t\t\t// FIXME: Support attribute without value\n\t\t\t\t\t\treturn std::make_pair(pairstrstr.first, xml::decode(pairstrstr.second));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto expect_attribute(auto const& strName) & MAYTHROW {\n\t\t\t\tauto ostr = attribute(strName);\n\t\t\t\tif (!ostr) {\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.attribute_expected)>(m_itchEntityBegin, m_strMain, strName); // MAYTHROW\n\t\t\t\t}\n\t\t\t\treturn *tc_move(ostr);\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto parse_attribute(auto const& parser, auto const& strName) & MAYTHROW {\n\t\t\t\treturn tc::and_then(attribute(strName), [&](auto const& strAttribute) MAYTHROW {\n\t\t\t\t\tauto ot = parser(strAttribute);\n\t\t\t\t\tif (!ot) {\n\t\t\t\t\t\tthis->template warning_at<tc_mem_fn(.parse_warning)>(m_itchEntityBegin, m_strMain, strName); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t\treturn ot;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto expect_parse_attribute(auto const& parser, auto const& strName) & MAYTHROW {\n\t\t\t\tauto ot = parser(expect_attribute(strName)); // MAYTHROW\n\t\t\t\tif (!ot) {\n\t\t\t\t\tthis->template error_at<tc_mem_fn(.parse_error)>(m_itchEntityBegin, m_strMain, strName); // MAYTHROW\n\t\t\t\t}\n\t\t\t\treturn *tc_move(ot);\n\t\t\t}\n\n\t\t\ttemplate<typename T, template<typename> typename Parser>\n\t\t\tvoid assign_expect_parse_attribute(T& t, Parser<tc::deduce_tag> const&, auto const& strName) & MAYTHROW {\n\t\t\t\tt = expect_parse_attribute(Parser<T>(), strName); // MAYTHROW\n\t\t\t}\n\n\t\t\ttemplate<typename Str>\n\t\t\tNamespace /* may be nullptr */ namespace_for_prefix(Str const& strNsPrefix) const& noexcept {\n\t\t\t\tif(auto const opairstrns = tc::find_last_if<tc::return_element_or_null>(\n\t\t\t\t\tm_stkpairstrns,\n\t\t\t\t\t[&](auto const& pairstrns) noexcept {\n\t\t\t\t\t\treturn c_nsStackSeparator!=pairstrns.second\n\t\t\t\t\t\t\t&& tc::equal(pairstrns.first, strNsPrefix);\n\t\t\t\t\t}\n\t\t\t\t)) {\n\t\t\t\t\treturn opairstrns->second;\n\t\t\t\t} else {\n\t\t\t\t\treturn nullptr;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\tprotected:\n\t\t\ttc::slice_t< String const& > m_strMain;\n\t\t\tEXmlEntity m_exmlentity=exmlentitySTART;\n\t\t\tbool m_bConsumed;\n\t\t\t\t\n#ifdef _MSC_VER\n\t\t\tstatic constexpr Namespace c_nsStackSeparator = std::addressof(tc_as_constexpr(tc::string<char_type>{}));\n#else\n\t\t\tstatic tc::string<char_type> const c_strDummy;\n\t\t\tstatic Namespace const c_nsStackSeparator;\n#endif\n\t\t\ttc::vector<std::pair<tc::string< char_type >, Namespace>> m_stkpairstrns; // must not store sub_range in case input string is discarded\n\n\t\t\t// For <mso:control id=\"...\"> return the range 'mso:control'\n\t\t\tauto qualified_tag_name() const& noexcept {\n\t\t\t\t_ASSERTANYOF(m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityEMPTYELEMENTCLOSING)(exmlentityOPENINGTAG)(exmlentityCLOSINGTAG));\n\t\t\t\treturn m_strMain;\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttc::iterator_t<String const> m_itchEntityBegin;\n\t\t\ttc::vector<std::pair<tc::slice_t< String const& >, tc::slice_t< String const& >>> m_vecpairstrAttributes;\n\t\t\t\n\t\t\tvoid WithCharacters(auto func) & MAYTHROW {\n\t\t\t\tIF_TC_CHECKS(bool bOnce = false;)\n\t\t\t\ttc::for_each(\n\t\t\t\t\tcharacters(), // MAYTHROW\n\t\t\t\t\tno_adl::with_iterator_range{\n\t\t\t\t\t\t[&](auto const& strCharacters) MAYTHROW {\n\t\t\t\t\t\t\t_ASSERT(tc::change(bOnce, true));\n\t\t\t\t\t\t\tfunc(strCharacters);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvoid SkipUntil(char_type const ch) & MAYTHROW {\n\t\t\t\tfor(;;) {\n\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\tif(ch==*this->m_itchInput) break;\n\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid SkipOverGreaterThan() & MAYTHROW {\n\t\t\t\tSkipUntil(tc::char_ascii('>')); // MAYTHROW\n\t\t\t\t++this->m_itchInput;\n\t\t\t}\n\n\t\t\tvoid SkipOver(char_type const ch1, char_type const ch2) & MAYTHROW {\n\t\t\t\tbool bHave1=false;\n\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\tfor(;;) {\n\t\t\t\t\tbHave1 = ch1==*this->m_itchInput;\n\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\tif(ch2==*this->m_itchInput && bHave1) break;\n\t\t\t\t}\n\t\t\t\t++this->m_itchInput;\n\t\t\t}\n\n\t\t\tvoid SkipRestOfElementInternal() & MAYTHROW {\n\t\t\t\tint nOpenElements=1;\n\t\t\t\tfor(;;) {\n\t\t\t\t\tswitch(m_exmlentity) {\n\t\t\t\t\tcase exmlentityOPENINGTAG:\n\t\t\t\t\t\t++nOpenElements;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\t\t\t--nOpenElements;\n\t\t\t\t\t\tif(0==nOpenElements) return;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault: ;\n\t\t\t\t\t}\n\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid Next() & MAYTHROW {\n\t\t\trestart:\n\t\t\t\tif constexpr (has_discard_until<decltype((*this->m_strInput))>::value) {\n\t\t\t\t\tthis->m_strInput->discard_until(tc::iterator2index<String>(this->m_itchInput));\n\t\t\t\t}\n\n\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\tm_itchEntityBegin=this->m_itchInput;\n\t\t\t\tswitch(m_exmlentity) {\n\t\t\t\tcase exmlentityCLOSINGTAG:\n\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\t\ttc::take_inplace(\n\t\t\t\t\t\tm_stkpairstrns,\n\t\t\t\t\t\ttc::find_last_if<tc::return_element>(m_stkpairstrns, [&](auto const& pairstrns) noexcept {\n\t\t\t\t\t\t\treturn c_nsStackSeparator==pairstrns.second;\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: ;\n\t\t\t\t};\n\n\t\t\t\tif(tc::char_ascii('<')==*this->m_itchInput) {\n\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\tswitch(*this->m_itchInput) {\n\t\t\t\t\tcase tc::explicit_cast<char_type>('>'):\n\t\t\t\t\t\tthis->template error<tc_mem_fn(.name_expected)>(); // MAYTHROW\n\t\t\t\t\tcase tc::explicit_cast<char_type>('?'): // processing instruction or prolog\n\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\tSkipOver(tc::char_ascii('?'), tc::char_ascii('>'));\n\t\t\t\t\t\tgoto restart;\n\t\t\t\t\tcase tc::explicit_cast<char_type>('/'): // closing tag\n\t\t\t\t\t{\n\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\tauto const itchBegin=this->m_itchInput;\n\t\t\t\t\t\tSkipOverGreaterThan();\n\t\t\t\t\t\tm_exmlentity=exmlentityCLOSINGTAG;\n\t\t\t\t\t\tm_strMain=tc::slice(this->input(), itchBegin, tc_modified(this->m_itchInput, --_));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase tc::explicit_cast<char_type>('!'):\n\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\t\tswitch(*this->m_itchInput) {\n\t\t\t\t\t\tcase tc::explicit_cast<char_type>('-'): // comment\n\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\tthis->expect_literal(\"-\"_tc);\n\t\t\t\t\t\t\tSkipOver(tc::char_ascii('-'), tc::char_ascii('-'));\n\t\t\t\t\t\t\tthis->expect_literal(\">\"_tc);\n\t\t\t\t\t\t\tgoto restart;\n\t\t\t\t\t\tcase tc::explicit_cast<char_type>('['): // CDATA\n\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\tthis->expect_literal(\"CDATA[\"_tc);\n\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tauto const itchBegin=this->m_itchInput;\n\t\t\t\t\t\t\t\tint nClosing;\n\t\t\t\t\t\t\t\tdecltype(this->m_itchInput) aitchEnd[2];\n\t\t\t\t\t\t\t\tgoto start;\n\n\t\t\t\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\tstart:\n\t\t\t\t\t\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\t\t\t\t\t} while(tc::char_ascii(']')!=*this->m_itchInput);\n\n\t\t\t\t\t\t\t\t\tnClosing=0;\n\t\t\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\t\t\taitchEnd[nClosing&1]=this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\t\t\t\t\t\t++nClosing;\n\t\t\t\t\t\t\t\t\t} while(tc::char_ascii(']')==*this->m_itchInput);\n\n\t\t\t\t\t\t\t\t\tif(2<=nClosing && tc::char_ascii('>')==*this->m_itchInput) break;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tm_strMain=tc::slice(this->input(), itchBegin, aitchEnd[nClosing&1]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\tm_exmlentity=exmlentityCDATA;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tdefault: // DOCTYPE, ENTITY, etc.\n\t\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.unsupported_declaration_found)>(m_itchEntityBegin); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\tdefault: // opening tag or empty element\n\t\t\t\t\t\ttc::cont_assign(m_vecpairstrAttributes);\n\t\t\t\t\t\ttc::cont_emplace_back(m_stkpairstrns, tc::take(this->input(), tc::begin(this->input())), c_nsStackSeparator);\n\n\t\t\t\t\t\tauto itchBegin=this->m_itchInput;\n\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\t\t\tswitch(*this->m_itchInput) {\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('>'):\n\t\t\t\t\t\t\t\tm_strMain=tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\tm_exmlentity=exmlentityOPENINGTAG;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('/'):\n\t\t\t\t\t\t\t\tm_strMain=tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\tthis->expect_literal(\">\"_tc);\n\t\t\t\t\t\t\t\tm_exmlentity=exmlentityEMPTYELEMENT;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\tcase_whitespace:\n\t\t\t\t\t\t\t\tm_strMain=tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\t\t\t\tthis->skip_whitespace();\n\t\t\t\t\t\t\t\t\tswitch(*this->m_itchInput) {\n\t\t\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('>'):\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\tm_exmlentity=exmlentityOPENINGTAG;\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('/'):\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\tthis->expect_literal(\">\"_tc);\n\t\t\t\t\t\t\t\t\t\tm_exmlentity=exmlentityEMPTYELEMENT;\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\tdefault: ;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tauto strAttribute=[&]() MAYTHROW {\n\t\t\t\t\t\t\t\t\t\tauto itchBegin = this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\tfor(;;) {\n\t\t\t\t\t\t\t\t\t\t\tswitch(auto const ch = *this->m_itchInput) {\n\t\t\t\t\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('='):\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tauto strAttribute=tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (tc::empty(strAttribute)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.attribute_name_expected)>(); // MAYTHROW\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn strAttribute;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tcase_whitespace:\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tauto strAttribute=tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis->skip_whitespace();\n\t\t\t\t\t\t\t\t\t\t\t\t\tthis->expect_literal(\"=\"_tc);\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn strAttribute;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\t\t\tthis->expect_not_end(); // MAYTHROW\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}();\n\t\t\t\t\t\t\t\t\tthis->skip_whitespace();\n\n\t\t\t\t\t\t\t\t\tswitch(auto const ch=*this->m_itchInput) {\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\tthis->template error<tc_mem_fn(.quotation_marks_expected)>(); // MAYTHROW\n\t\t\t\t\t\t\t\t\tcase tc::explicit_cast<char_type>('\"'): case tc::explicit_cast<char_type>('\\''):\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\titchBegin=this->m_itchInput;\n\t\t\t\t\t\t\t\t\t\tSkipUntil(ch);\n\n\t\t\t\t\t\t\t\t\t\tauto strValue = tc::slice(this->input(), itchBegin, this->m_itchInput);\n\t\t\t\t\t\t\t\t\t\tif(auto ostrPrefix = [&]() MAYTHROW -> std::optional<tc::slice_t<String const&>> {\n\t\t\t\t\t\t\t\t\t\t\tif(auto ostr = tc::starts_with<tc::return_drop_or_none>(strAttribute, tc_ascii(\"xmlns\"))) {\n\t\t\t\t\t\t\t\t\t\t\t\tif(tc::starts_with<tc::return_bool>(*ostr, tc_ascii(\":\"))) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttc::drop_first_inplace(*ostr);\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(tc::empty(*ostr)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.parse_error)>(m_itchEntityBegin, m_strMain, strAttribute); // MAYTHROW\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn ostr;\n\t\t\t\t\t\t\t\t\t\t\t\t} else if(tc::empty(*ostr)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn ostr;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn std::nullopt;\n\t\t\t\t\t\t\t\t\t\t}()) {\n\t\t\t\t\t\t\t\t\t\t\ttc::cont_emplace_back(\n\t\t\t\t\t\t\t\t\t\t\t\tm_stkpairstrns,\n\t\t\t\t\t\t\t\t\t\t\t\ttc_move_always(*ostrPrefix),\n\t\t\t\t\t\t\t\t\t\t\t\ttc::empty(strValue) ? nullptr : this->register_namespace(strValue)\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\ttc::cont_emplace_back(m_vecpairstrAttributes, tc_move(strAttribute), strValue);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t++this->m_itchInput;\n\t\t\t\t\tSkipUntil(tc::char_ascii('<'));\n\t\t\t\t\tm_strMain=tc::slice(this->input(), m_itchEntityBegin, this->m_itchInput);\n\t\t\t\t\tm_exmlentity=exmlentityCHARACTERS;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid SkipWhitespaceCharacters() & MAYTHROW {\n\t\t\t\tfor(;;) {\n\t\t\t\t\tswitch(m_exmlentity) {\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase exmlentityCDATA:\n\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.unsupported_declaration_found)>(m_itchEntityBegin); // MAYTHROW\n\t\t\t\t\tcase exmlentityCHARACTERS:\n\t\t\t\t\t\ttc_auto_cref(itEnd, tc::end(m_strMain));\n\t\t\t\t\t\tfor (auto it = tc::begin(m_strMain); itEnd != it; ++it) {\n\t\t\t\t\t\t\tswitch(*it) {\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tthis->template error_at<tc_mem_fn(.characters_unexpected)>(it); // MAYTHROW\n\t\t\t\t\t\t\tcase_whitespace:\n\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tNext(); // MAYTHROW\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid EnsureFresh() & MAYTHROW {\n\t\t\t\tif(m_bConsumed) {\n\t\t\t\t\tif(exmlentityEMPTYELEMENT==m_exmlentity) {\n\t\t\t\t\t\tm_exmlentity=exmlentityEMPTYELEMENTCLOSING;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tNext();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvoid EnsureFreshSkipWhitespaceCharacters() & MAYTHROW {\n\t\t\t\tEnsureFresh(); // MAYTHROW\n\t\t\t\tSkipWhitespaceCharacters(); // MAYTHROW\n\t\t\t}\n\t\t};\n#pragma pop_macro(\"case_whitespace\")\n\n#ifndef _MSC_VER\n\t\ttemplate<typename String, typename ErrorHandler> tc::string<typename parser<String, ErrorHandler>::char_type> const parser<String, ErrorHandler>::c_strDummy{};\n\t\ttemplate<typename String, typename ErrorHandler> typename parser<String, ErrorHandler>::Namespace const parser<String, ErrorHandler>::c_nsStackSeparator = std::addressof(c_strDummy);\n#endif\n\t}\n\tusing no_adl::namespace_info;\n\tusing no_adl::parser;\n\n\tinline auto constexpr throw_parse_error = simple_error_handler([](tc::unused /*strInput*/) THROW(tc::xml::parse_error) {\n\t\tthrow tc::xml::parse_error();\n\t});\n\n\ttemplate<typename String, typename ErrorHandler, typename... Args>\n\t[[nodiscard]] auto make_parser(String&& str, ErrorHandler&& errorhandler, Args&&... args) MAYTHROW {\n\t\treturn no_adl::parser<String, tc::decay_t<ErrorHandler>>(tc_move_if_owned(str), tc_move_if_owned(errorhandler), tc_move_if_owned(args)...); // MAYTHROW\n\t}\n\t\n\tvoid for_each_descendant( auto& parser, auto funcOpen, auto funcClose) MAYTHROW {\n\t\tint nOpenElements = 1;\n\t\tfor(;;) {\n\t\t\tif(parser.child()) { // MAYTHROW\n\t\t\t\t++nOpenElements;\n\t\t\t\tfuncOpen();\n\t\t\t} else {\n\t\t\t\t--nOpenElements;\n\t\t\t\tif(0==nOpenElements) break;\n\n\t\t\t\tparser.expect_element_end(); // MAYTHROW\n\t\t\t\tfuncClose();\n\t\t\t}\n\t\t}\n\t}\n\n\tnamespace no_adl {\n\t\tinline struct {\n\t\t\t[[nodiscard]] std::optional<bool> operator()(auto const& str) const& noexcept {\n\t\t\t\tif (tc::equal(str, tc_ascii(\"0\")) || tc::equal(str, tc_ascii(\"false\"))) {\n\t\t\t\t\treturn false;\n\t\t\t\t} else if (tc::equal(str, tc_ascii(\"1\")) || tc::equal(str, tc_ascii(\"true\"))) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t}\n\t\t\t}\n\t\t} constexpr boolean;\n\n\t\ttemplate<typename T>\n\t\tstruct IntegerParser final {\n\t\t\t[[nodiscard]] std::optional<T> operator()(auto const& str) const& noexcept requires tc::actual_integer<T> && std::is_signed<T>::value {\n\t\t\t\treturn tc::x3parser(x3::int_parser<T>())(str);\n\t\t\t}\n\t\t};\n\t\ttemplate<typename T=tc::deduce_tag>\n\t\tconstexpr IntegerParser<T> integer = IntegerParser<T>();\n\n\t\ttemplate<typename T>\n\t\tstruct NonNegativeIntegerParser final {\n\t\t\t[[nodiscard]] std::optional<T> operator()(auto const& str) const& noexcept requires tc::actual_integer<T> {\n\t\t\t\treturn tc::x3parser(x3::uint_parser<T>())(str);\n\t\t\t}\n\t\t};\n\t\ttemplate<typename T=tc::deduce_tag>\n\t\tconstexpr NonNegativeIntegerParser<T> nonNegativeInteger = NonNegativeIntegerParser<T>();\n\n\t\ttemplate<typename T>\n\t\tstruct RealParser final {\n\t\t\t[[nodiscard]] std::optional<T> operator()(auto const& str) const& noexcept requires std::floating_point<T> {\n\t\t\t\treturn tc::x3parser(x3::real_parser<T>())(str);\n\t\t\t}\n\t\t};\n\t\ttemplate<typename T=tc::deduce_tag>\n\t\tconstexpr RealParser<T> real = RealParser<T>();\n\t}\n\tusing no_adl::boolean;\n\tusing no_adl::integer;\n\tusing no_adl::nonNegativeInteger;\n\tusing no_adl::real;\n}\n\nnamespace tc {\n\ttemplate<typename Rng>\n\tconstexpr auto enable_stable_index_on_move<xml::no_adl::decode_adaptor<Rng>> = tc::stable_index_on_move<Rng>;\n}\n\n"
  },
  {
    "path": "tc/string/xmlparser.t.cpp",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#include \"../base/assert_defs.h\"\n#include \"../base/ref.h\"\n#include \"../unittest.h\"\n\n#include \"xmlparser.h\"\n#include \"xmltransform.h\"\n\nstruct ExErrorHandled final {};\n\nUNITTESTDEF(xmlparser_error_handling) {\n\t{\n\t\tstruct SErrorHandler final : decltype(tc::xml::assert_no_error) {\n\t\t\tvoid child_expected(tc::span<char const> strInput, char const* itch, tc::span<char const> strName) const& THROW(ExErrorHandled) {\n\t\t\t\t_ASSERT(tc::equal(strInput, \"<a></a>\"));\n\t\t\t\t_ASSERT(tc::equal(tc::drop(strInput, itch), \"</a>\"));\n\t\t\t\t_ASSERT(tc::equal(strName, \"b\"));\n\t\t\t\tthrow ExErrorHandled();\n\t\t\t}\n\t\t};\n\t\tauto parser = tc::xml::make_parser(\"<a></a>\", SErrorHandler());\n\t\tparser.expect_child(\"a\");\n\t\ttry {\n\t\t\tparser.expect_child(\"b\");\n\t\t\t_ASSERTFALSE;\n\t\t} catch (ExErrorHandled const&) {\n\t\t}\n\t}\n\t{\n\t\tstruct SErrorHandler final : decltype(tc::xml::assert_no_error) {\n\t\t\tvoid attribute_expected(tc::span<char const> strInput, char const* itch, tc::span<char const> strTag, tc::span<char const> strName) const& THROW(ExErrorHandled) {\n\t\t\t\t_ASSERT(tc::equal(tc::drop(strInput, itch), strInput));\n\t\t\t\t_ASSERT(tc::equal(strTag, \"tag\"));\n\t\t\t\t_ASSERT(tc::equal(strName, \"missing\"));\n\t\t\t\tthrow ExErrorHandled();\n\t\t\t}\n\t\t};\n\t\tauto parser = tc::xml::make_parser(\"<tag name=\\\"value\\\"></tag>\", SErrorHandler());\n\t\tparser.expect_child(\"tag\");\n\t\ttry {\n\t\t\ttc::discard(parser.expect_attribute(\"missing\"));\n\t\t\t_ASSERTFALSE;\n\t\t} catch (ExErrorHandled const&) {\n\t\t}\n\t}\n\t{\n\t\tstruct SErrorHandler final : decltype(tc::xml::assert_no_error) {\n\t\t\tvoid parse_error(tc::unused, tc::unused, tc::unused) const& THROW(ExErrorHandled) {\n\t\t\t\tthrow ExErrorHandled();\n\t\t\t}\n\t\t\tvoid parse_error(tc::unused, tc::unused, tc::unused, tc::unused) const& THROW(ExErrorHandled) {\n\t\t\t\tthrow ExErrorHandled();\n\t\t\t}\n\t\t};\n\t\tauto parser = tc::xml::make_parser(\"<a>one</a>\", SErrorHandler());\n\t\t_ASSERT(parser.child(\"a\"));\n\t\ttry {\n\t\t\ttc::discard(parser.expect_parse_characters(tc::xml::integer<int>));\n\t\t\t_ASSERTFALSE;\n\t\t} catch (ExErrorHandled const&) {\n\t\t}\n\t}\n\t{\n\t\tstruct SErrorHandler final : decltype(tc::xml::assert_no_error) {\n\t\t\tvoid parse_error(tc::unused, tc::unused, tc::unused, tc::unused) const& THROW(ExErrorHandled) {\n\t\t\t\tthrow ExErrorHandled();\n\t\t\t}\n\t\t};\n\t\tauto parser = tc::xml::make_parser(\"<a number=\\\"one\\\"></a>\", SErrorHandler());\n\t\t_ASSERT(parser.child(\"a\"));\n\t\ttry {\n\t\t\ttc::discard(parser.expect_parse_attribute(tc::xml::integer<int>, \"number\"));\n\t\t\t_ASSERTFALSE;\n\t\t} catch (ExErrorHandled const&) {\n\t\t}\n\t}\n}\n\nnamespace {\n\tconstexpr char c_strMsoNamespace[] = {\"http://schemas.microsoft.com/office/2009/07/customui\"};\n}\n\nUNITTESTDEF(namespace_) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<mso:customUI xmlns:mso=\"http://schemas.microsoft.com/office/2009/07/customui\">\n\t<mso:ribbon>\n\t\t<mso:qat/>\n\t\t<mso:tabs/>\n\t</mso:ribbon>\n</mso:customUI>\n)\");\n\tauto parser=tc::xml::make_parser(asz, tc::xml::assert_no_error);\n\tauto const nsMSO = parser.register_namespace(c_strMsoNamespace);\n\t_ASSERT(parser.register_namespace(\"http://schemas.microsoft.com/office/2009/07/CustomUI\") != nsMSO);\n\t_ASSERT(parser.register_namespace(\"http://schemas.microsoft.com/office/2009/&#x30;&#x37;/customui\") == nsMSO);\n\t_ASSERT(parser.register_namespace(\"http://schemas.microsoft.com/office/2009/&#48;&#55;/customui\") == nsMSO);\n\tNOEXCEPT(parser.expect_child(nsMSO, \"customUI\"));\n\t\tNOEXCEPT(parser.expect_child(nsMSO, \"ribbon\"));\n\t\t\t_ASSERT(!parser.child(\"qat\"));\n\t\t\t_ASSERT(!parser.child(\"mso:qat\"));\n\t\t\tNOEXCEPT(parser.expect_child(nsMSO, \"qat\"));\n\t\t\tNOEXCEPT(parser.skip_rest_of_element());\n\t\t\tNOEXCEPT(parser.expect_child(nsMSO, \"tabs\"));\n}\n\nUNITTESTDEF(default_namespace) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns=\"http://schemas.microsoft.com/office/2009/07/customui\">\n\t<ribbon>\n\t\t<qat/>\n\t\t<tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\t\n\tauto parser=tc::xml::make_parser(asz, tc::xml::assert_no_error);\n\tauto const nsMSO = parser.register_namespace(c_strMsoNamespace);\n\tNOEXCEPT(parser.expect_child(nsMSO, \"customUI\"));\n\t\tNOEXCEPT(parser.expect_child(nsMSO, \"ribbon\"));\n\t\t\t_ASSERT(!parser.child(\"qat\")); // default namespace has a namespace value, so it must match\n\t\t\tNOEXCEPT(parser.expect_child(nsMSO, \"qat\"));\n\t\t\tNOEXCEPT(parser.skip_rest_of_element());\n\t\t\tNOEXCEPT(parser.expect_child(nsMSO, \"tabs\"));\n}\n\nUNITTESTDEF(namespace_prefix_undeclared) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"\">\n\t<ribbon>\n\t\t<mso:qat/>\n\t\t<mso:tabs xmlns:mso=\"test\"/>\n\t\t<mso:tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\t\n\tstruct SErrorHandler final : decltype(tc::xml::assert_no_error) {\n\t\tvoid invalid_namespace_prefix(tc::unused, tc::unused) const& THROW(ExErrorHandled) {\n\t\t\tthrow ExErrorHandled();\n\t\t}\n\t};\n\t\n\tauto parser=tc::xml::make_parser(asz, SErrorHandler());\n\ttry {\n\t\tNOEXCEPT(parser.expect_child(\"customUI\")); // default namespace has no value\n\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\tparser.expect_child(\"qat\"); // Prefixes must be declared and not have empty value: https://www.w3.org/TR/2006/REC-xml-names11-20060816/#nsc-NSDeclared\n\t\t_ASSERTFALSE;\n\t} catch(ExErrorHandled const&) {\n\t}\n}\n\nUNITTESTDEF(namespace_override) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"\">\n\t<ribbon>\n\t\t<qat/>\n\t\t<mso:tabs xmlns:mso=\"test\"/>\n\t\t<mso:tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\t\n\tauto parser=tc::xml::make_parser(asz, tc::xml::assert_no_error);\n\tauto const nsTEST = parser.register_namespace(\"test\");\n\t\n\tNOEXCEPT(parser.expect_child(\"customUI\")); // default namespace has no value\n\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\tNOEXCEPT(parser.expect_child(\"qat\"));\n\tNOEXCEPT(parser.skip_rest_of_element());\n\tNOEXCEPT(parser.expect_child(nsTEST, \"tabs\"));\n}\n\nUNITTESTDEF(default_namespace_override) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns=\"test\">\n\t<ribbon>\n\t\t<qat/>\n\t\t<tabs xmlns=\"\"/>\n\t\t<tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\t\n\tauto parser=tc::xml::make_parser(asz, tc::xml::assert_no_error);\n\tauto const nsTEST = parser.register_namespace(\"test\");\n\t\n\tNOEXCEPT(parser.expect_child(nsTEST, \"customUI\")); // default namespace has a value\n\tNOEXCEPT(parser.expect_child(nsTEST, \"ribbon\"));\n\t_ASSERT(!parser.child(\"qat\"));\n\tNOEXCEPT(parser.expect_child(nsTEST, \"qat\"));\n\tNOEXCEPT(parser.skip_rest_of_element());\n\t_ASSERT(!parser.child(nsTEST, \"tabs\"));\n\tNOEXCEPT(parser.expect_child(\"tabs\"));\n}\n\nUNITTESTDEF(xml_transform_append) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"\">\n\t<ribbon>\n\t\t<qat></qat>\n\t\t<mso:tabs xmlns:mso=\"test\"/>\n\t\t<tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto const nsTEST = transform.register_namespace(\"test\");\n\t\t\t\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\tNOEXCEPT(transform.expect_child(\"qat\"));\n\n\t\tNOEXCEPT(tc::append(\n\t\t\ttransform,\n\t\t\ttc::xml::opening_element(\"test\"),\n\t\t\ttc::xml::closing_element(\"test\")\n\t\t));\n\t\t\n\t\tNOEXCEPT(transform.skip_rest_of_element());\n\t\tNOEXCEPT(transform.expect_child(nsTEST, \"tabs\"));\n\n\t\tauto const strPrefix = transform.prefix_for_namespace(nsTEST);\n\t\tNOEXCEPT(tc::append(\n\t\t\ttransform,\n\t\t\ttc::xml::opening_element(strPrefix, \"test\"),\n\t\t\ttc::xml::closing_element(strPrefix, \"test\"),\n\t\t\ttc::xml::opening_element(strPrefix, \"test2\"),\n\t\t\ttc::xml::closing_element(strPrefix, \"test2\")\n\t\t));\n\t\tNOEXCEPT(transform.expect_element_end());\n\t\tNOEXCEPT(transform.expect_child(\"tabs\"));\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto const nsTEST = parser.register_namespace(\"test\");\n\t\t\t\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"qat\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"test\"));\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t  \n\t\tNOEXCEPT(parser.expect_child(nsTEST, \"tabs\"));\n\t\t\tNOEXCEPT(parser.expect_child(nsTEST, \"test\"));\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_child(nsTEST, \"test2\"));\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\n\nUNITTESTDEF(xml_transform_insert_and_parse) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"\">\n\t<ribbon>\n\t\t<qat></qat>\n\t\t<mso:tabs xmlns:mso=\"test\"/>\n\t\t<tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto const nsTEST = transform.register_namespace(\"test\");\n\t\t\t\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\t{\n\t\t\tauto const e = NOEXCEPT(transform.insert_elements_after(\n\t\t\t\ttc::concat( \n\t\t\t\t\ttc::xml::opening_element(\"test\"),\n\t\t\t\t\ttc::xml::opening_element(\"test2\")\n\t\t\t\t),\n\t\t\t\ttc::concat( \n\t\t\t\t\ttc::xml::closing_element(\"test2\"),\n\t\t\t\t\ttc::xml::closing_element(\"test\")\n\t\t\t\t)\n\t\t\t));\n\n\t\t\tNOEXCEPT(transform.expect_child(\"qat\"));\n\t\t\tNOEXCEPT(transform.skip_rest_of_element());\n\t\t}\n\n\t\tNOEXCEPT(transform.expect_child(nsTEST, \"tabs\"));\n\n\t\t{\n\t\t\tauto const e = NOEXCEPT(transform.insert_elements_before(\n\t\t\t\ttc::concat( \n\t\t\t\t\ttc::xml::opening_element(\"test\"),\n\t\t\t\t\ttc::xml::opening_element(\"test2\")\n\t\t\t\t),\n\t\t\t\ttc::concat( \n\t\t\t\t\ttc::xml::closing_element(\"test2\"),\n\t\t\t\t\ttc::xml::closing_element(\"test\")\n\t\t\t\t)\n\t\t\t));\n\t\t\tNOEXCEPT(transform.expect_element_end());\n\t\t\tNOEXCEPT(transform.expect_child(\"tabs\"));\n\t\t\tNOEXCEPT(transform.drop_element());\n\t\t}\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto const nsTEST = parser.register_namespace(\"test\");\n\t\t\t\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\t\tNOEXCEPT(parser.expect_child(\"test\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(\"test2\"));\n\t\t\t\t\t\tNOEXCEPT(parser.expect_child(\"qat\"));\n\t\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\n\t\t\t\t\n\t\t\t\tNOEXCEPT(parser.expect_child(\"test\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(\"test2\"));\n\t\t\t\t\t\tNOEXCEPT(parser.expect_child(nsTEST, \"tabs\"));\n\t\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\nUNITTESTDEF(xml_transform_modify_attributes) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI>\n\t<ribbon foo=\"1\" bar=\"something\"/>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\tNOEXCEPT(transform.modify_element_attributes(\n\t\t\ttc::xml::format_attributes(\n\t\t\t\ttc::filter(\n\t\t\t\t\ttransform.attributes(),\n\t\t\t\t\t[](auto const& strKey, auto const& strValue) noexcept {\n\t\t\t\t\t\treturn !tc::equal(strKey, \"foo\");\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t),\n\t\t\t\" foo=\\\"2\\\"\"\n\t\t));\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\t\t\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t_ASSERT(tc::equal(*parser.attribute(\"bar\"), \"something\"));\n\t\t_ASSERT(tc::equal(*parser.attribute(\"foo\"), \"2\"));\n\t}\n}\n\nUNITTESTDEF(xml_transform_insert_empty_child_before) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"test\">\n\t<ribbon/>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto const nsTEST = transform.register_namespace(\"test\");\n\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\t// lookup strPrefix here because we are doing insert_before()!\n\t\t// <ribbon> may change the prefix of namespace test\n\t\tauto const strPrefix = transform.prefix_for_namespace(nsTEST);\n\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\tNOEXCEPT(tc::append(\n\t\t\ttransform.insert_before(),\n\t\t\ttc::xml::empty_element(\n\t\t\t\tstrPrefix,\n\t\t\t\t\"element\",\n\t\t\t\t\" foo=\\\"bar\\\"\"\n\t\t\t)\n\t\t));\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto const nsTEST = parser.register_namespace(\"test\");\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(nsTEST, \"element\"));\n\t\t\t_ASSERT(tc::equal(*parser.attribute(\"foo\"), \"bar\"));\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\n\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\n\nUNITTESTDEF(xml_transform_insert_before2) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"test\">\n\t<ribbon/>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto ons = transform.register_namespace(\"test\");\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\tNOEXCEPT(transform.expect_element_end());\n\n\t\tauto const strPrefix = transform.prefix_for_namespace(ons);\n\t\tNOEXCEPT(tc::append(\n\t\t\ttransform.insert_before(),\n\t\t\ttc::xml::opening_element(strPrefix, \"element\", \" foo=\\\"bar\\\"\"),\n\t\t\ttc::xml::opening_element(strPrefix, \"element2\", \" foo=\\\"bar\\\"\"),\n\t\t\ttc::xml::closing_element(strPrefix, \"element2\"),\n\t\t\ttc::xml::closing_element(strPrefix, \"element\")\n\t\t));\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto ons = parser.register_namespace(\"test\");\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\t\tNOEXCEPT(parser.expect_child(ons, \"element\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(ons, \"element2\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\nUNITTESTDEF(xml_transform_insert_elements_before) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"test\">\n\t<ribbon/>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto ons = transform.register_namespace(\"test\");\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\n\t\tauto const strPrefix = transform.prefix_for_namespace(ons);\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\n\t\tauto b = NOEXCEPT(transform.insert_elements_before(\n\t\t\ttc::concat(\n\t\t\t\ttc::xml::opening_element(strPrefix, \"element\", \" foo=\\\"bar\\\"\"),\n\t\t\t\ttc::xml::opening_element(strPrefix, \"element2\", \" foo=\\\"bar\\\"\")\n\t\t\t),\n\t\t\ttc::concat(\n\t\t\t\ttc::xml::closing_element(strPrefix, \"element2\"),\n\t\t\t\ttc::xml::closing_element(strPrefix, \"element\")\n\t\t\t)\n\t\t));\n\n\t\tNOEXCEPT(transform.expect_element_end());\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto ons = parser.register_namespace(\"test\");\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(ons, \"element\"));\n\t\t\t\tNOEXCEPT(parser.expect_child(ons, \"element2\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\n\nUNITTESTDEF(xml_transform_insert_child_before3) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI xmlns:mso=\"test\">\n\t<ribbon/>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tauto ons = transform.register_namespace(\"test\");\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\n\t\tauto const strPrefix = transform.prefix_for_namespace(ons);\n\t\tif(!NOEXCEPT(transform.child(\"element\"))) {\n\t\t\tNOEXCEPT(tc::append(\n\t\t\t\ttransform.insert_before(),\n\t\t\t\ttc::xml::opening_element(strPrefix, \"element\", \" foo=\\\"bar\\\"\"),\n\t\t\t\ttc::xml::opening_element(strPrefix, \"element2\", \" foo=\\\"bar\\\"\"),\n\t\t\t\ttc::xml::closing_element(strPrefix, \"element2\"),\n\t\t\t\ttc::xml::closing_element(strPrefix, \"element\")\n\t\t\t));\n\t\t}\n\n\t\tNOEXCEPT(transform.expect_element_end());\n\t\tNOEXCEPT(transform.expect_element_end());\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tauto ons = parser.register_namespace(\"test\");\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\t\tNOEXCEPT(parser.expect_child(ons, \"element\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(ons, \"element2\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\nUNITTESTDEF(xml_transform_drop_element) {\n\ttc_static_auto_constexpr_litstr(asz, R\"(\n<customUI>\n\t<ribbon>\n\t\t<qat></qat>\n\t\t<mso:tabs xmlns:mso=\"test\"/>\n\t\t<mso:tabs/>\n\t</ribbon>\n</customUI>\n)\");\n\ttc::string<char> strOutput;\n\t{\n\t\tauto transform=tc::xml::make_transform(asz, tc::xml::assert_no_error, strOutput);\n\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\tNOEXCEPT(transform.expect_child(\"ribbon\"));\n\t\tNOEXCEPT(transform.drop_element());\n\t}\n\t\n\t{\n\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\tNOEXCEPT(parser.expect_element_end());\n\t}\n}\n\nnamespace\n{\n\t// MSVC doesn't like it at function scope for some reason.\n\tauto constexpr MatchOrInsertTest = [](tc::span<char const> strXml) noexcept {\n\t\ttc::string<char> strOutput;\n\t\t{\n\t\t\tauto transform=tc::xml::make_transform(strXml, tc::xml::assert_no_error, strOutput);\n\t\t\tNOEXCEPT(transform.expect_child(\"customUI\"));\n\t\t\tauto on1 = NOEXCEPT(transform.match_or_insert_child(\"ribbon\"));\n\t\t\tauto on2 = NOEXCEPT(transform.match_or_insert_child(\"tabs\"));\n\t\t}\n\t\n\t\t{\n\t\t\tauto parser=tc::xml::make_parser(strOutput, tc::xml::assert_no_error);\n\t\t\tNOEXCEPT(parser.expect_child(\"customUI\"));\n\t\t\t\tNOEXCEPT(parser.expect_child(\"ribbon\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_child(\"tabs\"));\n\t\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t\tNOEXCEPT(parser.expect_element_end());\n\t\t}\n\t};\n}\n\nUNITTESTDEF(xml_transform_match_or_insert_child) {\n\tMatchOrInsertTest(R\"(\n\t\t<customUI>    \n\t\t</customUI>\n\t)\");\n\t\n\tMatchOrInsertTest(R\"(\n\t\t<customUI>\n\t\t\t<ribbon/>\n\t\t</customUI>\n\t)\");\n\t\n\tMatchOrInsertTest(R\"(\n\t\t<customUI>\n\t\t\t<ribbon></ribbon>\n\t\t</customUI>\n\t)\");\n\t\n\tMatchOrInsertTest(R\"(\n\t\t<customUI>\n\t\t\t<ribbon>\n\t\t\t\t<tabs/>\n\t\t\t</ribbon>\n\t\t</customUI>\n\t)\");\n\n\tMatchOrInsertTest(R\"(\n\t\t<customUI>\n\t\t\t<ribbon>\n\t\t\t\t<tabs>\n\t\t\t\t</tabs>\n\t\t\t</ribbon>\n\t\t</customUI>\n\t)\");\n}\n"
  },
  {
    "path": "tc/string/xmltransform.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"char.h\"\n#include \"xmlparser.h\"\n#include \"../range/conditional_range.h\"\n\nnamespace tc::xml {\n\t[[nodiscard]] auto format_attributes(auto&& rngattr) noexcept {\n\t\treturn tc::join_with_separator(\n\t\t\ttc_ascii(\" \"),\n\t\t\ttc::transform(\n\t\t\t\ttc_move_if_owned(rngattr),\n\t\t\t\t[&](auto const& strKey, auto const& strValue) noexcept {\n\t\t\t\t\treturn tc::concat(strKey, tc_ascii(\"=\\\"\"), strValue, tc_ascii(\"\\\"\"));\n\t\t\t\t}\n\t\t\t) \n\t\t);\n\t}\n\n\t[[nodiscard]] auto opening_element(auto&& strPrefix, auto&& strElement, auto&& strAttributes) noexcept {\n\t\tauto const bEmptyPrefix = tc::empty(strPrefix);\n\t\treturn tc::concat(\n\t\t\ttc_ascii(\"<\"),\n\t\t\ttc_move_if_owned(strPrefix),\n\t\t\ttc_conditional_range(!bEmptyPrefix, tc_ascii(\":\")),\n\t\t\ttc_move_if_owned(strElement),\n\t\t\ttc_move_if_owned(strAttributes),\n\t\t\ttc_ascii(\">\")\n\t\t);\n\t}\n\n\t[[nodiscard]] auto opening_element(auto&& strPrefix, auto&& strElement) noexcept {\n\t\treturn opening_element(tc_move_if_owned(strPrefix), tc_move_if_owned(strElement), tc::empty_range());\n\t}\n\n\t[[nodiscard]] auto opening_element(auto&& strElement) noexcept {\n\t\treturn opening_element(tc::empty_range(), tc_move_if_owned(strElement), tc::empty_range());\n\t}\n\n\t[[nodiscard]] auto closing_element(auto&& strPrefix, auto&& strElement) noexcept {\n\t\tauto const bEmptyPrefix = tc::empty(strPrefix);\n\t\treturn tc::concat(\n\t\t\ttc_ascii(\"</\"),\n\t\t\ttc_move_if_owned(strPrefix),\n\t\t\ttc_conditional_range(!bEmptyPrefix, tc_ascii(\":\")),\n\t\t\ttc_move_if_owned(strElement),\n\t\t\ttc_ascii(\">\")\n\t\t);\n\t}\n\n\t[[nodiscard]] auto closing_element(auto&& strElement) noexcept {\n\t\treturn closing_element(tc::empty_range(), tc_move_if_owned(strElement));\n\t}\n\n\t[[nodiscard]] auto empty_element(auto&& strPrefix, auto&& strElement, auto&& strAttributes) noexcept {\n\t\tauto const bEmptyPrefix = tc::empty(strPrefix);\n\t\treturn tc::concat(\n\t\t\ttc_ascii(\"<\"),\n\t\t\ttc_move_if_owned(strPrefix),\n\t\t\ttc_conditional_range(!bEmptyPrefix, tc_ascii(\":\")),\n\t\t\ttc_move_if_owned(strElement),\n\t\t\ttc_move_if_owned(strAttributes),\n\t\t\ttc_ascii(\"/>\")\n\t\t);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename String, typename ErrorHandler, typename Output>\n\t\tstruct [[nodiscard]] transform : private parser<String, ErrorHandler>, tc::inside_unwinding {\n\t\tprivate:\n\t\t\tusing base_ = parser<String, ErrorHandler>;\n\t\tpublic:\n\t\t\tusing typename base_::char_type;\n\t\t\t\n\t\t\tusing SetNamespace=typename base_::SetNamespace;\n\t\t\tusing Namespace=typename base_::Namespace;\n\n\t\t\tstatic_assert(!has_discard_until<decltype((*transform<String, ErrorHandler, Output>::m_strInput))>::value);\n\n\t\t\texplicit transform(String&& strInput, ErrorHandler errorhandler, Output& output) MAYTHROW\n\t\t\t\t: base_(tc_move_if_owned(strInput), tc_move(errorhandler)), m_output(output)\n\t\t\t\t, m_itchOut(tc::begin(*(this->m_strInput)))\n\t\t\t{}\n\t\t\t\n\t\t\t~transform() {\n\t\t\t\tif(!inside_stack_unwinding()) {\n\t\t\t\t\tif(OutputEmptyElementCloseTag()) { // MAYTHROW\n\t\t\t\t\t\t// Skip the original empty element tag\n\t\t\t\t\t\t_ASSERT(exmlentityEMPTYELEMENT==this->m_exmlentity || exmlentityEMPTYELEMENTCLOSING==this->m_exmlentity);\n\t\t\t\t\t\t_ASSERT(exmlentityEMPTYELEMENTCLOSING==this->m_exmlentity || this->m_bConsumed);\n\t\t\t\t\t\tif(exmlentityEMPTYELEMENT==this->m_exmlentity || !this->m_bConsumed) { \n\t\t\t\t\t\t\tbase_::expect_element_end(); // MAYTHROW\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_ASSERTEQUAL(this->m_exmlentity, exmlentityEMPTYELEMENTCLOSING);\n\t\t\t\t\t\t_ASSERT(this->m_bConsumed);\n\t\t\t\t\t\tm_itchOut = this->m_itchInput;\n\t\t\t\t\t}\n\t\t\t\t\ttc::append(\n\t\t\t\t\t\tm_output,\n\t\t\t\t\t\ttc::slice(*this->m_strInput, m_itchOut, tc::end(*this->m_strInput))\n\t\t\t\t\t); // MAYTHROW\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\ttemplate<typename ...Attributes>\n\t\t\tvoid modify_element_attributes(Attributes&& ...attr) & MAYTHROW {\n\t\t\t\t_ASSERT(this->m_bConsumed);\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityOPENINGTAG));\n\t\t\t\tOutputBeforeElement(); // MAYTHROW\n\n\t\t\t\ttc::append(\n\t\t\t\t\tm_output,\n\t\t\t\t\ttc_ascii(\"<\"), this->qualified_tag_name(),\n\t\t\t\t\ttc_ascii(\" \"),\n\t\t\t\t\ttc_move_if_owned(attr)...,\n\t\t\t\t\ttc_conditional_range(\n\t\t\t\t\t\texmlentityEMPTYELEMENT==this->m_exmlentity,\n\t\t\t\t\t\ttc_ascii(\"/>\"),\n\t\t\t\t\t\ttc_ascii(\">\")\n\t\t\t\t\t)\n\t\t\t\t); // MAYTHROW\n\t\t\t\tm_itchOut = this->m_itchInput;\n\t\t\t}\n\n\t\t\t[[nodiscard]] Output& insert_before() & noexcept {\n\t\t\t\tif(exmlentityEMPTYELEMENTCLOSING==this->m_exmlentity) {\n\t\t\t\t\tSplitEmptyElement(); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\tm_itchOut = OutputBeforeElement(); // MAYTHROW\n\t\t\t\t}\n\t\t\t\treturn m_output;\n\t\t\t}\n\n\t\tprivate:\n\t\t\t// just call tc::append(transform, ...) \n\t\t\t[[nodiscard]] Output& insert_after() & MAYTHROW {\n\t\t\t\t_ASSERT(this->m_bConsumed);\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityEMPTYELEMENTCLOSING)(exmlentityOPENINGTAG)(exmlentityCLOSINGTAG));\n\t\t\t\tif(exmlentityEMPTYELEMENT==this->m_exmlentity) {\n\t\t\t\t\tSplitEmptyElement(); // MAYTHROW\n\t\t\t\t} else {\n\t\t\t\t\ttc::append(m_output, tc::slice(*this->m_strInput, m_itchOut, this->m_itchInput)); // MAYTHROW\n\t\t\t\t\tm_itchOut = this->m_itchInput;\n\t\t\t\t}\n\t\t\t\treturn m_output;\n\t\t\t}\n\n\t\tpublic:\n\t\t\tfriend auto appender_impl(transform& self) noexcept {\n\t\t\t\treturn tc::appender(\n\t\t\t\t\tself.m_bConsumed\n\t\t\t\t\t? self.insert_after()\n\t\t\t\t\t: self.insert_before()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto insert_elements_before(auto&& strOpen, auto&& strClose) MAYTHROW {\n\t\t\t\t// If inserting before a closing tag: What do you need the RAII return value for?\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityOPENINGTAG));\n\t\t\t\ttc::append(insert_before(), tc_move_if_owned(strOpen)); // MAYTHROW\n\t\t\t\treturn tc::make_append_on_dtor(*this, tc_move_if_owned(strClose));\n\t\t\t}\n\n\t\t\t// insert_elements_after allows parsing and outputting further elements after\n\t\t\t// appending strOpen and before appending strClose\n\t\t\t[[nodiscard]] auto insert_elements_after(auto&& strOpen, auto&& strClose) MAYTHROW {\n\t\t\t\ttc::append(insert_after(), tc_move_if_owned(strOpen)); // MAYTHROW\n\t\t\t\treturn tc::make_append_on_dtor(*this, tc_move_if_owned(strClose));\n\t\t\t}\n\n\t\tprivate:\n\t\t\t[[nodiscard]] auto closing_element_on_dtor(auto&& strPrefix, auto&& strTag) noexcept {\n\t\t\t\treturn tc::make_append_on_dtor(\n\t\t\t\t\t*this,\n\t\t\t\t\ttc::xml::closing_element(tc_move_if_owned(strPrefix),tc_move_if_owned(strTag))\n\t\t\t\t);\n\t\t\t}\n\n\t\tpublic:\n\t\t\ttemplate<typename Str>\n\t\t\t[[nodiscard]] auto match_or_insert_child(Namespace ons, Str&& strTag) & MAYTHROW\n\t\t\t\t-> std::optional<decltype(\n\t\t\t\tclosing_element_on_dtor(std::declval<tc::string<char_type>&&>(), tc_move_if_owned(strTag))\n\t\t\t)> {\n\t\t\t\tauto strPrefix = prefix_for_namespace(ons);\n\t\t\t\tif(this->child(ons, strTag)) { // MAYTHROW\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERT(!this->m_bConsumed);\n\t\t\t\t\ttc::append(\n\t\t\t\t\t\tinsert_before(),\n\t\t\t\t\t\ttc::xml::opening_element(strPrefix, strTag)\n\t\t\t\t\t);\n\t\t\t\t\treturn closing_element_on_dtor(tc_move(strPrefix), tc_move_if_owned(strTag));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto match_or_insert_child(auto&& strTag) & MAYTHROW {\n\t\t\t\treturn match_or_insert_child(/*namespace*/ nullptr, tc_move_if_owned(strTag));\n\t\t\t}\n\n\t\t\t[[nodiscard]] auto drop_element_parse_children() & MAYTHROW {\n\t\t\t\t_ASSERT(this->m_bConsumed);\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityOPENINGTAG));\n\t\t\t\tOutputBeforeElement(); // MAYTHROW\n\t\t\t\tm_itchOut = this->m_itchInput;\n\n\t\t\t\tstruct drop_closing_tag final : tc::noncopyable, tc::inside_unwinding {\n\t\t\t\t\texplicit drop_closing_tag(transform& transform) noexcept : m_transform(transform) {}\n\t\t\t\t\tdrop_closing_tag(drop_closing_tag&&)=default;\n\t\t\t\t\t~drop_closing_tag() MAYTHROW {\n\t\t\t\t\t\tif(!inside_stack_unwinding()) {\n\t\t\t\t\t\t\tm_transform.expect_element_end(); // MAYTHROW\n\t\t\t\t\t\t\tif(exmlentityCLOSINGTAG==m_transform.m_exmlentity) {\n\t\t\t\t\t\t\t\tm_transform.OutputBeforeElement(); // MAYTHROW\n\t\t\t\t\t\t\t\tm_transform.m_itchOut = m_transform.m_itchInput;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t_ASSERTEQUAL(m_transform.m_exmlentity, exmlentityEMPTYELEMENTCLOSING);\n\t\t\t\t\t\t\t\t_ASSERTEQUAL(m_transform.m_itchOut, m_transform.m_itchInput);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tprivate:\n\t\t\t\t\ttransform& m_transform;\n\t\t\t\t};\n\t\t\t\treturn drop_closing_tag(*this);\n\t\t\t}\n\n\t\t\tvoid drop_element() & MAYTHROW {\n\t\t\t\t_ASSERT(this->m_bConsumed);\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityOPENINGTAG));\n\t\t\t\tOutputBeforeElement(); // MAYTHROW\n\t\t\t\tthis->skip_rest_of_element(); // MAYTHROW\n\t\t\t\tm_itchOut = this->m_itchInput;\n\t\t\t}\n\t\t\t\n\t\t\t// Methods inherited unchanged from tc::xml::parser\n\t\t\tusing base_::register_namespace;\n\t\t\tusing base_::namespace_for_prefix;\n\t\t\t\n\t\t\ttc::string<char_type> prefix_for_namespace(Namespace ons) const& noexcept {\n\t\t\t\tif(ons) {\n\t\t\t\t\tif(auto const opairstrns = tc::find_last_if<tc::return_element_or_null>(\n\t\t\t\t\t\tthis->m_stkpairstrns,\n\t\t\t\t\t\t[&](auto const& pairstrns) noexcept {\n\t\t\t\t\t\t\treturn ons==pairstrns.second;\n\t\t\t\t\t\t}\n\t\t\t\t\t)) {\n\t\t\t\t\t\treturn opairstrns->first;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t_ASSERTFALSE; // FIXME: Throw?\n\t\t\t\t\t\treturn tc::string<char_type>();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif(auto const opairstrns = tc::find_last_if<tc::return_element_or_null>(\n\t\t\t\t\t\tthis->m_stkpairstrns,\n\t\t\t\t\t\t[&](auto const& pairstrns) noexcept {\n\t\t\t\t\t\t\treturn tc::empty(pairstrns.first)\n\t\t\t\t\t\t\t\t&& pairstrns.second\n\t\t\t\t\t\t\t\t&& this->c_nsStackSeparator!=pairstrns.second;\n\t\t\t\t\t\t}\n\t\t\t\t\t)) {\n\t\t\t\t\t\t// Default namespace has been redefined\n\t\t\t\t\t\t_ASSERTFALSE; // FIXME: Throw? \n\t\t\t\t\t\treturn tc::string<char_type>();\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn tc::string<char_type>();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tusing base_::semantic_error;\n\n\t\t\tusing base_::attribute;\n\t\t\tusing base_::attributes;\n\t\t\tusing base_::expect_attribute;\n\n\t\t\tusing base_::expanded_name;\n\t\t\tusing base_::qualified_tag_name;\n\n\t\t\tusing base_::child;\n\t\t\tusing base_::expect_child;\n\n\t\t\tusing base_::skip_child;\n\n\t\t\t// Output the injected close tag for an empty element when the empty element close tag is parsed\n\t\t\tvoid skip_rest_of_element() & MAYTHROW { OutputEmptyElementCloseTag(); base_::skip_rest_of_element(); }\n\t\t\t// We deliberately do not offer bool element_end() because we want our code to be like the XML schema syntax.\n\t\t\t// Match whatever comes before the end, and if it does not match, expect_element_end().\n\t\t\tvoid expect_element_end() & MAYTHROW { OutputEmptyElementCloseTag(); base_::expect_element_end(); }\n\n\t\tprivate:\n\t\t\tOutput& m_output;\n\t\t\tstatic_assert(tc::appendable<tc::span<char_type const>, Output&>);\n\t\t\t\n\t\t\tdecltype(tc::begin(*transform<String, ErrorHandler, Output>::m_strInput)) m_itchOut;\n\t\t\ttc::string<char_type> m_strCloseTag;\n\n\t\t\tauto OutputBeforeElement() & MAYTHROW {\n\t\t\t\tauto itch = tc::begin(this->m_strMain); // MAYTHROW\n\t\t\t\tswitch_no_default(this->m_exmlentity) {\n\t\t\t\t\tcase exmlentityCLOSINGTAG: // </\n\t\t\t\t\t\t--itch; // MAYTHROW\n\t\t\t\t\t\t[[fallthrough]];\n\t\t\t\t\tcase exmlentityOPENINGTAG: // <\n\t\t\t\t\tcase exmlentityEMPTYELEMENT:\n\t\t\t\t\tcase exmlentityEMPTYELEMENTCLOSING:\n\t\t\t\t\t\t--itch; // MAYTHROW\n\t\t\t\t}\n\t\t\t\ttc::append(m_output, tc::slice(*this->m_strInput, m_itchOut, itch)); // MAYTHROW\n\t\t\t\treturn itch;\n\t\t\t}\n\n\t\t\tvoid SplitEmptyElement() & MAYTHROW {\n\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityEMPTYELEMENTCLOSING));\n\t\t\t\tif(tc::empty(m_strCloseTag)) {\n\t\t\t\t\tm_itchOut = OutputBeforeElement(); // MAYTHROW\n\t\t\t\t\tauto const str = tc::slice(*this->m_strInput, m_itchOut, this->m_itchInput);\n\t\t\t\t\ttc::append(\n\t\t\t\t\t\tm_output,\n\t\t\t\t\t\ttc::ends_with<tc::return_take>(str, tc_ascii(\"/>\")),\n\t\t\t\t\t\ttc_ascii(\">\")\n\t\t\t\t\t); // MAYTHROW\n\t\t\t\t\t\n\t\t\t\t\ttc::cont_assign(m_strCloseTag, this->qualified_tag_name());\n\t\t\t\t} else {\n\t\t\t\t\t_ASSERT(tc::equal(m_strCloseTag, this->qualified_tag_name()));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool OutputEmptyElementCloseTag() & MAYTHROW {\n\t\t\t\tif(!tc::empty(m_strCloseTag)) {\n\t\t\t\t\t_ASSERTANYOF(this->m_exmlentity, (exmlentityEMPTYELEMENT)(exmlentityEMPTYELEMENTCLOSING));\n\t\t\t\t\ttc::append(m_output, tc_ascii(\"</\"), m_strCloseTag, tc_ascii(\">\")); // MAYTHROW\n\t\t\t\t\ttc::cont_assign(m_strCloseTag);\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tusing no_adl::transform;\n\t\n\ttemplate<typename String, typename ErrorHandler, typename Output, typename... Args> requires tc::appendable<tc::span<tc::range_value_t<String>>, Output&>\n\t[[nodiscard]] auto make_transform(String&& str, ErrorHandler&& errorhandler, Output& output, Args&&... args) MAYTHROW {\n\t\treturn no_adl::transform<String, tc::decay_t<ErrorHandler>, Output>(tc_move_if_owned(str), tc_move_if_owned(errorhandler), output, tc_move_if_owned(args)...); // MAYTHROW\n\t}\n}\n"
  },
  {
    "path": "tc/tuple.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/invoke.h\"\n#include \"base/move.h\"\n#include \"base/explicit_cast_fwd.h\"\n\nnamespace tc {\n\ttemplate<typename Tuple>\n\tconcept tuple_or_derived = std::same_as<Tuple, std::remove_cvref_t<Tuple>> && requires { Tuple::tc_tuple_size; };\n\n\t// std::tuple from Microsofts STL is using a recursive implementation which is very slow.\n\t// We use the same technique to implement tuple as libc++, but omit all constructors\n\t// (std::tuple has 18 constructors and 14 are conditionally explicit) and use an almost\n\t// trivial get implementation.\n\tnamespace tuple_detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate<std::size_t n, typename T, bool bEmpty = tc::empty_type<T>>\n\t\t\tstruct tuple_member;\n\n\t\t\ttemplate<std::size_t n, typename T>\n\t\t\tstruct tuple_member<n, T, /*bEmpty*/false> { T m_t; };\n\n\t\t\ttemplate<std::size_t n, typename T>\n\t\t\tstruct TC_EMPTY_BASES tuple_member<n, T, /*bEmpty*/true> {\n\t\t\t\ttuple_member() = default;\n\t\t\t\tconstexpr tuple_member(T) noexcept {}\n\t\t\t};\n\n\t\t\ttemplate<std::size_t n, typename T>\n\t\t\tstruct tuple_member<n, T&, /*bEmpty*/false> {\n\t\t\t\tT& m_t;\n\n\t\t\t\tconstexpr tuple_member(T& t) noexcept : m_t(t) {}\n\t\t\t\tconstexpr tuple_member(tuple_member const&) noexcept = default;\n\t\t\t\tconstexpr void operator=(tuple_member const& src) /*no &*/ noexcept requires std::is_assignable<T&, T&>::value {\n\t\t\t\t\tm_t = src.m_t;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Do not provide tuple_member<n, T&&>::operator=(tuple_member &&/const&) for now, i.e., they are implicitly deleted.\n\n\t\t\ttemplate<typename IndexSeq, typename... T>\n\t\t\tstruct tuple_elements;\n\n\t\t\ttemplate<std::size_t... n, typename... T>\n\t\t\tstruct tuple_elements<std::index_sequence<n...>, T...> : tuple_member<n, T>... {};\n\t\t}\n\n\t\tusing no_adl::tuple_member;\n\t\tusing no_adl::tuple_elements;\n\n#pragma push_macro(\"GET_IMPL\")\n#define GET_IMPL(param1, param2, cvref) \\\n\t\ttemplate<param1, param2> \\\n\t\t[[nodiscard]] constexpr auto get(tuple_member<n, T, /*bEmpty*/false> cvref elem) noexcept -> T cvref { \\\n\t\t\treturn static_cast<T cvref>(elem.m_t); \\\n\t\t}\n\n\t\tGET_IMPL(std::size_t n, typename T, &)\n\t\tGET_IMPL(std::size_t n, typename T, &&)\n\t\tGET_IMPL(std::size_t n, typename T, const&)\n\t\tGET_IMPL(std::size_t n, typename T, const&&)\n\t\tGET_IMPL(typename T, std::size_t n, &)\n\t\tGET_IMPL(typename T, std::size_t n, &&)\n\t\tGET_IMPL(typename T, std::size_t n, const&)\n\t\tGET_IMPL(typename T, std::size_t n, const&&)\n\t\t// no volatile overloads, like std::get(std::tuple)\n#pragma pop_macro(\"GET_IMPL\")\n\n\t\ttemplate<std::size_t n, typename T>\n\t\tconstexpr T get(tuple_member<n, T, /*bEmpty*/true>) noexcept { return T{}; }\n\t\ttemplate<typename T, std::size_t n>\n\t\tconstexpr T get(tuple_member<n, T, /*bEmpty*/true>) noexcept { return T{}; }\n\n\t\ttemplate<std::size_t n, typename T>\n\t\tT std_tuple_element_impl(tuple_member<n, T> const&); // declaration only\n\n\t\ttemplate<std::size_t... n, typename... T, typename Rhs>\n\t\tconstexpr void assign(tuple_elements<std::index_sequence<n...>, T...>& lhs, Rhs&& rhs) // return_decltype_MAYTHROW confuses MSVC 19.39\n\t\t\tnoexcept((noexcept(tuple_detail::get<n>(lhs) = tc::get<n>(tc_move_if_owned(rhs))) && ...))\n\t\t\trequires((requires{tuple_detail::get<n>(lhs) = tc::get<n>(tc_move_if_owned(rhs));}) && ...)\n\t\t{\n\t\t\t(void(tuple_detail::get<n>(lhs) = tc::get<n>(tc_move_if_owned(rhs))), ...);\n\t\t}\n\n\t\ttemplate<std::size_t... n, typename... T>\n\t\tconstexpr auto convert(std::type_identity<tuple_elements<std::index_sequence<n...>, T...>>, auto&& tplelemsrc) return_MAYTHROW(\n\t\t\ttuple_elements<std::index_sequence<n...>, T...>{ {T{tuple_detail::get<n>(tc_move_if_owned(tplelemsrc))}}... }\n\t\t)\n\n\t\ttemplate<std::size_t... n, typename... T, typename... U>\n\t\tconstexpr bool equals(tuple_elements<std::index_sequence<n...>, T...> const& lhs, tuple_elements<std::index_sequence<n...>, U...> const& rhs) noexcept {\n\t\t\treturn ((tuple_detail::get<n>(lhs) == tuple_detail::get<n>(rhs)) && ...);\n\t\t}\n\n\t\ttemplate<std::size_t... n, typename... T>\n\t\tconstexpr void swap(tuple_elements<std::index_sequence<n...>, T...>& lhs, tuple_elements<std::index_sequence<n...>, T...>& rhs) noexcept {\n\t\t\t(tc::swap(tuple_detail::get<n>(lhs), tuple_detail::get<n>(rhs)), ...);\n\t\t}\n\t}\n\n\tnamespace tuple_adl {\n\t\t// Leave this as a class to have a shorter type in function signatures.\n\t\ttemplate<typename... T>\n\t\tstruct tuple {\n\t\t\t// To initialize every element from a single expression, use this syntax:\n\t\t\t//   tc::tuple<int, int> tuplenn = {1,2};\n\t\t\t// Otherwise, use the \"double-brace\" syntax:\n\t\t\t//   tc::tuple<X, X> tuplexx = {{ {a,b}, {c, d} }};\n\t\t\t[[no_unique_address]] tuple_detail::tuple_elements<std::make_index_sequence<sizeof...(T)>, T...> m_elements; // private except for get, aggregate initialization and usage as NTTP.\n\n\t\t\t// We use std::remove_reference_t<Tuple>::tc_tuple_size to restrict the argument Tuple&& to be tc::tuple in overloads found via adl.\n\t\t\tstatic constexpr std::size_t tc_tuple_size = sizeof...(T);\n\n\t\t\ttemplate<ENABLE_SFINAE, typename Src> requires\n\t\t\t\t(std::tuple_size<std::remove_cvref_t<Src>>::value == sizeof...(T)) &&\n\t\t\t\t(!tc::derived_from<std::remove_reference_t<Src>, tuple>) // make sure default assignment operator wins in overload resolution. e.g. tc::tuple is a mutable member.\n\t\t\tconstexpr auto/*=void, returning tuple& may turn xvalue into lvalue*/ operator=(Src&& src) /*no &*/ return_decltype_MAYTHROW(\n\t\t\t\ttuple_detail::assign(m_elements, tc_move_if_owned(src))\n\t\t\t)\n\n#pragma push_macro(\"DEFINE_CONVERSION_OPERATOR\")\n#define DEFINE_CONVERSION_OPERATOR(cvref) \\\n\t\t\ttemplate<typename... U> requires (tc::safely_convertible_to<T cvref, U> && ...) \\\n\t\t\tconstexpr operator tuple<U...>() cvref noexcept(std::conjunction<std::is_nothrow_constructible<U, T cvref>...>::value) { \\\n\t\t\t\treturn {tuple_detail::convert( \\\n\t\t\t\t\tstd::type_identity<tuple_detail::tuple_elements<std::make_index_sequence<sizeof...(U)>, U...>>(), \\\n\t\t\t\t\tstatic_cast<tuple cvref>(*this).m_elements \\\n\t\t\t\t)}; \\\n\t\t\t}\n\n\t\t\tDEFINE_CONVERSION_OPERATOR(&)\n\t\t\tDEFINE_CONVERSION_OPERATOR(const&)\n\t\t\tDEFINE_CONVERSION_OPERATOR(&&)\n\t\t\tDEFINE_CONVERSION_OPERATOR(const&&)\n#pragma pop_macro(\"DEFINE_CONVERSION_OPERATOR\")\n\t\t};\n\n\t\ttemplate<typename... T, typename... TSource, std::enable_if_t<sizeof...(T)==sizeof...(TSource)>* = nullptr>\n\t\tconstexpr auto explicit_convert_impl(std::type_identity<tuple<T...>>, TSource&&... src) return_decltype_MAYTHROW(\n\t\t\ttuple<T...>{\n\t\t\t\ttc::explicit_cast<T>(tc_move_if_owned(src))... // tc_move_if_owned doesn't compile with VS17.9\n\t\t\t}\n\t\t)\n\n\t\ttemplate<std::size_t n, typename Tuple> requires tuple_or_derived<std::remove_cvref_t<Tuple>>\n\t\t[[nodiscard]] constexpr decltype(auto) get(Tuple&& tuple) noexcept {\n\t\t\treturn tuple_detail::get<n>(tc_move_if_owned(tuple).m_elements);\n\t\t}\n\n\t\ttemplate<typename T, typename Tuple> requires tuple_or_derived<std::remove_cvref_t<Tuple>>\n\t\t[[nodiscard]] constexpr decltype(auto) get(Tuple&& tuple) noexcept {\n\t\t\treturn tuple_detail::get<T>(tc_move_if_owned(tuple).m_elements);\n\t\t}\n\n\t\ttemplate<std::size_t... n, typename... T, typename... U>\n\t\t[[nodiscard]] constexpr bool operator==(tuple<T...> const& lhs, tuple<U...> const& rhs) noexcept {\n\t\t\treturn tuple_detail::equals(lhs.m_elements, rhs.m_elements);\n\t\t}\n\n\t\ttemplate<typename... T>\n\t\tconstexpr void swap(tuple<T&...>&& lhs, tuple<T&...>&& rhs) noexcept {\n\t\t\ttc::swap(lhs, rhs);\n\t\t}\n\n\t\ttemplate<typename... T>\n\t\tconstexpr void swap(tuple<T...>& lhs, tuple<T...>& rhs) noexcept {\n\t\t\tstatic_assert((std::is_nothrow_swappable<T>::value && ...));\n\t\t\treturn tuple_detail::swap(lhs.m_elements, rhs.m_elements);\n\t\t}\n\n\t\t// </<= operators defined in compare.h\n\t\t// for_each defined in for_each.h\n\t}\n\tusing tuple_adl::tuple;\n\n\t// tc::safely_constructible_from<tc::tuple, ...>\n\tnamespace no_adl {\n\t\t// Consider every construction unsafe, except construction from ... \n\t\ttemplate <typename... T, typename... Args>\n\t\tstruct is_class_safely_constructible<tc::tuple<T...>, Args...> : tc::constant<false> {};\n\n\t\t//  - exact number of safely_constructible_from arguments\n\t\ttemplate <typename... T, typename... Args> requires (sizeof...(T) == sizeof...(Args))\n\t\tstruct is_class_safely_constructible<tc::tuple<T...>, Args...> : tc::constant<(tc::safely_constructible_from<T, Args> && ...)> {};\n\n\t\t//  - tuple-like with matching number of safely_constructible_from elements\n\t\ttemplate <typename TupleArg, typename IndexSeq, typename... T>\n\t\tstruct is_tuple_safely_constructible;\n\n\t\ttemplate <typename TupleArg, std::size_t... n, typename... T>\n\t\tstruct is_tuple_safely_constructible<TupleArg, std::index_sequence<n...>, T...>\n\t\t\t: tc::constant<(tc::safely_constructible_from<T, decltype(tc::get<n>(std::declval<TupleArg>()))> && ...)>\n\t\t{};\n\n\t\ttemplate <typename... T, typename TupleArg>\n\t\t\trequires (sizeof...(T) == std::tuple_size<tc::remove_ref_temporary_t<TupleArg>>::value)\n\t\tstruct is_class_safely_constructible<tc::tuple<T...>, TupleArg> : is_tuple_safely_constructible<TupleArg, std::index_sequence_for<T...>, T...> {};\n\t}\n\n\t// TODO tc::decay_t<tc::tuple>, reevaluate deep decay and adjust tc::common_type_t<tc::tuple> appropriately.\n\n\t// tc::common_type_t<tc::tuple, tc::tuple>\n\tnamespace no_adl {\n\t\ttemplate<typename... T, typename... U> requires requires { typename tc::tuple<tc::common_reference_t<T, U>...>; }\n\t\tstruct common_type_decayed_impl<tc::tuple<T...>, tc::tuple<U...>> : std::type_identity<\n\t\t\ttc::tuple<tc::common_reference_t<T, U>...>\n\t\t> {};\n\t}\n\n\t// tc::common_reference_t<tc::tuple, tc::tuple>\n\tnamespace tuple_detail {\n\t\ttemplate<typename Tuple0, typename Tuple1, std::size_t... n>\n\t\ttc::tuple<\n\t\t\ttc::common_reference_t<\n\t\t\t\ttc::apply_cvref_t<std::tuple_element_t<n, std::remove_reference_t<Tuple0>>, Tuple0>,\n\t\t\t\ttc::apply_cvref_t<std::tuple_element_t<n, std::remove_reference_t<Tuple1>>, Tuple1>\n\t\t\t>...\n\t\t> common_reference_tuple_impl(std::index_sequence<n...>); // declaration only\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Tuple0, typename Tuple1>\n\t\trequires tc::instance<std::remove_reference_t<Tuple0>, tc::tuple> && tc::instance<std::remove_reference_t<Tuple1>, tc::tuple>\n\t\t\t&& (std::tuple_size<std::remove_reference_t<Tuple0>>::value == std::tuple_size<std::remove_reference_t<Tuple1>>::value)\n\t\t\t&& (!std::same_as<std::remove_cvref_t<Tuple0>, std::remove_cvref_t<Tuple1>>)\n\t\t\t&& requires {\n\t\t\t\ttc::tuple_detail::common_reference_tuple_impl<Tuple0, Tuple1>(std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple0>>::value>());\n\t\t\t}\n\t\tstruct common_reference_impl<Tuple0, Tuple1> : std::type_identity<decltype(\n\t\t\ttc::tuple_detail::common_reference_tuple_impl<Tuple0, Tuple1>(std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple0>>::value>())\n\t\t)> {};\n\t}\n\n\ttemplate<typename T>\n\tusing unwrap_ref_decay_t = typename std::unwrap_reference<tc::decay_t<T>>::type;\n\n\t// Provide supporting functions that come with std::tuple.\n\ttemplate<typename... T>\n\t[[nodiscard]] constexpr tc::tuple<tc::unwrap_ref_decay_t<T>...> make_tuple(T&&... t) MAYTHROW {\n\t\treturn {{ {tc::unwrap_ref_decay_t<T>(tc_move_if_owned(t))}... }};\n\t}\n\n\ttemplate<typename... T>\n\t[[nodiscard]] constexpr tc::tuple<T&&...> tie(T&&... t) noexcept {\n\t\treturn {{ {tc_move_if_owned(t)}... }};\n\t}\n\n\tnamespace tuple_detail::no_adl {\n\t\ttemplate<typename Result>\n\t\tstruct fn_tuple_cat final { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tconstexpr auto operator()(auto&&... args) MAYTHROW {\n\t\t\t\treturn Result{{ {tc_move_if_owned(args)}... }}; // MAYTHROW\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename... Tuple>\n\t[[nodiscard]] constexpr auto tuple_cat(Tuple&&... tuple) MAYTHROW {\n\t\tusing tuple_type = boost::mp11::mp_apply<tc::tuple, boost::mp11::mp_append<typename tc::is_instance<tc::decay_t<Tuple>, tc::tuple>::arguments...>>;\n\t\treturn tc_apply_pack(tuple_detail::no_adl::fn_tuple_cat<tuple_type>(), tc_move_if_owned(tuple)); // MAYTHROW\n\t}\n\n\tnamespace tuple_detail::no_adl {\n\t\ttemplate<typename Fn>\n\t\tstruct fn_tuple_transform final { // MSVC workaround: not a lambda for shorter symbol names\n\t\t\tFn m_fn;\n\t\t\tconstexpr auto operator()(auto&&... args) MAYTHROW {\n\t\t\t\treturn tc::tuple<decltype(tc_invoke(m_fn, tc_move_if_owned(args)))...>{{ {tc_invoke(m_fn, tc_move_if_owned(args))}... }};\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename Tuple, typename Fn>\n\t[[nodiscard]] constexpr auto tuple_transform(Tuple&& tuple, Fn&& fn) MAYTHROW {\n\t\treturn tc_apply(tuple_detail::no_adl::fn_tuple_transform<tc::decay_t<Fn>>{tc_move_if_owned(fn)}, tc_move_if_owned(tuple));\n\t}\n}\n\nnamespace std {\n\t// Structured bindings use std::tuple_size and std::tuple_element\n\ttemplate<tc::tuple_or_derived Tuple>\n\tstruct tuple_size<Tuple> : tc::constant<Tuple::tc_tuple_size> {};\n\n\ttemplate<std::size_t n, tc::tuple_or_derived Tuple>\n\tstruct tuple_element<n, Tuple> {\n\t\tusing type = decltype(tc::tuple_detail::std_tuple_element_impl<n>(std::declval<Tuple>().m_elements));\n\t};\n}\n"
  },
  {
    "path": "tc/unittest.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n#include \"array.h\" // tc::single\n#include \"container/container.h\" // tc::vector\n\nnamespace tc {\n\t// create a generator range that gives the same values as the rng it takes (for testing)\n\ttemplate<typename Rng> \n\tconstexpr auto make_generator_range(Rng&& rng) noexcept {\n\t\treturn tc::generator_range_output<tc::mp_transform<std::add_rvalue_reference_t, tc::range_output_t<decltype(*tc::as_const(tc::as_lvalue(tc::make_reference_or_value(tc_move_if_owned(rng)))))>>>([rng=tc::make_reference_or_value(tc_move_if_owned(rng))](auto&& sink) noexcept {\n\t\t\treturn tc::for_each(*rng, tc_move_if_owned(sink));\n\t\t});\n\t}\n\t\n\t//--------------------------------------------------------------------------------------------------------------------------\n\t// chunk_range\n\t// convert range to range of chunks\n\n\tnamespace no_adl {\n\t\ttemplate<typename RngChunk, typename Sink>\n\t\tstruct chunk_range_sink {\n\t\t\tSink& m_sink;\n\n\t\t\tauto chunk(RngChunk rng) const& return_decltype_MAYTHROW(m_sink(static_cast<RngChunk&&>(rng)))\n\n\t\t\ttemplate<typename T>\n\t\t\tauto operator()(T&& t) const& return_decltype_MAYTHROW(chunk(tc::single(tc_move_if_owned(t))))\n\t\t};\n\n\t\ttemplate<typename RngChunk, typename Rng>\n\t\tstruct chunk_range_adaptor {\n\t\t\ttc::reference_or_value<Rng> m_baserng;\n\t\t\tfriend auto range_output_t_impl(chunk_range_adaptor const&) -> boost::mp11::mp_list<RngChunk>; // declaration only\n\n\t\t\ttemplate<typename Sink>\n\t\t\tauto operator()(Sink sink) const& noexcept {\n\t\t\t\treturn tc::for_each(*m_baserng, chunk_range_sink<RngChunk, Sink&>{sink});\n\t\t\t}\n\t\t};\n\t}\n\n\ttemplate<typename RngChunk, typename Rng>\n\tno_adl::chunk_range_adaptor<RngChunk, Rng> chunk_range(Rng&& rng) noexcept {\n\t\treturn {tc::make_reference_or_value(tc_move_if_owned(rng))};\n\t}\n\n}\n\n//-----------------------------------------------------------------------------------------------------------------------------\n// Unit test macros and output\n\n#ifdef TC_PRIVATE\n\n#include \"Library/ErrorReporting/UnitTest.h\"\n\n#define TEST_RANGE_EQUAL(EXPECT, IS) _ASSERT(tc::equal(EXPECT, IS))\n#define TEST_EQUAL(EXPECT, IS) _ASSERTEQUAL(IS, EXPECT);\n#define TEST_OUTPUT(...)\n\n#else\n\n#include <ostream>\n#include <sstream>\n#include <iostream>\n#define UNITTEST_PRINT_NAME(testname) std::cerr << \"Running Unit test '\" << #testname << \"' ...\" << std::endl;\n\n#define UNITTESTDEF(testname)                                                                                                 \\\n\tvoid testname##UnitTest();                                                                                                \\\n\tstruct C##testname##UnitTest{                                                                                             \\\n\t\tC##testname##UnitTest() {                                                                                             \\\n\t\t\tUNITTEST_PRINT_NAME(testname)                                                                                     \\\n\t\t\ttestname##UnitTest();                                                                                             \\\n\t\t}                                                                                                                     \\\n\t};                                                                                                                        \\\n\tC##testname##UnitTest g_unittest##testname;                                                                               \\\n\tvoid testname##UnitTest()\n\n\nnamespace tc {\n\t//-------------------------------------------------------------------------------------------------------------------------\n\t// print_range - debug helper\n\tnamespace detail {\n\t\ttemplate<typename OStream>\n\t\tstruct print_elem final {\n\t\t\tprint_elem(OStream& os_, std::size_t max_elems) noexcept : os(os_), elems(max_elems) {} \n\n\t\t\ttemplate<typename Elem>\n\t\t\tbreak_or_continue operator()(Elem&& e) noexcept {\n\t\t\t\tif constexpr (requires (OStream& os, Elem& e) { os << e; }) {\n\t\t\t\t\tos << e;\n\t\t\t\t} else {\n\t\t\t\t\tos << \"???\";\n\t\t\t\t}\n\t\t\t\tos << \", \";\n\t\t\t\t--elems;\n\t\t\t\tif( elems > 0 ) {\n\t\t\t\t\treturn continue_;\n\t\t\t\t} else {\n\t\t\t\t\treturn break_;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tprivate:\n\t\t\t\tOStream& os;\n\t\t\t\tstd::size_t elems;\n\t\t};\n\t}\n\n\ttemplate<typename Rng>\n\tauto dbg_print_rng(Rng&& rng, std::size_t const max_elems = 50) noexcept {\n\t\tstd::stringstream os;\n\t\tos << \"[\";\n\t\tfor_each(rng, std::ref(tc::as_lvalue(detail::print_elem<std::stringstream>(os, max_elems))) );\n\t\tos << \"]\";\n\t\treturn os.str();\n\t}\n}\n\n#\tdefine TEST_RANGE_EQUAL(EXPECT, IS) {   bool e = tc::equal(EXPECT, IS);\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\tif (!e) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\tstd::cerr << \"Fail: Ranges differ:\\n\"\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \"Expected: \" << tc::dbg_print_rng(EXPECT) << \"\\n\"\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \"Is      : \" << tc::dbg_print_rng(IS) << std::endl;\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t_ASSERT(tc::equal(EXPECT, IS));\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t}}\n#\tdefine TEST_EQUAL(EXPECT, IS)       {   bool e = EXPECT == IS;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\tif (!e) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\tstd::cerr << \"Fail: Values differ:\\n\"\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \"Expected: \" << EXPECT << \"\\n\"\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \"Is      : \" << IS << std::endl;\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t_ASSERTEQUAL(IS, EXPECT);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t}}\n#\tdefine TEST_OUTPUT(...) std::cerr __VA_ARGS__\n\n#endif\n\n#define TEST_init_hack(CTYPE, ETYPE, NAME, ...) \\\n\tETYPE internal_array_##NAME[] = __VA_ARGS__; \\\n\tauto NAME = CTYPE<ETYPE>(internal_array_##NAME, \\\n\t\t\t\t\t\t\t\t\tinternal_array_##NAME + sizeof(internal_array_##NAME)/sizeof(ETYPE));\n\n#define UNUSED_TEST_VARIABLE(v) static_cast<void>(v)\n\n#define TEST_RANGE_LENGTH(RNG, LENGTH) _ASSERTEQUAL(tc::size(RNG), LENGTH)\n#define TEST_RANGE_NOT_EQUAL(EXPECT, IS) _ASSERT(!tc::equal(EXPECT, IS))\n#define TEST_NOT_EQUAL(EXPECT, IS) _ASSERT(!(EXPECT == IS));\n\n#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__ \" is not true.\")\n\n\n#if defined(__clang__) || defined(_MSC_VER)\n\t#define GCC_WORKAROUND_STATIC_ASSERT static_assert\n#else // Fixed in GCC 13: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92505\n\t#define GCC_WORKAROUND_STATIC_ASSERT _ASSERT\n#endif\n"
  },
  {
    "path": "tc/variant.h",
    "content": "\n// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n#pragma once\n\n#include \"base/assert_defs.h\"\n#include \"base/type_traits.h\"\n#include \"base/functors.h\"\n#include \"base/casts.h\"\n#include \"base/explicit_cast.h\"\n#include \"base/invoke_with_constant.h\"\n#include \"optional.h\"\n#include <variant>\n\n/*\n Extensions to make std::variant easier to use\n\n std::get_if takes a pointer to the variant and returns a pointer.\n tc::get_if takes a reference to the variant and returns tc::optional<TRef>.\n*/\n\nnamespace tc {\n\ttemplate<std::size_t I, typename Variant> requires (I < boost::mp11::mp_size<typename tc::is_instance_or_derived<std::remove_reference_t<Variant>, std::variant>::arguments>::value)\n\t[[nodiscard]] constexpr auto get_if(Variant&& v) noexcept -> tc::optional<tc::apply_cvref_t<std::variant_alternative_t<I, typename tc::is_instance_or_derived<std::remove_reference_t<Variant>, std::variant>::base_instance>, Variant&&>> {\n\t\tif(auto pval=std::get_if<I>(std::addressof(v))) {\n\t\t\treturn tc::forward_like<Variant>(*pval);\n\t\t} else {\n\t\t\treturn std::nullopt;\n\t\t}\n\t}\n\n\ttemplate<typename T, typename Variant> requires boost::mp11::mp_set_contains<typename tc::is_instance_or_derived<std::remove_reference_t<Variant>, std::variant>::arguments, T>::value\n\t[[nodiscard]] constexpr auto get_if(Variant&& v) noexcept -> tc::optional<tc::apply_cvref_t<T, Variant&&>> {\n\t\tif(auto pval=std::get_if<T>(std::addressof(v))) {\n\t\t\treturn tc::forward_like<Variant>(*pval);\n\t\t} else {\n\t\t\treturn std::nullopt;\n\t\t}\n\t}\n}\n\n/*\n tc::get overloads for std::variant so we can use tc::get<I> with tuples and variants.\n \n```\n\tstd::variant<int, std::string> var = \"Hello World\";\n\t_ASSERT(tc::equal(tc::get<1>(var), \"Hello World\"));\n\n\tstatic_assert(std::is_same_v<decltype(tc::get<1>(tc_move(var))), std::string&&>);\n\tauto str(tc::get<1>(tc_move(var))); // will call move constructor\n\n```\n*/\nnamespace tc_get_impl {\n\ttemplate<std::size_t I, typename Variant> requires (I < boost::mp11::mp_size<typename tc::is_instance_or_derived<std::remove_reference_t<Variant>, std::variant>::arguments>::value)\n\t[[nodiscard]] constexpr decltype(auto) get(Variant&& v) noexcept {\n\t\treturn tc::forward_like<Variant>(*VERIFYNORETURN(tc::get_if<I>(v)));\n\t}\n\n\ttemplate<typename T, typename Variant> requires boost::mp11::mp_set_contains<typename tc::is_instance_or_derived<std::remove_reference_t<Variant>, std::variant>::arguments, T>::value\n\t[[nodiscard]] constexpr decltype(auto) get(Variant&& v) noexcept {\n\t\treturn tc::forward_like<Variant>(*VERIFYNORETURN(tc::get_if<T>(v)));\n\t}\n}\n\nnamespace tc {\n\tnamespace detail {\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Overload>\n\t\t\tstruct overload_result_type final {\n\t\t\t\ttemplate<typename... Args>\n\t\t\t\tusing with_args = decltype(tc_invoke_pack(std::declval<Overload const&>(), std::declval<Args>()));\n\n\t\t\t\ttemplate<typename ArgList>\n\t\t\t\tusing with_arglist = boost::mp11::mp_apply<with_args, ArgList>;\n\t\t\t};\n\t\t}\n\n\t\ttemplate<typename Overload, typename... Variants>\n\t\tusing visit_result_t = boost::mp11::mp_apply<\n\t\t\ttc::common_reference_t,\n\t\t\ttc::mp_transform<\n\t\t\t\tno_adl::overload_result_type<Overload>::template with_arglist,\n\t\t\t\tboost::mp11::mp_product<\n\t\t\t\t\tboost::mp11::mp_list,\n\t\t\t\t\ttc::mp_transform<\n\t\t\t\t\t\tboost::mp11::mp_bind_back<tc::same_cvref_t, Variants>::template fn,\n\t\t\t\t\t\ttypename tc::is_instance_or_derived<std::remove_reference_t<Variants>, std::variant>::arguments\n\t\t\t\t\t>...\n\t\t\t\t>\n\t\t\t>\n\t\t>;\n\n\t\tnamespace no_adl {\n\t\t\ttemplate<typename Result, typename Overload>\n\t\t\tstruct projected_result {\n\t\t\t\tOverload const& m_overload;\n\t\t\t\tconstexpr Result operator()(auto&&... args) MAYTHROW {\n\t\t\t\t\treturn tc_invoke_pack(m_overload, tc_move_if_owned(args));\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\n/*\n\ttc::fn_visit is a more flexible alternative to std::visit.\n\t\n\ttc::fn_visit(f...) returns a function that unwraps variants and passes the active alternative to the best match in the overload set f... using normal C++ rules.\n\tThe result of fn_visit(f...)(v...) is the result of the invocation g(a...), where a... are the active alternatives of v... and g the selected overload from the set f...,\n\tconverted to the common reference of decltype(f(a...))... for all combinations of alternatives in v...\n\t(i.e. tc::common_reference_prvalue_as_val, see base/type_traits_fwd.h and type_traits.t.cpp)\n```\n\tstruct A {} a;\n\tstruct B : A{} b;\n\t\n\tstd::variant<int, std::string> var = \"Hello World\";\n\tdecltype(auto) a2 = tc::fn_visit(\n\t\t[&](int) -> A const& { return a; },\n\t\t[&](const std::string& arg) -> B& { return b; }\n\t)(var);\n\tstatic_assert(std::is_same_v<decltype(a2), A const&>);\n```\n\n\tThe common type is specialized for our range library. The common type of a vector<T>& and\n\ta subrange<vector<T>&> is again a subrange<vector<T>&>:\n\n```\n\ttc::vector<int> vecn;\n\tauto rngn = tc::take(vecn, tc::end(vecn));\n\tdecltype(auto) a2 = tc::fn_visit(\n\t\t[&](int) -> tc::vector<int>& { return vecn; },\n\t\t[&](const std::string&) { return rngn; }\n\t)(var);\n\tstatic_assert(std::is_same_v<decltype(a2), tc::slice_t<tc::vector<int>&>>);\n```\n\t\n\tCurrying allows concise use with our range library avoiding additional indirections when they are not needed.\n```\n\ttc::vector<std::variant<int, double>> vecvarnf;\n\ttc::for_each(vecvarnf, tc::fn_visit(\n\t\t[](int& n) noexcept {\n\t\t\t// handle int alternative\n\t\t},\n\t\t[](double& f) noexcept {\n\t\t\t// handle double alternative\n\t\t}\n\t));\n```\n*/\n\tnamespace no_adl {\n\t\ttemplate<typename Overload>\n\t\tstruct [[nodiscard]] fn_visit_impl : private Overload {\n\t\t\tusing Overload::Overload;\n\t\t\ttemplate<typename... Variant> requires (... && tc::instance_or_derived<std::remove_reference_t<Variant>, std::variant>)\n\t\t\tconstexpr detail::visit_result_t<Overload, Variant...> operator()(Variant&&... v) const& MAYTHROW {\n\t\t\t\t([&]() noexcept { _ASSERTNORETURN( !v.valueless_by_exception() ); tc::discard(v); }(), ...);\n\t\t\t\treturn\n#ifdef TC_MAC\n\t\t\t\t\tstd::__variant_detail::__visitation::__variant::__visit_value // does not throw std::bad_variant_access, which is not supported until macOS 10.14\n#else\n\t\t\t\t\tstd::visit\n#endif\n\t\t\t\t\t(\n\t\t\t\t\t\tdetail::no_adl::projected_result<detail::visit_result_t<Overload, Variant...>, Overload>{*this},\n\t\t\t\t\t\ttc_move_if_owned(v)...\n\t\t\t\t\t);\n\t\t\t}\n\n\t\t\ttemplate<typename... T> requires (... && (!tc::instance_or_derived<std::remove_reference_t<T>, std::variant>))\n\t\t\tconstexpr decltype(auto) operator()(T&&... t) const& MAYTHROW {\n\t\t\t\treturn tc_invoke_pack(tc::base_cast<Overload>(*this), tc_move_if_owned(t));\n\t\t\t}\n\t\t};\n\t}\n\ttemplate<typename... F>\n\tconstexpr auto fn_visit(F&&... f) noexcept {\n\t\treturn no_adl::fn_visit_impl<tc::overload<F...>>(tc_move_if_owned(f)...);\n\t}\n\n\tnamespace no_adl {\n\t\ttemplate<typename Var, typename T>\n\t\tstruct variant_type_index;\n\n\t\ttemplate<typename... Ts, typename T> requires tc::mp_find_unique<std::variant<Ts...>, T>::found\n\t\tstruct variant_type_index<std::variant<Ts...>, T> final:\n\t\t\ttc::constant<tc::mp_find_unique<std::variant<Ts...>, T>::index>\n\t\t{};\n\t}\n\tusing no_adl::variant_type_index;\n\n\tnamespace explicit_convert_detail {\n\t\ttemplate<typename VarTarget, typename VarSourceNocvref, typename VarSource>\n\t\tconstexpr bool explicit_castable_between_variants_impl = false;\n\n\t\ttemplate<typename... TT, typename... TS, typename VarSource> requires (... && tc::explicit_castable_from<TT, tc::apply_cvref_t<TS, VarSource>>)\n\t\tconstexpr bool explicit_castable_between_variants_impl<std::variant<TT...>, std::variant<TS...>, VarSource> = true;\n\n\t\ttemplate<typename VarTarget, typename VarSource>\n\t\tconcept explicit_castable_between_variants=explicit_castable_between_variants_impl<VarTarget, typename tc::is_instance_or_derived<std::remove_reference_t<VarSource>, std::variant>::base_instance, VarSource>;\n\t}\n\n\tnamespace explicit_convert_adl {\n\t\ttemplate<typename TVariant, std::size_t I, typename... Args, tc::explicit_castable_from<Args...> Alternative = std::variant_alternative_t<I, TVariant>>\n\t\tconstexpr TVariant explicit_convert_impl(adl_tag_t, std::type_identity<TVariant>, std::in_place_index_t<I> tag, Args&&... args) noexcept(\n\t\t\tnoexcept(tc::explicit_cast<Alternative>(tc_move_if_owned(args)...))\n\t\t) {\n\t\t\treturn tc::with_lazy_explicit_cast<Alternative>(\n\t\t\t\t[](auto&&... args) return_ctor_MAYTHROW(TVariant, (std::in_place_index<I>, tc_move_if_owned(args)...)),\n\t\t\t\ttc_move_if_owned(args)...\n\t\t\t);\n\t\t}\n\n\t\ttemplate<typename TVariant, typename T, typename... Args>\n\t\tconstexpr auto explicit_convert_impl(adl_tag_t, std::type_identity<TVariant>, std::in_place_type_t<T>, Args&&... args) return_decltype_MAYTHROW(\n\t\t\ttc::explicit_cast<TVariant>(std::in_place_index_t<tc::variant_type_index<TVariant, T>::value>(), tc_move_if_owned(args)...)\n\t\t)\n\n\t\ttemplate<typename... TT, typename Variant> requires\ttc::explicit_convert_detail::explicit_castable_between_variants<std::variant<TT...>, Variant>\n\t\tstd::variant<TT...> explicit_convert_impl(adl_tag_t, std::type_identity<std::variant<TT...>>, Variant&& var) MAYTHROW {\n\t\t\tusing TTarget = std::variant<TT...>;\n\t\t\treturn tc::invoke_with_constant<std::make_index_sequence<sizeof...(TT)>>(\n\t\t\t\t[&](auto const nconstIndex) MAYTHROW -> TTarget {\n\t\t\t\t\treturn TTarget(std::in_place_index_t<nconstIndex()>(), tc::lazy_explicit_cast<std::variant_alternative_t<nconstIndex(), TTarget>>(tc::get<nconstIndex()>(tc_move_if_owned(var))));\n\t\t\t\t},\n\t\t\t\tvar.index()\n\t\t\t); // MAYTHROW\n\t\t}\n\t}\n\n\ttemplate<std::size_t I, typename TVariant, typename... Args>\n\tstd::variant_alternative_t<I, TVariant>& emplace(TVariant& var, Args&&... args) MAYTHROW {\n\t\tif constexpr (tc::safely_constructible_from<std::variant_alternative_t<I, TVariant>, Args&&...>) {\n\t\t\treturn var.template emplace<I>(tc_move_if_owned(args)...);\n\t\t} else {\n\t\t\treturn var.template emplace<I>(tc::lazy_explicit_cast<std::variant_alternative_t<I, TVariant>>(tc_move_if_owned(args)...));\n\t\t}\n\t}\n\n\ttemplate<typename T, typename TVariant, typename... Args>\n\tauto emplace (TVariant& var, Args&&... args) return_decltype_MAYTHROW (\n\t\ttc::emplace<tc::variant_type_index<TVariant, T>::value>(var, tc_move_if_owned(args)...)\n\t)\n}\n\nnamespace tc {\n\tnamespace no_adl {\n\t\ttemplate<typename Lhs, typename Rhs>\n\t\tstruct is_equality_comparable_with final: tc::constant<false> {};\n\n\t\ttemplate<typename Lhs, typename Rhs> requires\n\t\t\ttc::safely_convertible_to<decltype(std::declval<Lhs>()==std::declval<Rhs>()), bool> ||\n\t\t\ttc::safely_convertible_to<decltype(std::declval<Rhs>()==std::declval<Lhs>()), bool>\n\t\tstruct is_equality_comparable_with<Lhs, Rhs> final: tc::constant<true> {\n\t\t\tSTATICASSERTSAME(\n\t\t\t\tdecltype(std::declval<Lhs>()==std::declval<Rhs>()),\n\t\t\t\tdecltype(std::declval<Rhs>()==std::declval<Lhs>())\t\t\t\t\n\t\t\t);\n\t\t};\n\t}\n\tusing no_adl::is_equality_comparable_with;\n\n\tnamespace no_adl {\n\t\ttemplate<typename TVariant, typename TValue>\n\t\tstruct is_variant_equality_comparable_to_value final: tc::constant<false> {};\n\n\t\ttemplate<typename... Ts, typename TValue> requires\n\t\t\t(!tc::derived_from<TValue, std::variant<Ts...>>) &&\n\t\t\t(!tc::derived_from<TValue, std::optional<std::variant<Ts...>>>)\n\t\tstruct is_variant_equality_comparable_to_value<std::variant<Ts...>, TValue> final: \n\t\t\tboost::mp11::mp_any_of<boost::mp11::mp_list<Ts const&...>, boost::mp11::mp_bind_front<tc::is_equality_comparable_with, TValue const&>::template fn>\n\t\t{};\n\t}\n\tusing no_adl::is_variant_equality_comparable_to_value;\n}\n\nnamespace tc::variant_detail {\n\ttemplate<typename... Ts, typename TRhs> requires tc::is_variant_equality_comparable_to_value<std::variant<Ts...>, TRhs>::value\n\t[[nodiscard]] bool equal_to_impl(std::variant<Ts...> const& lhs, TRhs const& rhs) noexcept {\n\t#if 0 // TODO: subrange.h cannot be included here -> move and_then into separate header\n\t\treturn tc::and_then(\n\t\t\ttc::get_if<tc::mp_find_unique_if<boost::mp11::mp_list<Ts const&...>, boost::mp11::mp_bind_front<tc::is_equality_comparable_with, TRhs const&>::template fn>::index>(lhs),\n\t\t\t[&](auto const& t) noexcept { return t==rhs; }\n\t\t);\n\t#endif\n\t\tif (auto o = tc::get_if<tc::mp_find_unique_if<boost::mp11::mp_list<Ts const&...>, boost::mp11::mp_bind_front<tc::is_equality_comparable_with, TRhs const&>::template fn>::index>(lhs)) {\n\t\t\treturn *o==rhs;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nnamespace tc::equal_to_adl {\n\ttemplate<typename... Ts, typename TRhs>\n\tauto equal_to_impl(adl_tag_t, std::variant<Ts...> const& lhs, TRhs const& rhs) return_decltype_noexcept(\n\t\ttc::variant_detail::equal_to_impl(lhs, rhs)\n\t)\n\n\ttemplate<typename TLhs, typename... Ts>\n\tauto equal_to_impl(adl_tag_t, TLhs const& lhs, std::variant<Ts...> const& rhs) return_decltype_noexcept(\n\t\ttc::variant_detail::equal_to_impl(rhs, lhs)\n\t)\n}\n\nstatic_assert( std::is_move_constructible< std::variant<int, double, tc::string<char>> >::value );\nstatic_assert( std::is_move_assignable< std::variant<int, double, tc::string<char>> >::value );\nstatic_assert( std::is_nothrow_move_constructible< std::variant<int, double, tc::string<char>> >::value );\n\n#define tc_if_holds_else_value(var, val, type, ...) ([&](auto o) MAYTHROW -> decltype(auto) { \\\n\tauto const f=[&](auto& _) MAYTHROW -> decltype(auto) { return (__VA_ARGS__); }; \\\n\tstatic_assert( !std::is_rvalue_reference<decltype(f(*o))>::value ); \\\n\tstatic_assert( !std::is_rvalue_reference<decltype((val))>::value ); \\\n\treturn tc_conditional_prvalue_as_val(o, f(*o), TC_FWD(val)); \\\n}(tc::get_if<type>(var)))\n"
  },
  {
    "path": "tc/variant.t.cpp",
    "content": "// think-cell public library\n//\n// Copyright (C) think-cell Software GmbH\n//\n// Distributed under the Boost Software License, Version 1.0.\n// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt\n\n\n#include \"base/assert_defs.h\"\n#include \"unittest.h\"\n#include \"base/enum.h\"\n#include \"variant.h\"\n\nnamespace {\n\tTC_DEFINE_ENUM(EState, estate, (COPIEDONCE)(ONLYMOVED)(COPIEDFROM)(MOVEDFROM))\n\tstruct copy_move_tracker {\n\t\tmutable EState m_estate;\n\t\tcopy_move_tracker() : m_estate(estateONLYMOVED) {}\n\t\tcopy_move_tracker(copy_move_tracker const& tracker) noexcept\n\t\t\t: m_estate(estateCOPIEDONCE)\n\t\t{\n\t\t\tVERIFYPRED(tracker.m_estate, estateONLYMOVED == _) = estateCOPIEDFROM;\n\t\t}\n\t\tcopy_move_tracker(copy_move_tracker&& tracker) noexcept\n\t\t\t: m_estate(VERIFYPRED(tracker.m_estate, estateONLYMOVED == _ || estateCOPIEDONCE == _))\n\t\t{\n\t\t\tVERIFYPRED(tracker.m_estate, estateONLYMOVED == _ || estateCOPIEDONCE == _) = estateMOVEDFROM;\n\t\t}\n\t\tcopy_move_tracker& operator=(copy_move_tracker const& rhs) = delete;\n\t};\n\n\tstruct convert1to2_tag {};\n\tstruct copy_move_tracker1 : copy_move_tracker {};\n\tstruct copy_move_tracker2 : copy_move_tracker {\n\t\tusing copy_move_tracker::copy_move_tracker;\n\t\tcopy_move_tracker2(copy_move_tracker2 const&) noexcept = delete;\n\t\tcopy_move_tracker2(copy_move_tracker2&&) noexcept = default;\n\t\tcopy_move_tracker2(convert1to2_tag, copy_move_tracker const& tracker) noexcept : copy_move_tracker(tracker) {}\n\t\tcopy_move_tracker2(convert1to2_tag, copy_move_tracker&& tracker) noexcept : copy_move_tracker(tc_move(tracker)) {}\n\t};\n\n\tcopy_move_tracker2 explicit_convert_impl(tc::explicit_convert_adl::adl_tag_t, std::type_identity<copy_move_tracker2>, copy_move_tracker1 const& tracker) noexcept {\n\t\treturn {convert1to2_tag{}, tracker};\n\t}\n\tcopy_move_tracker2 explicit_convert_impl(tc::explicit_convert_adl::adl_tag_t, std::type_identity<copy_move_tracker2>, copy_move_tracker1&& tracker) noexcept {\n\t\treturn {convert1to2_tag{}, tc_move(tracker)};\n\t}\n\n\tUNITTESTDEF(VariantMovedByExplicitCast) { // TODO: naming\n\n\t\t// Check that explicit_cast<variant> moves the variant's internal data when possible (depending on the category of variant being passed to the function).\n\t\t// Variants cannot hold references so we don't need to test different reference types held within the source and target variants - only the type of the variant itself.\n\n\t\t{\n\t\t\tstd::variant<copy_move_tracker1, int> vars;\n\t\t\tauto vart = tc::explicit_cast<std::variant<copy_move_tracker2, double>>(vars);\n\t\t\tstatic_assert(std::is_same<decltype(vart), std::variant<copy_move_tracker2, double>>::value);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vars).m_estate, estateCOPIEDFROM);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vart).m_estate, estateCOPIEDONCE);\n\t\t}\n\n\t\t{\n\t\t\tstd::variant<copy_move_tracker1, int> vars;\n\t\t\tauto vart = tc::explicit_cast<std::variant<copy_move_tracker2, double>>(static_cast<decltype(vars) const&>(vars));\n\t\t\tstatic_assert(std::is_same<decltype(vart), std::variant<copy_move_tracker2, double>>::value);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vars).m_estate, estateCOPIEDFROM);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vart).m_estate, estateCOPIEDONCE);\n\t\t}\n\n\t\t{\n\t\t\tstd::variant<copy_move_tracker1, int> vars;\n\t\t\tauto vart = tc::explicit_cast<std::variant<copy_move_tracker2, double>>(static_cast<decltype(vars)&&>(vars));\n\t\t\tstatic_assert(std::is_same<decltype(vart), std::variant<copy_move_tracker2, double>>::value);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vars).m_estate, estateMOVEDFROM);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vart).m_estate, estateONLYMOVED);\n\t\t}\n\n\t\t{\n\t\t\tstd::variant<copy_move_tracker1, int> vars;\n\t\t\tauto vart = tc::explicit_cast<std::variant<copy_move_tracker2, double>>(static_cast<decltype(vars) const&&>(vars));\n\t\t\tstatic_assert(std::is_same<decltype(vart), std::variant<copy_move_tracker2, double>>::value);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vars).m_estate, estateCOPIEDFROM);\n\t\t\t_ASSERTEQUAL(tc::get<0>(vart).m_estate, estateCOPIEDONCE);\n\t\t}\n\t}\n}\n"
  }
]